diff options
Diffstat (limited to 'nest')
-rw-r--r-- | nest/route.h | 4 | ||||
-rw-r--r-- | nest/rt-attr.c | 40 |
2 files changed, 33 insertions, 11 deletions
diff --git a/nest/route.h b/nest/route.h index 799e0a21..e79affbd 100644 --- a/nest/route.h +++ b/nest/route.h @@ -265,12 +265,16 @@ typedef struct eattr { #define EA_PROTO(ea) ((ea) >> 8) #define EA_ID(ea) ((ea) & 0xff) +#define EA_CODE_MASK 0xffff +#define EA_ALLOW_UNDEF 0x10000 /* ea_find: allow EAF_TYPE_UNDEF */ + #define EAF_TYPE_MASK 0x0f /* Mask with this to get type */ #define EAF_TYPE_INT 0x01 /* 32-bit signed integer number */ #define EAF_TYPE_OPAQUE 0x02 /* Opaque byte string (not filterable) */ #define EAF_TYPE_IP_ADDRESS 0x04 /* IP address [FIXME: embed at least for IPv4?] */ #define EAF_TYPE_AS_PATH 0x06 /* BGP AS path [FIXME: define storage layout] */ #define EAF_TYPE_INT_SET 0x0a /* Set of integers (e.g., a community list) */ +#define EAF_TYPE_UNDEF 0x0f /* `force undefined' entry */ #define EAF_EMBEDDED 0x01 /* Data stored in eattr.u.data (part of type spec) */ #define EAF_VAR_LENGTH 0x02 /* Attribute length is variable */ #define EAF_INLINE 0x80 /* Copy of an attribute inlined in rte (temporary ea_lists only) */ diff --git a/nest/rt-attr.c b/nest/rt-attr.c index ca6cb101..2c50f4d2 100644 --- a/nest/rt-attr.c +++ b/nest/rt-attr.c @@ -27,8 +27,8 @@ static pool *rta_pool; * Extended Attributes */ -eattr * -ea_find(ea_list *e, unsigned id) +static inline eattr * +ea__find(ea_list *e, unsigned id) { eattr *a; int l, r, m; @@ -60,6 +60,17 @@ ea_find(ea_list *e, unsigned id) return NULL; } +eattr * +ea_find(ea_list *e, unsigned id) +{ + eattr *a = ea__find(e, id & EA_CODE_MASK); + + if (a && (a->type & EAF_TYPE_MASK) == EAF_TYPE_UNDEF && + !(id & EA_ALLOW_UNDEF)) + return NULL; + return a; +} + static inline void ea_do_sort(ea_list *e) { @@ -107,17 +118,24 @@ ea_do_sort(ea_list *e) static inline void ea_do_prune(ea_list *e) { - eattr *s, *d; - int i; + eattr *s, *d, *l; + int i = 0; - /* Discard duplicates. Do you remember sorting was stable? */ - s = d = e->attrs + 1; - for(i=1; i<e->count; i++) - if (s->id != d[-1].id) - *d++ = *s++; - else + /* Discard duplicates and undefs. Do you remember sorting was stable? */ + s = d = e->attrs; + l = e->attrs + e->count; + while (s < l) + { + if ((s->type & EAF_TYPE_MASK) != EAF_TYPE_UNDEF) + { + *d++ = *s; + i++; + } s++; - e->count = d - e->attrs; + while (s < l && s->id == s[-1].id) + s++; + } + e->count = i; } void |