From 004d770ec4a921c3ce0e074dc40da39e8ddb5e0e Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Mon, 18 Nov 2024 23:29:53 +0200 Subject: [PATCH] bgpd: Optimize the way parsing communities if no community alias exists If at least one community alias is configured, then let's do the work, otherwise we don't need to spend time on splitting stuff and creating a new string. This should improve the performance. Signed-off-by: Donatas Abraitis --- bgpd/bgp_clist.c | 38 ++++++++++++++++++++++++++++---------- bgpd/bgp_community_alias.c | 2 +- bgpd/bgp_community_alias.h | 1 + 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/bgpd/bgp_clist.c b/bgpd/bgp_clist.c index 61ba527498..6479126d06 100644 --- a/bgpd/bgp_clist.c +++ b/bgpd/bgp_clist.c @@ -534,20 +534,29 @@ static bool community_regexp_match(struct community *com, regex_t *reg) const char *str; char *regstr; int rv; + bool translate_alias = !!bgp_ca_alias_hash->count; /* When there is no communities attribute it is treated as empty string. */ if (com == NULL || com->size == 0) - str = ""; - else - str = community_str(com, false, true); + return false; - regstr = bgp_alias2community_str(str); + str = community_str(com, false, translate_alias); + + /* If at least one community alias is configured, then let's + * do the work, otherwise we don't need to spend time on splitting + * stuff and creating a new string. + */ + regstr = translate_alias ? bgp_alias2community_str(str) : (char *)str; /* Regular expression match. */ rv = regexec(reg, regstr, 0, NULL, 0); - XFREE(MTYPE_TMP, regstr); + /* This is allocated by frrstr_join(), and needs to be freed + * only if it was created. + */ + if (translate_alias) + XFREE(MTYPE_TMP, regstr); return rv == 0; } @@ -608,20 +617,29 @@ static bool lcommunity_regexp_match(struct lcommunity *com, regex_t *reg) const char *str; char *regstr; int rv; + bool translate_alias = !!bgp_ca_alias_hash->count; /* When there is no communities attribute it is treated as empty string. */ if (com == NULL || com->size == 0) - str = ""; - else - str = lcommunity_str(com, false, true); + return false; - regstr = bgp_alias2community_str(str); + str = lcommunity_str(com, false, translate_alias); + + /* If at least one community alias is configured, then let's + * do the work, otherwise we don't need to spend time on splitting + * stuff and creating a new string. + */ + regstr = translate_alias ? bgp_alias2community_str(str) : (char *)str; /* Regular expression match. */ rv = regexec(reg, regstr, 0, NULL, 0); - XFREE(MTYPE_TMP, regstr); + /* This is allocated by frrstr_join(), and needs to be freed + * only if it was created. + */ + if (translate_alias) + XFREE(MTYPE_TMP, regstr); return rv == 0; } diff --git a/bgpd/bgp_community_alias.c b/bgpd/bgp_community_alias.c index 96dc1ec8f9..d7567fcdd4 100644 --- a/bgpd/bgp_community_alias.c +++ b/bgpd/bgp_community_alias.c @@ -13,7 +13,7 @@ #include "bgpd/bgpd.h" #include "bgpd/bgp_community_alias.h" -static struct hash *bgp_ca_alias_hash; +struct hash *bgp_ca_alias_hash; static struct hash *bgp_ca_community_hash; static unsigned int bgp_ca_community_hash_key(const void *p) diff --git a/bgpd/bgp_community_alias.h b/bgpd/bgp_community_alias.h index cb7983e1a7..9dcab6fe30 100644 --- a/bgpd/bgp_community_alias.h +++ b/bgpd/bgp_community_alias.h @@ -17,6 +17,7 @@ struct community_alias { char alias[BUFSIZ]; }; +extern struct hash *bgp_ca_alias_hash; extern void bgp_community_alias_init(void); extern void bgp_community_alias_finish(void); extern struct community_alias *bgp_ca_alias_lookup(struct community_alias *ca);