diff options
author | Donatas Abraitis <donatas@opensourcerouting.org> | 2024-11-08 07:56:21 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-11-08 07:56:21 +0100 |
commit | af9a2cb875e699078a307e119a0009ae18eb26eb (patch) | |
tree | 2ce2d72a6214ec9536222318b6c2dd5e8c1f7f7f | |
parent | Merge pull request #12109 from donaldsharp/routemap_time_spent (diff) | |
parent | doc:the doc of extcomumnity color (diff) | |
download | frr-af9a2cb875e699078a307e119a0009ae18eb26eb.tar.xz frr-af9a2cb875e699078a307e119a0009ae18eb26eb.zip |
Merge pull request #17231 from guoguojia2021/guozhongfeng_alibaba
bgpd:support of color extended community color-only types
-rw-r--r-- | bgpd/bgp_ecommunity.c | 46 | ||||
-rw-r--r-- | bgpd/bgp_ecommunity.h | 14 | ||||
-rw-r--r-- | doc/user/bgp.rst | 17 | ||||
-rw-r--r-- | tests/topotests/bgp_color_extcommunities/r1/bgpd.conf | 4 | ||||
-rw-r--r-- | tests/topotests/bgp_color_extcommunities/test_bgp_color_extcommunities.py | 2 | ||||
-rw-r--r-- | yang/frr-bgp-route-map.yang | 7 |
6 files changed, 67 insertions, 23 deletions
diff --git a/bgpd/bgp_ecommunity.c b/bgpd/bgp_ecommunity.c index df32d7510..065f4fef3 100644 --- a/bgpd/bgp_ecommunity.c +++ b/bgpd/bgp_ecommunity.c @@ -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 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * 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; + 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); - 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. */ @@ -531,7 +537,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); } @@ -739,6 +745,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; @@ -753,6 +766,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 == '.') { @@ -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. */ 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; @@ -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++; @@ -1439,6 +1464,7 @@ unknown: sub_type); int r = strlcat(str_buf, encbuf, str_size); + assert(r < str_size); } diff --git a/bgpd/bgp_ecommunity.h b/bgpd/bgp_ecommunity.h index 0544cbd31..af9d481c1 100644 --- a/bgpd/bgp_ecommunity.h +++ b/bgpd/bgp_ecommunity.h @@ -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 @@ -328,26 +329,25 @@ static inline void encode_node_target(struct in_addr *node_id, /* * 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 - * 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 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * 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)); eval->val[0] = ECOMMUNITY_ENCODE_OPAQUE; eval->val[1] = ECOMMUNITY_COLOR; - eval->val[2] = 0x00; + eval->val[2] = (flags << 6) & 0xff; eval->val[3] = 0x00; eval->val[4] = (color_id >> 24) & 0xff; eval->val[5] = (color_id >> 16) & 0xff; diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst index 20a9ef84f..0c7fcecb9 100644 --- a/doc/user/bgp.rst +++ b/doc/user/bgp.rst @@ -2928,6 +2928,23 @@ BGP Extended Communities in Route Map 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] This command sets the BGP link-bandwidth extended community for the prefix diff --git a/tests/topotests/bgp_color_extcommunities/r1/bgpd.conf b/tests/topotests/bgp_color_extcommunities/r1/bgpd.conf index d4ca392b1..30cb6647a 100644 --- a/tests/topotests/bgp_color_extcommunities/r1/bgpd.conf +++ b/tests/topotests/bgp_color_extcommunities/r1/bgpd.conf @@ -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 diff --git a/tests/topotests/bgp_color_extcommunities/test_bgp_color_extcommunities.py b/tests/topotests/bgp_color_extcommunities/test_bgp_color_extcommunities.py index 09091198a..94a444d5c 100644 --- a/tests/topotests/bgp_color_extcommunities/test_bgp_color_extcommunities.py +++ b/tests/topotests/bgp_color_extcommunities/test_bgp_color_extcommunities.py @@ -105,7 +105,7 @@ def test_bgp_color_extended_communities(): { "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" }, } ], diff --git a/yang/frr-bgp-route-map.yang b/yang/frr-bgp-route-map.yang index 4ed80d7d0..5f701d514 100644 --- a/yang/frr-bgp-route-map.yang +++ b/yang/frr-bgp-route-map.yang @@ -532,7 +532,7 @@ identity set-extcommunity-color { typedef color-list { 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}|' + '42949[0-5][0-9]{4}|4294[0-8][0-9]{5}|' + '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*))+'; } 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 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" { |