]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: Allow setting BGP [large]community in route-maps
authorDonatas Abraitis <donatas@opensourcerouting.org>
Fri, 8 Apr 2022 19:57:47 +0000 (22:57 +0300)
committerDonatas Abraitis <donatas@opensourcerouting.org>
Wed, 13 Apr 2022 05:19:56 +0000 (08:19 +0300)
Before:
```
spine1-debian-11(config-route-map)# bgp community alias 65001:65001 test1
spine1-debian-11(config)# route-map rm permit 10
spine1-debian-11(config-route-map)# set community 65001:65001
% Malformed communities attribute
```

After:
```
spine1-debian-11(config)# bgp community alias 65001:65001 test1
spine1-debian-11(config)# route-map rm permit 10
spine1-debian-11(config-route-map)# set community 65001:65001
spine1-debian-11(config-route-map)#
```

Same for large-communities.

Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
bgpd/bgp_clist.c
bgpd/bgp_community.c
bgpd/bgp_community.h
bgpd/bgp_debug.c
bgpd/bgp_lcommunity.c
bgpd/bgp_lcommunity.h
bgpd/bgp_route.c
bgpd/bgp_routemap.c
bgpd/bgp_vty.c

index 0e590a463c90c5ece4f80bbbc05613fbfc1784c9..0631f8b95af81bd3628c40a63c98dfee7d47b9b7 100644 (file)
@@ -557,7 +557,7 @@ static bool community_regexp_match(struct community *com, regex_t *reg)
        if (com == NULL || com->size == 0)
                str = "";
        else
-               str = community_str(com, false);
+               str = community_str(com, false, true);
 
        regstr = bgp_alias2community_str(str);
 
@@ -631,7 +631,7 @@ static bool lcommunity_regexp_match(struct lcommunity *com, regex_t *reg)
        if (com == NULL || com->size == 0)
                str = "";
        else
-               str = lcommunity_str(com, false);
+               str = lcommunity_str(com, false, true);
 
        regstr = bgp_alias2community_str(str);
 
index a5dafd7757f64e334d71afe2ded03638c1f16622..b98ad3c74dd9d0b63f2a0694586bba14c9249100 100644 (file)
@@ -200,7 +200,8 @@ struct community *community_uniq_sort(struct community *com)
    0xFFFFFF04      "no-peer"
 
    For other values, "AS:VAL" format is used.  */
-static void set_community_string(struct community *com, bool make_json)
+static void set_community_string(struct community *com, bool make_json,
+                                bool translate_alias)
 {
        int i;
        char *str;
@@ -447,7 +448,9 @@ static void set_community_string(struct community *com, bool make_json)
                        val = comval & 0xFFFF;
                        char buf[32];
                        snprintf(buf, sizeof(buf), "%u:%d", as, val);
-                       const char *com2alias = bgp_community2alias(buf);
+                       const char *com2alias =
+                               translate_alias ? bgp_community2alias(buf)
+                                               : buf;
 
                        strlcat(str, com2alias, len);
                        if (make_json) {
@@ -487,7 +490,7 @@ struct community *community_intern(struct community *com)
 
        /* Make string.  */
        if (!find->str)
-               set_community_string(find, false);
+               set_community_string(find, false, true);
 
        return find;
 }
@@ -545,7 +548,7 @@ struct community *community_dup(struct community *com)
 }
 
 /* Return string representation of communities attribute. */
-char *community_str(struct community *com, bool make_json)
+char *community_str(struct community *com, bool make_json, bool translate_alias)
 {
        if (!com)
                return NULL;
@@ -554,7 +557,7 @@ char *community_str(struct community *com, bool make_json)
                XFREE(MTYPE_COMMUNITY_STR, com->str);
 
        if (!com->str)
-               set_community_string(com, make_json);
+               set_community_string(com, make_json, translate_alias);
        return com->str;
 }
 
