0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-11-18 09:08:42 +00:00

Merge commit 'ef4313e1667a8745c8d8813ac78342ec7c035895' into haugesund

This commit is contained in:
Maria Matejka 2022-05-30 16:47:30 +02:00
commit d7bec897ab
5 changed files with 103 additions and 112 deletions

View File

@ -739,7 +739,7 @@
ACCESS_EATTRS; ACCESS_EATTRS;
f_rta_cow(fs); f_rta_cow(fs);
ea_unset_attr(fs->eattrs, tmp_linpool, 1, da.ea_code); ea_unset_attr(fs->eattrs, 1, da.ea_code);
} }
INST(FI_LENGTH, 1, 1) { /* Get length of */ INST(FI_LENGTH, 1, 1) { /* Get length of */

View File

@ -222,58 +222,48 @@ struct ea_one_attr_list {
eattr a; eattr a;
}; };
#define EA_LITERAL_EMBEDDED(_id, _type, _flags, _val) ({ \
ASSERT_DIE(_type & EAF_EMBEDDED); \
EA_LITERAL_GENERIC(_id, _type, _flags, .u.i = _val); \
})
#define EA_LITERAL_ADATA(_id, _type, _flags, _buf, _len) ({ \
ASSERT_DIE(!(_type & EAF_EMBEDDED)); \
EA_LITERAL_GENERIC(_id, _type, _flags, .u.ad = tmp_store_adata(_buf, _len)); \
})
#define EA_LITERAL_GENERIC(_id, _type, _flags, ...) \
((eattr) { .id = _id, .type = _type, .flags = _flags, __VA_ARGS__ })
static inline eattr * static inline eattr *
ea_set_attr(ea_list **to, struct linpool *pool, uint id, uint flags, uint type, union bval val) ea_set_attr(ea_list **to, eattr a)
{ {
struct ea_one_attr_list *ea = lp_alloc(pool, sizeof(*ea)); struct ea_one_attr_list *ea = tmp_alloc(sizeof(*ea));
*ea = (struct ea_one_attr_list) { *ea = (struct ea_one_attr_list) {
.l.flags = EALF_SORTED, .l.flags = EALF_SORTED,
.l.count = 1, .l.count = 1,
.l.next = *to, .l.next = *to,
.a = a,
.a.id = id,
.a.type = type,
.a.flags = flags,
}; };
ea->a.u = val;
*to = &ea->l; *to = &ea->l;
return &ea->a; return &ea->a;
} }
static inline void static inline void
ea_unset_attr(ea_list **to, struct linpool *pool, _Bool local, uint code) ea_unset_attr(ea_list **to, _Bool local, uint code)
{ {
struct ea_one_attr_list *ea = lp_alloc(pool, sizeof(*ea)); ea_set_attr(to, EA_LITERAL_GENERIC(code, 0, 0,
*ea = (struct ea_one_attr_list) { .fresh = local, .originated = local, .undef = 1));
.l.flags = EALF_SORTED,
.l.count = 1,
.l.next = *to,
.a.id = code,
.a.fresh = local,
.a.originated = local,
.a.undef = 1,
};
*to = &ea->l;
} }
static inline void static inline void
ea_set_attr_u32(ea_list **to, struct linpool *pool, uint id, uint flags, uint type, u32 data) ea_set_attr_u32(ea_list **to, uint id, uint flags, uint type, u32 data)
{ { ea_set_attr(to, EA_LITERAL_EMBEDDED(id, type, flags, data)); }
union bval bv = { .data = data };
ea_set_attr(to, pool, id, flags, type, bv);
}
static inline void static inline void
ea_set_attr_data(ea_list **to, struct linpool *pool, uint id, uint flags, uint type, void *data, uint len) ea_set_attr_data(ea_list **to, uint id, uint flags, uint type, void *data, uint len)
{ { ea_set_attr(to, EA_LITERAL_ADATA(id, type, flags, data, len)); }
struct adata *a = lp_alloc_adata(pool, len);
memcpy(a->data, data, len);
union bval bv = { .ptr = a, };
ea_set_attr(to, pool, id, flags, type, bv);
}
#define NEXTHOP_MAX_SIZE (sizeof(struct nexthop) + sizeof(u32)*MPLS_MAX_LABEL_STACK) #define NEXTHOP_MAX_SIZE (sizeof(struct nexthop) + sizeof(u32)*MPLS_MAX_LABEL_STACK)

