summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_attr.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgp_attr.c')
-rw-r--r--bgpd/bgp_attr.c376
1 files changed, 240 insertions, 136 deletions
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index e4ee589a..1a2fa831 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -198,6 +198,7 @@ static struct hash *vnc_hash = NULL;
#endif
static struct hash *srv6_l3vpn_hash;
static struct hash *srv6_vpn_hash;
+static struct hash *evpn_overlay_hash;
struct bgp_attr_encap_subtlv *encap_tlv_dup(struct bgp_attr_encap_subtlv *orig)
{
@@ -479,22 +480,11 @@ static bool bgp_attr_aigp_get_tlv_metric(uint8_t *pnt, int length,
return false;
}
-static uint64_t bgp_aigp_metric_total(struct bgp_path_info *bpi)
-{
- uint64_t aigp = bgp_attr_get_aigp_metric(bpi->attr);
-
- if (bpi->nexthop)
- return aigp + bpi->nexthop->metric;
- else
- return aigp;
-}
-
-static void stream_put_bgp_aigp_tlv_metric(struct stream *s,
- struct bgp_path_info *bpi)
+static void stream_put_bgp_aigp_tlv_metric(struct stream *s, uint64_t aigp)
{
stream_putc(s, BGP_AIGP_TLV_METRIC);
stream_putw(s, BGP_AIGP_TLV_METRIC_LEN);
- stream_putq(s, bgp_aigp_metric_total(bpi));
+ stream_putq(s, aigp);
}
static bool bgp_attr_aigp_valid(uint8_t *pnt, int length)
@@ -549,6 +539,81 @@ static bool bgp_attr_aigp_valid(uint8_t *pnt, int length)
return true;
}
+static void *evpn_overlay_hash_alloc(void *p)
+{
+ return p;
+}
+
+void evpn_overlay_free(struct bgp_route_evpn *bre)
+{
+ XFREE(MTYPE_BGP_EVPN_OVERLAY, bre);
+}
+
+static struct bgp_route_evpn *evpn_overlay_intern(struct bgp_route_evpn *bre)
+{
+ struct bgp_route_evpn *find;
+
+ find = hash_get(evpn_overlay_hash, bre, evpn_overlay_hash_alloc);
+ if (find != bre)
+ evpn_overlay_free(bre);
+ find->refcnt++;
+ return find;
+}
+
+static void evpn_overlay_unintern(struct bgp_route_evpn **brep)
+{
+ struct bgp_route_evpn *bre = *brep;
+
+ if (!*brep)
+ return;
+
+ if (bre->refcnt)
+ bre->refcnt--;
+
+ if (bre->refcnt == 0) {
+ hash_release(evpn_overlay_hash, bre);
+ evpn_overlay_free(bre);
+ *brep = NULL;
+ }
+}
+
+static uint32_t evpn_overlay_hash_key_make(const void *p)
+{
+ const struct bgp_route_evpn *bre = p;
+ uint32_t key = 0;
+
+ if (IS_IPADDR_V4(&bre->gw_ip))
+ key = jhash_1word(bre->gw_ip.ipaddr_v4.s_addr, 0);
+ else
+ key = jhash2(bre->gw_ip.ipaddr_v6.s6_addr32,
+ array_size(bre->gw_ip.ipaddr_v6.s6_addr32), 0);
+
+ key = jhash_1word(bre->type, key);
+ key = jhash(bre->eth_s_id.val, sizeof(bre->eth_s_id.val), key);
+ return key;
+}
+
+static bool evpn_overlay_hash_cmp(const void *p1, const void *p2)
+{
+ const struct bgp_route_evpn *bre1 = p1;
+ const struct bgp_route_evpn *bre2 = p2;
+
+ return bgp_route_evpn_same(bre1, bre2);
+}
+
+static void evpn_overlay_init(void)
+{
+ evpn_overlay_hash = hash_create(evpn_overlay_hash_key_make,
+ evpn_overlay_hash_cmp,
+ "BGP EVPN Overlay");
+}
+
+static void evpn_overlay_finish(void)
+{
+ hash_clean_and_free(&evpn_overlay_hash,
+ (void (*)(void *))evpn_overlay_free);
+}
+
static void *srv6_l3vpn_hash_alloc(void *p)
{
return p;
@@ -788,6 +853,8 @@ unsigned int attrhash_key_make(const void *p)
MIX(encap_hash_key_make(attr->encap_subtlvs));
if (attr->srv6_l3vpn)
MIX(srv6_l3vpn_hash_key_make(attr->srv6_l3vpn));
+ if (bgp_attr_get_evpn_overlay(attr))
+ MIX(evpn_overlay_hash_key_make(bgp_attr_get_evpn_overlay(attr)));
if (attr->srv6_vpn)
MIX(srv6_vpn_hash_key_make(attr->srv6_vpn));
#ifdef ENABLE_BGP_VNC
@@ -814,19 +881,16 @@ bool attrhash_cmp(const void *p1, const void *p2)
const struct attr *attr1 = p1;
const struct attr *attr2 = p2;
- if (attr1->flag == attr2->flag && attr1->origin == attr2->origin
- && attr1->nexthop.s_addr == attr2->nexthop.s_addr
- && attr1->aspath == attr2->aspath
- && bgp_attr_get_community(attr1)
- == bgp_attr_get_community(attr2)
- && attr1->med == attr2->med
- && attr1->local_pref == attr2->local_pref
- && attr1->rmap_change_flags == attr2->rmap_change_flags) {
+ if (attr1->flag == attr2->flag && attr1->origin == attr2->origin &&
+ attr1->nexthop.s_addr == attr2->nexthop.s_addr &&
+ attr1->aspath == attr2->aspath &&
+ bgp_attr_get_community(attr1) == bgp_attr_get_community(attr2) &&
+ attr1->med == attr2->med && attr1->local_pref == attr2->local_pref &&
+ attr1->rmap_change_flags == attr2->rmap_change_flags) {
if (attr1->aggregator_as == attr2->aggregator_as &&
attr1->aggregator_addr.s_addr ==
attr2->aggregator_addr.s_addr &&
- attr1->weight == attr2->weight &&
- attr1->tag == attr2->tag &&
+ attr1->weight == attr2->weight && attr1->tag == attr2->tag &&
attr1->label_index == attr2->label_index &&
attr1->mp_nexthop_len == attr2->mp_nexthop_len &&
bgp_attr_get_ecommunity(attr1) ==
@@ -835,10 +899,8 @@ bool attrhash_cmp(const void *p1, const void *p2)
bgp_attr_get_ipv6_ecommunity(attr2) &&
bgp_attr_get_lcommunity(attr1) ==
bgp_attr_get_lcommunity(attr2) &&
- bgp_attr_get_cluster(attr1) ==
- bgp_attr_get_cluster(attr2) &&
- bgp_attr_get_transit(attr1) ==
- bgp_attr_get_transit(attr2) &&
+ bgp_attr_get_cluster(attr1) == bgp_attr_get_cluster(attr2) &&
+ bgp_attr_get_transit(attr1) == bgp_attr_get_transit(attr2) &&
bgp_attr_get_aigp_metric(attr1) ==
bgp_attr_get_aigp_metric(attr2) &&
attr1->rmap_table_id == attr2->rmap_table_id &&
@@ -870,8 +932,7 @@ bool attrhash_cmp(const void *p1, const void *p2)
srv6_vpn_same(attr1->srv6_vpn, attr2->srv6_vpn) &&
attr1->srte_color == attr2->srte_color &&
attr1->nh_type == attr2->nh_type &&
- attr1->bh_type == attr2->bh_type &&
- attr1->otc == attr2->otc)
+ attr1->bh_type == attr2->bh_type && attr1->otc == attr2->otc)
return true;
}
@@ -961,6 +1022,7 @@ struct attr *bgp_attr_intern(struct attr *attr)
struct ecommunity *ipv6_ecomm = NULL;
struct lcommunity *lcomm = NULL;
struct community *comm = NULL;
+ struct bgp_route_evpn *bre = NULL;
/* Intern referenced structure. */
if (attr->aspath) {
@@ -1027,6 +1089,16 @@ struct attr *bgp_attr_intern(struct attr *attr)
else
attr->encap_subtlvs->refcnt++;
}
+
+ bre = bgp_attr_get_evpn_overlay(attr);
+ if (bre) {
+ if (!bre->refcnt)
+ bgp_attr_set_evpn_overlay(attr,
+ evpn_overlay_intern(bre));
+ else
+ bre->refcnt++;
+ }
+
if (attr->srv6_l3vpn) {
if (!attr->srv6_l3vpn->refcnt)
attr->srv6_l3vpn = srv6_l3vpn_intern(attr->srv6_l3vpn);
@@ -1072,14 +1144,14 @@ struct attr *bgp_attr_default_set(struct attr *attr, struct bgp *bgp,
memset(attr, 0, sizeof(struct attr));
attr->origin = origin;
- attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_ORIGIN);
+ SET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_ORIGIN));
attr->aspath = aspath_empty(bgp->asnotation);
- attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_AS_PATH);
+ SET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AS_PATH));
attr->weight = BGP_ATTR_DEFAULT_WEIGHT;
attr->tag = 0;
attr->label_index = BGP_INVALID_LABEL_INDEX;
attr->label = MPLS_INVALID_LABEL;
- attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
+ SET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP));
attr->mp_nexthop_len = IPV6_MAX_BYTELEN;
attr->local_pref = bgp->default_local_pref;
@@ -1101,18 +1173,18 @@ struct attr *bgp_attr_aggregate_intern(
/* Origin attribute. */
attr.origin = origin;
- attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ORIGIN);
+ SET_FLAG(attr.flag, ATTR_FLAG_BIT(BGP_ATTR_ORIGIN));
/* MED */
attr.med = 0;
- attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
+ SET_FLAG(attr.flag, ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC));
/* AS path attribute. */
if (aspath)
attr.aspath = aspath_intern(aspath);
else
attr.aspath = aspath_empty(bgp->asnotation);
- attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_AS_PATH);
+ SET_FLAG(attr.flag, ATTR_FLAG_BIT(BGP_ATTR_AS_PATH));
if (community) {
uint32_t gshut = COMMUNITY_GSHUT;
@@ -1142,8 +1214,8 @@ struct attr *bgp_attr_aggregate_intern(
attr.weight = BGP_ATTR_DEFAULT_WEIGHT;
attr.mp_nexthop_len = IPV6_MAX_BYTELEN;
if (!aggregate->as_set || atomic_aggregate)
- attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE);
- attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR);
+ SET_FLAG(attr.flag, ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE));
+ SET_FLAG(attr.flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR));
if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION))
attr.aggregator_as = bgp->confed_id;
else
@@ -1161,7 +1233,7 @@ struct attr *bgp_attr_aggregate_intern(
*/
if (p->family == AF_INET) {
/* Next hop attribute. */
- attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
+ SET_FLAG(attr.flag, ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP));
attr.mp_nexthop_len = IPV4_MAX_BYTELEN;
}
@@ -1216,6 +1288,7 @@ void bgp_attr_unintern_sub(struct attr *attr)
struct lcommunity *lcomm = NULL;
struct community *comm = NULL;
struct transit *transit;
+ struct bgp_route_evpn *bre;
/* aspath refcount shoud be decrement. */
aspath_unintern(&attr->aspath);
@@ -1257,6 +1330,10 @@ void bgp_attr_unintern_sub(struct attr *attr)
srv6_l3vpn_unintern(&attr->srv6_l3vpn);
srv6_vpn_unintern(&attr->srv6_vpn);
+
+ bre = bgp_attr_get_evpn_overlay(attr);
+ evpn_overlay_unintern(&bre);
+ bgp_attr_set_evpn_overlay(attr, NULL);
}
/* Free bgp attribute and aspath. */
@@ -1289,6 +1366,7 @@ void bgp_attr_flush(struct attr *attr)
struct cluster_list *cluster;
struct lcommunity *lcomm;
struct community *comm;
+ struct bgp_route_evpn *bre;
if (attr->aspath && !attr->aspath->refcnt) {
aspath_free(attr->aspath);
@@ -1347,6 +1425,11 @@ void bgp_attr_flush(struct attr *attr)
bgp_attr_set_vnc_subtlvs(attr, NULL);
}
#endif
+ bre = bgp_attr_get_evpn_overlay(attr);
+ if (bre && !bre->refcnt) {
+ evpn_overlay_free(bre);
+ bgp_attr_set_evpn_overlay(attr, NULL);
+ }
}
/* Implement draft-scudder-idr-optional-transitive behaviour and
@@ -1467,8 +1550,8 @@ bgp_attr_flags_diagnose(struct bgp_attr_parser_args *args,
uint8_t real_flags = args->flags;
const uint8_t attr_code = args->type;
- desired_flags &= ~BGP_ATTR_FLAG_EXTLEN;
- real_flags &= ~BGP_ATTR_FLAG_EXTLEN;
+ UNSET_FLAG(desired_flags, BGP_ATTR_FLAG_EXTLEN);
+ UNSET_FLAG(real_flags, BGP_ATTR_FLAG_EXTLEN);
for (i = 0; i <= 2; i++) /* O,T,P, but not E */
if (CHECK_FLAG(desired_flags, attr_flag_str[i].key)
!= CHECK_FLAG(real_flags, attr_flag_str[i].key)) {
@@ -1582,7 +1665,7 @@ static bool bgp_attr_flag_invalid(struct bgp_attr_parser_args *args)
&& CHECK_FLAG(flags, BGP_ATTR_FLAG_TRANS))
SET_FLAG(mask, BGP_ATTR_FLAG_PARTIAL);
- if ((flags & ~mask) == attr_flags_values[attr_code])
+ if (CHECK_FLAG(flags, ~mask) == attr_flags_values[attr_code])
return false;
bgp_attr_flags_diagnose(args, attr_flags_values[attr_code]);
@@ -1624,7 +1707,7 @@ bgp_attr_origin(struct bgp_attr_parser_args *args)
}
/* Set oring attribute flag. */
- attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_ORIGIN);
+ SET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_ORIGIN));
return 0;
}
@@ -1674,7 +1757,7 @@ static int bgp_attr_aspath(struct bgp_attr_parser_args *args)
}
/* Set aspath attribute flag. */
- attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_AS_PATH);
+ SET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AS_PATH));
return BGP_ATTR_PARSE_PROCEED;
}
@@ -1778,7 +1861,7 @@ static int bgp_attr_as4_path(struct bgp_attr_parser_args *args,
}
/* Set aspath attribute flag. */
- attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_AS4_PATH);
+ SET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AS4_PATH));
return BGP_ATTR_PARSE_PROCEED;
}
@@ -1828,7 +1911,7 @@ bgp_attr_nexthop(struct bgp_attr_parser_args *args)
}
attr->nexthop.s_addr = stream_get_ipv4(peer->curr);
- attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
+ SET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP));
return BGP_ATTR_PARSE_PROCEED;
}
@@ -1851,7 +1934,7 @@ static enum bgp_attr_parse_ret bgp_attr_med(struct bgp_attr_parser_args *args)
attr->med = stream_getl(peer->curr);
- attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
+ SET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC));
return BGP_ATTR_PARSE_PROCEED;
}
@@ -1889,7 +1972,7 @@ bgp_attr_local_pref(struct bgp_attr_parser_args *args)
STREAM_GETL(peer->curr, attr->local_pref);
/* Set the local-pref flag. */
- attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
+ SET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF));
return BGP_ATTR_PARSE_PROCEED;
@@ -1918,7 +2001,7 @@ static int bgp_attr_atomic(struct bgp_attr_parser_args *args)
goto atomic_ignore;
/* Set atomic aggregate flag. */
- attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE);
+ SET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE));
return BGP_ATTR_PARSE_PROCEED;
@@ -1976,7 +2059,7 @@ static int bgp_attr_aggregator(struct bgp_attr_parser_args *args)
zlog_debug("%s: attributes: %s", __func__, attr_str);
}
} else {
- attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR);
+ SET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR));
}
return BGP_ATTR_PARSE_PROCEED;
@@ -2027,7 +2110,7 @@ bgp_attr_as4_aggregator(struct bgp_attr_parser_args *args,
zlog_debug("%s: attributes: %s", __func__, attr_str);
}
} else {
- attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_AS4_AGGREGATOR);
+ SET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AS4_AGGREGATOR));
}
return BGP_ATTR_PARSE_PROCEED;
@@ -2066,12 +2149,13 @@ bgp_attr_munge_as4_attrs(struct peer *const peer, struct attr *const attr,
* should not send them
*/
if (BGP_DEBUG(as4, AS4)) {
- if (attr->flag & (ATTR_FLAG_BIT(BGP_ATTR_AS4_PATH)))
+ if (CHECK_FLAG(attr->flag,
+ (ATTR_FLAG_BIT(BGP_ATTR_AS4_PATH))))
zlog_debug("[AS4] %s %s AS4_PATH", peer->host,
"AS4 capable peer, yet it sent");
- if (attr->flag
- & (ATTR_FLAG_BIT(BGP_ATTR_AS4_AGGREGATOR)))
+ if (CHECK_FLAG(attr->flag,
+ (ATTR_FLAG_BIT(BGP_ATTR_AS4_AGGREGATOR))))
zlog_debug("[AS4] %s %s AS4_AGGREGATOR",
peer->host,
"AS4 capable peer, yet it sent");
@@ -2083,8 +2167,9 @@ bgp_attr_munge_as4_attrs(struct peer *const peer, struct attr *const attr,
/* We have a asn16 peer. First, look for AS4_AGGREGATOR
* because that may override AS4_PATH
*/
- if (attr->flag & (ATTR_FLAG_BIT(BGP_ATTR_AS4_AGGREGATOR))) {
- if (attr->flag & (ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
+ if (CHECK_FLAG(attr->flag, (ATTR_FLAG_BIT(BGP_ATTR_AS4_AGGREGATOR)))) {
+ if (CHECK_FLAG(attr->flag,
+ (ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR)))) {
/* received both.
* if the as_number in aggregator is not AS_TRANS,
* then AS4_AGGREGATOR and AS4_PATH shall be ignored
@@ -2124,13 +2209,14 @@ bgp_attr_munge_as4_attrs(struct peer *const peer, struct attr *const attr,
attr->aggregator_as = as4_aggregator;
/* sweep it under the carpet and simulate a "good"
* AGGREGATOR */
- attr->flag |= (ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR));
+ SET_FLAG(attr->flag,
+ (ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR)));
}
}
/* need to reconcile NEW_AS_PATH and AS_PATH */
- if (!ignore_as4_path
- && (attr->flag & (ATTR_FLAG_BIT(BGP_ATTR_AS4_PATH)))) {
+ if (!ignore_as4_path &&
+ (CHECK_FLAG(attr->flag, (ATTR_FLAG_BIT(BGP_ATTR_AS4_PATH))))) {
newpath = aspath_reconcile_as4(attr->aspath, as4_path);
if (!newpath)
return BGP_ATTR_PARSE_ERROR;
@@ -2215,7 +2301,7 @@ bgp_attr_originator_id(struct bgp_attr_parser_args *args)
attr->originator_id.s_addr = stream_get_ipv4(peer->curr);
- attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID);
+ SET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID));
return BGP_ATTR_PARSE_PROCEED;
@@ -2473,7 +2559,7 @@ int bgp_mp_reach_parse(struct bgp_attr_parser_args *args,
stream_forward_getp(s, nlri_len);
- attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_MP_REACH_NLRI);
+ SET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_MP_REACH_NLRI));
return BGP_ATTR_PARSE_PROCEED;
#undef LEN_LEFT
@@ -2525,7 +2611,7 @@ int bgp_mp_unreach_parse(struct bgp_attr_parser_args *args,
stream_forward_getp(s, withdraw_len);
- attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_MP_UNREACH_NLRI);
+ SET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_MP_UNREACH_NLRI));
return BGP_ATTR_PARSE_PROCEED;
}
@@ -2575,7 +2661,6 @@ bgp_attr_ext_communities(struct bgp_attr_parser_args *args)
struct peer *const peer = args->peer;
struct attr *const attr = args->attr;
const bgp_size_t length = args->length;
- uint8_t sticky = 0;
bool proxy = false;
struct ecommunity *ecomm;
@@ -2586,10 +2671,9 @@ bgp_attr_ext_communities(struct bgp_attr_parser_args *args)
args->total);
}
- ecomm = ecommunity_parse(
- stream_pnt(peer->curr), length,
- CHECK_FLAG(peer->flags,
- PEER_FLAG_DISABLE_LINK_BW_ENCODING_IEEE));
+ ecomm = ecommunity_parse(stream_pnt(peer->curr), length,
+ CHECK_FLAG(peer->flags,
+ PEER_FLAG_DISABLE_LINK_BW_ENCODING_IEEE));
bgp_attr_set_ecommunity(attr, ecomm);
/* XXX: fix ecommunity_parse to use stream API */
stream_forward_getp(peer->curr, length);
@@ -2605,23 +2689,22 @@ bgp_attr_ext_communities(struct bgp_attr_parser_args *args)
attr->df_pref = bgp_attr_df_pref_from_ec(attr, &attr->df_alg);
/* Extract MAC mobility sequence number, if any. */
- attr->mm_seqnum = bgp_attr_mac_mobility_seqnum(attr, &sticky);
- attr->sticky = sticky;
+ attr->mm_seqnum = bgp_attr_mac_mobility_seqnum(attr);
/* Check if this is a Gateway MAC-IP advertisement */
- attr->default_gw = bgp_attr_default_gw(attr);
+ bgp_attr_default_gw(attr);
/* Handle scenario where router flag ecommunity is not
* set but default gw ext community is present.
* Use default gateway, set and propogate R-bit.
*/
- if (attr->default_gw)
- attr->router_flag = 1;
+ if (CHECK_FLAG(attr->evpn_flags, ATTR_EVPN_FLAG_DEFAULT_GW))
+ SET_FLAG(attr->evpn_flags, ATTR_EVPN_FLAG_ROUTER);
/* Check EVPN Neighbor advertisement flags, R-bit */
- bgp_attr_evpn_na_flag(attr, &attr->router_flag, &proxy);
+ bgp_attr_evpn_na_flag(attr, &proxy);
if (proxy)
- attr->es_flags |= ATTR_ES_PROXY_ADVERT;
+ SET_FLAG(attr->es_flags, ATTR_ES_PROXY_ADVERT);
/* Extract the Rmac, if any */
if (bgp_attr_rmac(attr, &attr->rmac)) {
@@ -2692,6 +2775,9 @@ static int bgp_attr_encap(struct bgp_attr_parser_args *args)
uint8_t type = args->type;
uint8_t flag = args->flags;
+ if (peer->discard_attrs[args->type] || peer->withdraw_attrs[args->type])
+ goto encap_ignore;
+
if (!CHECK_FLAG(flag, BGP_ATTR_FLAG_TRANS)
|| !CHECK_FLAG(flag, BGP_ATTR_FLAG_OPTIONAL)) {
zlog_err("Tunnel Encap attribute flag isn't optional and transitive %d",
@@ -2810,7 +2896,14 @@ static int bgp_attr_encap(struct bgp_attr_parser_args *args)
args->total);
}
- return 0;
+ SET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_ENCAP));
+
+ return BGP_ATTR_PARSE_PROCEED;
+
+encap_ignore:
+ stream_forward_getp(peer->curr, length);
+
+ return bgp_attr_ignore(peer, type);
}
@@ -3202,6 +3295,9 @@ enum bgp_attr_parse_ret bgp_attr_prefix_sid(struct bgp_attr_parser_args *args)
size_t headersz = sizeof(type) + sizeof(length);
size_t psid_parsed_length = 0;
+ if (peer->discard_attrs[args->type] || peer->withdraw_attrs[args->type])
+ goto prefix_sid_ignore;
+
while (STREAM_READABLE(peer->curr) > 0
&& psid_parsed_length < args->length) {
@@ -3249,6 +3345,11 @@ enum bgp_attr_parse_ret bgp_attr_prefix_sid(struct bgp_attr_parser_args *args)
SET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID));
return BGP_ATTR_PARSE_PROCEED;
+
+prefix_sid_ignore:
+ stream_forward_getp(peer->curr, args->length);
+
+ return bgp_attr_ignore(peer, args->type);
}
/* PMSI tunnel attribute (RFC 6514)
@@ -3263,6 +3364,9 @@ bgp_attr_pmsi_tunnel(struct bgp_attr_parser_args *args)
uint8_t tnl_type;
int attr_parse_len = 2 + BGP_LABEL_BYTES;
+ if (peer->discard_attrs[args->type] || peer->withdraw_attrs[args->type])
+ goto pmsi_tunnel_ignore;
+
/* Verify that the receiver is expecting "ingress replication" as we
* can only support that.
*/
@@ -3291,7 +3395,7 @@ bgp_attr_pmsi_tunnel(struct bgp_attr_parser_args *args)
}
}
- attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL);
+ SET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL));
bgp_attr_set_pmsi_tnl_type(attr, tnl_type);
stream_get(&attr->label, peer->curr, BGP_LABEL_BYTES);
@@ -3299,6 +3403,11 @@ bgp_attr_pmsi_tunnel(struct bgp_attr_parser_args *args)
stream_forward_getp(peer->curr, length - attr_parse_len);
return BGP_ATTR_PARSE_PROCEED;
+
+pmsi_tunnel_ignore:
+ stream_forward_getp(peer->curr, length);
+
+ return bgp_attr_ignore(peer, args->type);
}
/* AIGP attribute (rfc7311) */
@@ -3369,7 +3478,7 @@ static enum bgp_attr_parse_ret bgp_attr_otc(struct bgp_attr_parser_args *args)
args->total);
}
- attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_OTC);
+ SET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_OTC));
return BGP_ATTR_PARSE_PROCEED;
@@ -3566,18 +3675,17 @@ enum bgp_attr_parse_ret bgp_attr_parse(struct peer *peer, struct attr *attr,
* unused. They MUST be zero when sent and MUST be ignored when
* received.
*/
- flag = 0xF0 & stream_getc(BGP_INPUT(peer));
+ flag = CHECK_FLAG(0xF0, stream_getc(BGP_INPUT(peer)));
type = stream_getc(BGP_INPUT(peer));
/* Check whether Extended-Length applies and is in bounds */
if (CHECK_FLAG(flag, BGP_ATTR_FLAG_EXTLEN)
&& ((endp - startp) < (BGP_ATTR_MIN_LEN + 1))) {
- flog_warn(
- EC_BGP_EXT_ATTRIBUTE_TOO_SMALL,
- "%s: Extended length set, but just %lu bytes of attr header",
- peer->host,
- (unsigned long)(endp
- - stream_pnt(BGP_INPUT(peer))));
+ flog_warn(EC_BGP_EXT_ATTRIBUTE_TOO_SMALL,
+ "%s: Extended length set, but just %lu bytes of attr header",
+ peer->host,
+ (unsigned long)(endp -
+ stream_pnt(BGP_INPUT(peer))));
if (peer->sort != BGP_PEER_EBGP) {
bgp_notify_send(peer->connection,
@@ -3924,7 +4032,7 @@ enum bgp_attr_parse_ret bgp_attr_parse(struct peer *peer, struct attr *attr,
* Finally do the checks on the aspath we did not do yet
* because we waited for a potentially synthesized aspath.
*/
- if (attr->flag & (ATTR_FLAG_BIT(BGP_ATTR_AS_PATH))) {
+ if (CHECK_FLAG(attr->flag, (ATTR_FLAG_BIT(BGP_ATTR_AS_PATH)))) {
ret = bgp_attr_aspath_check(peer, attr);
if (ret != BGP_ATTR_PARSE_PROCEED)
goto done;
@@ -4102,8 +4210,8 @@ size_t bgp_packet_mpattr_start(struct stream *s, struct peer *peer, afi_t afi,
case SAFI_MULTICAST:
case SAFI_LABELED_UNICAST:
case SAFI_EVPN: {
- if (attr->mp_nexthop_len
- == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
+ if (attr->mp_nexthop_len ==
+ BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
stream_putc(s,
BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL);
stream_put(s, &attr->mp_nexthop_global,
@@ -4324,12 +4432,12 @@ static void bgp_packet_mpattr_tea(struct bgp *bgp, struct peer *peer,
BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL
| BGP_ATTR_FLAG_EXTLEN);
stream_putc(s, attrtype);
- stream_putw(s, attrlenfield & 0xffff);
+ stream_putw(s, CHECK_FLAG(attrlenfield, 0xffff));
} else {
/* 1-octet length field */
stream_putc(s, BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL);
stream_putc(s, attrtype);
- stream_putc(s, attrlenfield & 0xff);
+ stream_putc(s, CHECK_FLAG(attrlenfield, 0xff));
}
if (attrtype == BGP_ATTR_ENCAP) {
@@ -4440,14 +4548,11 @@ static void bgp_packet_ecommunity_attribute(struct stream *s, struct peer *peer,
}
/* Make attribute packet. */
-bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer,
- struct stream *s, struct attr *attr,
- struct bpacket_attr_vec_arr *vecarr,
- struct prefix *p, afi_t afi, safi_t safi,
- struct peer *from, struct prefix_rd *prd,
- mpls_label_t *label, uint8_t num_labels,
- bool addpath_capable, uint32_t addpath_tx_id,
- struct bgp_path_info *bpi)
+bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer, struct stream *s,
+ struct attr *attr, struct bpacket_attr_vec_arr *vecarr,
+ struct prefix *p, afi_t afi, safi_t safi, struct peer *from,
+ struct prefix_rd *prd, mpls_label_t *label, uint8_t num_labels,
+ bool addpath_capable, uint32_t addpath_tx_id)
{
size_t cp;
size_t aspath_sizep;
@@ -4476,6 +4581,8 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer,
bgp_packet_mpattr_end(s, mpattrlen_pos);
}
+ (void)peer_sort(peer);
+
/* Origin attribute. */
stream_putc(s, BGP_ATTR_FLAG_TRANS);
stream_putc(s, BGP_ATTR_ORIGIN);
@@ -4569,15 +4676,15 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer,
&& !peer_cap_enhe(peer, afi, safi)) {
afi_t nh_afi = BGP_NEXTHOP_AFI_FROM_NHLEN(attr->mp_nexthop_len);
- if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) {
+ if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP))) {
stream_putc(s, BGP_ATTR_FLAG_TRANS);
stream_putc(s, BGP_ATTR_NEXT_HOP);
bpacket_attr_vec_arr_set_vec(vecarr, BGP_ATTR_VEC_NH, s,
attr);
stream_putc(s, 4);
stream_put_ipv4(s, attr->nexthop.s_addr);
- } else if (peer_cap_enhe(from, afi, safi)
- || (nh_afi == AFI_IP6)) {
+ } else if (peer_cap_enhe(from, afi, safi) ||
+ (nh_afi == AFI_IP6)) {
/*
* Likely this is the case when an IPv4 prefix was
* received with Extended Next-hop capability in this
@@ -4599,8 +4706,8 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer,
}
/* MED attribute. */
- if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)
- || bgp->maxmed_active) {
+ if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) ||
+ bgp->maxmed_active) {
stream_putc(s, BGP_ATTR_FLAG_OPTIONAL);
stream_putc(s, BGP_ATTR_MULTI_EXIT_DISC);
stream_putc(s, 4);
@@ -4618,14 +4725,14 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer,
}
/* Atomic aggregate. */
- if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
+ if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))) {
stream_putc(s, BGP_ATTR_FLAG_TRANS);
stream_putc(s, BGP_ATTR_ATOMIC_AGGREGATE);
stream_putc(s, 0);
}
/* Aggregator. */
- if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR)) {
+ if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
/* Common to BGP_ATTR_AGGREGATOR, regardless of ASN size */
stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS);
stream_putc(s, BGP_ATTR_AGGREGATOR);
@@ -4656,8 +4763,8 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer,
}
/* Community attribute. */
- if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SEND_COMMUNITY)
- && (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))) {
+ if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SEND_COMMUNITY) &&
+ CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))) {
struct community *comm = NULL;
comm = bgp_attr_get_community(attr);
@@ -4681,8 +4788,8 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer,
* Large Community attribute.
*/
if (CHECK_FLAG(peer->af_flags[afi][safi],
- PEER_FLAG_SEND_LARGE_COMMUNITY)
- && (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES))) {
+ PEER_FLAG_SEND_LARGE_COMMUNITY) &&
+ CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES))) {
if (lcom_length(bgp_attr_get_lcommunity(attr)) > 255) {
stream_putc(s,
BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS
@@ -4712,7 +4819,8 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer,
stream_putc(s, BGP_ATTR_ORIGINATOR_ID);
stream_putc(s, 4);
- if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
+ if (CHECK_FLAG(attr->flag,
+ ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)))
stream_put_in_addr(s, &attr->originator_id);
else
stream_put_in_addr(s, &from->remote_id);
@@ -4725,7 +4833,7 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer,
stream_putc(s, cluster->length + 4);
/* If this peer configuration's parent BGP has
* cluster_id. */
- if (bgp->config & BGP_CONFIG_CLUSTER_ID)
+ if (CHECK_FLAG(bgp->config, BGP_CONFIG_CLUSTER_ID))
stream_put_in_addr(s, &bgp->cluster_id);
else
stream_put_in_addr(s, &bgp->router_id);
@@ -4734,7 +4842,7 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer,
stream_putc(s, 4);
/* If this peer configuration's parent BGP has
* cluster_id. */
- if (bgp->config & BGP_CONFIG_CLUSTER_ID)
+ if (CHECK_FLAG(bgp->config, BGP_CONFIG_CLUSTER_ID))
stream_put_in_addr(s, &bgp->cluster_id);
else
stream_put_in_addr(s, &bgp->router_id);
@@ -4902,7 +5010,7 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer,
}
/* PMSI Tunnel */
- if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
+ if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL))) {
stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS);
stream_putc(s, BGP_ATTR_PMSI_TUNNEL);
stream_putc(s, 9); // Length
@@ -4915,7 +5023,7 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer,
}
/* OTC */
- if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
+ if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_OTC))) {
stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS);
stream_putc(s, BGP_ATTR_OTC);
stream_putc(s, 4);
@@ -4923,10 +5031,7 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer,
}
/* AIGP */
- if (bpi && attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AIGP) &&
- (CHECK_FLAG(peer->flags, PEER_FLAG_AIGP) ||
- peer->sub_sort == BGP_PEER_EBGP_OAD ||
- peer->sort != BGP_PEER_EBGP)) {
+ if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AIGP)) && AIGP_TRANSMIT_ALLOWED(peer)) {
/* At the moment only AIGP Metric TLV exists for AIGP
* attribute. If more comes in, do not forget to update
* attr_len variable to include new ones.
@@ -4936,7 +5041,7 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer,
stream_putc(s, BGP_ATTR_FLAG_OPTIONAL);
stream_putc(s, BGP_ATTR_AIGP);
stream_putc(s, attr_len);
- stream_put_bgp_aigp_tlv_metric(s, bpi);
+ stream_put_bgp_aigp_tlv_metric(s, attr->aigp_metric);
}
/* Unknown transit attribute. */
@@ -5006,6 +5111,7 @@ void bgp_attr_init(void)
transit_init();
encap_init();
srv6_init();
+ evpn_overlay_init();
}
void bgp_attr_finish(void)
@@ -5019,6 +5125,7 @@ void bgp_attr_finish(void)
transit_finish();
encap_finish();
srv6_finish();
+ evpn_overlay_finish();
}
/* Make attribute packet. */
@@ -5064,7 +5171,7 @@ void bgp_dump_routes_attr(struct stream *s, struct bgp_path_info *bpi,
}
/* MED attribute. */
- if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
+ if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))) {
stream_putc(s, BGP_ATTR_FLAG_OPTIONAL);
stream_putc(s, BGP_ATTR_MULTI_EXIT_DISC);
stream_putc(s, 4);
@@ -5072,7 +5179,7 @@ void bgp_dump_routes_attr(struct stream *s, struct bgp_path_info *bpi,
}
/* Local preference. */
- if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
+ if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))) {
stream_putc(s, BGP_ATTR_FLAG_TRANS);
stream_putc(s, BGP_ATTR_LOCAL_PREF);
stream_putc(s, 4);
@@ -5080,14 +5187,14 @@ void bgp_dump_routes_attr(struct stream *s, struct bgp_path_info *bpi,
}
/* Atomic aggregate. */
- if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
+ if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))) {
stream_putc(s, BGP_ATTR_FLAG_TRANS);
stream_putc(s, BGP_ATTR_ATOMIC_AGGREGATE);
stream_putc(s, 0);
}
/* Aggregator. */
- if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR)) {
+ if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS);
stream_putc(s, BGP_ATTR_AGGREGATOR);
stream_putc(s, 8);
@@ -5096,7 +5203,7 @@ void bgp_dump_routes_attr(struct stream *s, struct bgp_path_info *bpi,
}
/* Community attribute. */
- if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
+ if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))) {
struct community *comm = NULL;
comm = bgp_attr_get_community(attr);
@@ -5107,9 +5214,8 @@ void bgp_dump_routes_attr(struct stream *s, struct bgp_path_info *bpi,
stream_putc(s, BGP_ATTR_COMMUNITIES);
stream_putw(s, comm->size * 4);
} else {
- stream_putc(s,
- BGP_ATTR_FLAG_OPTIONAL
- | BGP_ATTR_FLAG_TRANS);
+ stream_putc(s, BGP_ATTR_FLAG_OPTIONAL |
+ BGP_ATTR_FLAG_TRANS);
stream_putc(s, BGP_ATTR_COMMUNITIES);
stream_putc(s, comm->size * 4);
}
@@ -5117,7 +5223,7 @@ void bgp_dump_routes_attr(struct stream *s, struct bgp_path_info *bpi,
}
/* Large Community attribute. */
- if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
+ if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES))) {
if (lcom_length(bgp_attr_get_lcommunity(attr)) > 255) {
stream_putc(s,
BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS
@@ -5126,9 +5232,8 @@ void bgp_dump_routes_attr(struct stream *s, struct bgp_path_info *bpi,
stream_putw(s,
lcom_length(bgp_attr_get_lcommunity(attr)));
} else {
- stream_putc(s,
- BGP_ATTR_FLAG_OPTIONAL
- | BGP_ATTR_FLAG_TRANS);
+ stream_putc(s, BGP_ATTR_FLAG_OPTIONAL |
+ BGP_ATTR_FLAG_TRANS);
stream_putc(s, BGP_ATTR_LARGE_COMMUNITIES);
stream_putc(s,
lcom_length(bgp_attr_get_lcommunity(attr)));
@@ -5172,11 +5277,10 @@ void bgp_dump_routes_attr(struct stream *s, struct bgp_path_info *bpi,
}
/* Prefix SID */
- if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID)) {
+ if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID))) {
if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
- stream_putc(s,
- BGP_ATTR_FLAG_OPTIONAL
- | BGP_ATTR_FLAG_TRANS);
+ stream_putc(s, BGP_ATTR_FLAG_OPTIONAL |
+ BGP_ATTR_FLAG_TRANS);
stream_putc(s, BGP_ATTR_PREFIX_SID);
stream_putc(s, 10);
stream_putc(s, BGP_PREFIX_SID_LABEL_INDEX);
@@ -5188,7 +5292,7 @@ void bgp_dump_routes_attr(struct stream *s, struct bgp_path_info *bpi,
}
/* OTC */
- if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
+ if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_OTC))) {
stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS);
stream_putc(s, BGP_ATTR_OTC);
stream_putc(s, 4);
@@ -5196,7 +5300,7 @@ void bgp_dump_routes_attr(struct stream *s, struct bgp_path_info *bpi,
}
/* AIGP */
- if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AIGP)) {
+ if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AIGP))) {
/* At the moment only AIGP Metric TLV exists for AIGP
* attribute. If more comes in, do not forget to update
* attr_len variable to include new ones.
@@ -5206,7 +5310,7 @@ void bgp_dump_routes_attr(struct stream *s, struct bgp_path_info *bpi,
stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS);
stream_putc(s, BGP_ATTR_AIGP);
stream_putc(s, attr_len);
- stream_put_bgp_aigp_tlv_metric(s, bpi);
+ stream_put_bgp_aigp_tlv_metric(s, attr->aigp_metric);
}
/* Return total size of attribute. */