Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bgp ecommlist count #18159

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 78 additions & 0 deletions bgpd/bgp_routemap.c
Original file line number Diff line number Diff line change
Expand Up @@ -1358,6 +1358,61 @@ static const struct route_map_rule_cmd route_match_community_limit_cmd = {
route_match_community_limit_compile, route_match_community_limit_free
};

/* `match extcommunity-limit' */

/* Match function should return :
* - RMAP_MATCH if the bgp update extcommunity list count
* is less or equal to the configured limit.
* - RMAP_NOMATCH if the extcommunity list count is greater than the
* configured limit.
*/
static enum route_map_cmd_result_t
route_match_extcommunity_limit(void *rule, const struct prefix *prefix, void *object)
{
struct bgp_path_info *path = NULL;
struct ecommunity *piextcomm = NULL;
uint16_t count = 0;
uint16_t *limit_rule = rule;

path = (struct bgp_path_info *)object;

piextcomm = bgp_attr_get_ecommunity(path->attr);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please include also IPv6-address specific extended communities...

if (piextcomm)
count = piextcomm->size;

if (count <= *limit_rule)
return RMAP_MATCH;

return RMAP_NOMATCH;
}

/* Route map `extcommunity-limit' match statement. */
static void *route_match_extcommunity_limit_compile(const char *arg)
{
uint16_t *limit = NULL;
char *end = NULL;

limit = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(uint16_t));
*limit = strtoul(arg, &end, 10);
if (*end != '\0') {
XFREE(MTYPE_ROUTE_MAP_COMPILED, limit);
return NULL;
}
return limit;
}

/* Free route map's compiled `community-limit' value. */
static void route_match_extcommunity_limit_free(void *rule)
{
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
}

/* Route map commands for community limit matching. */
static const struct route_map_rule_cmd route_match_extcommunity_limit_cmd = {
"extcommunity-limit", route_match_extcommunity_limit,
route_match_extcommunity_limit_compile, route_match_extcommunity_limit_free
};

