Merge pull request #12738 from taspelund/adj-rib-specific

Improvements to advertised/received/bestpath-routes commands
This commit is contained in:
Donatas Abraitis 2023-02-09 11:02:11 +02:00 committed by GitHub
commit f83956c06d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 157 additions and 26 deletions

View file

@ -13976,16 +13976,17 @@ show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table,
const char *rmap_name, json_object *json, json_object *json_ar, const char *rmap_name, json_object *json, json_object *json_ar,
json_object *json_scode, json_object *json_ocode, json_object *json_scode, json_object *json_ocode,
uint16_t show_flags, int *header1, int *header2, char *rd_str, uint16_t show_flags, int *header1, int *header2, char *rd_str,
unsigned long *output_count, unsigned long *filtered_count) const struct prefix *match, unsigned long *output_count,
unsigned long *filtered_count)
{ {
struct bgp_adj_in *ain; struct bgp_adj_in *ain = NULL;
struct bgp_adj_out *adj; struct bgp_adj_out *adj = NULL;
struct bgp_dest *dest; struct bgp_dest *dest;
struct bgp *bgp; struct bgp *bgp;
struct attr attr; struct attr attr;
int ret; int ret;
struct update_subgroup *subgrp; struct update_subgroup *subgrp;
struct peer_af *paf; struct peer_af *paf = NULL;
bool route_filtered; bool route_filtered;
bool detail = CHECK_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL); bool detail = CHECK_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON); bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
@ -13999,6 +14000,98 @@ show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table,
bgp = peer->bgp; bgp = peer->bgp;
/* If the user supplied a prefix, look for a matching route instead
* of walking the whole table.
*/
if (match) {
dest = bgp_node_match(table, match);
if (!dest) {
if (!use_json)
vty_out(vty, "Network not in table\n");
return;
}
const struct prefix *rn_p = bgp_dest_get_prefix(dest);
if (rn_p->prefixlen != match->prefixlen) {
if (!use_json)
vty_out(vty, "Network not in table\n");
bgp_dest_unlock_node(dest);
return;
}
if (type == bgp_show_adj_route_received ||
type == bgp_show_adj_route_filtered) {
for (ain = dest->adj_in; ain; ain = ain->next) {
if (ain->peer == peer) {
attr = *ain->attr;
break;
}
}
/* bail out if if adj_out is empty, or
* if the prefix isn't in this peer's
* adj_in
*/
if (!ain || ain->peer != peer) {
if (!use_json)
vty_out(vty, "Network not in table\n");
bgp_dest_unlock_node(dest);
return;
}
} else if (type == bgp_show_adj_route_advertised) {
bool peer_found = false;
RB_FOREACH (adj, bgp_adj_out_rb, &dest->adj_out) {
SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
if (paf->peer == peer && adj->attr) {
attr = *adj->attr;
peer_found = true;
break;
}
}
if (peer_found)
break;
}
/* bail out if if adj_out is empty, or
* if the prefix isn't in this peer's
* adj_out
*/
if (!paf || !peer_found) {
if (!use_json)
vty_out(vty, "Network not in table\n");
bgp_dest_unlock_node(dest);
return;
}
}
ret = bgp_output_modifier(peer, rn_p, &attr, afi, safi,
rmap_name);
if (ret != RMAP_DENY) {
show_adj_route_header(vty, peer, table, header1,
header2, json, json_scode,
json_ocode, wide, detail);
if (use_json)
json_net = json_object_new_object();
bgp_show_path_info(NULL /* prefix_rd */, dest, vty, bgp,
afi, safi, json_net,
BGP_PATH_SHOW_ALL, &display,
RPKI_NOT_BEING_USED);
if (use_json)
json_object_object_addf(json_ar, json_net,
"%pFX", rn_p);
(*output_count)++;
} else
(*filtered_count)++;
bgp_attr_flush(&attr);
bgp_dest_unlock_node(dest);
return;
}
subgrp = peer_subgroup(peer, afi, safi); subgrp = peer_subgroup(peer, afi, safi);
if (type == bgp_show_adj_route_advertised && subgrp if (type == bgp_show_adj_route_advertised && subgrp
@ -14199,6 +14292,8 @@ show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table,
header2, json, json_scode, header2, json, json_scode,
json_ocode, wide, detail); json_ocode, wide, detail);
const struct prefix *rn_p = bgp_dest_get_prefix(dest);
for (pi = bgp_dest_get_bgp_path_info(dest); pi; for (pi = bgp_dest_get_bgp_path_info(dest); pi;
pi = pi->next) { pi = pi->next) {
if (pi->peer != peer) if (pi->peer != peer)
@ -14207,10 +14302,23 @@ show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table,
if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
continue; continue;
route_vty_out_tmp(vty, dest, if (detail) {
bgp_dest_get_prefix(dest), if (use_json)
pi->attr, safi, use_json, json_net =
json_ar, wide); json_object_new_object();
bgp_show_path_info(
NULL /* prefix_rd */, dest, vty,
bgp, afi, safi, json_net,
BGP_PATH_SHOW_BESTPATH,
&display, RPKI_NOT_BEING_USED);
if (use_json)
json_object_object_addf(
json_ar, json_net,
"%pFX", rn_p);
} else
route_vty_out_tmp(
vty, dest, rn_p, pi->attr, safi,
use_json, json_ar, wide);
(*output_count)++; (*output_count)++;
} }
} }
@ -14219,7 +14327,8 @@ show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table,
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, enum bgp_show_adj_route_type type, safi_t safi, enum bgp_show_adj_route_type type,
const char *rmap_name, uint16_t show_flags) const char *rmap_name, const struct prefix *match,
uint16_t show_flags)
{ {
struct bgp *bgp; struct bgp *bgp;
struct bgp_table *table; struct bgp_table *table;
@ -14345,11 +14454,11 @@ CPP_NOTICE("Drop `bgpOriginCodes` from JSON outputs")
prefix_rd2str(prd, rd_str, sizeof(rd_str)); prefix_rd2str(prd, rd_str, sizeof(rd_str));
show_adj_route(vty, peer, table, afi, safi, type, show_adj_route(
rmap_name, json, json_routes, json_scode, vty, peer, table, afi, safi, type, rmap_name,
json_ocode, show_flags, &header1, json, json_routes, json_scode, json_ocode,
&header2, rd_str, &output_count_per_rd, show_flags, &header1, &header2, rd_str, match,
&filtered_count_per_rd); &output_count_per_rd, &filtered_count_per_rd);
/* Don't include an empty RD in the output! */ /* Don't include an empty RD in the output! */
if (json_routes && (output_count_per_rd > 0)) if (json_routes && (output_count_per_rd > 0))
@ -14362,7 +14471,7 @@ CPP_NOTICE("Drop `bgpOriginCodes` from JSON outputs")
} else } else
show_adj_route(vty, peer, table, afi, safi, type, rmap_name, show_adj_route(vty, peer, table, afi, safi, type, rmap_name,
json, json_ar, json_scode, json_ocode, json, json_ar, json_scode, json_ocode,
show_flags, &header1, &header2, rd_str, show_flags, &header1, &header2, rd_str, match,
&output_count, &filtered_count); &output_count, &filtered_count);
if (use_json) { if (use_json) {
@ -14387,7 +14496,7 @@ CPP_NOTICE("Drop `bgpOriginCodes` from JSON outputs")
vty_json(vty, json); vty_json(vty, json);
} else if (output_count > 0) { } else if (output_count > 0) {
if (filtered_count > 0) if (!match && filtered_count > 0)
vty_out(vty, vty_out(vty,
"\nTotal number of prefixes %ld (%ld filtered)\n", "\nTotal number of prefixes %ld (%ld filtered)\n",
output_count, filtered_count); output_count, filtered_count);
@ -14401,7 +14510,7 @@ CPP_NOTICE("Drop `bgpOriginCodes` from JSON outputs")
DEFPY (show_ip_bgp_instance_neighbor_bestpath_route, DEFPY (show_ip_bgp_instance_neighbor_bestpath_route,
show_ip_bgp_instance_neighbor_bestpath_route_cmd, show_ip_bgp_instance_neighbor_bestpath_route_cmd,
"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> bestpath-routes [json$uj | wide$wide]", "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> bestpath-routes [detail$detail] [json$uj | wide$wide]",
SHOW_STR SHOW_STR
IP_STR IP_STR
BGP_STR BGP_STR
@ -14413,6 +14522,7 @@ DEFPY (show_ip_bgp_instance_neighbor_bestpath_route,
"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 routes selected by best path\n" "Display the routes selected by best path\n"
"Display detailed version of routes\n"
JSON_STR JSON_STR
"Increase table width for longer prefixes\n") "Increase table width for longer prefixes\n")
{ {
@ -14426,6 +14536,9 @@ DEFPY (show_ip_bgp_instance_neighbor_bestpath_route,
int idx = 0; int idx = 0;
uint16_t show_flags = 0; uint16_t show_flags = 0;
if (detail)
SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
if (uj) if (uj)
SET_FLAG(show_flags, BGP_SHOW_OPT_JSON); SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
@ -14445,13 +14558,13 @@ DEFPY (show_ip_bgp_instance_neighbor_bestpath_route,
if (!peer) if (!peer)
return CMD_WARNING; return CMD_WARNING;
return peer_adj_routes(vty, peer, afi, safi, type, rmap_name, return peer_adj_routes(vty, peer, afi, safi, type, rmap_name, NULL,
show_flags); show_flags);
} }
DEFPY(show_ip_bgp_instance_neighbor_advertised_route, DEFPY(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 "]] [all$all] neighbors <A.B.C.D|X:X::X:X|WORD> <advertised-routes|received-routes|filtered-routes> [route-map RMAP_NAME$route_map] [detail$detail] [json$uj | wide$wide]", "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR " [" BGP_SAFI_WITH_LABEL_CMD_STR "]] [all$all] neighbors <A.B.C.D|X:X::X:X|WORD> <advertised-routes|received-routes|filtered-routes> [route-map RMAP_NAME$route_map] [<A.B.C.D/M|X:X::X:X/M>$prefix | detail$detail] [json$uj | wide$wide]",
SHOW_STR SHOW_STR
IP_STR IP_STR
BGP_STR BGP_STR
@ -14468,6 +14581,8 @@ DEFPY(show_ip_bgp_instance_neighbor_advertised_route,
"Display the filtered routes received 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"
"IPv4 prefix\n"
"IPv6 prefix\n"
"Display detailed version of routes\n" "Display detailed version of routes\n"
JSON_STR JSON_STR
"Increase table width for longer prefixes\n") "Increase table width for longer prefixes\n")
@ -14484,7 +14599,7 @@ DEFPY(show_ip_bgp_instance_neighbor_advertised_route,
struct listnode *node; struct listnode *node;
struct bgp *abgp; struct bgp *abgp;
if (detail) if (detail || prefix_str)
SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL); SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
if (uj) { if (uj) {
@ -14526,7 +14641,7 @@ DEFPY(show_ip_bgp_instance_neighbor_advertised_route,
if (!all) if (!all)
return peer_adj_routes(vty, peer, afi, safi, type, route_map, return peer_adj_routes(vty, peer, afi, safi, type, route_map,
show_flags); prefix_str ? prefix : NULL, show_flags);
if (uj) if (uj)
vty_out(vty, "{\n"); vty_out(vty, "{\n");
@ -14554,7 +14669,7 @@ DEFPY(show_ip_bgp_instance_neighbor_advertised_route,
false)); false));
peer_adj_routes(vty, peer, afi, safi, type, peer_adj_routes(vty, peer, afi, safi, type,
route_map, show_flags); route_map, prefix, show_flags);
} }
} }
} else { } else {
@ -14578,7 +14693,7 @@ DEFPY(show_ip_bgp_instance_neighbor_advertised_route,
false)); false));
peer_adj_routes(vty, peer, afi, safi, type, peer_adj_routes(vty, peer, afi, safi, type,
route_map, show_flags); route_map, prefix, show_flags);
} }
} }
} }

