Merge pull request #17231 from guoguojia2021/guozhongfeng_alibaba

bgpd:support of color extended community color-only types
This commit is contained in:
Donatas Abraitis 2024-11-08 08:56:21 +02:00 committed by GitHub
commit af9a2cb875
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 67 additions and 23 deletions

View File

@ -361,16 +361,22 @@ static void ecommunity_color_str(char *buf, size_t bufsz, uint8_t *ptr)
{ {
/* /*
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | 0x03 | Sub-Type(0x0b) | Flags | * | 0x03 | Sub-Type(0x0b) | CO| Flags |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Color Value | * | Color Value |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* https://datatracker.ietf.org/doc/rfc9256/, Section 8.8.1
* The CO bits can have 4 different values: 00 01 10 11
*/ */
uint32_t colorid; uint32_t colorid;
uint8_t color_type;
/* get the color type */
ptr++;
color_type = (*ptr) >> 6;
memcpy(&colorid, ptr + 3, 4); memcpy(&colorid, ptr + 2, 4);
colorid = ntohl(colorid); 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. */ /* Initialize Extended Comminities related hash. */
@ -531,7 +537,7 @@ static int ecommunity_encode_internal(uint8_t type, uint8_t sub_type,
eval6->val[19] = val & 0xff; eval6->val[19] = val & 0xff;
} else if (type == ECOMMUNITY_ENCODE_OPAQUE && } else if (type == ECOMMUNITY_ENCODE_OPAQUE &&
sub_type == ECOMMUNITY_COLOR) { sub_type == ECOMMUNITY_COLOR) {
encode_color(val, eval); encode_color(val, as, eval);
} else { } else {
encode_route_target_as4(as, val, eval, trans); encode_route_target_as4(as, val, eval, trans);
} }
@ -739,6 +745,13 @@ static const char *ecommunity_gettoken(const char *str, void *eval_ptr,
*/ */
if (!asn_str2asn(buf, &as)) if (!asn_str2asn(buf, &as))
goto error; 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 { } else {
/* Parsing A AS number in A:MN */ /* Parsing A AS number in A:MN */
errno = 0; errno = 0;
@ -753,6 +766,8 @@ static const char *ecommunity_gettoken(const char *str, void *eval_ptr,
if (*endptr != '\0' || tmp_as > BGP_AS4_MAX || if (*endptr != '\0' || tmp_as > BGP_AS4_MAX ||
errno) errno)
goto error; goto error;
if (*token == ecommunity_token_color && as > 3)
goto error;
as = (as_t)tmp_as; as = (as_t)tmp_as;
} }
} else if (*p == '.') { } else if (*p == '.') {
@ -791,13 +806,15 @@ static const char *ecommunity_gettoken(const char *str, void *eval_ptr,
/* Encode result into extended community for AS format or color. */ /* Encode result into extended community for AS format or color. */
if (as > BGP_AS_MAX) if (as > BGP_AS_MAX)
ecomm_type = ECOMMUNITY_ENCODE_AS4; ecomm_type = ECOMMUNITY_ENCODE_AS4;
else if (as > 0) else if (type == ECOMMUNITY_COLOR) {
ecomm_type = ECOMMUNITY_ENCODE_AS;
else if (val_color) {
ecomm_type = ECOMMUNITY_ENCODE_OPAQUE; ecomm_type = ECOMMUNITY_ENCODE_OPAQUE;
sub_type = ECOMMUNITY_COLOR; 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)) if (ecommunity_encode(ecomm_type, sub_type, 1, as, ip, val, eval))
goto error; goto error;
@ -1419,7 +1436,15 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter)
else if (sub_type == ECOMMUNITY_EXTENDED_LINK_BANDWIDTH) else if (sub_type == ECOMMUNITY_EXTENDED_LINK_BANDWIDTH)
ipv6_ecommunity_lb_str(encbuf, sizeof(encbuf), ipv6_ecommunity_lb_str(encbuf, sizeof(encbuf),
pnt, len); 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; unk_ecom = true;
} else if (CHECK_FLAG(type, ECOMMUNITY_ENCODE_IP_NON_TRANS)) { } else if (CHECK_FLAG(type, ECOMMUNITY_ENCODE_IP_NON_TRANS)) {
sub_type = *pnt++; sub_type = *pnt++;
@ -1439,6 +1464,7 @@ unknown:
sub_type); sub_type);
int r = strlcat(str_buf, encbuf, str_size); int r = strlcat(str_buf, encbuf, str_size);
assert(r < str_size); assert(r < str_size);
} }

View File

