summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_routemap.c
diff options
context:
space:
mode:
authorPhilippe Guibert <philippe.guibert@6wind.com>2023-06-27 21:36:01 +0200
committerPhilippe Guibert <philippe.guibert@6wind.com>2023-10-02 15:24:18 +0200
commitaa511000e0394528ddcab0f7728811d19d7f9c62 (patch)
treee392fe8de396d8a28648ad3d98b3a2f9104658eb /bgpd/bgp_routemap.c
parentMerge pull request #14510 from opensourcerouting/fix/coccinelle_issues (diff)
downloadfrr-aa511000e0394528ddcab0f7728811d19d7f9c62.tar.xz
frr-aa511000e0394528ddcab0f7728811d19d7f9c62.zip
bgpd: add 'match community-list any' function
There is no match mechanism to match one community from the incoming community-list. Add the 'any' keyword to the 'match route-map' command of communit-list and large-community-list. > match community-list AAA any > match large-community-list AAA any Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
Diffstat (limited to 'bgpd/bgp_routemap.c')
-rw-r--r--bgpd/bgp_routemap.c161
1 files changed, 92 insertions, 69 deletions
diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c
index 274df5197..e0db43f67 100644
--- a/bgpd/bgp_routemap.c
+++ b/bgpd/bgp_routemap.c
@@ -1528,7 +1528,8 @@ static const struct route_map_rule_cmd route_match_aspath_cmd = {
struct rmap_community {
char *name;
uint32_t name_hash;
- int exact;
+ bool exact;
+ bool any;
};
/* Match function for community match. */
@@ -1551,6 +1552,12 @@ route_match_community(void *rule, const struct prefix *prefix, void *object)
if (community_list_exact_match(
bgp_attr_get_community(path->attr), list))
return RMAP_MATCH;
+ } else if (rcom->any) {
+ if (!bgp_attr_get_community(path->attr))
+ return RMAP_OKAY;
+ if (community_list_any_match(bgp_attr_get_community(path->attr),
+ list))
+ return RMAP_MATCH;
} else {
if (community_list_match(bgp_attr_get_community(path->attr),
list))
@@ -1574,10 +1581,15 @@ static void *route_match_community_compile(const char *arg)
len = p - arg;
rcom->name = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, len + 1);
memcpy(rcom->name, arg, len);
- rcom->exact = 1;
+ p++;
+ if (*p == 'e')
+ rcom->exact = true;
+ else
+ rcom->any = true;
} else {
rcom->name = XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
- rcom->exact = 0;
+ rcom->exact = false;
+ rcom->any = false;
}
rcom->name_hash = bgp_clist_hash_key(rcom->name);
@@ -1637,6 +1649,12 @@ route_match_lcommunity(void *rule, const struct prefix *prefix, void *object)
if (lcommunity_list_exact_match(
bgp_attr_get_lcommunity(path->attr), list))
return RMAP_MATCH;
+ } else if (rcom->any) {
+ if (!bgp_attr_get_lcommunity(path->attr))
+ return RMAP_OKAY;
+ if (lcommunity_list_any_match(bgp_attr_get_lcommunity(path->attr),
+ list))
+ return RMAP_MATCH;
} else {
if (lcommunity_list_match(bgp_attr_get_lcommunity(path->attr),
list))
@@ -1660,10 +1678,15 @@ static void *route_match_lcommunity_compile(const char *arg)
len = p - arg;
rcom->name = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, len + 1);
memcpy(rcom->name, arg, len);
- rcom->exact = 1;
+ p++;
+ if (*p == 'e')
+ rcom->exact = true;
+ else
+ rcom->any = true;
} else {
rcom->name = XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
- rcom->exact = 0;
+ rcom->exact = false;
+ rcom->any = false;
}
rcom->name_hash = bgp_clist_hash_key(rcom->name);
@@ -5493,15 +5516,15 @@ DEFUN_YANG(no_match_alias, no_match_alias_cmd, "no match alias [ALIAS_NAME]",
return nb_cli_apply_changes(vty, NULL);
}
-DEFPY_YANG (match_community,
- match_community_cmd,
- "match community <(1-99)|(100-500)|COMMUNITY_LIST_NAME> [exact-match]",
- MATCH_STR
- "Match BGP community list\n"
- "Community-list number (standard)\n"
- "Community-list number (expanded)\n"
- "Community-list name\n"
- "Do exact matching of communities\n")
+DEFPY_YANG(
+ match_community, match_community_cmd,
+ "match community <(1-99)|(100-500)|COMMUNITY_LIST_NAME> [<exact-match$exact|any$any>]",
+ MATCH_STR "Match BGP community list\n"
+ "Community-list number (standard)\n"
+ "Community-list number (expanded)\n"
+ "Community-list name\n"
+ "Do exact matching of communities\n"
+ "Do matching of any community\n")
{
const char *xpath =
"./match-condition[condition='frr-bgp-route-map:match-community']";
@@ -5517,35 +5540,35 @@ DEFPY_YANG (match_community,
xpath);
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, argv[idx_comm_list]->arg);
- if (argc == 4) {
- snprintf(
- xpath_match, sizeof(xpath_match),
- "%s/rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name-exact-match",
- xpath);
+ snprintf(xpath_match, sizeof(xpath_match),
+ "%s/rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name-exact-match",
+ xpath);
+ if (exact)
nb_cli_enqueue_change(vty, xpath_match, NB_OP_MODIFY,
"true");
- } else {
- snprintf(
- xpath_match, sizeof(xpath_match),
- "%s/rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name-exact-match",
- xpath);
- nb_cli_enqueue_change(vty, xpath_match, NB_OP_MODIFY,
- "false");
- }
+ else
+ nb_cli_enqueue_change(vty, xpath_match, NB_OP_MODIFY, "false");
+
+ snprintf(xpath_match, sizeof(xpath_match),
+ "%s/rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name-any",
+ xpath);
+ if (any)
+ nb_cli_enqueue_change(vty, xpath_match, NB_OP_MODIFY, "true");
+ else
+ nb_cli_enqueue_change(vty, xpath_match, NB_OP_MODIFY, "false");
return nb_cli_apply_changes(vty, NULL);
}
-DEFUN_YANG (no_match_community,
- no_match_community_cmd,
- "no match community [<(1-99)|(100-500)|COMMUNITY_LIST_NAME> [exact-match]]",
- NO_STR
- MATCH_STR
- "Match BGP community list\n"
- "Community-list number (standard)\n"
- "Community-list number (expanded)\n"
- "Community-list name\n"
- "Do exact matching of communities\n")
+DEFUN_YANG(
+ no_match_community, no_match_community_cmd,
+ "no match community [<(1-99)|(100-500)|COMMUNITY_LIST_NAME> [<exact-match$exact|any$any>]]",
+ NO_STR MATCH_STR "Match BGP community list\n"
+ "Community-list number (standard)\n"
+ "Community-list number (expanded)\n"
+ "Community-list name\n"
+ "Do exact matching of communities\n"
+ "Do matching of any community\n")
{
const char *xpath =
"./match-condition[condition='frr-bgp-route-map:match-community']";
@@ -5554,15 +5577,15 @@ DEFUN_YANG (no_match_community,
return nb_cli_apply_changes(vty, NULL);
}
-DEFPY_YANG (match_lcommunity,
- match_lcommunity_cmd,
- "match large-community <(1-99)|(100-500)|LCOMMUNITY_LIST_NAME> [exact-match]",
- MATCH_STR
- "Match BGP large community list\n"
- "Large Community-list number (standard)\n"
- "Large Community-list number (expanded)\n"
- "Large Community-list name\n"
- "Do exact matching of communities\n")
+DEFPY_YANG(
+ match_lcommunity, match_lcommunity_cmd,
+ "match large-community <(1-99)|(100-500)|LCOMMUNITY_LIST_NAME> [<exact-match$exact|any$any>]",
+ MATCH_STR "Match BGP large community list\n"
+ "Large Community-list number (standard)\n"
+ "Large Community-list number (expanded)\n"
+ "Large Community-list name\n"
+ "Do exact matching of communities\n"
+ "Do matching of any community\n")
{
const char *xpath =
"./match-condition[condition='frr-bgp-route-map:match-large-community']";
@@ -5578,35 +5601,35 @@ DEFPY_YANG (match_lcommunity,
xpath);
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, argv[idx_lcomm_list]->arg);
- if (argc == 4) {
- snprintf(
- xpath_match, sizeof(xpath_match),
- "%s/rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name-exact-match",
- xpath);
+ snprintf(xpath_match, sizeof(xpath_match),
+ "%s/rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name-exact-match",
+ xpath);
+ if (exact)
nb_cli_enqueue_change(vty, xpath_match, NB_OP_MODIFY,
"true");
- } else {
- snprintf(
- xpath_match, sizeof(xpath_match),
- "%s/rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name-exact-match",
- xpath);
- nb_cli_enqueue_change(vty, xpath_match, NB_OP_MODIFY,
- "false");
- }
+ else
+ nb_cli_enqueue_change(vty, xpath_match, NB_OP_MODIFY, "false");
+
+ snprintf(xpath_match, sizeof(xpath_match),
+ "%s/rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name-any",
+ xpath);
+ if (any)
+ nb_cli_enqueue_change(vty, xpath_match, NB_OP_MODIFY, "true");
+ else
+ nb_cli_enqueue_change(vty, xpath_match, NB_OP_MODIFY, "false");
return nb_cli_apply_changes(vty, NULL);
}
-DEFUN_YANG (no_match_lcommunity,
- no_match_lcommunity_cmd,
- "no match large-community [<(1-99)|(100-500)|LCOMMUNITY_LIST_NAME> [exact-match]]",
- NO_STR
- MATCH_STR
- "Match BGP large community list\n"
- "Large Community-list number (standard)\n"
- "Large Community-list number (expanded)\n"
- "Large Community-list name\n"
- "Do exact matching of communities\n")
+DEFUN_YANG(
+ no_match_lcommunity, no_match_lcommunity_cmd,
+ "no match large-community [<(1-99)|(100-500)|LCOMMUNITY_LIST_NAME> [<exact-match|any>]]",
+ NO_STR MATCH_STR "Match BGP large community list\n"
+ "Large Community-list number (standard)\n"
+ "Large Community-list number (expanded)\n"
+ "Large Community-list name\n"
+ "Do exact matching of communities\n"
+ "Do matching of any community\n")
{
const char *xpath =
"./match-condition[condition='frr-bgp-route-map:match-large-community']";