static enum route_map_cmd_result_t
route_set_evpn_gateway_ip(void *rule, const struct prefix *prefix, void *object)
{
Expand Down Expand Up @@ -5885,6 +5940,27 @@ DEFPY_YANG (match_ecommunity,
}


DEFPY_YANG(
match_extcommunity_limit, match_extcommunity_limit_cmd,
"[no$no] match extcommunity-limit ![(0-65535)$limit]",
NO_STR
MATCH_STR
"Match BGP extended community limit\n"
"Extended community limit number\n")
{
const char *xpath =
"./match-condition[condition='frr-bgp-route-map:match-extcommunity-limit']";
char xpath_value[XPATH_MAXLEN];

nb_cli_enqueue_change(vty, xpath, no ? NB_OP_DESTROY : NB_OP_CREATE, NULL);
snprintf(xpath_value, sizeof(xpath_value),
"%s/rmap-match-condition/frr-bgp-route-map:extcommunity-limit", xpath);

nb_cli_enqueue_change(vty, xpath_value, no ? NB_OP_DESTROY : NB_OP_MODIFY, limit_str);
return nb_cli_apply_changes(vty, NULL);
}


DEFUN_YANG (no_match_ecommunity,
no_match_ecommunity_cmd,
"no match extcommunity [<(1-99)|(100-500)|EXTCOMMUNITY_LIST_NAME>]",
Expand Down Expand Up @@ -7980,6 +8056,7 @@ void bgp_route_map_init(void)
route_map_install_match(&route_match_evpn_route_type_cmd);
route_map_install_match(&route_match_evpn_rd_cmd);
route_map_install_match(&route_match_community_limit_cmd);
route_map_install_match(&route_match_extcommunity_limit_cmd);
route_map_install_match(&route_match_evpn_default_route_cmd);
route_map_install_match(&route_match_vrl_source_vrf_cmd);

Expand Down Expand Up @@ -8053,6 +8130,7 @@ void bgp_route_map_init(void)
install_element(RMAP_NODE, &match_community_cmd);
install_element(RMAP_NODE, &no_match_community_cmd);
install_element(RMAP_NODE, &match_community_limit_cmd);
install_element(RMAP_NODE, &match_extcommunity_limit_cmd);
install_element(RMAP_NODE, &match_lcommunity_cmd);
install_element(RMAP_NODE, &no_match_lcommunity_cmd);
install_element(RMAP_NODE, &match_ecommunity_cmd);
Expand Down
7 changes: 7 additions & 0 deletions bgpd/bgp_routemap_nb.c
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,13 @@ const struct frr_yang_module_info frr_bgp_route_map_info = {
.destroy = lib_route_map_entry_set_action_rmap_set_action_distance_destroy,
}
},
{
.xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:extcommunity-limit",
.cbs = {
.modify = lib_route_map_entry_match_condition_rmap_match_condition_extcommunity_limit_modify,
.destroy = lib_route_map_entry_match_condition_rmap_match_condition_extcommunity_limit_destroy,
}
},
{
.xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:extcommunity-rt",
.cbs = {
Expand Down
4 changes: 4 additions & 0 deletions bgpd/bgp_routemap_nb.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ int lib_route_map_entry_match_condition_rmap_match_condition_community_limit_mod
struct nb_cb_modify_args *args);
int lib_route_map_entry_match_condition_rmap_match_condition_community_limit_destroy(
struct nb_cb_destroy_args *args);
int lib_route_map_entry_match_condition_rmap_match_condition_extcommunity_limit_modify(
struct nb_cb_modify_args *args);
int lib_route_map_entry_match_condition_rmap_match_condition_extcommunity_limit_destroy(
struct nb_cb_destroy_args *args);
int lib_route_map_entry_match_condition_rmap_match_condition_comm_list_create(
struct nb_cb_create_args *args);
int lib_route_map_entry_match_condition_rmap_match_condition_comm_list_destroy(
Expand Down
51 changes: 51 additions & 0 deletions bgpd/bgp_routemap_nb_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -1666,6 +1666,57 @@ int lib_route_map_entry_set_action_rmap_set_action_distance_destroy(
return NB_OK;
}

/*
* XPath: /frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:extcommunity-limit
*/
int lib_route_map_entry_match_condition_rmap_match_condition_extcommunity_limit_modify(
struct nb_cb_modify_args *args)
{
struct routemap_hook_context *rhc;
const char *limit;
enum rmap_compile_rets ret;

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);
limit = yang_dnode_get_string(args->dnode, NULL);

rhc->rhc_mhook = bgp_route_match_delete;
rhc->rhc_rule = "extcommunity-limit";
rhc->rhc_event = RMAP_EVENT_MATCH_DELETED;

ret = bgp_route_match_add(rhc->rhc_rmi, "extcommunity-limit", limit,
RMAP_EVENT_MATCH_ADDED, args->errmsg, args->errmsg_len);

if (ret != RMAP_COMPILE_SUCCESS) {
rhc->rhc_mhook = NULL;
return NB_ERR_INCONSISTENCY;
}
}

return NB_OK;
}

int lib_route_map_entry_match_condition_rmap_match_condition_extcommunity_limit_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-rt
Expand Down
15 changes: 14 additions & 1 deletion doc/user/bgp.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2907,7 +2907,13 @@ Extended Community Lists
Note that all extended community lists shares a single name space, so it's
not necessary to specify their type when creating or destroying them.

.. clicmd:: show bgp extcommunity-list [NAME detail]
.. clicmd:: match community-limit (0-65535)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need this duplicate? We already have this documented.


This command matches BGP updates that use community list, and with a community
list count less or equal than the defined limit. Setting community-limit to 0
will only match BGP updates with no community.

.. clicmd:: show bgp extcommunity-list [NAME detail]

This command displays current extcommunity-list information. When `name` is
specified the community list's information is shown.
Expand All @@ -2920,6 +2926,13 @@ BGP Extended Communities in Route Map

.. clicmd:: match extcommunity WORD

.. clicmd:: match extcommunity-limit (0-65535)

This command matches BGP updates that use extended community list, and with an
extended community list count less or equal than the defined limit. Setting
extended community-limit to 0 will only match BGP updates with no extended
community.

.. clicmd:: set extcommunity none

This command resets the extended community value in BGP updates. If the attribute is
Expand Down
1 change: 1 addition & 0 deletions lib/routemap.h
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@ DECLARE_QOBJ_TYPE(route_map);
(strmatch(C, "frr-bgp-route-map:match-large-community"))
#define IS_MATCH_EXTCOMMUNITY(C) \
(strmatch(C, "frr-bgp-route-map:match-extcommunity"))
#define IS_MATCH_EXTCOMMUNITY_LIMIT(C) (strmatch(C, "frr-bgp-route-map:match-extcommunity-limit"))
#define IS_MATCH_IPV4_NH(C) \
(strmatch(C, "frr-bgp-route-map:ipv4-nexthop"))
#define IS_MATCH_IPV6_NH(C) \
Expand Down
4 changes: 4 additions & 0 deletions lib/routemap_cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -715,6 +715,10 @@ void route_map_condition_show(struct vty *vty, const struct lyd_node *dnode,
yang_dnode_get_string(
dnode,
"./rmap-match-condition/frr-bgp-route-map:rpki"));
} else if (IS_MATCH_EXTCOMMUNITY_LIMIT(condition)) {
vty_out(vty, " match extcommunity-limit %s\n",
yang_dnode_get_string(dnode,
"./rmap-match-condition/frr-bgp-route-map:extcommunity-limit"));
} else if (IS_MATCH_RPKI_EXTCOMMUNITY(condition)) {
vty_out(vty, " match rpki-extcommunity %s\n",
yang_dnode_get_string(
Expand Down
17 changes: 17 additions & 0 deletions yang/frr-bgp-route-map.yang
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,12 @@ module frr-bgp-route-map {
"Match BGP extcommunity list";
}

identity match-extcommunity-limit {
base frr-route-map:rmap-match-type;
description
"Match BGP extcommunity limit count";
}

identity as-path-list {
base frr-route-map:rmap-match-type;
description
Expand Down Expand Up @@ -819,6 +825,17 @@ identity set-extcommunity-color {
}
}

case extcommunity-limit {
when "derived-from-or-self(../frr-route-map:condition, 'frr-bgp-route-map:match-extcommunity-limit')";
description
"Match BGP updates when the list of extended communities count is less than the configured limit.";
leaf extcommunity-limit {
type uint16 {
range "0..1024";
}
}
}

case comm-list-name {
when "derived-from-or-self(../frr-route-map:condition, 'frr-bgp-route-map:match-community') or "
+ "derived-from-or-self(../frr-route-map:condition, 'frr-bgp-route-map:match-large-community') or "
Expand Down