diff --git a/filter/f-inst.c b/filter/f-inst.c index 83d86295..e2212c5b 100644 --- a/filter/f-inst.c +++ b/filter/f-inst.c @@ -737,7 +737,9 @@ l->count = 1; l->attrs[0].id = da.ea_code; l->attrs[0].flags = 0; - l->attrs[0].type = da.type | EAF_ORIGINATED | EAF_FRESH; + l->attrs[0].type = da.type; + l->attrs[0].originated = 1; + l->attrs[0].fresh = 1; switch (da.type) { case EAF_TYPE_INT: @@ -800,7 +802,9 @@ l->count = 1; l->attrs[0].id = da.ea_code; l->attrs[0].flags = 0; - l->attrs[0].type = EAF_TYPE_UNDEF | EAF_ORIGINATED | EAF_FRESH; + l->attrs[0].type = EAF_TYPE_UNDEF; + l->attrs[0].originated = 1; + l->attrs[0].fresh = 1; l->attrs[0].u.data = 0; f_rta_cow(fs); diff --git a/nest/route.h b/nest/route.h index 595acabd..9fbac898 100644 --- a/nest/route.h +++ b/nest/route.h @@ -502,7 +502,9 @@ static inline int rte_is_reachable(rte *r) typedef struct eattr { word id; /* EA_CODE(PROTOCOL_..., protocol-dependent ID) */ byte flags; /* Protocol-dependent flags */ - byte type; /* Attribute type and several flags (EAF_...) */ + byte type:5; /* Attribute type */ + byte originated:1; /* The attribute has originated locally */ + byte fresh:1; /* An uncached attribute (e.g. modified in export filter) */ union { uintptr_t data; const struct adata *ptr; /* Attribute data elsewhere */ @@ -541,8 +543,6 @@ const char *ea_custom_name(uint ea); #define EAF_TYPE_UNDEF 0x1f /* `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 0x20 /* The attribute has originated locally */ -#define EAF_FRESH 0x40 /* An uncached attribute (e.g. modified in export filter) */ typedef struct adata { uint length; /* Length of data */ diff --git a/nest/rt-attr.c b/nest/rt-attr.c index 863d411b..2f0395c7 100644 --- a/nest/rt-attr.c +++ b/nest/rt-attr.c @@ -623,7 +623,10 @@ ea_do_prune(ea_list *e) *d = *s0; /* Preserve info whether it originated locally */ - d->type = (d->type & ~(EAF_ORIGINATED|EAF_FRESH)) | (s[-1].type & EAF_ORIGINATED); + d->originated = s[-1].originated; + + /* Not fresh any more, we prefer surstroemming */ + d->fresh = 0; /* Next destination */ d++; @@ -737,6 +740,8 @@ ea_same(ea_list *x, ea_list *y) if (a->id != b->id || a->flags != b->flags || a->type != b->type || + a->originated != b->originated || + a->fresh != b->fresh || ((a->type & EAF_EMBEDDED) ? a->u.data != b->u.data : !adata_same(a->u.ptr, b->u.ptr))) return 0; } @@ -1004,7 +1009,7 @@ ea_dump(ea_list *e) eattr *a = &e->attrs[i]; debug(" %02x:%02x.%02x", EA_PROTO(a->id), EA_ID(a->id), a->flags); debug("=%c", "?iO?I?P???S?????" [a->type & EAF_TYPE_MASK]); - if (a->type & EAF_ORIGINATED) + if (a->originated) debug("o"); if (a->type & EAF_EMBEDDED) debug(":%08x", a->u.data); diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c index 76b99c41..0513dd7c 100644 --- a/proto/bgp/attrs.c +++ b/proto/bgp/attrs.c @@ -1153,7 +1153,7 @@ bgp_export_attr(struct bgp_export_state *s, eattr *a, ea_list *to) a->flags = (a->flags & BAF_PARTIAL) | desc->flags; /* Set partial bit if new opt-trans attribute is attached to non-local route */ - if ((s->src != NULL) && (a->type & EAF_ORIGINATED) && + if ((s->src != NULL) && (a->originated) && (a->flags & BAF_OPTIONAL) && (a->flags & BAF_TRANSITIVE)) a->flags |= BAF_PARTIAL; @@ -1776,7 +1776,7 @@ bgp_update_attrs(struct bgp_proto *p, struct bgp_channel *c, rte *e, ea_list *at /* MULTI_EXIT_DESC attribute - accept only if set in export filter */ a = bgp_find_attr(attrs0, BA_MULTI_EXIT_DISC); - if (a && !(a->type & EAF_FRESH)) + if (a && !(a->fresh)) bgp_unset_attr(&attrs, pool, BA_MULTI_EXIT_DISC); } diff --git a/proto/bgp/packets.c b/proto/bgp/packets.c index 66f14150..7e978919 100644 --- a/proto/bgp/packets.c +++ b/proto/bgp/packets.c @@ -1062,7 +1062,7 @@ bgp_use_next_hop(struct bgp_export_state *s, eattr *a) return 1; /* Keep it when explicitly set in export filter */ - if (a->type & EAF_FRESH) + if (a->fresh) return 1; /* Check for non-matching AF */