mirror of
https://github.com/FRRouting/frr.git
synced 2025-05-01 05:57:15 +02:00
bgpd:support of color extended community color-only types
Add support of color extended community color-only types, RFC 9256. The type only support 00 01 10. configuration example: ! frr version 10.3-dev-my-manual-build frr defaults traditional hostname router3 ! route-map color permit 1 set extcommunity color 10:100 01:200 00:300 exit ! vrf Vrf1 exit-vrf ! interface lo ipv6 address 3::3/128 exit ! router bgp 3 bgp router-id 3.3.3.3 bgp log-neighbor-changes no bgp ebgp-requires-policy no bgp default ipv4-unicast bgp bestpath as-path multipath-relax timers bgp 10 30 neighbor 100.13.13.1 remote-as 1 neighbor 100.13.13.1 advertisement-interval 0 neighbor 100.23.23.2 remote-as 2 neighbor 100.23.23.2 advertisement-interval 0 neighbor 1000:3000::1 remote-as 1 neighbor 1000:3000::1 ebgp-multihop neighbor 1000:3000::1 update-source 1000:3000::3 neighbor 1000:3000::1 capability extended-nexthop neighbor 2000:3000::2 remote-as 2 neighbor 2000:3000::2 ebgp-multihop neighbor 2000:3000::2 update-source 2000:3000::3 neighbor 2000:3000::2 capability extended-nexthop ! address-family ipv4 unicast neighbor 100.13.13.1 activate neighbor 100.23.23.2 activate exit-address-family ! address-family ipv6 unicast redistribute connected route-map color neighbor 1000:3000::1 activate neighbor 2000:3000::2 activate exit-address-family exit ! end Signed-off-by: guozhongfeng.gzf <guozhongfeng.gzf@alibaba-inc.com>
This commit is contained in:
parent
91e157f3ae
commit
937cf4db17
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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" {
|
||||||
|
|
Loading…
Reference in a new issue