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

bgpd: add match community "any" to match any incoming community #13814

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
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
43 changes: 43 additions & 0 deletions bgpd/bgp_clist.c
Original file line number Diff line number Diff line change
Expand Up @@ -735,6 +735,27 @@ bool community_list_exact_match(struct community *com,
return false;
}

bool community_list_any_match(struct community *com, struct community_list *list)
{
struct community_entry *entry;
uint32_t val;
int i;

for (i = 0; i < com->size; i++) {
val = community_val_get(com, i);

for (entry = list->head; entry; entry = entry->next) {
if (entry->style == COMMUNITY_LIST_STANDARD &&
community_include(entry->u.com, val))
return entry->direct == COMMUNITY_PERMIT;
if ((entry->style == COMMUNITY_LIST_EXPANDED) &&
community_regexp_include(entry->reg, com, i))
return entry->direct == COMMUNITY_PERMIT;
}
}
return false;
}

/* Delete all permitted communities in the list from com. */
struct community *community_list_match_delete(struct community *com,
struct community_list *list)
Expand Down Expand Up @@ -922,6 +943,28 @@ int community_list_unset(struct community_list_handler *ch, const char *name,
return 0;
}

bool lcommunity_list_any_match(struct lcommunity *lcom,
struct community_list *list)
{
struct community_entry *entry;
uint8_t *ptr;
int i;

for (i = 0; i < lcom->size; i++) {
ptr = lcom->val + (i * LCOMMUNITY_SIZE);

for (entry = list->head; entry; entry = entry->next) {
if ((entry->style == LARGE_COMMUNITY_LIST_STANDARD) &&
lcommunity_include(entry->u.lcom, ptr))
return entry->direct == COMMUNITY_PERMIT;
if ((entry->style == LARGE_COMMUNITY_LIST_EXPANDED) &&
lcommunity_regexp_include(entry->reg, lcom, i))
return entry->direct == COMMUNITY_PERMIT;
}
}
return false;
}

/* Delete all permitted large communities in the list from com. */
struct lcommunity *lcommunity_list_match_delete(struct lcommunity *lcom,
struct community_list *list)
Expand Down
4 changes: 4 additions & 0 deletions bgpd/bgp_clist.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,12 @@ extern bool community_list_exact_match(struct community *com,
struct community_list *list);
extern bool lcommunity_list_exact_match(struct lcommunity *lcom,
struct community_list *list);
extern bool community_list_any_match(struct community *com,
struct community_list *list);
extern struct community *
community_list_match_delete(struct community *com, struct community_list *list);
extern bool lcommunity_list_any_match(struct lcommunity *lcom,
struct community_list *list);
extern struct lcommunity *
lcommunity_list_match_delete(struct lcommunity *lcom,
struct community_list *list);
Expand Down
161 changes: 92 additions & 69 deletions bgpd/bgp_routemap.c
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand All @@ -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))
Expand All @@ -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);
Expand Down Expand Up @@ -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))
Expand All @@ -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);
Expand Down Expand Up @@ -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,
Copy link
Member

Choose a reason for hiding this comment

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

Please fix this indentation.

Copy link
Member Author

Choose a reason for hiding this comment

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

clang format is guilty. is it possible to change clang rules to avoid this ?

"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']";
Expand All @@ -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,
Copy link
Member

Choose a reason for hiding this comment

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

Ditto.

Copy link
Member Author

Choose a reason for hiding this comment

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

clang format is guilty. is it possible to change clang rules to avoid this ?

"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']";
Expand All @@ -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,
Copy link
Member

Choose a reason for hiding this comment

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

Ditto.

Copy link
Member Author

Choose a reason for hiding this comment

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

clang format is guilty. is it possible to change clang rules to avoid this ?

"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']";
Expand All @@ -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,
Copy link
Member

Choose a reason for hiding this comment

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

Ditto.

Copy link
Member Author

Choose a reason for hiding this comment

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

clang format is guilty. is it possible to change clang rules to avoid this ?

"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']";
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 @@ -164,6 +164,13 @@ const struct frr_yang_module_info frr_bgp_route_map_info = {
.destroy = lib_route_map_entry_match_condition_rmap_match_condition_comm_list_comm_list_name_exact_match_destroy,
}
},
{
.xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name-any",
.cbs = {
.modify = lib_route_map_entry_match_condition_rmap_match_condition_comm_list_comm_list_name_any_modify,
.destroy = lib_route_map_entry_match_condition_rmap_match_condition_comm_list_comm_list_name_any_destroy,
}
},
{
.xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:ipv4-address",
.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 @@ -65,6 +65,10 @@ int lib_route_map_entry_match_condition_rmap_match_condition_comm_list_comm_list
int lib_route_map_entry_match_condition_rmap_match_condition_comm_list_comm_list_name_destroy(struct nb_cb_destroy_args *args);
int lib_route_map_entry_match_condition_rmap_match_condition_comm_list_comm_list_name_exact_match_modify(struct nb_cb_modify_args *args);
int lib_route_map_entry_match_condition_rmap_match_condition_comm_list_comm_list_name_exact_match_destroy(struct nb_cb_destroy_args *args);
int lib_route_map_entry_match_condition_rmap_match_condition_comm_list_comm_list_name_any_modify(
struct nb_cb_modify_args *args);
int lib_route_map_entry_match_condition_rmap_match_condition_comm_list_comm_list_name_any_destroy(
struct nb_cb_destroy_args *args);
int lib_route_map_entry_match_condition_rmap_match_condition_ipv4_address_modify(struct nb_cb_modify_args *args);
int lib_route_map_entry_match_condition_rmap_match_condition_ipv4_address_destroy(struct nb_cb_destroy_args *args);
int lib_route_map_entry_match_condition_rmap_match_condition_ipv6_address_modify(struct nb_cb_modify_args *args);
Expand Down
Loading