View File

@ -79,22 +79,44 @@ static const struct bgp_attr_desc bgp_attr_table[];
static inline int bgp_attr_known(uint code); static inline int bgp_attr_known(uint code);
eattr * void bgp_set_attr_u32(ea_list **to, uint code, uint flags, u32 val)
bgp_set_attr(ea_list **attrs, struct linpool *pool, uint code, uint flags, union bval val)
{ {
ASSERT(bgp_attr_known(code)); ASSERT(bgp_attr_known(code));
return ea_set_attr( ea_set_attr(to, EA_LITERAL_EMBEDDED(
attrs, EA_CODE(PROTOCOL_BGP, code),
pool, bgp_attr_table[code].type,
EA_CODE(PROTOCOL_BGP, code), flags & ~BAF_EXT_LEN,
flags & ~BAF_EXT_LEN, val
bgp_attr_table[code].type, ));
val
);
} }
void bgp_set_attr_ptr(ea_list **to, uint code, uint flags, const struct adata *ad)
{
ASSERT(bgp_attr_known(code));
ASSERT_DIE(!(bgp_attr_table[code].type & EAF_EMBEDDED));
ea_set_attr(to, EA_LITERAL_GENERIC(
EA_CODE(PROTOCOL_BGP, code),
bgp_attr_table[code].type,
flags & ~BAF_EXT_LEN,
.u.ad = ad
));
}
void
bgp_set_attr_data(ea_list **to, uint code, uint flags, void *data, uint len)
{
ASSERT(bgp_attr_known(code));
ea_set_attr(to, EA_LITERAL_ADATA(
EA_CODE(PROTOCOL_BGP, code),
bgp_attr_table[code].type,
flags & ~BAF_EXT_LEN,
data,
len
));
}
#define REPORT(msg, args...) \ #define REPORT(msg, args...) \
({ log(L_REMOTE "%s: " msg, s->proto->p.name, ## args); }) ({ log(L_REMOTE "%s: " msg, s->proto->p.name, ## args); })
@ -402,7 +424,7 @@ bgp_decode_origin(struct bgp_parse_state *s, uint code UNUSED, uint flags, byte
if (data[0] > 2) if (data[0] > 2)
WITHDRAW(BAD_VALUE, "ORIGIN", data[0]); WITHDRAW(BAD_VALUE, "ORIGIN", data[0]);
bgp_set_attr_u32(to, s->pool, BA_ORIGIN, flags, data[0]); bgp_set_attr_u32(to, BA_ORIGIN, flags, data[0]);
} }
static void static void
@ -470,7 +492,7 @@ bgp_decode_as_path(struct bgp_parse_state *s, uint code UNUSED, uint flags, byte
!bgp_as_path_first_as_equal(data, len, p->remote_as)) !bgp_as_path_first_as_equal(data, len, p->remote_as))
WITHDRAW("Malformed AS_PATH attribute - %s", "First AS differs from neigbor AS"); WITHDRAW("Malformed AS_PATH attribute - %s", "First AS differs from neigbor AS");
bgp_set_attr_data(to, s->pool, BA_AS_PATH, flags, data, len); bgp_set_attr_data(to, BA_AS_PATH, flags, data, len);
} }
@ -542,7 +564,7 @@ bgp_decode_med(struct bgp_parse_state *s, uint code UNUSED, uint flags, byte *da
WITHDRAW(BAD_LENGTH, "MULTI_EXIT_DISC", len); WITHDRAW(BAD_LENGTH, "MULTI_EXIT_DISC", len);
u32 val = get_u32(data); u32 val = get_u32(data);
bgp_set_attr_u32(to, s->pool, BA_MULTI_EXIT_DISC, flags, val); bgp_set_attr_u32(to, BA_MULTI_EXIT_DISC, flags, val);
} }
@ -563,7 +585,7 @@ bgp_decode_local_pref(struct bgp_parse_state *s, uint code UNUSED, uint flags, b
WITHDRAW(BAD_LENGTH, "LOCAL_PREF", len); WITHDRAW(BAD_LENGTH, "LOCAL_PREF", len);
u32 val = get_u32(data); u32 val = get_u32(data);
bgp_set_attr_u32(to, s->pool, BA_LOCAL_PREF, flags, val); bgp_set_attr_u32(to, BA_LOCAL_PREF, flags, val);
} }
@ -573,7 +595,7 @@ bgp_decode_atomic_aggr(struct bgp_parse_state *s, uint code UNUSED, uint flags,
if (len != 0) if (len != 0)
DISCARD(BAD_LENGTH, "ATOMIC_AGGR", len); DISCARD(BAD_LENGTH, "ATOMIC_AGGR", len);
bgp_set_attr_data(to, s->pool, BA_ATOMIC_AGGR, flags, NULL, 0); bgp_set_attr_data(to, BA_ATOMIC_AGGR, flags, NULL, 0);
} }
static int static int
@ -607,7 +629,7 @@ bgp_decode_aggregator(struct bgp_parse_state *s, uint code UNUSED, uint flags, b
len = aggregator_16to32(data, src); len = aggregator_16to32(data, src);
} }
bgp_set_attr_data(to, s->pool, BA_AGGREGATOR, flags, data, len); bgp_set_attr_data(to, BA_AGGREGATOR, flags, data, len);
} }
static void static void
@ -636,7 +658,7 @@ bgp_decode_community(struct bgp_parse_state *s, uint code UNUSED, uint flags, by
struct adata *ad = lp_alloc_adata(s->pool, len); struct adata *ad = lp_alloc_adata(s->pool, len);
get_u32s(data, (u32 *) ad->data, len / 4); get_u32s(data, (u32 *) ad->data, len / 4);
bgp_set_attr_ptr(to, s->pool, BA_COMMUNITY, flags, ad); bgp_set_attr_ptr(to, BA_COMMUNITY, flags, ad);
} }
@ -657,7 +679,7 @@ bgp_decode_originator_id(struct bgp_parse_state *s, uint code UNUSED, uint flags
WITHDRAW(BAD_LENGTH, "ORIGINATOR_ID", len); WITHDRAW(BAD_LENGTH, "ORIGINATOR_ID", len);
u32 val = get_u32(data); u32 val = get_u32(data);
bgp_set_attr_u32(to, s->pool, BA_ORIGINATOR_ID, flags, val); bgp_set_attr_u32(to, BA_ORIGINATOR_ID, flags, val);
} }
@ -682,7 +704,7 @@ bgp_decode_cluster_list(struct bgp_parse_state *s, uint code UNUSED, uint flags,
struct adata *ad = lp_alloc_adata(s->pool, len); struct adata *ad = lp_alloc_adata(s->pool, len);
get_u32s(data, (u32 *) ad->data, len / 4); get_u32s(data, (u32 *) ad->data, len / 4);
bgp_set_attr_ptr(to, s->pool, BA_CLUSTER_LIST, flags, ad); bgp_set_attr_ptr(to, BA_CLUSTER_LIST, flags, ad);
} }
static void static void
@ -801,7 +823,7 @@ bgp_decode_ext_community(struct bgp_parse_state *s, uint code UNUSED, uint flags
struct adata *ad = lp_alloc_adata(s->pool, len); struct adata *ad = lp_alloc_adata(s->pool, len);
get_u32s(data, (u32 *) ad->data, len / 4); get_u32s(data, (u32 *) ad->data, len / 4);
bgp_set_attr_ptr(to, s->pool, BA_EXT_COMMUNITY, flags, ad); bgp_set_attr_ptr(to, BA_EXT_COMMUNITY, flags, ad);
} }
@ -814,7 +836,7 @@ bgp_decode_as4_aggregator(struct bgp_parse_state *s, uint code UNUSED, uint flag
if (len != 8) if (len != 8)
DISCARD(BAD_LENGTH, "AS4_AGGREGATOR", len); DISCARD(BAD_LENGTH, "AS4_AGGREGATOR", len);
bgp_set_attr_data(to, s->pool, BA_AS4_AGGREGATOR, flags, data, len); bgp_set_attr_data(to, BA_AS4_AGGREGATOR, flags, data, len);
} }
static void static void
@ -844,7 +866,7 @@ bgp_decode_as4_path(struct bgp_parse_state *s, uint code UNUSED, uint flags, byt
a = as_path_strip_confed(s->pool, a); a = as_path_strip_confed(s->pool, a);
} }
bgp_set_attr_ptr(to, s->pool, BA_AS4_PATH, flags, a); bgp_set_attr_ptr(to, BA_AS4_PATH, flags, a);
} }
@ -868,7 +890,7 @@ bgp_decode_aigp(struct bgp_parse_state *s, uint code UNUSED, uint flags, byte *d
if (!bgp_aigp_valid(data, len, err, sizeof(err))) if (!bgp_aigp_valid(data, len, err, sizeof(err)))
DISCARD("Malformed AIGP attribute - %s", err); DISCARD("Malformed AIGP attribute - %s", err);
bgp_set_attr_data(to, s->pool, BA_AIGP, flags, data, len); bgp_set_attr_data(to, BA_AIGP, flags, data, len);
} }
static void static void
@ -900,7 +922,7 @@ bgp_decode_large_community(struct bgp_parse_state *s, uint code UNUSED, uint fla
struct adata *ad = lp_alloc_adata(s->pool, len); struct adata *ad = lp_alloc_adata(s->pool, len);
get_u32s(data, (u32 *) ad->data, len / 4); get_u32s(data, (u32 *) ad->data, len / 4);
bgp_set_attr_ptr(to, s->pool, BA_LARGE_COMMUNITY, flags, ad); bgp_set_attr_ptr(to, BA_LARGE_COMMUNITY, flags, ad);
} }
static void static void
@ -973,10 +995,10 @@ bgp_format_mpls_label_stack(const eattr *a, byte *buf, uint size)
} }
static inline void static inline void
bgp_decode_unknown(struct bgp_parse_state *s, uint code, uint flags, byte *data, uint len, ea_list **to) bgp_decode_unknown(struct bgp_parse_state *s UNUSED, uint code, uint flags, byte *data, uint len, ea_list **to)
{ {
/* Cannot use bgp_set_attr_data() as it works on known attributes only */ /* Cannot use bgp_set_attr_data() as it works on known attributes only */
ea_set_attr_data(to, s->pool, EA_CODE(PROTOCOL_BGP, code), flags, T_OPAQUE, data, len); ea_set_attr_data(to, EA_CODE(PROTOCOL_BGP, code), flags, T_OPAQUE, data, len);
} }
@ -1419,7 +1441,7 @@ bgp_decode_attrs(struct bgp_parse_state *s, byte *data, uint len)
/* If there is no local preference, define one */ /* If there is no local preference, define one */
if (!BIT32_TEST(s->attrs_seen, BA_LOCAL_PREF)) if (!BIT32_TEST(s->attrs_seen, BA_LOCAL_PREF))
bgp_set_attr_u32(&attrs, s->pool, BA_LOCAL_PREF, 0, p->cf->default_local_pref); bgp_set_attr_u32(&attrs, BA_LOCAL_PREF, 0, p->cf->default_local_pref);
return attrs; return attrs;
@ -1449,7 +1471,7 @@ bgp_finish_attrs(struct bgp_parse_state *s, rta *a)
if (BIT32_TEST(s->attrs_seen, BA_AIGP) && !s->channel->cf->aigp) if (BIT32_TEST(s->attrs_seen, BA_AIGP) && !s->channel->cf->aigp)
{ {
REPORT("Discarding AIGP attribute received on non-AIGP session"); REPORT("Discarding AIGP attribute received on non-AIGP session");
bgp_unset_attr(&a->eattrs, s->pool, BA_AIGP); bgp_unset_attr(&a->eattrs, BA_AIGP);
} }
} }
@ -1719,7 +1741,7 @@ bgp_update_attrs(struct bgp_proto *p, struct bgp_channel *c, rte *e, ea_list *at
/* ORIGIN attribute - mandatory, attach if missing */ /* ORIGIN attribute - mandatory, attach if missing */
if (! bgp_find_attr(attrs0, BA_ORIGIN)) if (! bgp_find_attr(attrs0, BA_ORIGIN))
bgp_set_attr_u32(&attrs, pool, BA_ORIGIN, 0, src ? ORIGIN_INCOMPLETE : ORIGIN_IGP); bgp_set_attr_u32(&attrs, BA_ORIGIN, 0, src ? ORIGIN_INCOMPLETE : ORIGIN_IGP);
/* AS_PATH attribute - mandatory */ /* AS_PATH attribute - mandatory */
a = bgp_find_attr(attrs0, BA_AS_PATH); a = bgp_find_attr(attrs0, BA_AS_PATH);
@ -1734,24 +1756,24 @@ bgp_update_attrs(struct bgp_proto *p, struct bgp_channel *c, rte *e, ea_list *at
{ {
/* IBGP or route server -> just ensure there is one */ /* IBGP or route server -> just ensure there is one */
if (!a) if (!a)
bgp_set_attr_ptr(&attrs, pool, BA_AS_PATH, 0, &null_adata); bgp_set_attr_ptr(&attrs, BA_AS_PATH, 0, &null_adata);
} }
else if (p->is_interior) else if (p->is_interior)
{ {
/* Confederation -> prepend ASN as AS_CONFED_SEQUENCE */ /* Confederation -> prepend ASN as AS_CONFED_SEQUENCE */
ad = as_path_prepend2(pool, ad, AS_PATH_CONFED_SEQUENCE, p->public_as); ad = as_path_prepend2(pool, ad, AS_PATH_CONFED_SEQUENCE, p->public_as);
bgp_set_attr_ptr(&attrs, pool, BA_AS_PATH, 0, ad); bgp_set_attr_ptr(&attrs, BA_AS_PATH, 0, ad);
} }
else /* Regular EBGP (no RS, no confederation) */ else /* Regular EBGP (no RS, no confederation) */
{ {
/* Regular EBGP -> prepend ASN as regular sequence */ /* Regular EBGP -> prepend ASN as regular sequence */
ad = as_path_prepend2(pool, ad, AS_PATH_SEQUENCE, p->public_as); ad = as_path_prepend2(pool, ad, AS_PATH_SEQUENCE, p->public_as);
bgp_set_attr_ptr(&attrs, pool, BA_AS_PATH, 0, ad); bgp_set_attr_ptr(&attrs, BA_AS_PATH, 0, ad);
/* MULTI_EXIT_DESC attribute - accept only if set in export filter */ /* MULTI_EXIT_DESC attribute - accept only if set in export filter */
a = bgp_find_attr(attrs0, BA_MULTI_EXIT_DISC); a = bgp_find_attr(attrs0, BA_MULTI_EXIT_DISC);
if (a && !(a->fresh)) if (a && !(a->fresh))
bgp_unset_attr(&attrs, pool, BA_MULTI_EXIT_DISC); bgp_unset_attr(&attrs, BA_MULTI_EXIT_DISC);
} }
/* NEXT_HOP attribute - delegated to AF-specific hook */ /* NEXT_HOP attribute - delegated to AF-specific hook */
@ -1760,7 +1782,7 @@ bgp_update_attrs(struct bgp_proto *p, struct bgp_channel *c, rte *e, ea_list *at
/* LOCAL_PREF attribute - required for IBGP, attach if missing */ /* LOCAL_PREF attribute - required for IBGP, attach if missing */
if (p->is_interior && ! bgp_find_attr(attrs0, BA_LOCAL_PREF)) if (p->is_interior && ! bgp_find_attr(attrs0, BA_LOCAL_PREF))
bgp_set_attr_u32(&attrs, pool, BA_LOCAL_PREF, 0, p->cf->default_local_pref); bgp_set_attr_u32(&attrs, BA_LOCAL_PREF, 0, p->cf->default_local_pref);
/* AIGP attribute - accumulate local metric or originate new one */ /* AIGP attribute - accumulate local metric or originate new one */
u64 metric; u64 metric;
@ -1769,7 +1791,7 @@ bgp_update_attrs(struct bgp_proto *p, struct bgp_channel *c, rte *e, ea_list *at
(c->cf->aigp_originate && bgp_init_aigp_metric(e, &metric, &ad)))) (c->cf->aigp_originate && bgp_init_aigp_metric(e, &metric, &ad))))
{ {
ad = bgp_aigp_set_metric(pool, ad, metric); ad = bgp_aigp_set_metric(pool, ad, metric);
bgp_set_attr_ptr(&attrs, pool, BA_AIGP, 0, ad); bgp_set_attr_ptr(&attrs, BA_AIGP, 0, ad);
} }
/* IBGP route reflection, RFC 4456 */ /* IBGP route reflection, RFC 4456 */
@ -1777,7 +1799,7 @@ bgp_update_attrs(struct bgp_proto *p, struct bgp_channel *c, rte *e, ea_list *at
{ {
/* ORIGINATOR_ID attribute - attach if not already set */ /* ORIGINATOR_ID attribute - attach if not already set */
if (! bgp_find_attr(attrs0, BA_ORIGINATOR_ID)) if (! bgp_find_attr(attrs0, BA_ORIGINATOR_ID))
bgp_set_attr_u32(&attrs, pool, BA_ORIGINATOR_ID, 0, src->remote_id); bgp_set_attr_u32(&attrs, BA_ORIGINATOR_ID, 0, src->remote_id);
/* CLUSTER_LIST attribute - prepend cluster ID */ /* CLUSTER_LIST attribute - prepend cluster ID */
a = bgp_find_attr(attrs0, BA_CLUSTER_LIST); a = bgp_find_attr(attrs0, BA_CLUSTER_LIST);
@ -1792,7 +1814,7 @@ bgp_update_attrs(struct bgp_proto *p, struct bgp_channel *c, rte *e, ea_list *at
ad = int_set_prepend(pool, ad, p->rr_cluster_id); ad = int_set_prepend(pool, ad, p->rr_cluster_id);
/* Should be at least one prepended cluster ID */ /* Should be at least one prepended cluster ID */
bgp_set_attr_ptr(&attrs, pool, BA_CLUSTER_LIST, 0, ad); bgp_set_attr_ptr(&attrs, BA_CLUSTER_LIST, 0, ad);
} }
/* AS4_* transition attributes, RFC 6793 4.2.2 */ /* AS4_* transition attributes, RFC 6793 4.2.2 */
@ -1801,15 +1823,15 @@ bgp_update_attrs(struct bgp_proto *p, struct bgp_channel *c, rte *e, ea_list *at
a = bgp_find_attr(attrs, BA_AS_PATH); a = bgp_find_attr(attrs, BA_AS_PATH);
if (a && as_path_contains_as4(a->u.ptr)) if (a && as_path_contains_as4(a->u.ptr))
{ {
bgp_set_attr_ptr(&attrs, pool, BA_AS_PATH, 0, as_path_to_old(pool, a->u.ptr)); bgp_set_attr_ptr(&attrs, BA_AS_PATH, 0, as_path_to_old(pool, a->u.ptr));
bgp_set_attr_ptr(&attrs, pool, BA_AS4_PATH, 0, as_path_strip_confed(pool, a->u.ptr)); bgp_set_attr_ptr(&attrs, BA_AS4_PATH, 0, as_path_strip_confed(pool, a->u.ptr));
} }
a = bgp_find_attr(attrs, BA_AGGREGATOR); a = bgp_find_attr(attrs, BA_AGGREGATOR);
if (a && aggregator_contains_as4(a->u.ptr)) if (a && aggregator_contains_as4(a->u.ptr))
{ {
bgp_set_attr_ptr(&attrs, pool, BA_AGGREGATOR, 0, aggregator_to_old(pool, a->u.ptr)); bgp_set_attr_ptr(&attrs, BA_AGGREGATOR, 0, aggregator_to_old(pool, a->u.ptr));
bgp_set_attr_ptr(&attrs, pool, BA_AS4_AGGREGATOR, 0, a->u.ptr); bgp_set_attr_ptr(&attrs, BA_AS4_AGGREGATOR, 0, a->u.ptr);
} }
} }
@ -2276,7 +2298,7 @@ bgp_rte_modify_stale(struct rte *r, struct linpool *pool)
e0 = *r; e0 = *r;
e0.attrs = a; e0.attrs = a;
bgp_set_attr_ptr(&(a->eattrs), pool, BA_COMMUNITY, flags, bgp_set_attr_ptr(&(a->eattrs), BA_COMMUNITY, flags,
int_set_add(pool, ad, BGP_COMM_LLGR_STALE)); int_set_add(pool, ad, BGP_COMM_LLGR_STALE));
e0.pflags |= BGP_REF_STALE; e0.pflags |= BGP_REF_STALE;
@ -2296,8 +2318,8 @@ bgp_process_as4_attrs(ea_list **attrs, struct linpool *pool)
eattr *a4 = bgp_find_attr(*attrs, BA_AS4_AGGREGATOR); eattr *a4 = bgp_find_attr(*attrs, BA_AS4_AGGREGATOR);
/* First, unset AS4_* attributes */ /* First, unset AS4_* attributes */
if (p4) bgp_unset_attr(attrs, pool, BA_AS4_PATH); if (p4) bgp_unset_attr(attrs, BA_AS4_PATH);
if (a4) bgp_unset_attr(attrs, pool, BA_AS4_AGGREGATOR); if (a4) bgp_unset_attr(attrs, BA_AS4_AGGREGATOR);
/* Handle AGGREGATOR attribute */ /* Handle AGGREGATOR attribute */
if (a2 && a4) if (a2 && a4)

View File

@ -544,32 +544,11 @@ bgp_find_attr(ea_list *attrs, uint code)
return ea_find(attrs, EA_CODE(PROTOCOL_BGP, code)); return ea_find(attrs, EA_CODE(PROTOCOL_BGP, code));
} }
eattr * void bgp_set_attr_u32(ea_list **to, uint code, uint flags, u32 val);
bgp_set_attr(ea_list **attrs, struct linpool *pool, uint code, uint flags, union bval val); void bgp_set_attr_ptr(ea_list **to, uint code, uint flags, const struct adata *ad);
void bgp_set_attr_data(ea_list **to, uint code, uint flags, void *data, uint len);
static inline void #define bgp_unset_attr(to, code) ea_unset_attr(to, 0, code)
bgp_set_attr_u32(ea_list **to, struct linpool *pool, uint code, uint flags, u32 val)
{
union bval bv = { .data = val };
bgp_set_attr(to, pool, code, flags, bv);
}
static inline void
bgp_set_attr_ptr(ea_list **to, struct linpool *pool, uint code, uint flags, const struct adata *ad)
{
union bval bv = { .ptr = ad };
bgp_set_attr(to, pool, code, flags, bv);
}
static inline void
bgp_set_attr_data(ea_list **to, struct linpool *pool, uint code, uint flags, void *data, uint len)
{
struct adata *a = lp_alloc_adata(pool, len);
bmemcpy(a->data, data, len);
bgp_set_attr_ptr(to, pool, code, flags, a);
}
#define bgp_unset_attr(to, pool, code) ea_unset_attr(to, pool, 0, code)
int bgp_encode_mp_reach_mrt(struct bgp_write_state *s, eattr *a, byte *buf, uint size); int bgp_encode_mp_reach_mrt(struct bgp_write_state *s, eattr *a, byte *buf, uint size);

