diff options
Diffstat (limited to 'bgpd/bgp_route.c')
| -rw-r--r-- | bgpd/bgp_route.c | 591 |
1 files changed, 235 insertions, 356 deletions
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index e51bf55696..cd9893fd91 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -548,6 +548,25 @@ void bgp_path_info_path_with_addpath_rx_str(struct bgp_path_info *pi, char *buf, snprintf(buf, buf_len, "path %s", pi->peer->host); } + +/* + * Get the ultimate path info. + */ +struct bgp_path_info *bgp_get_imported_bpi_ultimate(struct bgp_path_info *info) +{ + struct bgp_path_info *bpi_ultimate; + + if (info->sub_type != BGP_ROUTE_IMPORTED) + return info; + + for (bpi_ultimate = info; + bpi_ultimate->extra && bpi_ultimate->extra->parent; + bpi_ultimate = bpi_ultimate->extra->parent) + ; + + return bpi_ultimate; +} + /* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1. */ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new, @@ -587,6 +606,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new, bool old_proxy; bool new_proxy; bool new_origin, exist_origin; + struct bgp_path_info *bpi_ultimate; *paths_eq = 0; @@ -598,9 +618,11 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new, return 0; } - if (debug) - bgp_path_info_path_with_addpath_rx_str(new, new_buf, + if (debug) { + bpi_ultimate = bgp_get_imported_bpi_ultimate(new); + bgp_path_info_path_with_addpath_rx_str(bpi_ultimate, new_buf, sizeof(new_buf)); + } if (exist == NULL) { *reason = bgp_path_selection_first; @@ -611,7 +633,8 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new, } if (debug) { - bgp_path_info_path_with_addpath_rx_str(exist, exist_buf, + bpi_ultimate = bgp_get_imported_bpi_ultimate(exist); + bgp_path_info_path_with_addpath_rx_str(bpi_ultimate, exist_buf, sizeof(exist_buf)); zlog_debug("%s(%s): Comparing %s flags 0x%x with %s flags 0x%x", pfx_buf, bgp->name_pretty, new_buf, new->flags, @@ -859,6 +882,14 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new, return 0; } + /* Here if these are imported routes then get ultimate pi for + * path compare. + */ + new = bgp_get_imported_bpi_ultimate(new); + exist = bgp_get_imported_bpi_ultimate(exist); + newattr = new->attr; + existattr = exist->attr; + /* 4. AS path length check. */ if (!CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_IGNORE)) { int exist_hops = aspath_count_hops(existattr->aspath); @@ -2058,7 +2089,7 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, if ((CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED) && IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_local)) - || (!reflect + || (!reflect && !transparent && IN6_IS_ADDR_LINKLOCAL(&peer->nexthop.v6_local) && peer->shared_network && (from == bgp->peer_self @@ -3629,6 +3660,7 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, uint8_t pi_type = 0; uint8_t pi_sub_type = 0; bool force_evpn_import = false; + safi_t orig_safi = safi; if (frrtrace_enabled(frr_bgp, process_update)) { char pfxprint[PREFIX2STR_BUFFER]; @@ -3643,6 +3675,10 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, #endif int same_attr = 0; + /* Special case for BGP-LU - map LU safi to ordinary unicast safi */ + if (orig_safi == SAFI_LABELED_UNICAST) + safi = SAFI_UNICAST; + memset(&new_attr, 0, sizeof(struct attr)); new_attr.label_index = BGP_INVALID_LABEL_INDEX; new_attr.label = MPLS_INVALID_LABEL; @@ -3730,7 +3766,7 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, } /* Apply incoming filter. */ - if (bgp_input_filter(peer, p, attr, afi, safi) == FILTER_DENY) { + if (bgp_input_filter(peer, p, attr, afi, orig_safi) == FILTER_DENY) { peer->stat_pfx_filter++; reason = "filter;"; goto filtered; @@ -3773,7 +3809,7 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, * commands, so we need bgp_attr_flush in the error paths, until we * intern * the attr (which takes over the memory references) */ - if (bgp_input_modifier(peer, p, &new_attr, afi, safi, NULL, label, + if (bgp_input_modifier(peer, p, &new_attr, afi, orig_safi, NULL, label, num_labels, dest) == RMAP_DENY) { peer->stat_pfx_filter++; @@ -8384,7 +8420,6 @@ static void route_vty_out_route(struct bgp_dest *dest, const struct prefix *p, { int len = 0; char buf[BUFSIZ]; - char buf2[BUFSIZ]; if (p->family == AF_INET) { if (!json) { @@ -8395,8 +8430,7 @@ static void route_vty_out_route(struct bgp_dest *dest, const struct prefix *p, &p->u.prefix, buf, BUFSIZ)); json_object_int_add(json, "prefixLen", p->prefixlen); - prefix2str(p, buf2, PREFIX_STRLEN); - json_object_string_add(json, "network", buf2); + json_object_string_addf(json, "network", "%pFX", p); json_object_int_add(json, "version", dest->version); } } else if (p->family == AF_ETHERNET) { @@ -8420,8 +8454,7 @@ static void route_vty_out_route(struct bgp_dest *dest, const struct prefix *p, &p->u.prefix, buf, BUFSIZ)); json_object_int_add(json, "prefixLen", p->prefixlen); - prefix2str(p, buf2, PREFIX_STRLEN); - json_object_string_add(json, "network", buf2); + json_object_string_addf(json, "network", "%pFX", p); json_object_int_add(json, "version", dest->version); } } @@ -8733,14 +8766,10 @@ void route_vty_out(struct vty *vty, const struct prefix *p, } } else if (safi == SAFI_EVPN) { if (json_paths) { - char buf[BUFSIZ] = {0}; - json_nexthop_global = json_object_new_object(); - json_object_string_add(json_nexthop_global, "ip", - inet_ntop(AF_INET, - &attr->nexthop, buf, - sizeof(buf))); + json_object_string_addf(json_nexthop_global, "ip", + "%pI4", &attr->nexthop); if (path->peer->hostname) json_object_string_add(json_nexthop_global, @@ -8768,16 +8797,13 @@ void route_vty_out(struct vty *vty, const struct prefix *p, } else if (safi == SAFI_FLOWSPEC) { if (attr->nexthop.s_addr != INADDR_ANY) { if (json_paths) { - char buf[BUFSIZ] = {0}; - json_nexthop_global = json_object_new_object(); json_object_string_add(json_nexthop_global, "afi", "ipv4"); - json_object_string_add( - json_nexthop_global, "ip", - inet_ntop(AF_INET, &attr->nexthop, buf, - sizeof(buf))); + json_object_string_addf(json_nexthop_global, + "ip", "%pI4", + &attr->nexthop); if (path->peer->hostname) json_object_string_add( @@ -8807,14 +8833,10 @@ void route_vty_out(struct vty *vty, const struct prefix *p, } } else if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) { if (json_paths) { - char buf[BUFSIZ] = {0}; - json_nexthop_global = json_object_new_object(); - json_object_string_add(json_nexthop_global, "ip", - inet_ntop(AF_INET, - &attr->nexthop, buf, - sizeof(buf))); + json_object_string_addf(json_nexthop_global, "ip", + "%pI4", &attr->nexthop); if (path->peer->hostname) json_object_string_add(json_nexthop_global, @@ -8843,14 +8865,11 @@ void route_vty_out(struct vty *vty, const struct prefix *p, /* IPv6 Next Hop */ else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) { - char buf[BUFSIZ]; - if (json_paths) { json_nexthop_global = json_object_new_object(); - json_object_string_add( - json_nexthop_global, "ip", - inet_ntop(AF_INET6, &attr->mp_nexthop_global, - buf, BUFSIZ)); + json_object_string_addf(json_nexthop_global, "ip", + "%pI6", + &attr->mp_nexthop_global); if (path->peer->hostname) json_object_string_add(json_nexthop_global, @@ -8868,11 +8887,9 @@ void route_vty_out(struct vty *vty, const struct prefix *p, == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) || (path->peer->conf_if)) { json_nexthop_ll = json_object_new_object(); - json_object_string_add( - json_nexthop_ll, "ip", - inet_ntop(AF_INET6, - &attr->mp_nexthop_local, buf, - BUFSIZ)); + json_object_string_addf( + json_nexthop_ll, "ip", "%pI6", + &attr->mp_nexthop_local); if (path->peer->hostname) json_object_string_add( @@ -9116,8 +9133,7 @@ void route_vty_out_tmp(struct vty *vty, struct bgp_dest *dest, BUFSIZ)); json_object_int_add(json_net, "prefixLen", p->prefixlen); - prefix2str(p, buff, PREFIX_STRLEN); - json_object_string_add(json_net, "network", buff); + json_object_string_addf(json_net, "network", "%pFX", p); } } else route_vty_out_route(dest, p, vty, NULL, wide); @@ -9125,42 +9141,27 @@ void route_vty_out_tmp(struct vty *vty, struct bgp_dest *dest, /* Print attribute */ if (attr) { if (use_json) { - char buf[BUFSIZ] = {0}; - if (p->family == AF_INET && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) { if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) - json_object_string_add( - json_net, "nextHop", - inet_ntop( - AF_INET, - &attr->mp_nexthop_global_in, - buf, sizeof(buf))); + json_object_string_addf( + json_net, "nextHop", "%pI4", + &attr->mp_nexthop_global_in); else - json_object_string_add( - json_net, "nextHop", - inet_ntop(AF_INET, - &attr->nexthop, buf, - sizeof(buf))); + json_object_string_addf( + json_net, "nextHop", "%pI4", + &attr->nexthop); } else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) { - char buf[BUFSIZ]; - - json_object_string_add( - json_net, "nextHopGlobal", - inet_ntop(AF_INET6, - &attr->mp_nexthop_global, buf, - BUFSIZ)); + json_object_string_addf( + json_net, "nextHopGlobal", "%pI6", + &attr->mp_nexthop_global); } else if (p->family == AF_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) { - char buf[BUFSIZ] = {0}; - - json_object_string_add( - json_net, "nextHop", - inet_ntop(AF_INET, - &attr->mp_nexthop_global_in, - buf, sizeof(buf))); + json_object_string_addf( + json_net, "nextHop", "%pI4", + &attr->mp_nexthop_global_in); } if (attr->flag @@ -9279,25 +9280,19 @@ void route_vty_out_tag(struct vty *vty, const struct prefix *p, && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) || (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr))) { - char buf[BUFSIZ] = {0}; - if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) { if (json) - json_object_string_add( - json_out, "mpNexthopGlobalIn", - inet_ntop(AF_INET, - &attr->mp_nexthop_global_in, - buf, sizeof(buf))); + json_object_string_addf( + json_out, "mpNexthopGlobalIn", "%pI4", + &attr->mp_nexthop_global_in); else vty_out(vty, "%-16pI4", &attr->mp_nexthop_global_in); } else { if (json) - json_object_string_add( - json_out, "nexthop", - inet_ntop(AF_INET, &attr->nexthop, buf, - sizeof(buf))); + json_object_string_addf(json_out, "nexthop", + "%pI4", &attr->nexthop); else vty_out(vty, "%-16pI4", &attr->nexthop); } @@ -9309,11 +9304,9 @@ void route_vty_out_tag(struct vty *vty, const struct prefix *p, if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) { if (json) - json_object_string_add( - json_out, "mpNexthopGlobalIn", - inet_ntop(AF_INET6, - &attr->mp_nexthop_global, - buf_a, sizeof(buf_a))); + json_object_string_addf( + json_out, "mpNexthopGlobalIn", "%pI6", + &attr->mp_nexthop_global); else vty_out(vty, "%s", inet_ntop(AF_INET6, @@ -9887,14 +9880,10 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) { if (json_paths) { - char buf[BUFSIZ] = {0}; - json_object_int_add(json_path, "aggregatorAs", attr->aggregator_as); - json_object_string_add(json_path, "aggregatorId", - inet_ntop(AF_INET, - &attr->aggregator_addr, - buf, sizeof(buf))); + json_object_string_addf(json_path, "aggregatorId", + "%pI4", &attr->aggregator_addr); } else { vty_out(vty, ", (aggregated by %u %pI4)", attr->aggregator_as, &attr->aggregator_addr); @@ -9944,16 +9933,12 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, || bn_p->family == AF_EVPN) && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) { - char buf[BUFSIZ] = {0}; - if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) { if (json_paths) { - json_object_string_add( - json_nexthop_global, "ip", - inet_ntop(AF_INET, - &attr->mp_nexthop_global_in, - buf, sizeof(buf))); + json_object_string_addf( + json_nexthop_global, "ip", "%pI4", + &attr->mp_nexthop_global_in); if (path->peer->hostname) json_object_string_add( @@ -9970,10 +9955,9 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, } } else { if (json_paths) { - json_object_string_add( - json_nexthop_global, "ip", - inet_ntop(AF_INET, &attr->nexthop, buf, - sizeof(buf))); + json_object_string_addf(json_nexthop_global, + "ip", "%pI4", + &attr->nexthop); if (path->peer->hostname) json_object_string_add( @@ -9995,10 +9979,9 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, "ipv4"); } else { if (json_paths) { - json_object_string_add( - json_nexthop_global, "ip", - inet_ntop(AF_INET6, &attr->mp_nexthop_global, - buf, INET6_ADDRSTRLEN)); + json_object_string_addf(json_nexthop_global, "ip", + "%pI6", + &attr->mp_nexthop_global); if (path->peer->hostname) json_object_string_add(json_nexthop_global, @@ -10070,16 +10053,11 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, vty_out(vty, " from :: "); } - if (json_paths) { - char buf[BUFSIZ] = {0}; - - json_object_string_add(json_peer, "routerId", - inet_ntop(AF_INET, - &bgp->router_id, buf, - sizeof(buf))); - } else { + if (json_paths) + json_object_string_addf(json_peer, "routerId", "%pI4", + &bgp->router_id); + else vty_out(vty, "(%pI4)", &bgp->router_id); - } } /* We RXed this path from one of our peers */ @@ -10090,10 +10068,8 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, sockunion2str(&path->peer->su, buf, SU_ADDRSTRLEN)); - json_object_string_add(json_peer, "routerId", - inet_ntop(AF_INET, - &path->peer->remote_id, - buf1, sizeof(buf1))); + json_object_string_addf(json_peer, "routerId", "%pI4", + &path->peer->remote_id); if (path->peer->hostname) json_object_string_add(json_peer, "hostname", @@ -10193,10 +10169,8 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) { if (json_paths) { json_nexthop_ll = json_object_new_object(); - json_object_string_add( - json_nexthop_ll, "ip", - inet_ntop(AF_INET6, &attr->mp_nexthop_local, - buf, INET6_ADDRSTRLEN)); + json_object_string_addf(json_nexthop_ll, "ip", "%pI6", + &attr->mp_nexthop_local); if (path->peer->hostname) json_object_string_add(json_nexthop_ll, @@ -10459,10 +10433,9 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) { if (json_paths) - json_object_string_add( - json_path, "originatorId", - inet_ntop(AF_INET, &attr->originator_id, - buf, sizeof(buf))); + json_object_string_addf(json_path, + "originatorId", "%pI4", + &attr->originator_id); else vty_out(vty, " Originator: %pI4", &attr->originator_id); @@ -10694,21 +10667,6 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n" #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n" -static int bgp_show_prefix_list(struct vty *vty, struct bgp *bgp, - const char *prefix_list_str, afi_t afi, - safi_t safi, enum bgp_show_type type); -static int bgp_show_filter_list(struct vty *vty, struct bgp *bgp, - const char *filter, afi_t afi, safi_t safi, - enum bgp_show_type type); -static int bgp_show_route_map(struct vty *vty, struct bgp *bgp, - const char *rmap_str, afi_t afi, safi_t safi, - enum bgp_show_type type); -static int bgp_show_community_list(struct vty *vty, struct bgp *bgp, - const char *com, int exact, afi_t afi, - safi_t safi); -static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp, - const char *prefix, afi_t afi, safi_t safi, - enum bgp_show_type type); static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr, afi_t afi, safi_t safi, enum bgp_show_type type, bool use_json); @@ -11306,7 +11264,6 @@ void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp, struct peer *peer; struct listnode *node, *nnode; char buf1[RD_ADDRSTRLEN]; - char prefix_str[BUFSIZ]; int count = 0; int best = 0; int suppress = 0; @@ -11360,8 +11317,7 @@ void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp, dest->version); } else { - json_object_string_add(json, "prefix", - prefix2str(p, prefix_str, sizeof(prefix_str))); + json_object_string_addf(json, "prefix", "%pFX", p); json_object_int_add(json, "version", dest->version); } @@ -11733,10 +11689,7 @@ static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp, } if (use_json) { - vty_out(vty, "%s\n", json_object_to_json_string_ext( - json, JSON_C_TO_STRING_PRETTY | - JSON_C_TO_STRING_NOSLASHESCAPE)); - json_object_free(json); + vty_json(vty, json); } else { if (!display) { vty_out(vty, "%% Network not in table\n"); @@ -12071,45 +12024,28 @@ DEFUN(show_ip_bgp_afi_safi_statistics, show_ip_bgp_afi_safi_statistics_cmd, return ret; } -/* BGP route print out function without JSON */ -DEFPY(show_ip_bgp, show_ip_bgp_cmd, +DEFPY(show_ip_bgp_dampening_params, show_ip_bgp_dampening_params_cmd, "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR " [" BGP_SAFI_WITH_LABEL_CMD_STR - "]]\ - <[all$all] dampening <parameters>\ - |route-map WORD\ - |prefix-list WORD\ - |filter-list AS_PATH_FILTER_NAME\ - |community-list <(1-500)|COMMUNITY_LIST_NAME> [exact-match]\ - |A.B.C.D/M longer-prefixes\ - |X:X::X:X/M longer-prefixes\ - >", + "]] [all$all] dampening parameters [json]", 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" - "A route-map to match on\n" - "Display routes conforming to the prefix-list\n" - "Prefix-list name\n" - "Display routes conforming to the filter-list\n" - "Regular expression access list name\n" - "Display routes matching the community-list\n" - "community-list number\n" - "community-list name\n" - "Exact match of the communities\n" - "IPv4 prefix\n" - "Display route and more specific routes\n" - "IPv6 prefix\n" - "Display route and more specific routes\n") + JSON_STR) { afi_t afi = AFI_IP6; safi_t safi = SAFI_UNICAST; - int exact_match = 0; struct bgp *bgp = NULL; int idx = 0; uint16_t show_flags = 0; + bool uj = use_json(argc, argv); + + if (uj) { + argc--; + SET_FLAG(show_flags, BGP_SHOW_OPT_JSON); + } /* [<ipv4|ipv6> [all]] */ if (all) { @@ -12126,43 +12062,11 @@ DEFPY(show_ip_bgp, show_ip_bgp_cmd, if (!idx) return CMD_WARNING; - if (argv_find(argv, argc, "dampening", &idx)) { - if (argv_find(argv, argc, "parameters", &idx)) - return bgp_show_dampening_parameters(vty, afi, safi, - show_flags); - } - - if (argv_find(argv, argc, "prefix-list", &idx)) - return bgp_show_prefix_list(vty, bgp, argv[idx + 1]->arg, afi, - safi, bgp_show_type_prefix_list); - - if (argv_find(argv, argc, "filter-list", &idx)) - return bgp_show_filter_list(vty, bgp, argv[idx + 1]->arg, afi, - safi, bgp_show_type_filter_list); - - if (argv_find(argv, argc, "route-map", &idx)) - return bgp_show_route_map(vty, bgp, argv[idx + 1]->arg, afi, - safi, bgp_show_type_route_map); - - if (argv_find(argv, argc, "community-list", &idx)) { - const char *clist_number_or_name = argv[++idx]->arg; - if (++idx < argc && strmatch(argv[idx]->text, "exact-match")) - exact_match = 1; - return bgp_show_community_list(vty, bgp, clist_number_or_name, - exact_match, afi, safi); - } - /* prefix-longer */ - if (argv_find(argv, argc, "A.B.C.D/M", &idx) - || argv_find(argv, argc, "X:X::X:X/M", &idx)) - return bgp_show_prefix_longer(vty, bgp, argv[idx]->arg, afi, - safi, - bgp_show_type_prefix_longer); - - return CMD_WARNING; + return bgp_show_dampening_parameters(vty, afi, safi, show_flags); } -/* BGP route print out function with JSON */ -DEFPY(show_ip_bgp_json, show_ip_bgp_json_cmd, +/* BGP route print out function */ +DEFPY(show_ip_bgp, show_ip_bgp_cmd, "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR " [" BGP_SAFI_WITH_LABEL_CMD_STR "]]\ @@ -12174,9 +12078,15 @@ DEFPY(show_ip_bgp_json, show_ip_bgp_json_cmd, |accept-own|accept-own-nexthop|route-filter-v6\ |route-filter-v4|route-filter-translated-v6\ |route-filter-translated-v4] [exact-match]\ + |community-list <(1-500)|COMMUNITY_LIST_NAME> [exact-match]\ + |filter-list AS_PATH_FILTER_NAME\ + |prefix-list WORD\ + |route-map WORD\ |rpki <invalid|valid|notfound>\ |version (1-4294967295)\ |alias ALIAS_NAME\ + |A.B.C.D/M longer-prefixes\ + |X:X::X:X/M longer-prefixes\ ] [json$uj [detail$detail] | wide$wide]", SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR BGP_SAFI_WITH_LABEL_HELP_STR @@ -12201,6 +12111,16 @@ DEFPY(show_ip_bgp_json, show_ip_bgp_json_cmd, "RT translated VPNv6 route filtering (well-known community)\n" "RT translated VPNv4 route filtering (well-known community)\n" "Exact match of the communities\n" + "Community-list number\n" + "Community-list name\n" + "Display routes matching the community-list\n" + "Exact match of the communities\n" + "Display routes conforming to the filter-list\n" + "Regular expression access list name\n" + "Display routes conforming to the prefix-list\n" + "Prefix-list name\n" + "Display routes matching the route-map\n" + "A route-map to match on\n" "RPKI route types\n" "A valid path as determined by rpki\n" "A invalid path as determined by rpki\n" @@ -12208,19 +12128,23 @@ DEFPY(show_ip_bgp_json, show_ip_bgp_json_cmd, "Display prefixes with matching version numbers\n" "Version number and above\n" "Display prefixes with matching BGP community alias\n" - "BGP community alias\n" JSON_STR + "BGP community alias\n" + "IPv4 prefix\n" + "Display route and more specific routes\n" + "IPv6 prefix\n" + "Display route and more specific routes\n" + JSON_STR "Display detailed version of JSON output\n" "Increase table width for longer prefixes\n") { afi_t afi = AFI_IP6; safi_t safi = SAFI_UNICAST; enum bgp_show_type sh_type = bgp_show_type_normal; + void *output_arg = NULL; struct bgp *bgp = NULL; int idx = 0; int exact_match = 0; char *community = NULL; - char *prefix_version = NULL; - char *bgp_community_alias = NULL; bool first = true; uint16_t show_flags = 0; enum rpki_states rpki_target_state = RPKI_NOT_BEING_USED; @@ -12283,6 +12207,75 @@ DEFPY(show_ip_bgp_json, show_ip_bgp_json_cmd, sh_type = bgp_show_type_community_all; } + if (argv_find(argv, argc, "community-list", &idx)) { + const char *clist_number_or_name = argv[++idx]->arg; + struct community_list *list; + + if (argv_find(argv, argc, "exact-match", &idx)) + exact_match = 1; + + list = community_list_lookup(bgp_clist, clist_number_or_name, 0, + COMMUNITY_LIST_MASTER); + if (list == NULL) { + vty_out(vty, + "%% %s is not a valid community-list name\n", + clist_number_or_name); + return CMD_WARNING; + } + + if (exact_match) + sh_type = bgp_show_type_community_list_exact; + else + sh_type = bgp_show_type_community_list; + output_arg = list; + } + + if (argv_find(argv, argc, "filter-list", &idx)) { + const char *filter = argv[++idx]->arg; + struct as_list *as_list; + + as_list = as_list_lookup(filter); + if (as_list == NULL) { + vty_out(vty, + "%% %s is not a valid AS-path access-list name\n", + filter); + return CMD_WARNING; + } + + sh_type = bgp_show_type_filter_list; + output_arg = as_list; + } + + if (argv_find(argv, argc, "prefix-list", &idx)) { + const char *prefix_list_str = argv[++idx]->arg; + struct prefix_list *plist; + + plist = prefix_list_lookup(afi, prefix_list_str); + if (plist == NULL) { + vty_out(vty, "%% %s is not a valid prefix-list name\n", + prefix_list_str); + return CMD_WARNING; + } + + sh_type = bgp_show_type_prefix_list; + output_arg = plist; + } + + if (argv_find(argv, argc, "route-map", &idx)) { + const char *rmap_str = argv[++idx]->arg; + struct route_map *rmap; + + rmap = route_map_lookup_by_name(rmap_str); + if (!rmap) { + vty_out(vty, "%% %s is not a valid route-map name\n", + rmap_str); + return CMD_WARNING; + } + + sh_type = bgp_show_type_route_map; + output_arg = rmap; + } + if (argv_find(argv, argc, "rpki", &idx)) { sh_type = bgp_show_type_rpki; if (argv_find(argv, argc, "valid", &idx)) @@ -12294,13 +12287,28 @@ DEFPY(show_ip_bgp_json, show_ip_bgp_json_cmd, /* Display prefixes with matching version numbers */ if (argv_find(argv, argc, "version", &idx)) { sh_type = bgp_show_type_prefix_version; - prefix_version = argv[idx + 1]->arg; + output_arg = argv[idx + 1]->arg; } /* Display prefixes with matching BGP community alias */ if (argv_find(argv, argc, "alias", &idx)) { sh_type = bgp_show_type_community_alias; - bgp_community_alias = argv[idx + 1]->arg; + output_arg = argv[idx + 1]->arg; + } + + /* prefix-longer */ + if (argv_find(argv, argc, "A.B.C.D/M", &idx) + || argv_find(argv, argc, "X:X::X:X/M", &idx)) { + const char *prefix_str = argv[idx]->arg; + struct prefix p; + + if (!str2prefix(prefix_str, &p)) { + vty_out(vty, "%% Malformed Prefix\n"); + return CMD_WARNING; + } + + sh_type = bgp_show_type_prefix_longer; + output_arg = &p; } if (!all) { @@ -12309,17 +12317,10 @@ DEFPY(show_ip_bgp_json, show_ip_bgp_json_cmd, return bgp_show_community(vty, bgp, community, exact_match, afi, safi, show_flags); - else if (prefix_version) - return bgp_show(vty, bgp, afi, safi, sh_type, - prefix_version, show_flags, - rpki_target_state); - else if (bgp_community_alias) + else return bgp_show(vty, bgp, afi, safi, sh_type, - bgp_community_alias, show_flags, + output_arg, show_flags, rpki_target_state); - else - return bgp_show(vty, bgp, afi, safi, sh_type, NULL, - show_flags, rpki_target_state); } else { /* show <ip> bgp ipv4 all: AFI_IP, show <ip> bgp ipv6 all: * AFI_IP6 */ @@ -12354,19 +12355,9 @@ DEFPY(show_ip_bgp_json, show_ip_bgp_json_cmd, bgp_show_community(vty, bgp, community, exact_match, afi, safi, show_flags); - else if (prefix_version) - return bgp_show(vty, bgp, afi, safi, - sh_type, prefix_version, - show_flags, - rpki_target_state); - else if (bgp_community_alias) - return bgp_show( - vty, bgp, afi, safi, sh_type, - bgp_community_alias, show_flags, - rpki_target_state); else bgp_show(vty, bgp, afi, safi, sh_type, - NULL, show_flags, + output_arg, show_flags, rpki_target_state); if (uj) vty_out(vty, "}\n"); @@ -12396,14 +12387,9 @@ DEFPY(show_ip_bgp_json, show_ip_bgp_json_cmd, bgp_show_community(vty, bgp, community, exact_match, afi, safi, show_flags); - else if (prefix_version) - return bgp_show(vty, bgp, afi, safi, - sh_type, prefix_version, - show_flags, - rpki_target_state); else bgp_show(vty, bgp, afi, safi, sh_type, - NULL, show_flags, + output_arg, show_flags, rpki_target_state); if (uj) vty_out(vty, "}\n"); @@ -12591,59 +12577,6 @@ static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr, return rc; } -static int bgp_show_prefix_list(struct vty *vty, struct bgp *bgp, - const char *prefix_list_str, afi_t afi, - safi_t safi, enum bgp_show_type type) -{ - struct prefix_list *plist; - uint16_t show_flags = 0; - - plist = prefix_list_lookup(afi, prefix_list_str); - if (plist == NULL) { - vty_out(vty, "%% %s is not a valid prefix-list name\n", - prefix_list_str); - return CMD_WARNING; - } - - return bgp_show(vty, bgp, afi, safi, type, plist, show_flags, - RPKI_NOT_BEING_USED); -} - -static int bgp_show_filter_list(struct vty *vty, struct bgp *bgp, - const char *filter, afi_t afi, safi_t safi, - enum bgp_show_type type) -{ - struct as_list *as_list; - uint16_t show_flags = 0; - - as_list = as_list_lookup(filter); - if (as_list == NULL) { - vty_out(vty, "%% %s is not a valid AS-path access-list name\n", - filter); - return CMD_WARNING; - } - - return bgp_show(vty, bgp, afi, safi, type, as_list, show_flags, - RPKI_NOT_BEING_USED); -} - -static int bgp_show_route_map(struct vty *vty, struct bgp *bgp, - const char *rmap_str, afi_t afi, safi_t safi, - enum bgp_show_type type) -{ - struct route_map *rmap; - uint16_t show_flags = 0; - - rmap = route_map_lookup_by_name(rmap_str); - if (!rmap) { - vty_out(vty, "%% %s is not a valid route-map name\n", rmap_str); - return CMD_WARNING; - } - - return bgp_show(vty, bgp, afi, safi, type, rmap, show_flags, - RPKI_NOT_BEING_USED); -} - static int bgp_show_community(struct vty *vty, struct bgp *bgp, const char *comstr, int exact, afi_t afi, safi_t safi, uint16_t show_flags) @@ -12666,47 +12599,6 @@ static int bgp_show_community(struct vty *vty, struct bgp *bgp, return ret; } -static int bgp_show_community_list(struct vty *vty, struct bgp *bgp, - const char *com, int exact, afi_t afi, - safi_t safi) -{ - struct community_list *list; - uint16_t show_flags = 0; - - list = community_list_lookup(bgp_clist, com, 0, COMMUNITY_LIST_MASTER); - if (list == NULL) { - vty_out(vty, "%% %s is not a valid community-list name\n", com); - return CMD_WARNING; - } - - return bgp_show(vty, bgp, afi, safi, - (exact ? bgp_show_type_community_list_exact - : bgp_show_type_community_list), - list, show_flags, RPKI_NOT_BEING_USED); -} - -static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp, - const char *prefix, afi_t afi, safi_t safi, - enum bgp_show_type type) -{ - int ret; - struct prefix *p; - uint16_t show_flags = 0; - - p = prefix_new(); - - ret = str2prefix(prefix, p); - if (!ret) { - vty_out(vty, "%% Malformed Prefix\n"); - return CMD_WARNING; - } - - ret = bgp_show(vty, bgp, afi, safi, type, p, show_flags, - RPKI_NOT_BEING_USED); - prefix_free(&p); - return ret; -} - enum bgp_stats { BGP_STATS_MAXBITLEN = 0, BGP_STATS_RIB, @@ -13262,9 +13154,7 @@ static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi, json, "recommended", "Please report this bug, with the above command output"); } - vty_out(vty, "%s\n", json_object_to_json_string_ext( - json, JSON_C_TO_STRING_PRETTY)); - json_object_free(json); + vty_json(vty, json); } else { if (peer->hostname @@ -13435,15 +13325,12 @@ static void show_adj_route_header(struct vty *vty, struct bgp *bgp, json_object *json_ocode, bool wide) { uint64_t version = table ? table->version : 0; - char buf[BUFSIZ] = {0}; if (*header1) { if (json) { json_object_int_add(json, "bgpTableVersion", version); - json_object_string_add(json, "bgpLocalRouterId", - inet_ntop(AF_INET, - &bgp->router_id, buf, - sizeof(buf))); + json_object_string_addf(json, "bgpLocalRouterId", + "%pI4", &bgp->router_id); json_object_int_add(json, "defaultLocPrf", bgp->default_local_pref); json_object_int_add(json, "localAS", bgp->as); @@ -13509,15 +13396,11 @@ show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table, if (type == bgp_show_adj_route_advertised && subgrp && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) { - char buf[BUFSIZ] = {0}; - if (use_json) { json_object_int_add(json, "bgpTableVersion", table->version); - json_object_string_add(json, "bgpLocalRouterId", - inet_ntop(AF_INET, - &bgp->router_id, buf, - sizeof(buf))); + json_object_string_addf(json, "bgpLocalRouterId", + "%pI4", &bgp->router_id); json_object_int_add(json, "defaultLocPrf", bgp->default_local_pref); json_object_int_add(json, "localAS", bgp->as); @@ -13831,10 +13714,6 @@ static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi, 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)); - /* * These fields only give up ownership to `json` when `header1` * is used (set to zero). See code in `show_adj_route` and @@ -13845,7 +13724,7 @@ static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi, json_object_free(json_ocode); } - json_object_free(json); + vty_json(vty, json); } else if (output_count > 0) { if (filtered_count > 0) vty_out(vty, @@ -15168,10 +15047,10 @@ void bgp_route_init(void) install_element(BGP_IPV4L_NODE, &aggregate_addressv4_cmd); install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd); - install_element(VIEW_NODE, &show_ip_bgp_cmd); install_element(VIEW_NODE, &show_ip_bgp_afi_safi_statistics_cmd); install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_statistics_cmd); - install_element(VIEW_NODE, &show_ip_bgp_json_cmd); + install_element(VIEW_NODE, &show_ip_bgp_dampening_params_cmd); + install_element(VIEW_NODE, &show_ip_bgp_cmd); install_element(VIEW_NODE, &show_ip_bgp_route_cmd); install_element(VIEW_NODE, &show_ip_bgp_regexp_cmd); install_element(VIEW_NODE, &show_ip_bgp_statistics_all_cmd); |
