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:
commit
d7bec897ab
@ -739,7 +739,7 @@
|
||||
ACCESS_EATTRS;
|
||||
|
||||
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 */
|
||||
|
56
lib/route.h
56
lib/route.h
@ -222,58 +222,48 @@ struct ea_one_attr_list {
|
||||
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 *
|
||||
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) {
|
||||
.l.flags = EALF_SORTED,
|
||||
.l.count = 1,
|
||||
.l.next = *to,
|
||||
|
||||
.a.id = id,
|
||||
.a.type = type,
|
||||
.a.flags = flags,
|
||||
.a = a,
|
||||
};
|
||||
|
||||
ea->a.u = val;
|
||||
*to = &ea->l;
|
||||
|
||||
return &ea->a;
|
||||
}
|
||||
|
||||
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 = (struct ea_one_attr_list) {
|
||||
.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;
|
||||
ea_set_attr(to, EA_LITERAL_GENERIC(code, 0, 0,
|
||||
.fresh = local, .originated = local, .undef = 1));
|
||||
}
|
||||
|
||||
static inline void
|
||||
ea_set_attr_u32(ea_list **to, struct linpool *pool, uint id, uint flags, uint type, u32 data)
|
||||
{
|
||||
union bval bv = { .data = data };
|
||||
ea_set_attr(to, pool, id, flags, type, bv);
|
||||
}
|
||||
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)); }
|
||||
|
||||
static inline void
|
||||
ea_set_attr_data(ea_list **to, struct linpool *pool, uint id, uint flags, uint type, void *data, uint 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);
|
||||
}
|
||||
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)); }
|
||||
|
||||
|
||||
#define NEXTHOP_MAX_SIZE (sizeof(struct nexthop) + sizeof(u32)*MPLS_MAX_LABEL_STACK)
|
||||
|
@ -79,22 +79,44 @@ static const struct bgp_attr_desc bgp_attr_table[];
|
||||
|
||||
static inline int bgp_attr_known(uint code);
|
||||
|
||||
eattr *
|
||||
bgp_set_attr(ea_list **attrs, struct linpool *pool, uint code, uint flags, union bval val)
|
||||
void bgp_set_attr_u32(ea_list **to, uint code, uint flags, u32 val)
|
||||
{
|
||||
ASSERT(bgp_attr_known(code));
|
||||
|
||||
return ea_set_attr(
|
||||
attrs,
|
||||
pool,
|
||||
ea_set_attr(to, EA_LITERAL_EMBEDDED(
|
||||
EA_CODE(PROTOCOL_BGP, code),
|
||||
flags & ~BAF_EXT_LEN,
|
||||
bgp_attr_table[code].type,
|
||||
flags & ~BAF_EXT_LEN,
|
||||
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...) \
|
||||
({ 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)
|
||||
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
|
||||
@ -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))
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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)
|
||||
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
|
||||
@ -607,7 +629,7 @@ bgp_decode_aggregator(struct bgp_parse_state *s, uint code UNUSED, uint flags, b
|
||||
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
|
||||
@ -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);
|
||||
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);
|
||||
|
||||
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);
|
||||
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
|
||||
@ -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);
|
||||
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)
|
||||
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
|
||||
@ -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);
|
||||
}
|
||||
|
||||
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)))
|
||||
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
|
||||
@ -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);
|
||||
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
|
||||
@ -973,10 +995,10 @@ bgp_format_mpls_label_stack(const eattr *a, byte *buf, uint size)
|
||||
}
|
||||
|
||||
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 */
|
||||
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 (!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;
|
||||
|
||||
@ -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)
|
||||
{
|
||||
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 */
|
||||
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 */
|
||||
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 */
|
||||
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)
|
||||
{
|
||||
/* Confederation -> prepend ASN as AS_CONFED_SEQUENCE */
|
||||
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) */
|
||||
{
|
||||
/* Regular EBGP -> prepend ASN as regular sequence */
|
||||
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 */
|
||||
a = bgp_find_attr(attrs0, BA_MULTI_EXIT_DISC);
|
||||
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 */
|
||||
@ -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 */
|
||||
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 */
|
||||
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))))
|
||||
{
|
||||
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 */
|
||||
@ -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 */
|
||||
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 */
|
||||
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);
|
||||
|
||||
/* 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 */
|
||||
@ -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);
|
||||
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, pool, BA_AS4_PATH, 0, as_path_strip_confed(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, BA_AS4_PATH, 0, as_path_strip_confed(pool, a->u.ptr));
|
||||
}
|
||||
|
||||
a = bgp_find_attr(attrs, BA_AGGREGATOR);
|
||||
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, pool, BA_AS4_AGGREGATOR, 0, a->u.ptr);
|
||||
bgp_set_attr_ptr(&attrs, BA_AGGREGATOR, 0, aggregator_to_old(pool, 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.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));
|
||||
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);
|
||||
|
||||
/* First, unset AS4_* attributes */
|
||||
if (p4) bgp_unset_attr(attrs, pool, BA_AS4_PATH);
|
||||
if (a4) bgp_unset_attr(attrs, pool, BA_AS4_AGGREGATOR);
|
||||
if (p4) bgp_unset_attr(attrs, BA_AS4_PATH);
|
||||
if (a4) bgp_unset_attr(attrs, BA_AS4_AGGREGATOR);
|
||||
|
||||
/* Handle AGGREGATOR attribute */
|
||||
if (a2 && a4)
|
||||
|
@ -544,32 +544,11 @@ bgp_find_attr(ea_list *attrs, uint code)
|
||||
return ea_find(attrs, EA_CODE(PROTOCOL_BGP, code));
|
||||
}
|
||||
|
||||
eattr *
|
||||
bgp_set_attr(ea_list **attrs, struct linpool *pool, uint code, uint flags, union bval val);
|
||||
void bgp_set_attr_u32(ea_list **to, uint code, uint flags, u32 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
|
||||
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)
|
||||
#define bgp_unset_attr(to, code) ea_unset_attr(to, 0, code)
|
||||
|
||||
int bgp_encode_mp_reach_mrt(struct bgp_write_state *s, eattr *a, byte *buf, uint size);
|
||||
|
||||
|
@ -1115,27 +1115,27 @@ bgp_update_next_hop_ip(struct bgp_export_state *s, eattr *a, ea_list **to)
|
||||
{
|
||||
rta *ra = s->route->attrs;
|
||||
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)
|
||||
{
|
||||
u32 implicit_null = BGP_MPLS_NULL;
|
||||
u32 *labels = ra->nh.labels ? ra->nh.label : &implicit_null;
|
||||
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
|
||||
{
|
||||
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;
|
||||
|
||||
/* TODO: Use local MPLS assigned label */
|
||||
if (s->mpls)
|
||||
{
|
||||
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
|
||||
|
||||
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]);
|
||||
}
|
||||
|
||||
@ -1320,7 +1320,7 @@ bgp_decode_next_hop_vpn(struct bgp_parse_state *s, byte *data, uint len, rta *a)
|
||||
|
||||
// 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]);
|
||||
}
|
||||
|
||||
@ -1345,11 +1345,11 @@ bgp_decode_next_hop_none(struct bgp_parse_state *s UNUSED, byte *data UNUSED, ui
|
||||
}
|
||||
|
||||
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 */
|
||||
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)
|
||||
{
|
||||
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 */
|
||||
|
Loading…
Reference in New Issue
Block a user