View File

@ -1115,27 +1115,27 @@ bgp_update_next_hop_ip(struct bgp_export_state *s, eattr *a, ea_list **to)
{ {
rta *ra = s->route->attrs; rta *ra = s->route->attrs;
ip_addr nh[1] = { ra->nh.gw }; ip_addr nh[1] = { ra->nh.gw };
bgp_set_attr_data(to, s->pool, BA_NEXT_HOP, 0, nh, 16); bgp_set_attr_data(to, BA_NEXT_HOP, 0, nh, 16);
if (s->mpls) if (s->mpls)
{ {
u32 implicit_null = BGP_MPLS_NULL; u32 implicit_null = BGP_MPLS_NULL;
u32 *labels = ra->nh.labels ? ra->nh.label : &implicit_null; u32 *labels = ra->nh.labels ? ra->nh.label : &implicit_null;
uint lnum = ra->nh.labels ? ra->nh.labels : 1; uint lnum = ra->nh.labels ? ra->nh.labels : 1;
bgp_set_attr_data(to, s->pool, BA_MPLS_LABEL_STACK, 0, labels, lnum * 4); bgp_set_attr_data(to, BA_MPLS_LABEL_STACK, 0, labels, lnum * 4);
} }
} }
else else
{ {
ip_addr nh[2] = { s->channel->next_hop_addr, s->channel->link_addr }; ip_addr nh[2] = { s->channel->next_hop_addr, s->channel->link_addr };
bgp_set_attr_data(to, s->pool, BA_NEXT_HOP, 0, nh, ipa_nonzero(nh[1]) ? 32 : 16); bgp_set_attr_data(to, BA_NEXT_HOP, 0, nh, ipa_nonzero(nh[1]) ? 32 : 16);
s->local_next_hop = 1; s->local_next_hop = 1;
/* TODO: Use local MPLS assigned label */ /* TODO: Use local MPLS assigned label */
if (s->mpls) if (s->mpls)
{ {
u32 implicit_null = BGP_MPLS_NULL; u32 implicit_null = BGP_MPLS_NULL;
bgp_set_attr_data(to, s->pool, BA_MPLS_LABEL_STACK, 0, &implicit_null, 4); bgp_set_attr_data(to, BA_MPLS_LABEL_STACK, 0, &implicit_null, 4);
} }
} }
} }
@ -1239,7 +1239,7 @@ bgp_decode_next_hop_ip(struct bgp_parse_state *s, byte *data, uint len, rta *a)
// XXXX validate next hop // XXXX validate next hop
bgp_set_attr_ptr(&(a->eattrs), s->pool, BA_NEXT_HOP, 0, ad); bgp_set_attr_ptr(&(a->eattrs), BA_NEXT_HOP, 0, ad);
bgp_apply_next_hop(s, a, nh[0], nh[1]); bgp_apply_next_hop(s, a, nh[0], nh[1]);
} }
@ -1320,7 +1320,7 @@ bgp_decode_next_hop_vpn(struct bgp_parse_state *s, byte *data, uint len, rta *a)
// XXXX validate next hop // XXXX validate next hop
bgp_set_attr_ptr(&(a->eattrs), s->pool, BA_NEXT_HOP, 0, ad); bgp_set_attr_ptr(&(a->eattrs), BA_NEXT_HOP, 0, ad);
bgp_apply_next_hop(s, a, nh[0], nh[1]); bgp_apply_next_hop(s, a, nh[0], nh[1]);
} }
@ -1345,11 +1345,11 @@ bgp_decode_next_hop_none(struct bgp_parse_state *s UNUSED, byte *data UNUSED, ui
} }
static void static void
bgp_update_next_hop_none(struct bgp_export_state *s, eattr *a, ea_list **to) bgp_update_next_hop_none(struct bgp_export_state *s UNUSED, eattr *a, ea_list **to)
{ {
/* NEXT_HOP shall not pass */ /* NEXT_HOP shall not pass */
if (a) if (a)
bgp_unset_attr(to, s->pool, BA_NEXT_HOP); bgp_unset_attr(to, BA_NEXT_HOP);
} }
@ -1445,7 +1445,7 @@ bgp_decode_mpls_labels(struct bgp_parse_state *s, byte **pos, uint *len, uint *p
if (!s->mpls_labels) if (!s->mpls_labels)
{ {
s->mpls_labels = lp_alloc_adata(s->pool, 4*BGP_MPLS_MAX); s->mpls_labels = lp_alloc_adata(s->pool, 4*BGP_MPLS_MAX);
bgp_set_attr_ptr(&(a->eattrs), s->pool, BA_MPLS_LABEL_STACK, 0, s->mpls_labels); bgp_set_attr_ptr(&(a->eattrs), BA_MPLS_LABEL_STACK, 0, s->mpls_labels);
} }
/* Overwrite data in the attribute */ /* Overwrite data in the attribute */