Merge pull request #8701 from ton31337/feature/show_ip_bgp_alias

bgpd: Show BGP prefixes by community alias
This commit is contained in:
Donald Sharp 2021-05-21 07:23:10 -04:00 committed by GitHub
commit 2db528e384
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 148 additions and 54 deletions

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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,

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -6,7 +6,14 @@ router bgp 65002
neighbor 192.168.1.1 route-map r1 out
exit-address-family
!
route-map r1 permit 10
set community 65002:1 65002:2
set large-community 65002:1:1 65002:2:1
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
!

View File

@ -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
!

View File

@ -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:]