From f4dd829679f33495622a9f3d40c9a5aca925df72 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Mon, 9 Aug 2021 13:34:57 +0300 Subject: [PATCH] bgpd: BGP extended [l]community-list regexp match must work with aliases We have to convert BGP alias to numerical format to compare in regexp. Signed-off-by: Donatas Abraitis --- bgpd/bgp_clist.c | 5 +++-- bgpd/bgp_community_alias.c | 40 ++++++++++++++++++++++++++++++++++++++ bgpd/bgp_community_alias.h | 2 ++ 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/bgpd/bgp_clist.c b/bgpd/bgp_clist.c index 50122ad7da..fd8f51fed3 100644 --- a/bgpd/bgp_clist.c +++ b/bgpd/bgp_clist.c @@ -33,6 +33,7 @@ #include "bgpd/bgp_community.h" #include "bgpd/bgp_ecommunity.h" #include "bgpd/bgp_lcommunity.h" +#include "bgpd/bgp_community_alias.h" #include "bgpd/bgp_aspath.h" #include "bgpd/bgp_regex.h" #include "bgpd/bgp_clist.h" @@ -557,7 +558,7 @@ static bool community_regexp_match(struct community *com, regex_t *reg) str = community_str(com, false); /* Regular expression match. */ - if (regexec(reg, str, 0, NULL, 0) == 0) + if (regexec(reg, bgp_alias2community_str(str), 0, NULL, 0) == 0) return true; /* No match. */ @@ -627,7 +628,7 @@ static bool lcommunity_regexp_match(struct lcommunity *com, regex_t *reg) str = lcommunity_str(com, false); /* Regular expression match. */ - if (regexec(reg, str, 0, NULL, 0) == 0) + if (regexec(reg, bgp_alias2community_str(str), 0, NULL, 0) == 0) return true; /* No match. */ diff --git a/bgpd/bgp_community_alias.c b/bgpd/bgp_community_alias.c index f770ebdd5d..5f45e19a3b 100644 --- a/bgpd/bgp_community_alias.c +++ b/bgpd/bgp_community_alias.c @@ -20,6 +20,7 @@ #include "memory.h" #include "lib/jhash.h" +#include "frrstr.h" #include "bgpd/bgpd.h" #include "bgpd/bgp_community_alias.h" @@ -153,6 +154,45 @@ const char *bgp_community2alias(char *community) return community; } +const char *bgp_alias2community(char *alias) +{ + struct community_alias ca; + struct community_alias *find; + + memset(&ca, 0, sizeof(ca)); + strlcpy(ca.alias, alias, sizeof(ca.alias)); + + find = bgp_ca_alias_lookup(&ca); + if (find) + return find->community; + + return alias; +} + +/* Communities structs have `->str` which is used + * for vty outputs and extended BGP community lists + * with regexp. + * This is a helper to convert already aliased version + * of communities into numerical-only format. + */ +const char *bgp_alias2community_str(const char *str) +{ + char **aliases; + int num; + + frrstr_split(str, " ", &aliases, &num); + const char *communities[num + 1]; + + for (int i = 0; i < num; i++) { + communities[i] = + XSTRDUP(MTYPE_TMP, bgp_alias2community(aliases[i])); + XFREE(MTYPE_TMP, aliases[i]); + } + XFREE(MTYPE_TMP, aliases); + + return frrstr_join(communities, num, " "); +} + static int bgp_community_alias_vector_walker(struct hash_bucket *bucket, void *data) { diff --git a/bgpd/bgp_community_alias.h b/bgpd/bgp_community_alias.h index ab8ed06ee6..fc9eb9f9e4 100644 --- a/bgpd/bgp_community_alias.h +++ b/bgpd/bgp_community_alias.h @@ -42,6 +42,8 @@ extern void bgp_ca_community_delete(struct community_alias *ca); extern void bgp_ca_alias_delete(struct community_alias *ca); extern int bgp_community_alias_write(struct vty *vty); extern const char *bgp_community2alias(char *community); +extern const char *bgp_alias2community(char *alias); +extern const char *bgp_alias2community_str(const char *str); extern void bgp_community_alias_command_completion_setup(void); #endif /* FRR_BGP_COMMUNITY_ALIAS_H */ -- 2.39.5