View file

@ -1837,11 +1837,21 @@ Configuring Peers
Displaying Information about Peers Displaying Information about Peers
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. clicmd:: show bgp <afi> <safi> neighbors WORD bestpath-routes [json] [wide] .. clicmd:: show bgp <afi> <safi> neighbors WORD bestpath-routes [detail] [json] [wide]
For the given neighbor, WORD, that is specified list the routes selected For the given neighbor, WORD, that is specified list the routes selected
by BGP as having the best path. by BGP as having the best path.
If ``detail`` option is specified, the detailed version of all routes
will be displayed. The same format as ``show [ip] bgp [afi] [safi] PREFIX``
will be used, but for the whole table of received, advertised or filtered
prefixes.
If ``json`` option is specified, output is displayed in JSON format.
If ``wide`` option is specified, then the prefix table's width is increased
to fully display the prefix and the nexthop.
.. _bgp-peer-filtering: .. _bgp-peer-filtering:
Peer Filtering Peer Filtering
@ -3916,7 +3926,7 @@ structure is extended with :clicmd:`show bgp [afi] [safi]`.
The ``terse`` option can be used in combination with the remote-as, neighbor, The ``terse`` option can be used in combination with the remote-as, neighbor,
failed and established filters, and with the ``wide`` option as well. failed and established filters, and with the ``wide`` option as well.
.. clicmd:: show bgp [afi] [safi] [neighbor [PEER] [routes|advertised-routes|received-routes] [detail] [json] .. clicmd:: show bgp [afi] [safi] [neighbor [PEER] [routes|advertised-routes|received-routes] [<A.B.C.D/M|X:X::X:X/M> | detail] [json]
This command shows information on a specific BGP peer of the relevant This command shows information on a specific BGP peer of the relevant
afi and safi selected. afi and safi selected.
@ -3931,6 +3941,9 @@ structure is extended with :clicmd:`show bgp [afi] [safi]`.
The ``received-routes`` keyword displays all routes belonging to this The ``received-routes`` keyword displays all routes belonging to this
address-family (prior to inbound policy) that were received by this peer. address-family (prior to inbound policy) that were received by this peer.
If a specific prefix is specified, the detailed version of that prefix will
be displayed.
If ``detail`` option is specified, the detailed version of all routes If ``detail`` option is specified, the detailed version of all routes
will be displayed. The same format as ``show [ip] bgp [afi] [safi] PREFIX`` will be displayed. The same format as ``show [ip] bgp [afi] [safi] PREFIX``
will be used, but for the whole table of received, advertised or filtered will be used, but for the whole table of received, advertised or filtered
@ -4030,7 +4043,7 @@ structure is extended with :clicmd:`show bgp [afi] [safi]`.
If the ``json`` option is specified, output is displayed in JSON format. If the ``json`` option is specified, output is displayed in JSON format.
.. clicmd:: show [ip] bgp [afi] [safi] [all] neighbors A.B.C.D [advertised-routes|received-routes|filtered-routes] [detail] [json|wide] .. clicmd:: show [ip] bgp [afi] [safi] [all] neighbors A.B.C.D [advertised-routes|received-routes|filtered-routes] [<A.B.C.D/M|X:X::X:X/M> | detail] [json|wide]
Display the routes advertised to a BGP neighbor or received routes Display the routes advertised to a BGP neighbor or received routes
from neighbor or filtered routes received from neighbor based on the from neighbor or filtered routes received from neighbor based on the
@ -4047,6 +4060,9 @@ structure is extended with :clicmd:`show bgp [afi] [safi]`.
if afi is specified, with ``all`` option, routes will be displayed for if afi is specified, with ``all`` option, routes will be displayed for
each SAFI in the selcted AFI each SAFI in the selcted AFI
If a specific prefix is specified, the detailed version of that prefix will
be displayed.
If ``detail`` option is specified, the detailed version of all routes If ``detail`` option is specified, the detailed version of all routes
will be displayed. The same format as ``show [ip] bgp [afi] [safi] PREFIX`` will be displayed. The same format as ``show [ip] bgp [afi] [safi] PREFIX``
will be used, but for the whole table of received, advertised or filtered will be used, but for the whole table of received, advertised or filtered