summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDonatas Abraitis <donatas@opensourcerouting.org>2023-02-09 11:02:11 +0200
committerGitHub <noreply@github.com>2023-02-09 11:02:11 +0200
commitf83956c06d22c5b48447eca7adc9c0e38793502c (patch)
tree24ac38a920513e4449271be08edd61f34b967015
parent5a77b9d61d21c30244503616419b14b0cd289e68 (diff)
parent200631aa65c151ba1c1563e2a6aa8757cd4024f0 (diff)
Merge pull request #12738 from taspelund/adj-rib-specific
Improvements to advertised/received/bestpath-routes commands
-rw-r--r--bgpd/bgp_route.c161
-rw-r--r--doc/user/bgp.rst22
2 files changed, 157 insertions, 26 deletions
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 24f5725fe4..23e6195d34 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -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,
json_object *json_scode, json_object *json_ocode,
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_out *adj;
+ struct bgp_adj_in *ain = NULL;
+ struct bgp_adj_out *adj = NULL;
struct bgp_dest *dest;
struct bgp *bgp;
struct attr attr;
int ret;
struct update_subgroup *subgrp;
- struct peer_af *paf;
+ struct peer_af *paf = NULL;
bool route_filtered;
bool detail = CHECK_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
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;
+ /* 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);
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,
json_ocode, wide, detail);
+ const struct prefix *rn_p = bgp_dest_get_prefix(dest);
+
for (pi = bgp_dest_get_bgp_path_info(dest); pi;
pi = pi->next) {
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))
continue;
- route_vty_out_tmp(vty, dest,
- bgp_dest_get_prefix(dest),
- pi->attr, safi, use_json,
- json_ar, wide);
+ if (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_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)++;
}
}
@@ -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,
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_table *table;
@@ -14345,11 +14454,11 @@ CPP_NOTICE("Drop `bgpOriginCodes` from JSON outputs")
prefix_rd2str(prd, rd_str, sizeof(rd_str));
- show_adj_route(vty, peer, table, afi, safi, type,
- rmap_name, json, json_routes, json_scode,
- json_ocode, show_flags, &header1,
- &header2, rd_str, &output_count_per_rd,
- &filtered_count_per_rd);
+ show_adj_route(
+ vty, peer, table, afi, safi, type, rmap_name,
+ json, json_routes, json_scode, json_ocode,
+ show_flags, &header1, &header2, rd_str, match,
+ &output_count_per_rd, &filtered_count_per_rd);
/* Don't include an empty RD in the output! */
if (json_routes && (output_count_per_rd > 0))
@@ -14362,7 +14471,7 @@ CPP_NOTICE("Drop `bgpOriginCodes` from JSON outputs")
} else
show_adj_route(vty, peer, table, afi, safi, type, rmap_name,
json, json_ar, json_scode, json_ocode,
- show_flags, &header1, &header2, rd_str,
+ show_flags, &header1, &header2, rd_str, match,
&output_count, &filtered_count);
if (use_json) {
@@ -14387,7 +14496,7 @@ CPP_NOTICE("Drop `bgpOriginCodes` from JSON outputs")
vty_json(vty, json);
} else if (output_count > 0) {
- if (filtered_count > 0)
+ if (!match && filtered_count > 0)
vty_out(vty,
"\nTotal number of prefixes %ld (%ld filtered)\n",
output_count, filtered_count);
@@ -14401,7 +14510,7 @@ CPP_NOTICE("Drop `bgpOriginCodes` from JSON outputs")
DEFPY (show_ip_bgp_instance_neighbor_bestpath_route,
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
IP_STR
BGP_STR
@@ -14413,6 +14522,7 @@ DEFPY (show_ip_bgp_instance_neighbor_bestpath_route,
"Neighbor to display information about\n"
"Neighbor on BGP configured interface\n"
"Display the routes selected by best path\n"
+ "Display detailed version of routes\n"
JSON_STR
"Increase table width for longer prefixes\n")
{
@@ -14426,6 +14536,9 @@ DEFPY (show_ip_bgp_instance_neighbor_bestpath_route,
int idx = 0;
uint16_t show_flags = 0;
+ if (detail)
+ SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
+
if (uj)
SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
@@ -14445,13 +14558,13 @@ DEFPY (show_ip_bgp_instance_neighbor_bestpath_route,
if (!peer)
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);
}
DEFPY(show_ip_bgp_instance_neighbor_advertised_route,
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
IP_STR
BGP_STR
@@ -14468,6 +14581,8 @@ DEFPY(show_ip_bgp_instance_neighbor_advertised_route,
"Display the filtered routes received from neighbor\n"
"Route-map to modify the attributes\n"
"Name of the route map\n"
+ "IPv4 prefix\n"
+ "IPv6 prefix\n"
"Display detailed version of routes\n"
JSON_STR
"Increase table width for longer prefixes\n")
@@ -14484,7 +14599,7 @@ DEFPY(show_ip_bgp_instance_neighbor_advertised_route,
struct listnode *node;
struct bgp *abgp;
- if (detail)
+ if (detail || prefix_str)
SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
if (uj) {
@@ -14526,7 +14641,7 @@ DEFPY(show_ip_bgp_instance_neighbor_advertised_route,
if (!all)
return peer_adj_routes(vty, peer, afi, safi, type, route_map,
- show_flags);
+ prefix_str ? prefix : NULL, show_flags);
if (uj)
vty_out(vty, "{\n");
@@ -14554,7 +14669,7 @@ DEFPY(show_ip_bgp_instance_neighbor_advertised_route,
false));
peer_adj_routes(vty, peer, afi, safi, type,
- route_map, show_flags);
+ route_map, prefix, show_flags);
}
}
} else {
@@ -14578,7 +14693,7 @@ DEFPY(show_ip_bgp_instance_neighbor_advertised_route,
false));
peer_adj_routes(vty, peer, afi, safi, type,
- route_map, show_flags);
+ route_map, prefix, show_flags);
}
}
}
diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst
index 9c69848258..b17442f641 100644
--- a/doc/user/bgp.rst
+++ b/doc/user/bgp.rst
@@ -1837,11 +1837,21 @@ Configuring 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
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:
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,
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
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
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
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
@@ -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.
-.. 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
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
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
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