diff options
-rw-r--r-- | nest/route.h | 1 | ||||
-rw-r--r-- | nest/rt-attr.c | 17 |
2 files changed, 12 insertions, 6 deletions
diff --git a/nest/route.h b/nest/route.h index a7879c1..31dfa5d 100644 --- a/nest/route.h +++ b/nest/route.h @@ -298,6 +298,7 @@ typedef struct eattr { #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 (part of type spec) */ +#define EAF_ORIGINATED 0x40 /* The attribute has originated locally */ #define EAF_TEMP 0x80 /* A temporary attribute (the one stored in the tmp attr list) */ struct adata { diff --git a/nest/rt-attr.c b/nest/rt-attr.c index c16d08b..42317e9 100644 --- a/nest/rt-attr.c +++ b/nest/rt-attr.c @@ -117,7 +117,7 @@ ea_do_sort(ea_list *e) static inline void ea_do_prune(ea_list *e) { - eattr *s, *d, *l; + eattr *s, *d, *l, *s0; int i = 0; /* Discard duplicates and undefs. Do you remember sorting was stable? */ @@ -125,14 +125,17 @@ ea_do_prune(ea_list *e) l = e->attrs + e->count; while (s < l) { - if ((s->type & EAF_TYPE_MASK) != EAF_TYPE_UNDEF) + s0 = s++; + while (s < l && s->id == s[-1].id) + s++; + /* s0 is the most recent version, s[-1] the oldest one */ + if ((s0->type & EAF_TYPE_MASK) != EAF_TYPE_UNDEF) { - *d++ = *s; + *d = *s0; + d->type = (d->type & ~EAF_ORIGINATED) | (s[-1].type & EAF_ORIGINATED); + d++; i++; } - s++; - while (s < l && s->id == s[-1].id) - s++; } e->count = i; } @@ -320,6 +323,8 @@ ea_dump(ea_list *e) if (a->type & EAF_TEMP) debug("T"); debug("=%c", "?iO?I?P???S?????" [a->type & EAF_TYPE_MASK]); + if (a->type & EAF_ORIGINATED) + debug("o"); if (a->type & EAF_EMBEDDED) debug(":%08x", a->u.data); else |