Skip to content

Commit ef48338

Browse files
authored
Merge pull request #22021 from opensourcerouting/fix/bgp_move_otc_attribute_to_extra
bgpd: Move OTC and IPv6 extended community attributes to attr_extra
2 parents b63d16f + 5b3c780 commit ef48338

3 files changed

Lines changed: 54 additions & 23 deletions

File tree

bgpd/bgp_attr.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1108,7 +1108,7 @@ unsigned int attrhash_key_make(const void *p)
11081108
key = jhash(attr->mp_nexthop_global.s6_addr, IPV6_MAX_BYTELEN, key);
11091109
key = jhash(attr->mp_nexthop_local.s6_addr, IPV6_MAX_BYTELEN, key);
11101110
MIX3(attr->nh_ifindex, attr->nh_lla_ifindex, attr->distance);
1111-
MIX3(attr->bh_type, attr->otc, bgp_attr_get_aigp_metric(attr));
1111+
MIX3(attr->bh_type, bgp_attr_get_otc(attr), bgp_attr_get_aigp_metric(attr));
11121112
MIX3(attr->mm_seqnum, attr->df_alg, attr->df_pref);
11131113
MIX(attr->encap_tunneltype);
11141114
MIX(bgp_attr_get_pmsi_tnl_type(attr));
@@ -1167,7 +1167,8 @@ bool attrhash_cmp(const void *p1, const void *p2)
11671167
bgp_attr_get_srv6_l3service(attr2)) &&
11681168
srv6_vpn_same(bgp_attr_get_srv6_vpn(attr1), bgp_attr_get_srv6_vpn(attr2)) &&
11691169
attr1->srte_color == attr2->srte_color && attr1->nh_type == attr2->nh_type &&
1170-
attr1->bh_type == attr2->bh_type && attr1->otc == attr2->otc &&
1170+
attr1->bh_type == attr2->bh_type &&
1171+
bgp_attr_get_otc(attr1) == bgp_attr_get_otc(attr2) &&
11711172
!memcmp(&attr1->rmac, &attr2->rmac, sizeof(struct ethaddr)) &&
11721173
bgp_nhc_same(bgp_attr_get_nhc(attr1), bgp_attr_get_nhc(attr2)) &&
11731174
bgp_ls_attr_same(bgp_attr_get_ls_attr(attr1), bgp_attr_get_ls_attr(attr2)) &&
@@ -1242,7 +1243,7 @@ static void attr_show_all_iterator(struct hash_bucket *bucket, void *args[])
12421243
lcommunity_str(attr->lcommunity, false, false));
12431244
vty_out(vty, "\tExtended Community: %s Extended IPv6 Community: %s\n",
12441245
ecommunity_str(attr->ecommunity),
1245-
ecommunity_str(attr->ipv6_ecommunity));
1246+
ecommunity_str(bgp_attr_get_ipv6_ecommunity(attr)));
12461247

12471248
if (nhc) {
12481249
vty_out(vty, "\tNHC: TLVs length %d\n", nhc->tlvs_length);
@@ -4261,14 +4262,15 @@ static enum bgp_attr_parse_ret bgp_attr_otc(struct bgp_attr_parser_args *args)
42614262
if (peer->discard_attrs[args->type] || peer->withdraw_attrs[args->type])
42624263
goto otc_ignore;
42634264

4264-
attr->otc = stream_getl(connection->curr);
4265-
if (!attr->otc) {
4265+
uint32_t otc = stream_getl(connection->curr);
4266+
4267+
if (!otc) {
42664268
flog_err(EC_BGP_ATTR_MAL_AS_PATH, "OTC attribute value is 0");
42674269
return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_MAL_AS_PATH,
42684270
args->total);
42694271
}
42704272

4271-
bgp_attr_set(attr, BGP_ATTR_OTC);
4273+
bgp_attr_set_otc(attr, otc);
42724274

42734275
return BGP_ATTR_PARSE_PROCEED;
42744276

@@ -5935,7 +5937,7 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer, struct strea
59355937
stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS);
59365938
stream_putc(s, BGP_ATTR_OTC);
59375939
stream_putc(s, 4);
5938-
stream_putl(s, attr->otc);
5940+
stream_putl(s, bgp_attr_get_otc(attr));
59395941
}
59405942

59415943
/* AIGP */
@@ -6217,7 +6219,7 @@ void bgp_dump_routes_attr(struct stream *s, struct bgp_path_info *bpi,
62176219
stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS);
62186220
stream_putc(s, BGP_ATTR_OTC);
62196221
stream_putc(s, 4);
6220-
stream_putl(s, attr->otc);
6222+
stream_putl(s, bgp_attr_get_otc(attr));
62216223
}
62226224

62236225
/* AIGP */

bgpd/bgp_attr.h

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,12 @@ struct attr_extra {
162162

163163
/* PMSI Tunnel Id */
164164
struct in6_addr tunn_id;
165+
166+
/* RFC 9234 */
167+
uint32_t otc;
168+
169+
/* IPv6 Extended Communities attribute. */
170+
struct ecommunity *ipv6_ecommunity;
165171
};
166172

