Skip to content

Commit

Permalink
bgpd:support of color extended community color-only types
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
guoguojia2021 committed Oct 24, 2024
1 parent 91e157f commit a3a9ba1
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 13 deletions.
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;

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;
eval->val[3] = 0x00;
eval->val[4] = (color_id >> 24) & 0xff;
eval->val[5] = (color_id >> 16) & 0xff;
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

0 comments on commit a3a9ba1

Please sign in to comment.