index 2a1fbf526aaa310c0ad4521ee3043ffcd9fded8d..6f0ae0235c3e74c9613507683d2b1dc9b6562794 100644 (file)
@@ -76,7 +76,8 @@ extern struct community *community_uniq_sort(struct community *);
 extern struct community *community_parse(uint32_t *, unsigned short);
 extern struct community *community_intern(struct community *);
 extern void community_unintern(struct community **);
-extern char *community_str(struct community *, bool make_json);
+extern char *community_str(struct community *, bool make_json,
+                          bool translate_alias);
 extern unsigned int community_hash_make(const struct community *);
 extern struct community *community_str2com(const char *);
 extern bool community_match(const struct community *, const struct community *);
index 64f71bebc976d96329903a95f48df99464f9d065..81ad39be61d357a30c13bd4c06e6e4a772220b04 100644 (file)
@@ -411,12 +411,12 @@ bool bgp_dump_attr(struct attr *attr, char *buf, size_t size)
        if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)))
                snprintf(buf + strlen(buf), size - strlen(buf),
                         ", community %s",
-                        community_str(attr->community, false));
+                        community_str(attr->community, false, true));
 
        if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)))
                snprintf(buf + strlen(buf), size - strlen(buf),
                         ", large-community %s",
-                        lcommunity_str(attr->lcommunity, false));
+                        lcommunity_str(attr->lcommunity, false, true));
 
        if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)))
                snprintf(buf + strlen(buf), size - strlen(buf),
index 9d8196878992e111c23d391632c5ec4bd159d610..5e515d3f8afd6227e14ff1cd164ef3d3464e58b2 100644 (file)
@@ -175,7 +175,8 @@ struct lcommunity *lcommunity_merge(struct lcommunity *lcom1,
        return lcom1;
 }
 
-static void set_lcommunity_string(struct lcommunity *lcom, bool make_json)
+static void set_lcommunity_string(struct lcommunity *lcom, bool make_json,
+                                 bool translate_alias)
 {
        int i;
        int len;
@@ -228,7 +229,8 @@ static void set_lcommunity_string(struct lcommunity *lcom, bool make_json)
                snprintf(lcsb, sizeof(lcsb), "%u:%u:%u", global, local1,
                         local2);
 
-               const char *com2alias = bgp_community2alias(lcsb);
+               const char *com2alias =
+                       translate_alias ? bgp_community2alias(lcsb) : lcsb;
 
                len = strlcat(str_buf, com2alias, str_buf_sz);
                assert((unsigned int)len < str_buf_sz);
@@ -264,7 +266,7 @@ struct lcommunity *lcommunity_intern(struct lcommunity *lcom)
        find->refcnt++;
 
        if (!find->str)
-               set_lcommunity_string(find, false);
+               set_lcommunity_string(find, false, true);
 
        return find;
 }
@@ -288,7 +290,8 @@ void lcommunity_unintern(struct lcommunity **lcom)
 }
 
 /* Return string representation of lcommunities attribute. */
-char *lcommunity_str(struct lcommunity *lcom, bool make_json)
+char *lcommunity_str(struct lcommunity *lcom, bool make_json,
+                    bool translate_alias)
 {
        if (!lcom)
                return NULL;
@@ -297,7 +300,7 @@ char *lcommunity_str(struct lcommunity *lcom, bool make_json)
                XFREE(MTYPE_LCOMMUNITY_STR, lcom->str);
 
        if (!lcom->str)
-               set_lcommunity_string(lcom, make_json);
+               set_lcommunity_string(lcom, make_json, translate_alias);
 
        return lcom->str;
 }
index 6ccb6b7879e4520a747068bdd26f037e8a6aa555..b9b5fe35d56e789ada2b846f81b5e6f0e1e9787d 100644 (file)
@@ -69,7 +69,8 @@ extern struct hash *lcommunity_hash(void);
 extern struct lcommunity *lcommunity_str2com(const char *);
 extern bool lcommunity_match(const struct lcommunity *,
                             const struct lcommunity *);
