From 04925e9040330afc92f8001e6a19ae2146e36782 Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Mon, 7 Dec 1998 21:59:15 +0000 Subject: [PATCH] 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...) --- nest/route.h | 4 ++++ nest/rt-attr.c | 3 +++ nest/rt-table.c | 15 +++++++++++++-- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/nest/route.h b/nest/route.h index cfad72fe..a5cc2f71 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 9f7fd2b8..afce7f81 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 1eb3395b..386738c9 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -136,8 +136,16 @@ 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) {