bgpd: Implement new adjacent route show commands

This commit changes the behavior of `show bgp [afi] [safi] neighbor
<neighbor> received-routes [json]` to return all received prefixes
instead of filtering rejected/denied prefixes.

Compared to Cisco and Juniper products, this is the usual way how this
command is supposed to work, as `show bgp [afi] [safi] neighbor
<neighbor> routes` will already return all accepted prefixes.

Additionally, the new command `show bgp [afi] [safi] neighbor <neighbor>
filtered-routes` has been added, which returns a list of all prefixes
that got filtered away, so it can be roughly described as a subset of
"received prefixes - accepted prefixes".

As the already available `filtered_count` variable inside
`show_adj_route` has not been used before, the last output line
summarizing the amount of prefixes found was extended to also mention
the amount of filtered prefixes if present.

Signed-off-by: Pascal Mathis <mail@pascalmathis.com>
This commit is contained in:
Pascal Mathis 2018-05-16 19:17:42 +02:00
parent 51f9d3e70f
commit 6392aaa654
No known key found for this signature in database
GPG Key ID: E208DBA7BFC9B28C
2 changed files with 62 additions and 43 deletions

View File

@ -10219,8 +10219,9 @@ DEFUN (show_ip_bgp_l2vpn_evpn_all_route_prefix,
} }
static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi, static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
safi_t safi, int in, const char *rmap_name, safi_t safi, enum bgp_show_adj_route_type type,
uint8_t use_json, json_object *json) const char *rmap_name, uint8_t use_json,
json_object *json)
{ {
struct bgp_table *table; struct bgp_table *table;
struct bgp_adj_in *ain; struct bgp_adj_in *ain;
@ -10277,7 +10278,7 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
output_count = filtered_count = 0; output_count = filtered_count = 0;
subgrp = peer_subgroup(peer, afi, safi); subgrp = peer_subgroup(peer, afi, safi);
if (!in && subgrp if (type == bgp_show_adj_route_advertised && subgrp
&& CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) { && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
if (use_json) { if (use_json) {
json_object_int_add(json, "bgpTableVersion", json_object_int_add(json, "bgpTableVersion",
@ -10310,10 +10311,12 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
} }
for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) { for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
if (in) { if (type == bgp_show_adj_route_received
|| type == bgp_show_adj_route_filtered) {
for (ain = rn->adj_in; ain; ain = ain->next) { for (ain = rn->adj_in; ain; ain = ain->next) {
if (ain->peer != peer) if (ain->peer != peer || !ain->attr)
continue; continue;
if (header1) { if (header1) {
if (use_json) { if (use_json) {
json_object_int_add( json_object_int_add(
@ -10356,22 +10359,24 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
vty_out(vty, BGP_SHOW_HEADER); vty_out(vty, BGP_SHOW_HEADER);
header2 = 0; header2 = 0;
} }
if (ain->attr) {
bgp_attr_dup(&attr, ain->attr); bgp_attr_dup(&attr, ain->attr);
if (bgp_input_modifier(peer, &rn->p, ret = bgp_input_modifier(peer, &rn->p, &attr,
&attr, afi, safi, afi, safi, rmap_name);
rmap_name)
!= RMAP_DENY) { if (type == bgp_show_adj_route_filtered
route_vty_out_tmp(vty, &rn->p, && ret != RMAP_DENY)
&attr, safi, continue;
use_json,
json_ar); if (type == bgp_show_adj_route_received
output_count++; && ret == RMAP_DENY)
} else filtered_count++;
filtered_count++;
} route_vty_out_tmp(vty, &rn->p, &attr, safi,
use_json, json_ar);
output_count++;
} }
} else { } else if (type == bgp_show_adj_route_advertised) {
for (adj = rn->adj_out; adj; adj = adj->next) for (adj = rn->adj_out; adj; adj = adj->next)
SUBGRP_FOREACH_PEER (adj->subgroup, paf) { SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
if (paf->peer != peer) if (paf->peer != peer)
@ -10451,27 +10456,30 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
} }
} }
} }
if (use_json)
json_object_object_add(json, "advertisedRoutes", json_ar);
if (output_count != 0) { if (use_json) {
if (use_json) json_object_object_add(json, "advertisedRoutes", json_ar);
json_object_int_add(json, "totalPrefixCounter", json_object_int_add(json, "totalPrefixCounter", output_count);
output_count); json_object_int_add(json, "filteredPrefixCounter",
filtered_count);
vty_out(vty, "%s\n", json_object_to_json_string_ext(
json, JSON_C_TO_STRING_PRETTY));
json_object_free(json);
} else if (output_count > 0) {
if (filtered_count > 0)
vty_out(vty,
"\nTotal number of prefixes %ld (%ld filtered)\n",
output_count, filtered_count);
else else
vty_out(vty, "\nTotal number of prefixes %ld\n", vty_out(vty, "\nTotal number of prefixes %ld\n",
output_count); output_count);
} }
if (use_json) {
vty_out(vty, "%s\n", json_object_to_json_string_ext(
json, JSON_C_TO_STRING_PRETTY));
json_object_free(json);
}
} }
static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi, static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
safi_t safi, int in, const char *rmap_name, safi_t safi, enum bgp_show_adj_route_type type,
uint8_t use_json) const char *rmap_name, uint8_t use_json)
{ {
json_object *json = NULL; json_object *json = NULL;
@ -10495,7 +10503,8 @@ static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
return CMD_WARNING; return CMD_WARNING;
} }
if (in if ((type == bgp_show_adj_route_received
|| type == bgp_show_adj_route_filtered)
&& !CHECK_FLAG(peer->af_flags[afi][safi], && !CHECK_FLAG(peer->af_flags[afi][safi],
PEER_FLAG_SOFT_RECONFIG)) { PEER_FLAG_SOFT_RECONFIG)) {
if (use_json) { if (use_json) {
@ -10511,7 +10520,7 @@ static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
return CMD_WARNING; return CMD_WARNING;
} }
show_adj_route(vty, peer, afi, safi, in, rmap_name, use_json, json); show_adj_route(vty, peer, afi, safi, type, rmap_name, use_json, json);
return CMD_SUCCESS; return CMD_SUCCESS;
} }
@ -10519,7 +10528,7 @@ static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
DEFUN (show_ip_bgp_instance_neighbor_advertised_route, DEFUN (show_ip_bgp_instance_neighbor_advertised_route,
show_ip_bgp_instance_neighbor_advertised_route_cmd, show_ip_bgp_instance_neighbor_advertised_route_cmd,
"show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] " "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] "
"neighbors <A.B.C.D|X:X::X:X|WORD> <received-routes|advertised-routes> [route-map WORD] [json]", "neighbors <A.B.C.D|X:X::X:X|WORD> <advertised-routes|received-routes|filtered-routes> [route-map WORD] [json]",
SHOW_STR SHOW_STR
IP_STR IP_STR
BGP_STR BGP_STR
@ -10530,8 +10539,9 @@ DEFUN (show_ip_bgp_instance_neighbor_advertised_route,
"Neighbor to display information about\n" "Neighbor to display information about\n"
"Neighbor to display information about\n" "Neighbor to display information about\n"
"Neighbor on BGP configured interface\n" "Neighbor on BGP configured interface\n"
"Display the received routes from neighbor\n"
"Display the routes advertised to a BGP neighbor\n" "Display the routes advertised to a BGP neighbor\n"
"Display the received routes from neighbor\n"
"Display the filtered routes received from neighbor\n"
"Route-map to modify the attributes\n" "Route-map to modify the attributes\n"
"Name of the route map\n" "Name of the route map\n"
JSON_STR) JSON_STR)
@ -10540,18 +10550,18 @@ DEFUN (show_ip_bgp_instance_neighbor_advertised_route,
safi_t safi = SAFI_UNICAST; safi_t safi = SAFI_UNICAST;
char *rmap_name = NULL; char *rmap_name = NULL;
char *peerstr = NULL; char *peerstr = NULL;
int rcvd = 0;
struct bgp *bgp = NULL; struct bgp *bgp = NULL;
struct peer *peer; struct peer *peer;
enum bgp_show_adj_route_type type = bgp_show_adj_route_advertised;
int idx = 0; int idx = 0;
bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi, bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
&bgp); &bgp);
if (!idx) if (!idx)
return CMD_WARNING; return CMD_WARNING;
int uj = use_json(argc, argv); int uj = use_json(argc, argv);
if (uj) if (uj)
argc--; argc--;
@ -10563,14 +10573,17 @@ DEFUN (show_ip_bgp_instance_neighbor_advertised_route,
if (!peer) if (!peer)
return CMD_WARNING; return CMD_WARNING;
if (argv_find(argv, argc, "received-routes", &idx))
rcvd = 1;
if (argv_find(argv, argc, "advertised-routes", &idx)) if (argv_find(argv, argc, "advertised-routes", &idx))
rcvd = 0; type = bgp_show_adj_route_advertised;
else if (argv_find(argv, argc, "received-routes", &idx))
type = bgp_show_adj_route_received;
else if (argv_find(argv, argc, "filtered-routes", &idx))
type = bgp_show_adj_route_filtered;
if (argv_find(argv, argc, "route-map", &idx)) if (argv_find(argv, argc, "route-map", &idx))
rmap_name = argv[++idx]->arg; rmap_name = argv[++idx]->arg;
return peer_adj_routes(vty, peer, afi, safi, rcvd, rmap_name, uj); return peer_adj_routes(vty, peer, afi, safi, type, rmap_name, uj);
} }
DEFUN (show_ip_bgp_neighbor_received_prefix_filter, DEFUN (show_ip_bgp_neighbor_received_prefix_filter,

View File

@ -52,6 +52,12 @@ enum bgp_show_type {
bgp_show_type_detail, bgp_show_type_detail,
}; };
enum bgp_show_adj_route_type {
bgp_show_adj_route_advertised,
bgp_show_adj_route_received,
bgp_show_adj_route_filtered,
};
#define BGP_SHOW_SCODE_HEADER \ #define BGP_SHOW_SCODE_HEADER \
"Status codes: s suppressed, d damped, " \ "Status codes: s suppressed, d damped, " \