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...)
This commit is contained in:
Martin Mares 1998-12-07 21:59:15 +00:00
parent cdc6bfa70f
commit 04925e9040
3 changed files with 20 additions and 2 deletions

View file

@ -122,6 +122,7 @@ rte *rte_get_temp(struct rtattr *);
void rte_update(net *net, struct proto *p, rte *new); void rte_update(net *net, struct proto *p, rte *new);
void rte_discard(rte *old); void rte_discard(rte *old);
void rte_dump(rte *); void rte_dump(rte *);
void rte_free(rte *);
void rt_dump(rtable *); void rt_dump(rtable *);
void rt_dump_all(void); void rt_dump_all(void);
void rt_feed_baby(struct proto *p); void rt_feed_baby(struct proto *p);
@ -145,6 +146,7 @@ typedef struct rtattr {
byte dest; /* Route destination type (RTD_...) */ byte dest; /* Route destination type (RTD_...) */
byte tos; /* TOS of this route */ byte tos; /* TOS of this route */
byte flags; /* Route flags (RTF_...) */ byte flags; /* Route flags (RTF_...) */
byte aflags; /* Attribute cache flags (RTAF_...) */
ip_addr gw; /* Next hop */ ip_addr gw; /* Next hop */
ip_addr from; /* Advertising router */ ip_addr from; /* Advertising router */
struct iface *iface; /* Outgoing interface */ struct iface *iface; /* Outgoing interface */
@ -180,6 +182,8 @@ typedef struct rtattr {
#define RTF_EXTERIOR 1 /* Learned via exterior protocol */ #define RTF_EXTERIOR 1 /* Learned via exterior protocol */
#define RTF_TAGGED 2 /* Tagged external route learned via IGP */ #define RTF_TAGGED 2 /* Tagged external route learned via IGP */
#define RTAF_CACHED 1 /* This is a cached rta */
/* /*
* Extended Route Attributes * Extended Route Attributes
*/ */

View file

@ -116,6 +116,7 @@ rta_lookup(rta *o)
if (rta_same(r, o)) if (rta_same(r, o))
return rta_clone(r); return rta_clone(r);
r = rta_copy(o); r = rta_copy(o);
r->aflags = RTAF_CACHED;
r->next = first_rta; r->next = first_rta;
first_rta = r; first_rta = r;
return r; return r;
@ -144,6 +145,8 @@ rta_dump(rta *a)
debug(" EXT"); debug(" EXT");
if (a->flags & RTF_TAGGED) if (a->flags & RTF_TAGGED)
debug(" TAG"); debug(" TAG");
if (!(a->aflags & RTAF_CACHED))
debug(" !CACHED");
debug(" <-%I", a->from); debug(" <-%I", a->from);
if (a->dest == RTD_ROUTER) if (a->dest == RTD_ROUTER)
debug(" ->%I", a->gw); debug(" ->%I", a->gw);

View file

@ -136,8 +136,16 @@ rt_feed_baby(struct proto *p)
} }
} }
static inline void void
rte_free(rte *e) 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); rta_free(e->attrs);
sl_free(rte_slab, e); sl_free(rte_slab, e);
@ -150,6 +158,9 @@ rte_update(net *net, struct proto *p, rte *new)
rte *old = NULL; rte *old = NULL;
rte **k, *r, *s; 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 */ k = &net->routes; /* Find and remove original route from the same protocol */
while (old = *k) while (old = *k)
{ {
@ -202,7 +213,7 @@ rte_update(net *net, struct proto *p, rte *new)
{ {
if (p->rte_remove) if (p->rte_remove)
p->rte_remove(net, old); p->rte_remove(net, old);
rte_free(old); rte_free_quick(old);
} }
if (new) if (new)
{ {