@ -85,6 +85,7 @@
/* Low-order octet of the Extended Communities type field for OPAQUE types */ /* Low-order octet of the Extended Communities type field for OPAQUE types */
#define ECOMMUNITY_OPAQUE_SUBTYPE_ENCAP 0x0c #define ECOMMUNITY_OPAQUE_SUBTYPE_ENCAP 0x0c
#define ECOMMUNITY_OPAQUE_SUBTYPE_COLOR 0x0b
/* Extended communities attribute string format. */ /* Extended communities attribute string format. */
#define ECOMMUNITY_FORMAT_ROUTE_MAP 0 #define ECOMMUNITY_FORMAT_ROUTE_MAP 0
@ -328,26 +329,25 @@ static inline void encode_node_target(struct in_addr *node_id,
/* /*
* Encode BGP Color extended community * Encode BGP Color extended community
* is's a transitive opaque Extended community (RFC 9012 4.3) * is's a transitive opaque Extended community (RFC 9256 8.8.1)
* flag is set to 0 * flag is set to 0
* RFC 9012 14.10: No values have currently been registered.
* 4.3: this field MUST be set to zero by the originator
* 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, uint32_t flags, struct ecommunity_val *eval)
{ {
/* /*
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | 0x03 | Sub-Type(0x0b) | Flags | * | 0x03 | Sub-Type(0x0b) |CO | Flags |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Color Value | * | Color Value |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* https://datatracker.ietf.org/doc/rfc9256/, Section 8.8.1
* The CO bits can have 4 different values: 00 01 10 11
*/ */
memset(eval, 0, sizeof(*eval)); memset(eval, 0, sizeof(*eval));
eval->val[0] = ECOMMUNITY_ENCODE_OPAQUE; eval->val[0] = ECOMMUNITY_ENCODE_OPAQUE;
eval->val[1] = ECOMMUNITY_COLOR; eval->val[1] = ECOMMUNITY_COLOR;
eval->val[2] = 0x00; eval->val[2] = (flags << 6) & 0xff;
eval->val[3] = 0x00; eval->val[3] = 0x00;
eval->val[4] = (color_id >> 24) & 0xff; eval->val[4] = (color_id >> 24) & 0xff;
eval->val[5] = (color_id >> 16) & 0xff; eval->val[5] = (color_id >> 16) & 0xff;

View File

@ -2928,6 +2928,23 @@ BGP Extended Communities in Route Map
This command sets colors values. This command sets colors values.
:rfc:`9256`.
``CO:COLOR``
This is a format to define colors value. ``CO`` part is always 00 (default),
it can be used to support the requirements of Color-Only steering when using
a Null Endpoint in the SR-TE Policy as specified in Section 8.8 of [RFC9256].
The below shows in detail what the different combinations of ``CO`` bits can
match on to for the purpose of determining what type of SR-TE Policy Tunnel
a BGP route can resolve over, and it also shows the order for resolving the
BGP route if there are different tunnels.
- ``00`` Can match on a specific endpoint only which should be the nexthop
of the route(Default Setting).
- ``01`` Can match on a specific endpoint or a null endpoint.
- ``10`` Can match on a specific endpoint, null endpoint or any endpoint.
- ``11`` Reserved for future use and shuould not be used.
.. clicmd:: set extcommunity bandwidth <(1-25600) | cumulative | num-multipaths> [non-transitive] .. clicmd:: set extcommunity bandwidth <(1-25600) | cumulative | num-multipaths> [non-transitive]
This command sets the BGP link-bandwidth extended community for the prefix This command sets the BGP link-bandwidth extended community for the prefix

View File

@ -11,7 +11,7 @@ router bgp 65001
exit-address-family exit-address-family
! !
route-map rmap permit 10 route-map rmap permit 10
set extcommunity color 1 set extcommunity color 01:1
set extcommunity rt 80:987 set extcommunity rt 80:987
set extcommunity color 100 55555 200 set extcommunity color 01:100 01:55555 01:200
exit exit

View File

@ -105,7 +105,7 @@ def test_bgp_color_extended_communities():
{ {
"valid": True, "valid": True,
"extendedCommunity": { "extendedCommunity": {
"string": "RT:80:987 Color:100 Color:200 Color:55555" "string": "RT:80:987 Color:01:100 Color:01:200 Color:01:55555"
}, },
} }
], ],

View File

@ -532,7 +532,7 @@ identity set-extcommunity-color {
typedef color-list { typedef color-list {
type string { type string {
pattern '((429496729[0-5]|42949672[0-8][0-9]|' pattern '((00|01|10|11):(429496729[0-5]|42949672[0-8][0-9]|'
+ '4294967[0-1][0-9]{2}|429496[0-6][0-9]{3}|' + '4294967[0-1][0-9]{2}|429496[0-6][0-9]{3}|'
+ '42949[0-5][0-9]{4}|4294[0-8][0-9]{5}|' + '42949[0-5][0-9]{4}|4294[0-8][0-9]{5}|'
+ '429[0-3][0-9]{6}|42[0-8][0-9]{7}|' + '429[0-3][0-9]{6}|42[0-8][0-9]{7}|'
@ -540,10 +540,11 @@ identity set-extcommunity-color {
+ '[1-9][0-9]{0,8})(\s*))+'; + '[1-9][0-9]{0,8})(\s*))+';
} }
description 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"; values are separated by white spaces";
reference reference
"RFC 9012 - The BGP Tunnel Encapsulation Attribute"; "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" { 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" {