diff options
| author | Donatas Abraitis <donatas@opensourcerouting.org> | 2023-02-09 11:02:11 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-02-09 11:02:11 +0200 |
| commit | f83956c06d22c5b48447eca7adc9c0e38793502c (patch) | |
| tree | 24ac38a920513e4449271be08edd61f34b967015 | |
| parent | 5a77b9d61d21c30244503616419b14b0cd289e68 (diff) | |
| parent | 200631aa65c151ba1c1563e2a6aa8757cd4024f0 (diff) | |
Merge pull request #12738 from taspelund/adj-rib-specific
Improvements to advertised/received/bestpath-routes commands
| -rw-r--r-- | bgpd/bgp_route.c | 161 | ||||
| -rw-r--r-- | doc/user/bgp.rst | 22 |
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 |
