summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Mares <mj@ucw.cz>1998-12-07 22:59:15 +0100
committerMartin Mares <mj@ucw.cz>1998-12-07 22:59:15 +0100
commit04925e9040330afc92f8001e6a19ae2146e36782 (patch)
tree66f976a8ebb63fc1e29206a345a142df59286ed5
parentcdc6bfa70f730c3741537cc21cdd0a5d13ed2af9 (diff)
downloadbird-04925e9040330afc92f8001e6a19ae2146e36782.tar
bird-04925e9040330afc92f8001e6a19ae2146e36782.zip
Minor rte/rta interface changes:
o rte can now contain a pointer to both cached and uncached rta. Protocols which don't need their own attribute caching can now just fill-in a rta, link it to rte without any calls to attribute cache and call rte_update() which will replace rte->attrs by a cached copy. o In order to support this, one of previously pad bytes in struct rta now holds new attribute flags (RTAF_CACHED). If you call rte_update() with uncached rta, you _must_ clear these flags. In other cases rta_lookup() sets it appropriately. o Added rte_free() which is useful when you construct a rte and then the circumstances change and you decide not to use it for an update. (Needed for temporary rte's in kernel syncer...)
-rw-r--r--nest/route.h4
-rw-r--r--nest/rt-attr.c3
-rw-r--r--nest/rt-table.c15
3 files changed, 20 insertions, 2 deletions
diff --git a/nest/route.h b/nest/route.h
index cfad72f..a5cc2f7 100644
--- a/nest/route.h
+++ b/nest/route.h
@@ -122,6 +122,7 @@ rte *rte_get_temp(struct rtattr *);
void rte_update(net *net, struct proto *p, rte *new);
void rte_discard(rte *old);
void rte_dump(rte *);
+void rte_free(rte *);
void rt_dump(rtable *);
void rt_dump_all(void);
void rt_feed_baby(struct proto *p);
@@ -145,6 +146,7 @@ typedef struct rtattr {
byte dest; /* Route destination type (RTD_...) */
byte tos; /* TOS of this route */
byte flags; /* Route flags (RTF_...) */
+ byte aflags; /* Attribute cache flags (RTAF_...) */
ip_addr gw; /* Next hop */
ip_addr from; /* Advertising router */
struct iface *iface; /* Outgoing interface */
@@ -180,6 +182,8 @@ typedef struct rtattr {
#define RTF_EXTERIOR 1 /* Learned via exterior protocol */
#define RTF_TAGGED 2 /* Tagged external route learned via IGP */
+#define RTAF_CACHED 1 /* This is a cached rta */
+
/*
* Extended Route Attributes
*/
diff --git a/nest/rt-attr.c b/nest/rt-attr.c
index 9f7fd2b..afce7f8 100644
--- a/nest/rt-attr.c
+++ b/nest/rt-attr.c
@@ -116,6 +116,7 @@ rta_lookup(rta *o)
if (rta_same(r, o))
return rta_clone(r);
r = rta_copy(o);
+ r->aflags = RTAF_CACHED;
r->next = first_rta;
first_rta = r;
return r;
@@ -144,6 +145,8 @@ rta_dump(rta *a)
debug(" EXT");
if (a->flags & RTF_TAGGED)
debug(" TAG");
+ if (!(a->aflags & RTAF_CACHED))
+ debug(" !CACHED");
debug(" <-%I", a->from);
if (a->dest == RTD_ROUTER)
debug(" ->%I", a->gw);
diff --git a/nest/rt-table.c b/nest/rt-table.c
index 1eb3395..386738c 100644
--- a/nest/rt-table.c
+++ b/nest/rt-table.c
@@ -136,9 +136,17 @@ rt_feed_baby(struct proto *p)
}
}
-static inline void
+void
rte_free(rte *e)
{
+ if (e->attrs->aflags & RTAF_CACHED)
+ rta_free(e->attrs);
+ sl_free(rte_slab, e);
+}
+
+static inline void
+rte_free_quick(rte *e)
+{
rta_free(e->attrs);
sl_free(rte_slab, e);
}
@@ -150,6 +158,9 @@ rte_update(net *net, struct proto *p, rte *new)
rte *old = NULL;
rte **k, *r, *s;
+ if (new && !(new->attrs->aflags & RTAF_CACHED)) /* Need to copy attributes */
+ new->attrs = rta_lookup(new->attrs);
+
k = &net->routes; /* Find and remove original route from the same protocol */
while (old = *k)
{
@@ -202,7 +213,7 @@ rte_update(net *net, struct proto *p, rte *new)
{
if (p->rte_remove)
p->rte_remove(net, old);
- rte_free(old);
+ rte_free_quick(old);
}
if (new)
{