diff --git a/bgpd/bgp_damp.c b/bgpd/bgp_damp.c index 565d0b8e19..9992168182 100644 --- a/bgpd/bgp_damp.c +++ b/bgpd/bgp_damp.c @@ -36,6 +36,8 @@ #include "bgpd/bgp_attr.h" #include "bgpd/bgp_advertise.h" +const char *get_afi_safi_str(afi_t afi, safi_t safi, bool for_json); + /* Global variable to access damping configuration */ static struct bgp_damp_config damp[AFI_MAX][SAFI_MAX]; @@ -653,16 +655,9 @@ const char *bgp_damp_reuse_time_vty(struct vty *vty, struct bgp_path_info *path, json); } -int bgp_show_dampening_parameters(struct vty *vty, afi_t afi, safi_t safi) +static int bgp_print_dampening_parameters(struct bgp *bgp, struct vty *vty, + afi_t afi, safi_t safi) { - struct bgp *bgp; - bgp = bgp_get_default(); - - if (bgp == NULL) { - vty_out(vty, "No BGP process is configured\n"); - return CMD_WARNING; - } - if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)) { vty_out(vty, "Half-life time: %lld min\n", (long long)damp[afi][safi].half_life / 60); @@ -677,7 +672,52 @@ int bgp_show_dampening_parameters(struct vty *vty, afi_t afi, safi_t safi) vty_out(vty, "\n"); } else vty_out(vty, "dampening not enabled for %s\n", - afi == AFI_IP ? "IPv4" : "IPv6"); + get_afi_safi_str(afi, safi, false)); return CMD_SUCCESS; } + +int bgp_show_dampening_parameters(struct vty *vty, afi_t afi, safi_t safi, + uint8_t show_flags) +{ + struct bgp *bgp; + bgp = bgp_get_default(); + + if (bgp == NULL) { + vty_out(vty, "No BGP process is configured\n"); + return CMD_WARNING; + } + + if (!CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL)) + return bgp_print_dampening_parameters(bgp, vty, afi, safi); + + if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP) + || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) { + afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP) ? AFI_IP + : AFI_IP6; + FOREACH_SAFI (safi) { + if (strmatch(get_afi_safi_str(afi, safi, true), + "Unknown")) + continue; + + if (!CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON)) + vty_out(vty, "\nFor address family: %s\n\n", + get_afi_safi_str(afi, safi, false)); + + bgp_print_dampening_parameters(bgp, vty, afi, safi); + } + } else { + FOREACH_AFI_SAFI (afi, safi) { + if (strmatch(get_afi_safi_str(afi, safi, true), + "Unknown")) + continue; + + if (!CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON)) + vty_out(vty, "\nFor address family: %s\n", + get_afi_safi_str(afi, safi, false)); + + bgp_print_dampening_parameters(bgp, vty, afi, safi); + } + } + return CMD_SUCCESS; +} diff --git a/bgpd/bgp_damp.h b/bgpd/bgp_damp.h index 4ab38326e2..604706300b 100644 --- a/bgpd/bgp_damp.h +++ b/bgpd/bgp_damp.h @@ -151,6 +151,7 @@ extern const char *bgp_damp_reuse_time_vty(struct vty *vty, char *timebuf, size_t len, afi_t afi, safi_t safi, bool use_json, json_object *json); -extern int bgp_show_dampening_parameters(struct vty *vty, afi_t, safi_t); +extern int bgp_show_dampening_parameters(struct vty *vty, afi_t, safi_t, + uint8_t); #endif /* _QUAGGA_BGP_DAMP_H */ diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 8eaee36c2e..626f766987 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -9757,15 +9757,14 @@ static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr, bool use_json); static int bgp_show_community(struct vty *vty, struct bgp *bgp, const char *comstr, int exact, afi_t afi, - safi_t safi, bool use_json); + 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, bool use_json, char *rd, - int is_last, unsigned long *output_cum, - unsigned long *total_cum, - unsigned long *json_header_depth, bool wide) + void *output_arg, char *rd, int is_last, + unsigned long *output_cum, unsigned long *total_cum, + unsigned long *json_header_depth, uint8_t show_flags) { struct bgp_path_info *pi; struct bgp_dest *dest; @@ -9776,13 +9775,23 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, struct prefix *p; json_object *json_paths = NULL; int first = 1; + bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON); + bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE); + bool all = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL); if (output_cum && *output_cum != 0) header = 0; if (use_json && !*json_header_depth) { + if (all) + *json_header_depth = 1; + else { + vty_out(vty, "{\n"); + *json_header_depth = 2; + } + vty_out(vty, - "{\n \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64",\n \"routerId\": \"%s\",\n \"defaultLocPrf\": %u,\n" + " \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64",\n \"routerId\": \"%s\",\n \"defaultLocPrf\": %u,\n" " \"localAS\": %u,\n \"routes\": { ", bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id, bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT @@ -9790,7 +9799,6 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, : bgp->name, table->version, inet_ntoa(bgp->router_id), bgp->default_local_pref, bgp->as); - *json_header_depth = 2; if (rd) { vty_out(vty, " \"routeDistinguishers\" : {"); ++*json_header_depth; @@ -10071,7 +10079,8 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, unsigned long i; for (i = 0; i < *json_header_depth; ++i) vty_out(vty, " } "); - vty_out(vty, "\n"); + if (!all) + vty_out(vty, "\n"); } } else { if (is_last) { @@ -10101,9 +10110,13 @@ int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi, unsigned long json_header_depth = 0; struct bgp_table *itable; bool show_msg; + uint8_t show_flags = 0; show_msg = (!use_json && type == bgp_show_type_normal); + if (use_json) + SET_FLAG(show_flags, BGP_SHOW_OPT_JSON); + for (dest = bgp_table_top(table); dest; dest = next) { const struct prefix *dest_p = bgp_dest_get_prefix(dest); @@ -10119,8 +10132,9 @@ int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi, memcpy(&prd, dest_p, sizeof(struct prefix_rd)); prefix_rd2str(&prd, rd, sizeof(rd)); bgp_show_table(vty, bgp, safi, itable, type, output_arg, - use_json, rd, next == NULL, &output_cum, - &total_cum, &json_header_depth, false); + rd, next == NULL, &output_cum, + &total_cum, &json_header_depth, + show_flags); if (next == NULL) show_msg = false; } @@ -10137,11 +10151,12 @@ int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi, return CMD_SUCCESS; } static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, - enum bgp_show_type type, void *output_arg, bool use_json, - bool wide) + enum bgp_show_type type, void *output_arg, + uint8_t show_flags) { struct bgp_table *table; unsigned long json_header_depth = 0; + bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON); if (bgp == NULL) { bgp = bgp_get_default(); @@ -10171,18 +10186,18 @@ static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, else if (safi == SAFI_LABELED_UNICAST) safi = SAFI_UNICAST; - return bgp_show_table(vty, bgp, safi, table, type, output_arg, use_json, - NULL, 1, NULL, NULL, &json_header_depth, wide); + return bgp_show_table(vty, bgp, safi, table, type, output_arg, NULL, 1, + NULL, NULL, &json_header_depth, show_flags); } static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi, - safi_t safi, bool use_json, - bool wide) + safi_t safi, uint8_t show_flags) { struct listnode *node, *nnode; struct bgp *bgp; int is_first = 1; bool route_output = false; + bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON); if (use_json) vty_out(vty, "{\n"); @@ -10206,7 +10221,7 @@ static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi, : bgp->name); } bgp_show(vty, bgp, afi, safi, bgp_show_type_normal, NULL, - use_json, wide); + show_flags); } if (use_json) @@ -10667,6 +10682,10 @@ static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc, int i; char *str; int first = 0; + uint8_t show_flags = 0; + + if (uj) + SET_FLAG(show_flags, BGP_SHOW_OPT_JSON); b = buffer_new(1024); for (i = 0; i < argc; i++) { @@ -10694,7 +10713,7 @@ static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc, return bgp_show(vty, bgp, afi, safi, (exact ? bgp_show_type_lcommunity_exact : bgp_show_type_lcommunity), - lcom, uj, false); + lcom, show_flags); } static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp, @@ -10702,6 +10721,11 @@ static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp, safi_t safi, bool uj) { struct community_list *list; + uint8_t show_flags = 0; + + if (uj) + SET_FLAG(show_flags, BGP_SHOW_OPT_JSON); + list = community_list_lookup(bgp_clist, lcom, 0, LARGE_COMMUNITY_LIST_MASTER); @@ -10714,7 +10738,7 @@ static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp, return bgp_show(vty, bgp, afi, safi, (exact ? bgp_show_type_lcommunity_list_exact : bgp_show_type_lcommunity_list), - list, uj, false); + list, show_flags); } DEFUN (show_ip_bgp_large_community_list, @@ -10777,14 +10801,17 @@ DEFUN (show_ip_bgp_large_community, bool exact_match = 0; struct bgp *bgp = NULL; bool uj = use_json(argc, argv); + uint8_t show_flags = 0; - if (uj) - argc--; + if (uj) { + argc--; + SET_FLAG(show_flags, BGP_SHOW_OPT_JSON); + } - bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi, - &bgp, uj); - if (!idx) - return CMD_WARNING; + bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi, + &bgp, uj); + if (!idx) + return CMD_WARNING; if (argv_find(argv, argc, "AA:BB:CC", &idx)) { if (argv_find(argv, argc, "exact-match", &idx)) @@ -10793,7 +10820,7 @@ DEFUN (show_ip_bgp_large_community, exact_match, afi, safi, uj); } else return bgp_show(vty, bgp, afi, safi, - bgp_show_type_lcommunity_all, NULL, uj, false); + bgp_show_type_lcommunity_all, NULL, show_flags); } static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi, @@ -10940,11 +10967,11 @@ DEFUN(show_ip_bgp_afi_safi_statistics, show_ip_bgp_afi_safi_statistics_cmd, } /* BGP route print out function without JSON */ -DEFUN(show_ip_bgp, show_ip_bgp_cmd, +DEFPY(show_ip_bgp, show_ip_bgp_cmd, "show [ip] bgp [ VIEWVRFNAME] [" BGP_AFI_CMD_STR " [" BGP_SAFI_WITH_LABEL_CMD_STR "]]\ - \ + <[all$all] dampening \ |route-map WORD\ |prefix-list WORD\ |filter-list WORD\ @@ -10954,6 +10981,7 @@ DEFUN(show_ip_bgp, show_ip_bgp_cmd, >", 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 detailed information about dampening\n" "Display detail of configured dampening parameters\n" "Display routes matching the route-map\n" @@ -10976,6 +11004,17 @@ DEFUN(show_ip_bgp, show_ip_bgp_cmd, int exact_match = 0; struct bgp *bgp = NULL; int idx = 0; + uint8_t show_flags = 0; + + /* [ [all]] */ + if (all) { + SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL); + if (argv_find(argv, argc, "ipv4", &idx)) + SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP); + + if (argv_find(argv, argc, "ipv6", &idx)) + SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6); + } bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi, &bgp, false); @@ -10984,7 +11023,8 @@ DEFUN(show_ip_bgp, show_ip_bgp_cmd, if (argv_find(argv, argc, "dampening", &idx)) { if (argv_find(argv, argc, "parameters", &idx)) - return bgp_show_dampening_parameters(vty, afi, safi); + return bgp_show_dampening_parameters(vty, afi, safi, + show_flags); } if (argv_find(argv, argc, "prefix-list", &idx)) @@ -11020,6 +11060,7 @@ DEFUN(show_ip_bgp, show_ip_bgp_cmd, DEFPY (show_ip_bgp_json, show_ip_bgp_json_cmd, "show [ip] bgp [ VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]]\ + [all$all]\ [cidr-only\ |dampening \ |community [AA:NN|local-AS|no-advertise|no-export\ @@ -11034,6 +11075,7 @@ DEFPY (show_ip_bgp_json, 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" @@ -11064,9 +11106,29 @@ DEFPY (show_ip_bgp_json, struct bgp *bgp = NULL; int idx = 0; int exact_match = 0; + char *community = NULL; + bool first = true; + uint8_t show_flags = 0; - if (uj) + + if (uj) { argc--; + SET_FLAG(show_flags, BGP_SHOW_OPT_JSON); + } + + /* [ [all]] */ + if (all) { + SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL); + + if (argv_find(argv, argc, "ipv4", &idx)) + SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP); + + if (argv_find(argv, argc, "ipv6", &idx)) + SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6); + } + + if (wide) + SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE); bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi, &bgp, uj); @@ -11074,23 +11136,17 @@ DEFPY (show_ip_bgp_json, return CMD_WARNING; if (argv_find(argv, argc, "cidr-only", &idx)) - return bgp_show(vty, bgp, afi, safi, bgp_show_type_cidr_only, - NULL, uj, wide); + sh_type = bgp_show_type_cidr_only; if (argv_find(argv, argc, "dampening", &idx)) { if (argv_find(argv, argc, "dampened-paths", &idx)) - return bgp_show(vty, bgp, afi, safi, - bgp_show_type_dampend_paths, NULL, uj, - wide); + sh_type = bgp_show_type_dampend_paths; else if (argv_find(argv, argc, "flap-statistics", &idx)) - return bgp_show(vty, bgp, afi, safi, - bgp_show_type_flap_statistics, NULL, uj, - wide); + sh_type = bgp_show_type_flap_statistics; } if (argv_find(argv, argc, "community", &idx)) { char *maybecomm = NULL; - char *community = NULL; if (idx + 1 < argc) { if (argv[idx + 1]->type == VARIABLE_TKN) @@ -11106,16 +11162,103 @@ DEFPY (show_ip_bgp_json, if (argv_find(argv, argc, "exact-match", &idx)) exact_match = 1; - if (community) - return bgp_show_community(vty, bgp, community, - exact_match, afi, safi, uj); - else - return (bgp_show(vty, bgp, afi, safi, - bgp_show_type_community_all, NULL, uj, - wide)); + if (!community) + sh_type = bgp_show_type_community_all; } - return bgp_show(vty, bgp, afi, safi, sh_type, NULL, uj, wide); + if (!all) { + /* show bgp: AFI_IP6, show ip bgp: AFI_IP */ + if (community) + return bgp_show_community(vty, bgp, community, + exact_match, afi, safi, + show_flags); + else + return bgp_show(vty, bgp, afi, safi, sh_type, NULL, + show_flags); + } else { + /* show bgp ipv4 all: AFI_IP, show bgp ipv6 all: + * AFI_IP6 */ + + if (uj) + vty_out(vty, "{\n"); + + if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP) + || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) { + afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP) + ? AFI_IP + : AFI_IP6; + FOREACH_SAFI (safi) { + if (strmatch(get_afi_safi_str(afi, safi, true), + "Unknown")) + continue; + + if (!bgp_afi_safi_peer_exists(bgp, afi, safi)) + continue; + + if (uj) { + if (first) + first = false; + else + vty_out(vty, ",\n"); + vty_out(vty, "\"%s\":{\n", + get_afi_safi_str(afi, safi, + true)); + } else + vty_out(vty, + "\nFor address family: %s\n", + get_afi_safi_str(afi, safi, + false)); + + if (community) + bgp_show_community(vty, bgp, community, + exact_match, afi, + safi, show_flags); + else + bgp_show(vty, bgp, afi, safi, sh_type, + NULL, show_flags); + if (uj) + vty_out(vty, "}\n"); + } + } else { + /* show bgp all: for each AFI and SAFI*/ + FOREACH_AFI_SAFI (afi, safi) { + if (strmatch(get_afi_safi_str(afi, safi, true), + "Unknown")) + continue; + + if (!bgp_afi_safi_peer_exists(bgp, afi, safi)) + continue; + + if (uj) { + if (first) + first = false; + else + vty_out(vty, ",\n"); + + vty_out(vty, "\"%s\":{\n", + get_afi_safi_str(afi, safi, + true)); + } else + vty_out(vty, + "\nFor address family: %s\n", + get_afi_safi_str(afi, safi, + false)); + + if (community) + bgp_show_community(vty, bgp, community, + exact_match, afi, + safi, show_flags); + else + bgp_show(vty, bgp, afi, safi, sh_type, + NULL, show_flags); + if (uj) + vty_out(vty, "}\n"); + } + } + if (uj) + vty_out(vty, "}\n"); + } + return CMD_SUCCESS; } DEFUN (show_ip_bgp_route, @@ -11242,16 +11385,22 @@ DEFPY (show_ip_bgp_instance_all, safi_t safi = SAFI_UNICAST; struct bgp *bgp = NULL; int idx = 0; + uint8_t show_flags = 0; - if (uj) + if (uj) { argc--; + SET_FLAG(show_flags, BGP_SHOW_OPT_JSON); + } + + if (wide) + SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE); bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi, &bgp, uj); if (!idx) return CMD_WARNING; - bgp_show_all_instances_routes_vty(vty, afi, safi, uj, wide); + bgp_show_all_instances_routes_vty(vty, afi, safi, show_flags); return CMD_SUCCESS; } @@ -11261,6 +11410,10 @@ static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr, { regex_t *regex; int rc; + uint8_t show_flags = 0; + + if (use_json) + SET_FLAG(show_flags, BGP_SHOW_OPT_JSON); if (!config_bgp_aspath_validate(regstr)) { vty_out(vty, "Invalid character in REGEX %s\n", @@ -11274,7 +11427,7 @@ static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr, return CMD_WARNING; } - rc = bgp_show(vty, bgp, afi, safi, type, regex, use_json, false); + rc = bgp_show(vty, bgp, afi, safi, type, regex, show_flags); bgp_regex_free(regex); return rc; } @@ -11284,6 +11437,7 @@ static int bgp_show_prefix_list(struct vty *vty, struct bgp *bgp, safi_t safi, enum bgp_show_type type) { struct prefix_list *plist; + uint8_t show_flags = 0; plist = prefix_list_lookup(afi, prefix_list_str); if (plist == NULL) { @@ -11292,7 +11446,7 @@ static int bgp_show_prefix_list(struct vty *vty, struct bgp *bgp, return CMD_WARNING; } - return bgp_show(vty, bgp, afi, safi, type, plist, 0, false); + return bgp_show(vty, bgp, afi, safi, type, plist, show_flags); } static int bgp_show_filter_list(struct vty *vty, struct bgp *bgp, @@ -11300,6 +11454,7 @@ static int bgp_show_filter_list(struct vty *vty, struct bgp *bgp, enum bgp_show_type type) { struct as_list *as_list; + uint8_t show_flags = 0; as_list = as_list_lookup(filter); if (as_list == NULL) { @@ -11308,7 +11463,7 @@ static int bgp_show_filter_list(struct vty *vty, struct bgp *bgp, return CMD_WARNING; } - return bgp_show(vty, bgp, afi, safi, type, as_list, 0, false); + return bgp_show(vty, bgp, afi, safi, type, as_list, show_flags); } static int bgp_show_route_map(struct vty *vty, struct bgp *bgp, @@ -11316,6 +11471,7 @@ static int bgp_show_route_map(struct vty *vty, struct bgp *bgp, enum bgp_show_type type) { struct route_map *rmap; + uint8_t show_flags = 0; rmap = route_map_lookup_by_name(rmap_str); if (!rmap) { @@ -11323,12 +11479,12 @@ static int bgp_show_route_map(struct vty *vty, struct bgp *bgp, return CMD_WARNING; } - return bgp_show(vty, bgp, afi, safi, type, rmap, 0, false); + return bgp_show(vty, bgp, afi, safi, type, rmap, show_flags); } static int bgp_show_community(struct vty *vty, struct bgp *bgp, const char *comstr, int exact, afi_t afi, - safi_t safi, bool use_json) + safi_t safi, uint8_t show_flags) { struct community *com; int ret = 0; @@ -11342,7 +11498,7 @@ static int bgp_show_community(struct vty *vty, struct bgp *bgp, ret = bgp_show(vty, bgp, afi, safi, (exact ? bgp_show_type_community_exact : bgp_show_type_community), - com, use_json, false); + com, show_flags); community_free(&com); return ret; @@ -11353,6 +11509,7 @@ static int bgp_show_community_list(struct vty *vty, struct bgp *bgp, safi_t safi) { struct community_list *list; + uint8_t show_flags = 0; list = community_list_lookup(bgp_clist, com, 0, COMMUNITY_LIST_MASTER); if (list == NULL) { @@ -11363,7 +11520,7 @@ static int bgp_show_community_list(struct vty *vty, struct bgp *bgp, return bgp_show(vty, bgp, afi, safi, (exact ? bgp_show_type_community_list_exact : bgp_show_type_community_list), - list, 0, false); + list, show_flags); } static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp, @@ -11372,6 +11529,7 @@ static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp, { int ret; struct prefix *p; + uint8_t show_flags = 0; p = prefix_new(); @@ -11381,7 +11539,7 @@ static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp, return CMD_WARNING; } - ret = bgp_show(vty, bgp, afi, safi, type, p, 0, false); + ret = bgp_show(vty, bgp, afi, safi, type, p, show_flags); prefix_free(&p); return ret; } @@ -12195,8 +12353,8 @@ static void show_adj_route_header(struct vty *vty, struct bgp *bgp, static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi, safi_t safi, enum bgp_show_adj_route_type type, - const char *rmap_name, bool use_json, - json_object *json, bool wide) + const char *rmap_name, json_object *json, + uint8_t show_flags) { struct bgp_table *table; struct bgp_adj_in *ain; @@ -12215,6 +12373,8 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi, json_object *json_ar = NULL; struct peer_af *paf; bool route_filtered; + bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON); + bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE); if (use_json) { json_scode = json_object_new_object(); @@ -12423,9 +12583,10 @@ static void show_adj_route(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, - const char *rmap_name, bool use_json, bool wide) + const char *rmap_name, uint8_t show_flags) { json_object *json = NULL; + bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON); if (use_json) json = json_object_new_object(); @@ -12460,8 +12621,7 @@ static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi, return CMD_WARNING; } - show_adj_route(vty, peer, afi, safi, type, rmap_name, use_json, json, - wide); + show_adj_route(vty, peer, afi, safi, type, rmap_name, json, show_flags); return CMD_SUCCESS; } @@ -12491,6 +12651,13 @@ DEFPY (show_ip_bgp_instance_neighbor_bestpath_route, struct peer *peer; enum bgp_show_adj_route_type type = bgp_show_adj_route_bestpath; int idx = 0; + uint8_t show_flags = 0; + + if (uj) + SET_FLAG(show_flags, BGP_SHOW_OPT_JSON); + + if (wide) + SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE); bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi, &bgp, uj); @@ -12505,18 +12672,20 @@ DEFPY (show_ip_bgp_instance_neighbor_bestpath_route, if (!peer) return CMD_WARNING; - return peer_adj_routes(vty, peer, afi, safi, type, rmap_name, uj, wide); + return peer_adj_routes(vty, peer, afi, safi, type, rmap_name, + show_flags); } DEFPY (show_ip_bgp_instance_neighbor_advertised_route, show_ip_bgp_instance_neighbor_advertised_route_cmd, - "show [ip] bgp [ VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] neighbors [route-map WORD] [json$uj | wide$wide]", + "show [ip] bgp [ VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [all$all] neighbors [route-map WORD] [json$uj | 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" "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" @@ -12537,9 +12706,25 @@ DEFPY (show_ip_bgp_instance_neighbor_advertised_route, struct peer *peer; enum bgp_show_adj_route_type type = bgp_show_adj_route_advertised; int idx = 0; + bool first = true; + uint8_t show_flags = 0; - if (uj) + if (uj) { argc--; + SET_FLAG(show_flags, BGP_SHOW_OPT_JSON); + } + + if (all) { + SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL); + if (argv_find(argv, argc, "ipv4", &idx)) + SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP); + + if (argv_find(argv, argc, "ipv6", &idx)) + SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6); + } + + if (wide) + SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE); bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi, &bgp, uj); @@ -12564,7 +12749,66 @@ DEFPY (show_ip_bgp_instance_neighbor_advertised_route, if (argv_find(argv, argc, "route-map", &idx)) rmap_name = argv[++idx]->arg; - return peer_adj_routes(vty, peer, afi, safi, type, rmap_name, uj, wide); + if (!all) + return peer_adj_routes(vty, peer, afi, safi, type, rmap_name, + show_flags); + if (uj) + vty_out(vty, "{\n"); + + if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP) + || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) { + afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP) ? AFI_IP + : AFI_IP6; + FOREACH_SAFI (safi) { + if (strmatch(get_afi_safi_str(afi, safi, true), + "Unknown")) + continue; + + if (!bgp_afi_safi_peer_exists(bgp, afi, safi)) + continue; + + if (uj) { + if (first) + first = false; + else + vty_out(vty, ",\n"); + vty_out(vty, "\"%s\":", + get_afi_safi_str(afi, safi, true)); + } else + vty_out(vty, "\nFor address family: %s\n", + get_afi_safi_str(afi, safi, false)); + + peer_adj_routes(vty, peer, afi, safi, type, rmap_name, + show_flags); + } + } else { + FOREACH_AFI_SAFI (afi, safi) { + if (strmatch(get_afi_safi_str(afi, safi, true), + "Unknown")) + continue; + + if (!bgp_afi_safi_peer_exists(bgp, afi, safi)) + continue; + + if (uj) { + if (first) + first = false; + else + vty_out(vty, ",\n"); + vty_out(vty, "\"%s\":", + get_afi_safi_str(afi, safi, true)); + } else + vty_out(vty, "\nFor address family: %s\n", + get_afi_safi_str(afi, safi, false)); + + peer_adj_routes(vty, peer, afi, safi, type, rmap_name, + show_flags); + } + } + if (uj) + vty_out(vty, "}\n"); + + return CMD_SUCCESS; } DEFUN (show_ip_bgp_neighbor_received_prefix_filter, @@ -12653,6 +12897,11 @@ static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer, afi_t afi, safi_t safi, enum bgp_show_type type, bool use_json) { + uint8_t show_flags = 0; + + if (use_json) + SET_FLAG(show_flags, BGP_SHOW_OPT_JSON); + /* labeled-unicast routes live in the unicast table */ if (safi == SAFI_LABELED_UNICAST) safi = SAFI_UNICAST; @@ -12672,8 +12921,7 @@ static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer, return CMD_WARNING; } - return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, use_json, - false); + return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, show_flags); } DEFUN (show_ip_bgp_flowspec_routes_detailed, @@ -12693,17 +12941,20 @@ DEFUN (show_ip_bgp_flowspec_routes_detailed, struct bgp *bgp = NULL; int idx = 0; bool uj = use_json(argc, argv); + uint8_t show_flags = 0; - if (uj) + if (uj) { argc--; + SET_FLAG(show_flags, BGP_SHOW_OPT_JSON); + } bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi, &bgp, uj); if (!idx) return CMD_WARNING; - return bgp_show(vty, bgp, afi, safi, bgp_show_type_detail, NULL, uj, - false); + return bgp_show(vty, bgp, afi, safi, bgp_show_type_detail, NULL, + show_flags); } DEFUN (show_ip_bgp_neighbor_routes, diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index 3f734d2672..3407884897 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -498,6 +498,13 @@ DECLARE_HOOK(bgp_process, struct peer *peer, bool withdraw), (bgp, afi, safi, bn, peer, withdraw)) +/* BGP show options */ +#define BGP_SHOW_OPT_JSON (1 << 0) +#define BGP_SHOW_OPT_WIDE (1 << 1) +#define BGP_SHOW_OPT_AFI_ALL (1 << 2) +#define BGP_SHOW_OPT_AFI_IP (1 << 3) +#define BGP_SHOW_OPT_AFI_IP6 (1 << 4) + /* Prototypes. */ extern void bgp_rib_remove(struct bgp_dest *dest, struct bgp_path_info *pi, struct peer *peer, afi_t afi, safi_t safi); diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 47c5237aa6..505f743e29 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -9867,15 +9867,16 @@ int bgp_show_summary_vty(struct vty *vty, const char *name, afi_t afi, } /* `show [ip] bgp summary' commands. */ -DEFUN (show_ip_bgp_summary, +DEFPY (show_ip_bgp_summary, show_ip_bgp_summary_cmd, - "show [ip] bgp [ VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] summary [established|failed] [json]", + "show [ip] bgp [ VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [all$all] summary [established|failed] [json$uj]", 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" "Summary of BGP neighbor status\n" "Show only sessions in Established state\n" "Show only sessions not in Established state\n" @@ -9890,7 +9891,7 @@ DEFUN (show_ip_bgp_summary, int idx = 0; /* show [ip] bgp */ - if (argv_find(argv, argc, "ip", &idx)) + if (!all && argv_find(argv, argc, "ip", &idx)) afi = AFI_IP; /* [ VIEWVRFNAME] */ if (argv_find(argv, argc, "vrf", &idx)) { @@ -9910,8 +9911,6 @@ DEFUN (show_ip_bgp_summary, if (argv_find(argv, argc, "established", &idx)) show_established = true; - bool uj = use_json(argc, argv); - return bgp_show_summary_vty(vty, vrf, afi, safi, show_failed, show_established, uj); } diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst index 63f3d05a93..427349c037 100644 --- a/doc/user/bgp.rst +++ b/doc/user/bgp.rst @@ -2721,17 +2721,17 @@ daemon project, while :clicmd:`show bgp` command is the new format. The choice has been done to keep old format with IPv4 routing table, while new format displays IPv6 routing table. -.. index:: show ip bgp [wide] -.. clicmd:: show ip bgp [wide] +.. index:: show ip bgp [all] [wide|json] +.. clicmd:: show ip bgp [all] [wide|json] -.. index:: show ip bgp A.B.C.D [wide] -.. clicmd:: show ip bgp A.B.C.D [wide] +.. index:: show ip bgp A.B.C.D [json] +.. clicmd:: show ip bgp A.B.C.D [json] -.. index:: show bgp [wide] -.. clicmd:: show bgp [wide] +.. index:: show bgp [all] [wide|json] +.. clicmd:: show bgp [all] [wide|json] -.. index:: show bgp X:X::X:X [wide] -.. clicmd:: show bgp X:X::X:X [wide] +.. index:: show bgp X:X::X:X [json] +.. clicmd:: show bgp X:X::X:X [json] These commands display BGP routes. When no route is specified, the default is to display all BGP routes. @@ -2753,6 +2753,11 @@ displays IPv6 routing table. This is especially handy dealing with IPv6 prefixes and if :clicmd:`[no] bgp default show-nexthop-hostname` is enabled. + If _all_ option is specified, _ip_ keyword is ignored, show bgp all and + show ip bgp all commands display routes for all AFIs and SAFIs. + + If _json_ option is specified, output is displayed in JSON format. + Some other commands provide additional options for filtering the output. .. index:: show [ip] bgp regexp LINE @@ -2761,8 +2766,8 @@ Some other commands provide additional options for filtering the output. This command displays BGP routes using AS path regular expression (:ref:`bgp-regular-expressions`). -.. index:: show [ip] bgp summary -.. clicmd:: show [ip] bgp summary +.. index:: show [ip] bgp [all] summary [json] +.. clicmd:: show [ip] bgp [all] summary [json] Show a bgp peer summary for the specified address family. @@ -2771,8 +2776,8 @@ and should no longer be used. In order to reach the other BGP routing tables other than the IPv6 routing table given by :clicmd:`show bgp`, the new command structure is extended with :clicmd:`show bgp [afi] [safi]`. -.. index:: show bgp [afi] [safi] -.. clicmd:: show bgp [afi] [safi] +.. index:: show bgp [afi] [safi] [all] [wide|json] +.. clicmd:: show bgp [afi] [safi] [all] [wide|json] .. index:: show bgp .. clicmd:: show bgp @@ -2788,20 +2793,20 @@ structure is extended with :clicmd:`show bgp [afi] [safi]`. Additionally, you can also filter this output by route type. -.. index:: show bgp [afi] [safi] summary -.. clicmd:: show bgp [afi] [safi] summary +.. index:: show bgp [afi] [safi] [all] summary [json] +.. clicmd:: show bgp [afi] [safi] [all] summary [json] Show a bgp peer summary for the specified address family, and subsequent address-family. -.. index:: show bgp [afi] [safi] summary failed [json] -.. clicmd:: show bgp [afi] [safi] summary failed [json] +.. index:: show bgp [afi] [safi] [all] summary failed [json] +.. clicmd:: show bgp [afi] [safi] [all] summary failed [json] Show a bgp peer summary for peers that are not succesfully exchanging routes for the specified address family, and subsequent address-family. -.. index:: show bgp [afi] [safi] summary established [json] -.. clicmd:: show bgp [afi] [safi] summary established [json] +.. index:: show bgp [afi] [safi] [all] summary established [json] +.. clicmd:: show bgp [afi] [safi] [all] summary established [json] Show a bgp peer summary for peers that are succesfully exchanging routes for the specified address family, and subsequent address-family. @@ -2812,14 +2817,14 @@ structure is extended with :clicmd:`show bgp [afi] [safi]`. This command shows information on a specific BGP peer of the relevant afi and safi selected. -.. index:: show bgp [afi] [safi] dampening dampened-paths -.. clicmd:: show bgp [afi] [safi] dampening dampened-paths +.. index:: show bgp [afi] [safi] [all] dampening dampened-paths [wide|json] +.. clicmd:: show bgp [afi] [safi] [all] dampening dampened-paths [wide|json] Display paths suppressed due to dampening of the selected afi and safi selected. -.. index:: show bgp [afi] [safi] dampening flap-statistics -.. clicmd:: show bgp [afi] [safi] dampening flap-statistics +.. index:: show bgp [afi] [safi] [all] dampening flap-statistics [wide|json] +.. clicmd:: show bgp [afi] [safi] [all] dampening flap-statistics [wide|json] Display flap statistics of routes of the selected afi and safi selected. @@ -2833,6 +2838,31 @@ structure is extended with :clicmd:`show bgp [afi] [safi]`. Display statistics of routes of all the afi and safi. +.. index:: show [ip] bgp [afi] [safi] [all] cidr-only [wide|json] +.. clicmd:: show [ip] bgp [afi] [safi] [all] cidr-only [wide|json] + + Display routes with non-natural netmasks. + +.. index:: show [ip] bgp [afi] [safi] [all] neighbors A.B.C.D [advertised-routes|received-routes|filtered-routes] [json|wide] +.. clicmd:: show [ip] bgp [afi] [safi] [all] neighbors A.B.C.D [advertised-routes|received-routes|filtered-routes] [json|wide] + + Display the routes advertised to a BGP neighbor or received routes + from neighbor or filtered routes received from neighbor based on the + option specified. + + If _wide_ option is specified, then the prefix table's width is increased + to fully display the prefix and the nexthop. + + This is especially handy dealing with IPv6 prefixes and + if :clicmd:`[no] bgp default show-nexthop-hostname` is enabled. + + If _all_ option is specified, _ip_ keyword is ignored and, + routes displayed for all AFIs and SAFIs. + if afi is specified, with _all_ option, routes will be displayed for + each SAFI in the selcted AFI + + If _json_ option is specified, output is displayed in JSON format. + .. _bgp-display-routes-by-community: Displaying Routes by Community Attribute @@ -2841,14 +2871,14 @@ Displaying Routes by Community Attribute The following commands allow displaying routes based on their community attribute. -.. index:: show [ip] bgp community -.. clicmd:: show [ip] bgp community +.. index:: show [ip] bgp [all] community [wide|json] +.. clicmd:: show [ip] bgp [all] community [wide|json] -.. index:: show [ip] bgp community COMMUNITY -.. clicmd:: show [ip] bgp community COMMUNITY +.. index:: show [ip] bgp [all] community COMMUNITY [wide|json] +.. clicmd:: show [ip] bgp [all] community COMMUNITY [wide|json] -.. index:: show [ip] bgp community COMMUNITY exact-match -.. clicmd:: show [ip] bgp community COMMUNITY exact-match +.. index:: show [ip] bgp [all] community COMMUNITY exact-match [wide|json] +.. clicmd:: show [ip] bgp [all] community COMMUNITY exact-match [wide|json] These commands display BGP routes which have the community attribute. attribute. When ``COMMUNITY`` is specified, BGP routes that match that @@ -2865,6 +2895,19 @@ attribute. match the specified community list. When `exact-match` is specified, it displays only routes that have an exact match. + If _wide_ option is specified, then the prefix table's width is increased + to fully display the prefix and the nexthop. + + This is especially handy dealing with IPv6 prefixes and + if :clicmd:`[no] bgp default show-nexthop-hostname` is enabled. + + If _all_ option is specified, _ip_ keyword is ignored and, + routes displayed for all AFIs and SAFIs. + if afi is specified, with _all_ option, routes will be displayed for + each SAFI in the selcted AFI + + If _json_ option is specified, output is displayed in JSON format. + .. _bgp-display-routes-by-lcommunity: Displaying Routes by Large Community Attribute