Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bgpd:support of color extended community color-only types #17231

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 33 additions & 8 deletions bgpd/bgp_ecommunity.c
Original file line number Diff line number Diff line change
Expand Up @@ -367,10 +367,15 @@ static void ecommunity_color_str(char *buf, size_t bufsz, uint8_t *ptr)
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
uint32_t colorid;
uint8_t color_type;
/* get the color type */
ptr++;
color_type = (*ptr) >> 6;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add the references in the comments about this and where they come from to allow people to find the information faster.


memcpy(&colorid, ptr + 3, 4);
memcpy(&colorid, ptr + 2, 4);
colorid = ntohl(colorid);
snprintf(buf, bufsz, "Color:%d", colorid);
snprintf(buf, bufsz, "Color:%d%d:%d",
(color_type & 0x2) >> 1, color_type & 0x1, colorid);
}

/* Initialize Extended Comminities related hash. */
Expand Down Expand Up @@ -531,7 +536,7 @@ static int ecommunity_encode_internal(uint8_t type, uint8_t sub_type,
eval6->val[19] = val & 0xff;
} else if (type == ECOMMUNITY_ENCODE_OPAQUE &&
sub_type == ECOMMUNITY_COLOR) {
encode_color(val, eval);
encode_color(val, as, eval);
} else {
encode_route_target_as4(as, val, eval, trans);
}
Expand Down Expand Up @@ -739,6 +744,13 @@ static const char *ecommunity_gettoken(const char *str, void *eval_ptr,
*/
if (!asn_str2asn(buf, &as))
goto error;
} else if (type == ECOMMUNITY_COLOR) {
/* If extcommunity is color, only support 00/01/10/11, max value is 3 */
/* color value */
as = strtoul(buf, &endptr, 2);
if (*endptr != '\0' || as > 3)
goto error;
val_color = 0;
} else {
/* Parsing A AS number in A:MN */
errno = 0;
Expand All @@ -753,6 +765,8 @@ static const char *ecommunity_gettoken(const char *str, void *eval_ptr,
if (*endptr != '\0' || tmp_as > BGP_AS4_MAX ||
errno)
goto error;
if (*token == ecommunity_token_color && as > 3)
goto error;
as = (as_t)tmp_as;
}
} else if (*p == '.') {
Expand Down Expand Up @@ -791,13 +805,16 @@ static const char *ecommunity_gettoken(const char *str, void *eval_ptr,
/* Encode result into extended community for AS format or color. */
if (as > BGP_AS_MAX)
ecomm_type = ECOMMUNITY_ENCODE_AS4;
else if (as > 0)
ecomm_type = ECOMMUNITY_ENCODE_AS;
else if (val_color) {
else if (type == ECOMMUNITY_COLOR) {
ecomm_type = ECOMMUNITY_ENCODE_OPAQUE;
sub_type = ECOMMUNITY_COLOR;
val = val_color;
if (val_color) {
val = val_color;
as = 1;
}
}
else if (as > 0)
ecomm_type = ECOMMUNITY_ENCODE_AS;
}
if (ecommunity_encode(ecomm_type, sub_type, 1, as, ip, val, eval))
goto error;
Expand Down Expand Up @@ -1419,7 +1436,15 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter)
else if (sub_type == ECOMMUNITY_EXTENDED_LINK_BANDWIDTH)
ipv6_ecommunity_lb_str(encbuf, sizeof(encbuf),
pnt, len);
else
else if (sub_type == ECOMMUNITY_OPAQUE_SUBTYPE_COLOR) {
uint32_t color;
/* get the color type */
uint8_t color_type = (*pnt) >> 6;
memcpy(&color, pnt + 2, 4);
color = ntohl(color);
snprintf(encbuf, sizeof(encbuf), "Color:%d%d:%u",
(color_type & 0x2) >> 1, color_type & 0x1, color);
} else
unk_ecom = true;
} else if (CHECK_FLAG(type, ECOMMUNITY_ENCODE_IP_NON_TRANS)) {
sub_type = *pnt++;
Expand Down
5 changes: 3 additions & 2 deletions bgpd/bgp_ecommunity.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@

/* Low-order octet of the Extended Communities type field for OPAQUE types */
#define ECOMMUNITY_OPAQUE_SUBTYPE_ENCAP 0x0c
#define ECOMMUNITY_OPAQUE_SUBTYPE_COLOR 0x0b

/* Extended communities attribute string format. */
#define ECOMMUNITY_FORMAT_ROUTE_MAP 0
Expand Down Expand Up @@ -335,7 +336,7 @@ static inline void encode_node_target(struct in_addr *node_id,
* and ignored by the receiver;
*
*/
static inline void encode_color(uint32_t color_id, struct ecommunity_val *eval)
static inline void encode_color(uint32_t color_id, as_t as, struct ecommunity_val *eval)
{
/*
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Expand All @@ -347,7 +348,7 @@ static inline void encode_color(uint32_t color_id, struct ecommunity_val *eval)
memset(eval, 0, sizeof(*eval));
eval->val[0] = ECOMMUNITY_ENCODE_OPAQUE;
eval->val[1] = ECOMMUNITY_COLOR;
eval->val[2] = 0x00;
eval->val[2] = (as << 6) & 0xff;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is this NEW encoding defined? Could you point to the right RFC (section)?

Copy link
Contributor Author

@guoguojia2021 guoguojia2021 Oct 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this sectino:8.8.1. Color-Only BGP Destination Steering
This section defines an alternative steering mechanism based only on the Color Extended community.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see any paragraph saying about this encoding, or am I blind?

Copy link
Contributor Author

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, now I see. This is called CO flags.

While this is fine, I find the naming confusing. Why these flags are called as?

eval->val[3] = 0x00;
eval->val[4] = (color_id >> 24) & 0xff;
eval->val[5] = (color_id >> 16) & 0xff;
Expand Down
4 changes: 2 additions & 2 deletions tests/topotests/bgp_color_extcommunities/r1/bgpd.conf
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ router bgp 65001
exit-address-family
!
route-map rmap permit 10
set extcommunity color 1
set extcommunity color 01:1
set extcommunity rt 80:987
set extcommunity color 100 55555 200
set extcommunity color 01:100 01:55555 01:200
exit
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ def _bgp_check_route(router, exists):
{
"valid": True,
"extendedCommunity": {
"string": "RT:80:987 Color:100 Color:200 Color:55555"
"string": "RT:80:987 Color:01:100 Color:01:200 Color:01:55555"
},
}
],
Expand Down
6 changes: 3 additions & 3 deletions yang/frr-bgp-route-map.yang
Original file line number Diff line number Diff line change
Expand Up @@ -532,18 +532,18 @@ identity set-extcommunity-color {

typedef color-list {
type string {
pattern '((429496729[0-5]|42949672[0-8][0-9]|'
pattern '((00|01|10):(429496729[0-5]|42949672[0-8][0-9]|'
+ '4294967[0-1][0-9]{2}|429496[0-6][0-9]{3}|'
+ '42949[0-5][0-9]{4}|4294[0-8][0-9]{5}|'
+ '429[0-3][0-9]{6}|42[0-8][0-9]{7}|'
+ '4[0-1][0-9]{8}|[1-3][0-9]{9}|'
+ '[1-9][0-9]{0,8})(\s*))+';
}
description
"The color-list type represent a set of colors of value (1..4294967295)
"The color-list type represent a set of colors of value (examples 00:200 01:200 10:200)
values are separated by white spaces";
reference
"RFC 9012 - The BGP Tunnel Encapsulation Attribute";
"RFC 9256 - Segment Routing Policy Architecture";
}

augment "/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:rmap-match-condition/frr-route-map:match-condition" {
Expand Down
Loading