-extern char *lcommunity_str(struct lcommunity *, bool make_json);
+extern char *lcommunity_str(struct lcommunity *, bool make_json,
+                           bool translate_alias);
 extern bool lcommunity_include(struct lcommunity *lcom, uint8_t *ptr);
 extern void lcommunity_del_val(struct lcommunity *lcom, uint8_t *ptr);
 
index 56d5847db9444393fc06466ea3b48235b77e7505..1edb10ea4c126862f6dc1ea22adddf0f2bd07bed 100644 (file)
@@ -10505,7 +10505,7 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
        if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
                if (json_paths) {
                        if (!attr->community->json)
-                               community_str(attr->community, true);
+                               community_str(attr->community, true, true);
                        json_object_lock(attr->community->json);
                        json_object_object_add(json_path, "community",
                                               attr->community->json);
@@ -10533,7 +10533,7 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
        if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
                if (json_paths) {
                        if (!attr->lcommunity->json)
-                               lcommunity_str(attr->lcommunity, true);
+                               lcommunity_str(attr->lcommunity, true, true);
                        json_object_lock(attr->lcommunity->json);
                        json_object_object_add(json_path, "largeCommunity",
                                               attr->lcommunity->json);
index c42e3c9b9496c7c71934dc94024edbd262eb7150..2216d5140d1bbc7c911b3f2c426f33b91c0e2cda 100644 (file)
@@ -5548,19 +5548,19 @@ DEFUN_YANG (set_community,
        str = buffer_getstr(b);
        buffer_free(b);
 
-       if (str) {
+       if (str)
                com = community_str2com(str);
-               XFREE(MTYPE_TMP, str);
-       }
 
        /* Can't compile user input into communities attribute.  */
        if (!com) {
-               vty_out(vty, "%% Malformed communities attribute\n");
+               vty_out(vty, "%% Malformed communities attribute '%s'\n", str);
+               XFREE(MTYPE_TMP, str);
                return CMD_WARNING_CONFIG_FAILED;
        }
+       XFREE(MTYPE_TMP, str);
 
        /* Set communites attribute string.  */
-       str = community_str(com, false);
+       str = community_str(com, false, false);
 
        if (additive) {
                size_t argstr_sz = strlen(str) + strlen(" additive") + 1;
index 4df2abef85f508210b506768fa8cdb3b74890a33..85438a2356fb898bf3d5f35718b66147cfeafa62 100644 (file)
@@ -14466,7 +14466,7 @@ static void community_show_all_iterator(struct hash_bucket *bucket,
 
        com = (struct community *)bucket->data;
        vty_out(vty, "[%p] (%ld) %s\n", (void *)com, com->refcnt,
-               community_str(com, false));
+               community_str(com, false, false));
 }
 
 /* Show BGP's community internal data. */
@@ -14495,7 +14495,7 @@ static void lcommunity_show_all_iterator(struct hash_bucket *bucket,
 
        lcom = (struct lcommunity *)bucket->data;
        vty_out(vty, "[%p] (%ld) %s\n", (void *)lcom, lcom->refcnt,
-               lcommunity_str(lcom, false));
+               lcommunity_str(lcom, false, false));
 }
 
 /* Show BGP's community internal data. */
@@ -19291,9 +19291,9 @@ static const char *community_list_config_str(struct community_entry *entry)
                str = "";
        else {
                if (entry->style == COMMUNITY_LIST_STANDARD)
-                       str = community_str(entry->u.com, false);
+                       str = community_str(entry->u.com, false, false);
                else if (entry->style == LARGE_COMMUNITY_LIST_STANDARD)
-                       str = lcommunity_str(entry->u.lcom, false);
+                       str = lcommunity_str(entry->u.lcom, false, false);
                else
                        str = entry->config;
        }