summaryrefslogtreecommitdiff
path: root/bgpd/bgp_route.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgp_route.c')
-rw-r--r--bgpd/bgp_route.c591
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);