167173
extern struct attr_extra *bgp_attr_extra_get(struct attr *attr);
@@ -279,9 +285,6 @@ struct attr {
279285
/* Extended Communities attribute. */
280286
struct ecommunity *ecommunity;
281287

282-
/* Extended Communities attribute. */
283-
struct ecommunity *ipv6_ecommunity;
284-
285288
/* Large Communities attribute. */
286289
struct lcommunity *lcommunity;
287290

@@ -344,9 +347,6 @@ struct attr {
344347
/* If NEXTHOP_TYPE_BLACKHOLE, then blackhole type */
345348
enum blackhole_type bh_type;
346349

347-
/* OTC value if set */
348-
uint32_t otc;
349-
350350
/* Optional feature-specific attributes */
351351
struct attr_extra *extra;
352352
};
@@ -640,13 +640,22 @@ static inline void bgp_attr_set_community(struct attr *attr,
640640
static inline struct ecommunity *
641641
bgp_attr_get_ipv6_ecommunity(const struct attr *attr)
642642
{
643-
return attr->ipv6_ecommunity;
643+
return attr->extra ? attr->extra->ipv6_ecommunity : NULL;
644644
}
645645

646646
static inline void bgp_attr_set_ipv6_ecommunity(struct attr *attr,
647647
struct ecommunity *ipv6_ecomm)
648648
{
649-
attr->ipv6_ecommunity = ipv6_ecomm;
649+
struct ecommunity *old = bgp_attr_get_ipv6_ecommunity(attr);
650+
651+
if (ipv6_ecomm && !old) {
652+
bgp_attr_extra_get(attr)->ipv6_ecommunity = ipv6_ecomm;
653+
} else if (ipv6_ecomm && old) {
654+
attr->extra->ipv6_ecommunity = ipv6_ecomm; /* replace; refcnt unchanged */
655+
} else if (!ipv6_ecomm && old) {
656+
attr->extra->ipv6_ecommunity = NULL;
657+
bgp_attr_extra_put(attr);
658+
}
650659

651660
if (ipv6_ecomm && ipv6_ecomm->size)
652661
SET_FLAG(attr->flag,
@@ -825,6 +834,28 @@ static inline void bgp_attr_set_link_bw(struct attr *attr, uint64_t link_bw)
825834
}
826835
}
827836

837+
static inline uint32_t bgp_attr_get_otc(const struct attr *attr)
838+
{
839+
return attr->extra ? attr->extra->otc : 0;
840+
}
841+
842+
static inline void bgp_attr_set_otc(struct attr *attr, uint32_t otc)
843+
{
844+
uint32_t old = bgp_attr_get_otc(attr);
845+
846+
if (otc && !old) {
847+
bgp_attr_extra_get(attr)->otc = otc;
848+
bgp_attr_set(attr, BGP_ATTR_OTC);
849+
} else if (otc && old) {
850+
attr->extra->otc = otc; /* replace; refcnt unchanged */
851+
bgp_attr_set(attr, BGP_ATTR_OTC);
852+
} else if (!otc && old) {
853+
attr->extra->otc = 0;
854+
bgp_attr_extra_put(attr);
855+
bgp_attr_unset(attr, BGP_ATTR_OTC);
856+
}
857+
}
858+
828859
static inline struct bgp_attr_srv6_vpn *bgp_attr_get_srv6_vpn(const struct attr *attr)
829860
{
830861
return attr->extra ? attr->extra->srv6_vpn : NULL;

bgpd/bgp_route.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2038,15 +2038,14 @@ static bool bgp_otc_filter(struct peer *peer, struct attr *attr)
20382038
if (peer->local_role == ROLE_PROVIDER ||
20392039
peer->local_role == ROLE_RS_SERVER)
20402040
return true;
2041-
if (peer->local_role == ROLE_PEER && attr->otc != peer->as)
2041+
if (peer->local_role == ROLE_PEER && bgp_attr_get_otc(attr) != peer->as)
20422042
return true;
20432043
return false;
20442044
}
20452045
if (peer->local_role == ROLE_CUSTOMER ||
20462046
peer->local_role == ROLE_PEER ||
20472047
peer->local_role == ROLE_RS_CLIENT) {
2048-
bgp_attr_set(attr, BGP_ATTR_OTC);
2049-
attr->otc = peer->as;
2048+
bgp_attr_set_otc(attr, peer->as);
20502049
}
20512050
return false;
20522051
}
@@ -2063,8 +2062,7 @@ static bool bgp_otc_egress(struct peer *peer, struct attr *attr)
20632062
if (peer->local_role == ROLE_PROVIDER ||
20642063
peer->local_role == ROLE_PEER ||
20652064
peer->local_role == ROLE_RS_SERVER) {
2066-
bgp_attr_set(attr, BGP_ATTR_OTC);
2067-
attr->otc = peer->bgp->as;
2065+
bgp_attr_set_otc(attr, peer->bgp->as);
20682066
}
20692067
return false;
20702068
}
@@ -13131,9 +13129,9 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
1313113129

1313213130
if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_OTC))) {
1313313131
if (json_paths)
13134-
json_object_int_add(json_path, "otc", attr->otc);
13132+
json_object_int_add(json_path, "otc", bgp_attr_get_otc(attr));
1313513133
else
13136-
vty_out(vty, ", otc %u", attr->otc);
13134+
vty_out(vty, ", otc %u", bgp_attr_get_otc(attr));
1313713135
}
1313813136

1313913137
if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH) ||

0 commit comments

Comments
 (0)