summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_community.c6
-rw-r--r--bgpd/bgp_lcommunity.c6
-rw-r--r--bgpd/bgp_route.c138
-rw-r--r--bgpd/bgp_route.h1
-rw-r--r--doc/user/bgp.rst4
-rw-r--r--tests/topotests/bgp_community_alias/r1/bgpd.conf4
-rw-r--r--tests/topotests/bgp_community_alias/r2/bgpd.conf9
-rw-r--r--tests/topotests/bgp_community_alias/r2/zebra.conf4
-rw-r--r--tests/topotests/bgp_community_alias/test_bgp-community-alias.py26
9 files changed, 146 insertions, 52 deletions
diff --git a/bgpd/bgp_community.c b/bgpd/bgp_community.c
index b034ec9f7b..2aa6a56a5e 100644
--- a/bgpd/bgp_community.c
+++ b/bgpd/bgp_community.c
@@ -451,9 +451,11 @@ 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);
- strlcat(str, bgp_community2alias(buf), len);
+ const char *com2alias = bgp_community2alias(buf);
+
+ strlcat(str, com2alias, len);
if (make_json) {
- json_string = json_object_new_string(buf);
+ json_string = json_object_new_string(com2alias);
json_object_array_add(json_community_list,
json_string);
}
diff --git a/bgpd/bgp_lcommunity.c b/bgpd/bgp_lcommunity.c
index ff34937efc..fa4d4aee28 100644
--- a/bgpd/bgp_lcommunity.c
+++ b/bgpd/bgp_lcommunity.c
@@ -232,11 +232,13 @@ static void set_lcommunity_string(struct lcommunity *lcom, bool make_json)
snprintf(lcsb, sizeof(lcsb), "%u:%u:%u", global, local1,
local2);
- len = strlcat(str_buf, bgp_community2alias(lcsb), str_buf_sz);
+ const char *com2alias = bgp_community2alias(lcsb);
+
+ len = strlcat(str_buf, com2alias, str_buf_sz);
assert((unsigned int)len < str_buf_sz);
if (make_json) {
- json_string = json_object_new_string(lcsb);
+ json_string = json_object_new_string(com2alias);
json_object_array_add(json_lcommunity_list,
json_string);
}
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 2c792b7abf..dd1e8471e6 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -23,6 +23,7 @@
#include <math.h>
#include "printfrr.h"
+#include "frrstr.h"
#include "prefix.h"
#include "linklist.h"
#include "memory.h"
@@ -10570,7 +10571,6 @@ static int bgp_show_community(struct vty *vty, struct bgp *bgp,
const char *comstr, int exact, afi_t afi,
safi_t safi, uint8_t show_flags);
-
static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
struct bgp_table *table, enum bgp_show_type type,
void *output_arg, char *rd, int is_last,
@@ -10647,6 +10647,48 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
continue;
}
+ if (type == bgp_show_type_community_alias) {
+ char *alias = output_arg;
+ char **communities;
+ int num;
+ bool found = false;
+
+ if (pi->attr->community) {
+ frrstr_split(pi->attr->community->str,
+ " ", &communities, &num);
+ for (int i = 0; i < num; i++) {
+ const char *com2alias =
+ bgp_community2alias(
+ communities[i]);
+ if (strncmp(alias, com2alias,
+ strlen(com2alias))
+ == 0) {
+ found = true;
+ break;
+ }
+ }
+ }
+
+ if (!found && pi->attr->lcommunity) {
+ frrstr_split(pi->attr->lcommunity->str,
+ " ", &communities, &num);
+ for (int i = 0; i < num; i++) {
+ const char *com2alias =
+ bgp_community2alias(
+ communities[i]);
+ if (strncmp(alias, com2alias,
+ strlen(com2alias))
+ == 0) {
+ found = true;
+ break;
+ }
+ }
+ }
+
+ if (!found)
+ continue;
+ }
+
if (type == bgp_show_type_rpki) {
if (dest_p->family == AF_INET
|| dest_p->family == AF_INET6)
@@ -11920,9 +11962,10 @@ DEFPY(show_ip_bgp, show_ip_bgp_cmd,
}
/* BGP route print out function with JSON */
-DEFPY (show_ip_bgp_json,
- show_ip_bgp_json_cmd,
- "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]]\
+DEFPY(show_ip_bgp_json, show_ip_bgp_json_cmd,
+ "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
+ " [" BGP_SAFI_WITH_LABEL_CMD_STR
+ "]]\
[all$all]\
[cidr-only\
|dampening <flap-statistics|dampened-paths>\
@@ -11933,44 +11976,41 @@ DEFPY (show_ip_bgp_json,
|route-filter-translated-v4] [exact-match]\
|rpki <invalid|valid|notfound>\
|version (1-4294967295)\
+ |alias WORD\
] [json$uj [detail$detail] | wide$wide]",
- SHOW_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- BGP_AFI_HELP_STR
- BGP_SAFI_WITH_LABEL_HELP_STR
- "Display the entries for all address families\n"
- "Display only routes with non-natural netmasks\n"
- "Display detailed information about dampening\n"
- "Display flap statistics of routes\n"
- "Display paths suppressed due to dampening\n"
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Graceful shutdown (well-known community)\n"
- "Do not export to any peer (well-known community)\n"
- "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
- "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
- "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
- "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
- "Should accept VPN route with local nexthop (well-known community)\n"
- "RT VPNv6 route filtering (well-known community)\n"
- "RT VPNv4 route filtering (well-known community)\n"
- "RT translated VPNv6 route filtering (well-known community)\n"
- "RT translated VPNv4 route filtering (well-known community)\n"
- "Exact match of the communities\n"
- "RPKI route types\n"
- "A valid path as determined by rpki\n"
- "A invalid path as determined by rpki\n"
- "A path that has no rpki data\n"
- "Display prefixes with matching version numbers\n"
- "Version number and above\n"
- JSON_STR
- "Display detailed version of JSON output\n"
- "Increase table width for longer prefixes\n")
+ SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
+ BGP_SAFI_WITH_LABEL_HELP_STR
+ "Display the entries for all address families\n"
+ "Display only routes with non-natural netmasks\n"
+ "Display detailed information about dampening\n"
+ "Display flap statistics of routes\n"
+ "Display paths suppressed due to dampening\n"
+ "Display routes matching the communities\n" COMMUNITY_AANN_STR
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "Graceful shutdown (well-known community)\n"
+ "Do not export to any peer (well-known community)\n"
+ "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
+ "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
+ "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
+ "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
+ "Should accept VPN route with local nexthop (well-known community)\n"
+ "RT VPNv6 route filtering (well-known community)\n"
+ "RT VPNv4 route filtering (well-known community)\n"
+ "RT translated VPNv6 route filtering (well-known community)\n"
+ "RT translated VPNv4 route filtering (well-known community)\n"
+ "Exact match of the communities\n"
+ "RPKI route types\n"
+ "A valid path as determined by rpki\n"
+ "A invalid path as determined by rpki\n"
+ "A path that has no rpki data\n"
+ "Display prefixes with matching version numbers\n"
+ "Version number and above\n"
+ "Display prefixes with matching BGP community alias\n"
+ "BGP community alias\n" JSON_STR
+ "Display detailed version of JSON output\n"
+ "Increase table width for longer prefixes\n")
{
afi_t afi = AFI_IP6;
safi_t safi = SAFI_UNICAST;
@@ -11980,6 +12020,7 @@ DEFPY (show_ip_bgp_json,
int exact_match = 0;
char *community = NULL;
char *prefix_version = NULL;
+ char *bgp_community_alias = NULL;
bool first = true;
uint8_t show_flags = 0;
enum rpki_states rpki_target_state = RPKI_NOT_BEING_USED;
@@ -12056,6 +12097,12 @@ DEFPY (show_ip_bgp_json,
prefix_version = argv[idx + 1]->arg;
}
+ /* Display prefixes with matching BGP community alias */
+ if (argv_find(argv, argc, "alias", &idx)) {
+ sh_type = bgp_show_type_community_alias;
+ bgp_community_alias = argv[idx + 1]->arg;
+ }
+
if (!all) {
/* show bgp: AFI_IP6, show ip bgp: AFI_IP */
if (community)
@@ -12066,6 +12113,10 @@ DEFPY (show_ip_bgp_json,
return bgp_show(vty, bgp, afi, safi, sh_type,
prefix_version, show_flags,
rpki_target_state);
+ else if (bgp_community_alias)
+ return bgp_show(vty, bgp, afi, safi, sh_type,
+ bgp_community_alias, show_flags,
+ rpki_target_state);
else
return bgp_show(vty, bgp, afi, safi, sh_type, NULL,
show_flags, rpki_target_state);
@@ -12108,6 +12159,11 @@ DEFPY (show_ip_bgp_json,
sh_type, prefix_version,
show_flags,
rpki_target_state);
+ else if (bgp_community_alias)
+ return bgp_show(
+ vty, bgp, afi, safi, sh_type,
+ bgp_community_alias, show_flags,
+ rpki_target_state);
else
bgp_show(vty, bgp, afi, safi, sh_type,
NULL, show_flags,
diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h
index e58213a688..6d6008ff55 100644
--- a/bgpd/bgp_route.h
+++ b/bgpd/bgp_route.h
@@ -42,6 +42,7 @@ enum bgp_show_type {
bgp_show_type_neighbor,
bgp_show_type_cidr_only,
bgp_show_type_prefix_longer,
+ bgp_show_type_community_alias,
bgp_show_type_community_all,
bgp_show_type_community,
bgp_show_type_community_exact,
diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst
index f6aa5d1ca0..7f653cb7b7 100644
--- a/doc/user/bgp.rst
+++ b/doc/user/bgp.rst
@@ -2111,6 +2111,10 @@ things on the wire.
Large Community: lcommunity-1 65001:123:2
Last update: Fri Apr 16 12:51:27 2021
+.. clicmd:: show bgp [afi] [safi] [all] alias WORD [wide|json]
+
+ Display prefixes with matching BGP community alias.
+
.. _bgp-using-communities-in-route-map:
Using Communities in Route Maps
diff --git a/tests/topotests/bgp_community_alias/r1/bgpd.conf b/tests/topotests/bgp_community_alias/r1/bgpd.conf
index 2cf84d0b70..06113bdd2a 100644
--- a/tests/topotests/bgp_community_alias/r1/bgpd.conf
+++ b/tests/topotests/bgp_community_alias/r1/bgpd.conf
@@ -1,7 +1,7 @@
!
-bgp community alias 65002:1 community-r2-1
+bgp community alias 65001:1 community-r2-1
bgp community alias 65002:2 community-r2-2
-bgp community alias 65002:1:1 large-community-r2-1
+bgp community alias 65001:1:1 large-community-r2-1
!
router bgp 65001
no bgp ebgp-requires-policy
diff --git a/tests/topotests/bgp_community_alias/r2/bgpd.conf b/tests/topotests/bgp_community_alias/r2/bgpd.conf
index 517ef70f2a..fc67ff2ad2 100644
--- a/tests/topotests/bgp_community_alias/r2/bgpd.conf
+++ b/tests/topotests/bgp_community_alias/r2/bgpd.conf
@@ -6,7 +6,14 @@ router bgp 65002
neighbor 192.168.1.1 route-map r1 out
exit-address-family
!
+ip prefix-list p1 permit 172.16.16.1/32
+ip prefix-list p2 permit 172.16.16.2/32
+!
route-map r1 permit 10
+ match ip address prefix-list p1
+ set community 65001:1 65001:2
+ set large-community 65001:1:1 65001:1:2
+route-map r1 permit 20
+ match ip address prefix-list p2
set community 65002:1 65002:2
- set large-community 65002:1:1 65002:2:1
!
diff --git a/tests/topotests/bgp_community_alias/r2/zebra.conf b/tests/topotests/bgp_community_alias/r2/zebra.conf
index cffe827363..a806628a8e 100644
--- a/tests/topotests/bgp_community_alias/r2/zebra.conf
+++ b/tests/topotests/bgp_community_alias/r2/zebra.conf
@@ -1,4 +1,8 @@
!
+int lo
+ ip address 172.16.16.1/32
+ ip address 172.16.16.2/32
+!
int r2-eth0
ip address 192.168.1.2/24
!
diff --git a/tests/topotests/bgp_community_alias/test_bgp-community-alias.py b/tests/topotests/bgp_community_alias/test_bgp-community-alias.py
index a43e5f937e..90eeaaa731 100644
--- a/tests/topotests/bgp_community_alias/test_bgp-community-alias.py
+++ b/tests/topotests/bgp_community_alias/test_bgp-community-alias.py
@@ -84,12 +84,14 @@ def test_bgp_community_alias():
router = tgen.gears["r1"]
def _bgp_converge(router):
- output = json.loads(router.vtysh_cmd("show ip bgp 192.168.1.0/24 json"))
+ output = json.loads(
+ router.vtysh_cmd("show bgp ipv4 unicast 172.16.16.1/32 json")
+ )
expected = {
"paths": [
{
- "community": {"string": "community-r2-1 community-r2-2"},
- "largeCommunity": {"string": "large-community-r2-1 65002:2:1"},
+ "community": {"string": "community-r2-1 65001:2"},
+ "largeCommunity": {"string": "large-community-r2-1 65001:1:2"},
}
]
}
@@ -97,9 +99,25 @@ def test_bgp_community_alias():
test_func = functools.partial(_bgp_converge, router)
success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
-
assert result is None, 'Cannot see BGP community aliases "{}"'.format(router)
+ def _bgp_show_prefixes_by_alias(router):
+ output = json.loads(
+ router.vtysh_cmd("show bgp ipv4 unicast alias community-r2-2 json detail")
+ )
+ expected = {
+ "routes": {
+ "172.16.16.2/32": [{"community": {"string": "65002:1 community-r2-2"}}]
+ }
+ }
+ return topotest.json_cmp(output, expected)
+
+ test_func = functools.partial(_bgp_show_prefixes_by_alias, router)
+ success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
+ assert result is None, 'Cannot see BGP prefixes by community alias "{}"'.format(
+ router
+ )
+
if __name__ == "__main__":
args = ["-s"] + sys.argv[1:]