forked from Mirror/frr
bgpd: add colored extended communities support
add support of color extended community, conforming to RFC 9012. This extended community will be added to the existing one, RT,SOO and Node Target. The configuration will be made through the route-map service. find above a configuration example: router bgp 65001 bgp router-id 192.168.1.1 no bgp ebgp-requires-policy no bgp network import-check neighbor 192.168.1.2 remote-as external neighbor 192.168.1.3 remote-as external neighbor 192.168.1.4 remote-as external address-family ipv4 unicast network 10.10.10.10/24 route-map rmap exit-address-family ! route-map rmap permit 10 set extcommunity color 55555 200 exit Signed-off-by: Francois Dumontet <francois.dumontet@6wind.com>
This commit is contained in:
parent
53a9aee618
commit
b80ebc2d8c
|
@ -355,6 +355,22 @@ bool ecommunity_cmp(const void *arg1, const void *arg2)
|
|||
ecom1->unit_size) == 0);
|
||||
}
|
||||
|
||||
static void ecommunity_color_str(char *buf, size_t bufsz, uint8_t *ptr)
|
||||
{
|
||||
/*
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | 0x03 | Sub-Type(0x0b) | Flags |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Color Value |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
uint32_t colorid;
|
||||
|
||||
memcpy(&colorid, ptr + 3, 4);
|
||||
colorid = ntohl(colorid);
|
||||
snprintf(buf, bufsz, "Color:%d", colorid);
|
||||
}
|
||||
|
||||
/* Initialize Extended Comminities related hash. */
|
||||
void ecommunity_init(void)
|
||||
{
|
||||
|
@ -373,6 +389,7 @@ enum ecommunity_token {
|
|||
ecommunity_token_rt,
|
||||
ecommunity_token_nt,
|
||||
ecommunity_token_soo,
|
||||
ecommunity_token_color,
|
||||
ecommunity_token_val,
|
||||
ecommunity_token_rt6,
|
||||
ecommunity_token_val6,
|
||||
|
@ -510,6 +527,9 @@ static int ecommunity_encode_internal(uint8_t type, uint8_t sub_type,
|
|||
memcpy(&eval6->val[2], ip6, sizeof(struct in6_addr));
|
||||
eval6->val[18] = (val >> 8) & 0xff;
|
||||
eval6->val[19] = val & 0xff;
|
||||
} else if (type == ECOMMUNITY_ENCODE_OPAQUE &&
|
||||
sub_type == ECOMMUNITY_COLOR) {
|
||||
encode_color(val, eval);
|
||||
} else {
|
||||
encode_route_target_as4(as, val, eval, trans);
|
||||
}
|
||||
|
@ -537,16 +557,22 @@ static const char *ecommunity_gettoken(const char *str, void *eval_ptr,
|
|||
int dot = 0;
|
||||
int digit = 0;
|
||||
int separator = 0;
|
||||
int i;
|
||||
const char *p = str;
|
||||
char *endptr;
|
||||
struct in_addr ip;
|
||||
struct in6_addr ip6;
|
||||
as_t as = 0;
|
||||
uint32_t val = 0;
|
||||
uint8_t ecomm_type;
|
||||
uint32_t val_color = 0;
|
||||
uint8_t ecomm_type = 0;
|
||||
uint8_t sub_type = 0;
|
||||
char buf[INET_ADDRSTRLEN + 1];
|
||||
struct ecommunity_val *eval = (struct ecommunity_val *)eval_ptr;
|
||||
uint64_t tmp_as = 0;
|
||||
static const char str_color[5] = "color";
|
||||
const char *ptr_color;
|
||||
bool val_color_set = false;
|
||||
|
||||
/* Skip white space. */
|
||||
while (isspace((unsigned char)*p)) {
|
||||
|
@ -558,7 +584,7 @@ static const char *ecommunity_gettoken(const char *str, void *eval_ptr,
|
|||
if (*p == '\0')
|
||||
return NULL;
|
||||
|
||||
/* "rt", "nt", and "soo" keyword parse. */
|
||||
/* "rt", "nt", "soo", and "color" keyword parse. */
|
||||
if (!isdigit((unsigned char)*p)) {
|
||||
/* "rt" match check. */
|
||||
if (tolower((unsigned char)*p) == 'r') {
|
||||
|
@ -612,10 +638,33 @@ static const char *ecommunity_gettoken(const char *str, void *eval_ptr,
|
|||
return p;
|
||||
}
|
||||
goto error;
|
||||
} else if (tolower((unsigned char)*p) == 'c') {
|
||||
/* "color" match check.
|
||||
* 'c', 'co', 'col', 'colo' are also accepted
|
||||
*/
|
||||
for (i = 0; i < 5; i++) {
|
||||
ptr_color = &str_color[0];
|
||||
if (tolower((unsigned char)*p) == *ptr_color) {
|
||||
p++;
|
||||
ptr_color++;
|
||||
} else if (i > 0) {
|
||||
if (isspace((unsigned char)*p) ||
|
||||
*p == '\0') {
|
||||
*token = ecommunity_token_color;
|
||||
return p;
|
||||
}
|
||||
goto error;
|
||||
}
|
||||
if (isspace((unsigned char)*p) || *p == '\0') {
|
||||
*token = ecommunity_token_color;
|
||||
return p;
|
||||
}
|
||||
goto error;
|
||||
}
|
||||
goto error;
|
||||
}
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* What a mess, there are several possibilities:
|
||||
*
|
||||
* a) A.B.C.D:MN
|
||||
|
@ -716,17 +765,24 @@ static const char *ecommunity_gettoken(const char *str, void *eval_ptr,
|
|||
} else {
|
||||
digit = 1;
|
||||
|
||||
/* We're past the IP/ASN part */
|
||||
/* We're past the IP/ASN part,
|
||||
* or we have a color
|
||||
*/
|
||||
if (separator) {
|
||||
val *= 10;
|
||||
val += (*p - '0');
|
||||
val_color_set = false;
|
||||
} else {
|
||||
val_color *= 10;
|
||||
val_color += (*p - '0');
|
||||
val_color_set = true;
|
||||
}
|
||||
}
|
||||
p++;
|
||||
}
|
||||
|
||||
/* Low digit part must be there. */
|
||||
if (!digit || !separator)
|
||||
if (!digit && (!separator || !val_color_set))
|
||||
goto error;
|
||||
|
||||
/* Encode result into extended community. */
|
||||
|
@ -734,9 +790,15 @@ static const char *ecommunity_gettoken(const char *str, void *eval_ptr,
|
|||
ecomm_type = ECOMMUNITY_ENCODE_IP;
|
||||
else if (as > BGP_AS_MAX)
|
||||
ecomm_type = ECOMMUNITY_ENCODE_AS4;
|
||||
else
|
||||
else if (as > 0)
|
||||
ecomm_type = ECOMMUNITY_ENCODE_AS;
|
||||
if (ecommunity_encode(ecomm_type, type, 1, as, ip, val, eval))
|
||||
else if (val_color) {
|
||||
ecomm_type = ECOMMUNITY_ENCODE_OPAQUE;
|
||||
sub_type = ECOMMUNITY_COLOR;
|
||||
val = val_color;
|
||||
}
|
||||
|
||||
if (ecommunity_encode(ecomm_type, sub_type, 1, as, ip, val, eval))
|
||||
goto error;
|
||||
*token = ecommunity_token_val;
|
||||
return p;
|
||||
|
@ -763,6 +825,7 @@ static struct ecommunity *ecommunity_str2com_internal(const char *str, int type,
|
|||
case ecommunity_token_nt:
|
||||
case ecommunity_token_rt6:
|
||||
case ecommunity_token_soo:
|
||||
case ecommunity_token_color:
|
||||
if (!keyword_included || keyword) {
|
||||
if (ecom)
|
||||
ecommunity_free(&ecom);
|
||||
|
@ -771,15 +834,14 @@ static struct ecommunity *ecommunity_str2com_internal(const char *str, int type,
|
|||
keyword = 1;
|
||||
|
||||
if (token == ecommunity_token_rt ||
|
||||
token == ecommunity_token_rt6) {
|
||||
token == ecommunity_token_rt6)
|
||||
type = ECOMMUNITY_ROUTE_TARGET;
|
||||
}
|
||||
if (token == ecommunity_token_soo) {
|
||||
if (token == ecommunity_token_soo)
|
||||
type = ECOMMUNITY_SITE_ORIGIN;
|
||||
}
|
||||
if (token == ecommunity_token_nt) {
|
||||
if (token == ecommunity_token_nt)
|
||||
type = ECOMMUNITY_NODE_TARGET;
|
||||
}
|
||||
if (token == ecommunity_token_color)
|
||||
type = ECOMMUNITY_COLOR;
|
||||
break;
|
||||
case ecommunity_token_val:
|
||||
if (keyword_included) {
|
||||
|
@ -998,10 +1060,12 @@ static int ecommunity_lb_str(char *buf, size_t bufsz, const uint8_t *pnt,
|
|||
"rt 100:1 100:2soo 100:3"
|
||||
|
||||
extcommunity-list
|
||||
"rt 100:1 rt 100:2 soo 100:3show [ip] bgp" and extcommunity-list regular expression matching
|
||||
"rt 100:1 rt 100:2 soo 100:3
|
||||
show [ip] bgp"
|
||||
and extcommunity-list regular expression matching
|
||||
"RT:100:1 RT:100:2 SoO:100:3"
|
||||
|
||||
For each formath please use below definition for format:
|
||||
For each format please use below definition for format:
|
||||
|
||||
ECOMMUNITY_FORMAT_ROUTE_MAP
|
||||
ECOMMUNITY_FORMAT_COMMUNITY_LIST
|
||||
|
@ -1086,6 +1150,9 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter)
|
|||
} else if (*pnt == ECOMMUNITY_EVPN_SUBTYPE_DEF_GW) {
|
||||
strlcpy(encbuf, "Default Gateway",
|
||||
sizeof(encbuf));
|
||||
} else if (*pnt == ECOMMUNITY_COLOR) {
|
||||
ecommunity_color_str(encbuf, sizeof(encbuf),
|
||||
pnt);
|
||||
} else {
|
||||
unk_ecom = 1;
|
||||
}
|
||||
|
|
|
@ -46,6 +46,8 @@
|
|||
#define ECOMMUNITY_REDIRECT_VRF 0x08
|
||||
#define ECOMMUNITY_TRAFFIC_MARKING 0x09
|
||||
#define ECOMMUNITY_REDIRECT_IP_NH 0x00
|
||||
#define ECOMMUNITY_COLOR 0x0b /* RFC9012 - color */
|
||||
|
||||
/* from IANA: bgp-extended-communities/bgp-extended-communities.xhtml
|
||||
* 0x0c Flow-spec Redirect to IPv4 - draft-ietf-idr-flowspec-redirect
|
||||
*/
|
||||
|
@ -290,6 +292,35 @@ static inline void encode_node_target(struct in_addr *node_id,
|
|||
eval->val[7] = ECOMMUNITY_NODE_TARGET_RESERVED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Encode BGP Color extended community
|
||||
* is's a transitive opaque Extended community (RFC 9012 4.3)
|
||||
* 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)
|
||||
{
|
||||
/*
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | 0x03 | Sub-Type(0x0b) | Flags |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Color Value |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
memset(eval, 0, sizeof(*eval));
|
||||
eval->val[0] = ECOMMUNITY_ENCODE_OPAQUE;
|
||||
eval->val[1] = ECOMMUNITY_COLOR;
|
||||
eval->val[2] = 0x00;
|
||||
eval->val[3] = 0x00;
|
||||
eval->val[4] = (color_id >> 24) & 0xff;
|
||||
eval->val[5] = (color_id >> 16) & 0xff;
|
||||
eval->val[6] = (color_id >> 8) & 0xff;
|
||||
eval->val[7] = color_id & 0xff;
|
||||
}
|
||||
|
||||
extern void ecommunity_init(void);
|
||||
extern void ecommunity_finish(void);
|
||||
extern void ecommunity_free(struct ecommunity **);
|
||||
|
@ -314,7 +345,7 @@ extern void ecommunity_strfree(char **s);
|
|||
extern bool ecommunity_include(struct ecommunity *e1, struct ecommunity *e2);
|
||||
extern bool ecommunity_match(const struct ecommunity *,
|
||||
const struct ecommunity *);
|
||||
extern char *ecommunity_str(struct ecommunity *);
|
||||
extern char *ecommunity_str(struct ecommunity *ecom);
|
||||
extern struct ecommunity_val *ecommunity_lookup(const struct ecommunity *,
|
||||
uint8_t, uint8_t);
|
||||
|
||||
|
|
|
@ -3055,6 +3055,44 @@ static void *route_set_ecommunity_lb_compile(const char *arg)
|
|||
return rels;
|
||||
}
|
||||
|
||||
static enum route_map_cmd_result_t
|
||||
route_set_ecommunity_color(void *rule, const struct prefix *prefix,
|
||||
void *object)
|
||||
{
|
||||
struct bgp_path_info *path;
|
||||
|
||||
path = object;
|
||||
|
||||
route_set_ecommunity(rule, prefix, object);
|
||||
|
||||
path->attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_SRTE_COLOR);
|
||||
return RMAP_OKAY;
|
||||
}
|
||||
|
||||
static void *route_set_ecommunity_color_compile(const char *arg)
|
||||
{
|
||||
struct rmap_ecom_set *rcs;
|
||||
struct ecommunity *ecom;
|
||||
|
||||
ecom = ecommunity_str2com(arg, ECOMMUNITY_COLOR, 0);
|
||||
if (!ecom)
|
||||
return NULL;
|
||||
|
||||
rcs = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct rmap_ecom_set));
|
||||
rcs->ecom = ecommunity_intern(ecom);
|
||||
rcs->none = false;
|
||||
|
||||
return rcs;
|
||||
}
|
||||
|
||||
static const struct route_map_rule_cmd route_set_ecommunity_color_cmd = {
|
||||
"extcommunity color",
|
||||
route_set_ecommunity_color,
|
||||
route_set_ecommunity_color_compile,
|
||||
route_set_ecommunity_free,
|
||||
};
|
||||
|
||||
|
||||
static void route_set_ecommunity_lb_free(void *rule)
|
||||
{
|
||||
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
|
||||
|
@ -6522,6 +6560,57 @@ DEFPY_YANG (no_set_ecommunity_nt,
|
|||
return nb_cli_apply_changes(vty, NULL);
|
||||
}
|
||||
|
||||
DEFPY_YANG(set_ecommunity_color, set_ecommunity_color_cmd,
|
||||
"set extcommunity color RTLIST...",
|
||||
SET_STR
|
||||
"BGP extended community attribute\n"
|
||||
"Color extended community\n"
|
||||
"Color ID\n")
|
||||
{
|
||||
int idx_color = 3;
|
||||
char *str;
|
||||
int ret;
|
||||
const char *xpath =
|
||||
"./set-action[action='frr-bgp-route-map:set-extcommunity-color']";
|
||||
char xpath_value[XPATH_MAXLEN];
|
||||
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
||||
|
||||
snprintf(xpath_value, sizeof(xpath_value),
|
||||
"%s/rmap-set-action/frr-bgp-route-map:extcommunity-color",
|
||||
xpath);
|
||||
str = argv_concat(argv, argc, idx_color);
|
||||
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, str);
|
||||
ret = nb_cli_apply_changes(vty, NULL);
|
||||
XFREE(MTYPE_TMP, str);
|
||||
return ret;
|
||||
}
|
||||
|
||||
DEFPY_YANG(no_set_ecommunity_color_all, no_set_ecommunity_color_all_cmd,
|
||||
"no set extcommunity color",
|
||||
NO_STR SET_STR
|
||||
"BGP extended community attribute\n"
|
||||
"Color extended community\n")
|
||||
{
|
||||
const char *xpath =
|
||||
"./set-action[action='frr-bgp-route-map:set-extcommunity-color']";
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
||||
return nb_cli_apply_changes(vty, NULL);
|
||||
}
|
||||
|
||||
DEFPY_YANG(no_set_ecommunity_color, no_set_ecommunity_color_cmd,
|
||||
"no set extcommunity color RTLIST...",
|
||||
NO_STR SET_STR
|
||||
"BGP extended community attribute\n"
|
||||
"Color extended community\n"
|
||||
"Color ID\n")
|
||||
{
|
||||
const char *xpath =
|
||||
"./set-action[action='frr-bgp-route-map:set-extcommunity-color']";
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
||||
return nb_cli_apply_changes(vty, NULL);
|
||||
}
|
||||
|
||||
ALIAS_YANG (no_set_ecommunity_nt,
|
||||
no_set_ecommunity_nt_short_cmd,
|
||||
"no set extcommunity nt",
|
||||
|
@ -7375,6 +7464,7 @@ void bgp_route_map_init(void)
|
|||
route_map_install_set(&route_set_ecommunity_nt_cmd);
|
||||
route_map_install_set(&route_set_ecommunity_soo_cmd);
|
||||
route_map_install_set(&route_set_ecommunity_lb_cmd);
|
||||
route_map_install_set(&route_set_ecommunity_color_cmd);
|
||||
route_map_install_set(&route_set_ecommunity_none_cmd);
|
||||
route_map_install_set(&route_set_tag_cmd);
|
||||
route_map_install_set(&route_set_label_index_cmd);
|
||||
|
@ -7478,6 +7568,9 @@ void bgp_route_map_init(void)
|
|||
install_element(RMAP_NODE, &set_ecommunity_nt_cmd);
|
||||
install_element(RMAP_NODE, &no_set_ecommunity_nt_cmd);
|
||||
install_element(RMAP_NODE, &no_set_ecommunity_nt_short_cmd);
|
||||
install_element(RMAP_NODE, &set_ecommunity_color_cmd);
|
||||
install_element(RMAP_NODE, &no_set_ecommunity_color_cmd);
|
||||
install_element(RMAP_NODE, &no_set_ecommunity_color_all_cmd);
|
||||
#ifdef KEEP_OLD_VPN_COMMANDS
|
||||
install_element(RMAP_NODE, &set_vpn_nexthop_cmd);
|
||||
install_element(RMAP_NODE, &no_set_vpn_nexthop_cmd);
|
||||
|
|
|
@ -400,6 +400,13 @@ const struct frr_yang_module_info frr_bgp_route_map_info = {
|
|||
.destroy = lib_route_map_entry_set_action_rmap_set_action_extcommunity_lb_bandwidth_destroy,
|
||||
}
|
||||
},
|
||||
{
|
||||
.xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:extcommunity-color",
|
||||
.cbs = {
|
||||
.modify = lib_route_map_entry_set_action_rmap_set_action_extcommunity_color_modify,
|
||||
.destroy = lib_route_map_entry_set_action_rmap_set_action_extcommunity_color_destroy,
|
||||
}
|
||||
},
|
||||
{
|
||||
.xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:extcommunity-lb/two-octet-as-specific",
|
||||
.cbs = {
|
||||
|
|
|
@ -153,6 +153,10 @@ int lib_route_map_entry_set_action_rmap_set_action_evpn_gateway_ip_ipv6_modify(
|
|||
struct nb_cb_modify_args *args);
|
||||
int lib_route_map_entry_set_action_rmap_set_action_evpn_gateway_ip_ipv6_destroy(
|
||||
struct nb_cb_destroy_args *args);
|
||||
int lib_route_map_entry_set_action_rmap_set_action_extcommunity_color_modify(
|
||||
struct nb_cb_modify_args *args);
|
||||
int lib_route_map_entry_set_action_rmap_set_action_extcommunity_color_destroy(
|
||||
struct nb_cb_destroy_args *args);
|
||||
int lib_route_map_entry_set_action_rmap_set_action_l3vpn_nexthop_encapsulation_modify(
|
||||
struct nb_cb_modify_args *args);
|
||||
int lib_route_map_entry_set_action_rmap_set_action_l3vpn_nexthop_encapsulation_destroy(
|
||||
|
|
|
@ -2952,6 +2952,58 @@ lib_route_map_entry_set_action_rmap_set_action_extcommunity_lb_bandwidth_destroy
|
|||
return lib_route_map_entry_set_destroy(args);
|
||||
}
|
||||
|
||||
/*
|
||||
* XPath:
|
||||
* /frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:extcommunity-color
|
||||
*/
|
||||
int lib_route_map_entry_set_action_rmap_set_action_extcommunity_color_modify(
|
||||
struct nb_cb_modify_args *args)
|
||||
{
|
||||
struct routemap_hook_context *rhc;
|
||||
const char *str;
|
||||
int rv;
|
||||
|
||||
switch (args->event) {
|
||||
case NB_EV_VALIDATE:
|
||||
case NB_EV_PREPARE:
|
||||
case NB_EV_ABORT:
|
||||
break;
|
||||
case NB_EV_APPLY:
|
||||
/* Add configuration. */
|
||||
rhc = nb_running_get_entry(args->dnode, NULL, true);
|
||||
str = yang_dnode_get_string(args->dnode, NULL);
|
||||
|
||||
/* Set destroy information. */
|
||||
rhc->rhc_shook = generic_set_delete;
|
||||
rhc->rhc_rule = "extcommunity color";
|
||||
rhc->rhc_event = RMAP_EVENT_SET_DELETED;
|
||||
|
||||
rv = generic_set_add(rhc->rhc_rmi, "extcommunity color", str,
|
||||
args->errmsg, args->errmsg_len);
|
||||
if (rv != CMD_SUCCESS) {
|
||||
rhc->rhc_shook = NULL;
|
||||
return NB_ERR_INCONSISTENCY;
|
||||
}
|
||||
}
|
||||
|
||||
return NB_OK;
|
||||
}
|
||||
|
||||
int lib_route_map_entry_set_action_rmap_set_action_extcommunity_color_destroy(
|
||||
struct nb_cb_destroy_args *args)
|
||||
{
|
||||
switch (args->event) {
|
||||
case NB_EV_VALIDATE:
|
||||
case NB_EV_PREPARE:
|
||||
case NB_EV_ABORT:
|
||||
break;
|
||||
case NB_EV_APPLY:
|
||||
return lib_route_map_entry_match_destroy(args);
|
||||
}
|
||||
|
||||
return NB_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* XPath:
|
||||
* /frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:extcommunity-lb/two-octet-as-specific
|
||||
|
|
|
@ -362,6 +362,9 @@ DECLARE_QOBJ_TYPE(route_map);
|
|||
(strmatch(A, "frr-bgp-route-map:set-extcommunity-soo"))
|
||||
#define IS_SET_EXTCOMMUNITY_LB(A) \
|
||||
(strmatch(A, "frr-bgp-route-map:set-extcommunity-lb"))
|
||||
#define IS_SET_EXTCOMMUNITY_COLOR(A) \
|
||||
(strmatch(A, "frr-bgp-route-map:set-extcommunity-color"))
|
||||
|
||||
#define IS_SET_AGGREGATOR(A) \
|
||||
(strmatch(A, "frr-bgp-route-map:aggregator"))
|
||||
#define IS_SET_AS_PREPEND(A) \
|
||||
|
|
|
@ -1259,6 +1259,11 @@ void route_map_action_show(struct vty *vty, const struct lyd_node *dnode,
|
|||
strlcat(str, " non-transitive", sizeof(str));
|
||||
|
||||
vty_out(vty, " set extcommunity bandwidth %s\n", str);
|
||||
} else if (IS_SET_EXTCOMMUNITY_COLOR(action)) {
|
||||
vty_out(vty, " set extcommunity color %s\n",
|
||||
yang_dnode_get_string(
|
||||
dnode,
|
||||
"./rmap-set-action/frr-bgp-route-map:extcommunity-color"));
|
||||
} else if (IS_SET_EXTCOMMUNITY_NONE(action)) {
|
||||
if (yang_dnode_get_bool(
|
||||
dnode,
|
||||
|
|
|
@ -214,6 +214,12 @@ module frr-bgp-route-map {
|
|||
"Set BGP extended community attribute";
|
||||
}
|
||||
|
||||
identity set-extcommunity-color {
|
||||
base frr-route-map:rmap-set-type;
|
||||
description
|
||||
"Set BGP extended community attribute";
|
||||
}
|
||||
|
||||
identity set-ipv4-nexthop {
|
||||
base frr-route-map:rmap-set-type;
|
||||
description
|
||||
|
@ -511,6 +517,22 @@ module frr-bgp-route-map {
|
|||
}
|
||||
}
|
||||
|
||||
typedef color-list {
|
||||
type string {
|
||||
pattern '((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)
|
||||
values are separated by white spaces";
|
||||
reference
|
||||
"RFC 9012 - The BGP Tunnel Encapsulation Attribute";
|
||||
}
|
||||
|
||||
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" {
|
||||
case local-preference {
|
||||
when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'frr-bgp-route-map:match-local-preference')";
|
||||
|
@ -852,6 +874,19 @@ module frr-bgp-route-map {
|
|||
}
|
||||
}
|
||||
|
||||
case extcommunity-color {
|
||||
when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:set-extcommunity-color')";
|
||||
description
|
||||
"Value of the ext-community";
|
||||
leaf extcommunity-color {
|
||||
type color-list;
|
||||
description
|
||||
"Set BGP ext-community color attribute with a list of colors";
|
||||
reference
|
||||
"RFC9012";
|
||||
}
|
||||
}
|
||||
|
||||
case ipv4-address {
|
||||
when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:ipv4-vpn-address')";
|
||||
description
|
||||
|
|
Loading…
Reference in a new issue