Merge pull request #1295 from donaldsharp/more_1270

More 1270
This commit is contained in:
Lou Berger 2017-10-06 09:31:30 -04:00 committed by GitHub
commit 3782fb37b1
4 changed files with 514 additions and 712 deletions

View File

@ -356,19 +356,6 @@ int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd,
{ {
struct bgp *bgp; struct bgp *bgp;
struct bgp_table *table; struct bgp_table *table;
struct bgp_node *rn;
struct bgp_node *rm;
struct bgp_info *ri;
int rd_header;
int header = 1;
unsigned long output_count = 0;
unsigned long total_count = 0;
json_object *json = NULL;
json_object *json_mroute = NULL;
json_object *json_nroute = NULL;
json_object *json_array = NULL;
json_object *json_scode = NULL;
json_object *json_ocode = NULL;
bgp = bgp_get_default(); bgp = bgp_get_default();
if (bgp == NULL) { if (bgp == NULL) {
@ -378,279 +365,31 @@ int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd,
vty_out(vty, "{}\n"); vty_out(vty, "{}\n");
return CMD_WARNING; return CMD_WARNING;
} }
table = bgp->rib[afi][SAFI_MPLS_VPN];
if (use_json) { return bgp_show_table_rd(vty, bgp, SAFI_MPLS_VPN,
json_scode = json_object_new_object(); table, prd, type, output_arg, use_json);
json_ocode = json_object_new_object();
json = json_object_new_object();
json_mroute = json_object_new_object();
json_nroute = json_object_new_object();
json_object_string_add(json_scode, "suppressed", "s");
json_object_string_add(json_scode, "damped", "d");
json_object_string_add(json_scode, "history", "h");
json_object_string_add(json_scode, "valid", "*");
json_object_string_add(json_scode, "best", ">");
json_object_string_add(json_scode, "internal", "i");
json_object_string_add(json_ocode, "igp", "i");
json_object_string_add(json_ocode, "egp", "e");
json_object_string_add(json_ocode, "incomplete", "?");
}
if ((afi != AFI_IP) && (afi != AFI_IP6)) {
vty_out(vty, "Afi %d not supported\n", afi);
return CMD_WARNING;
}
for (rn = bgp_table_top(bgp->rib[afi][SAFI_MPLS_VPN]); rn;
rn = bgp_route_next(rn)) {
if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0)
continue;
if ((table = rn->info) != NULL) {
rd_header = 1;
for (rm = bgp_table_top(table); rm;
rm = bgp_route_next(rm)) {
total_count++;
if (use_json)
json_array = json_object_new_array();
else
json_array = NULL;
for (ri = rm->info; ri; ri = ri->next) {
if (type == bgp_show_type_neighbor) {
union sockunion *su =
output_arg;
if (ri->peer->su_remote == NULL
|| !sockunion_same(
ri->peer->su_remote,
su))
continue;
}
if (header) {
if (use_json) {
if (!tags) {
json_object_int_add(
json,
"bgpTableVersion",
0);
json_object_string_add(
json,
"bgpLocalRouterId",
inet_ntoa(
bgp->router_id));
json_object_object_add(
json,
"bgpStatusCodes",
json_scode);
json_object_object_add(
json,
"bgpOriginCodes",
json_ocode);
}
} else {
if (tags)
vty_out(vty,
V4_HEADER_TAG);
else {
vty_out(vty,
"BGP table version is 0, local router ID is %s\n",
inet_ntoa(
bgp->router_id));
vty_out(vty,
"Status codes: s suppressed, d damped, h history, * valid, > best, i - internal\n");
vty_out(vty,
"Origin codes: i - IGP, e - EGP, ? - incomplete\n\n");
vty_out(vty,
V4_HEADER);
}
}
header = 0;
}
if (rd_header) {
u_int16_t type;
struct rd_as rd_as;
struct rd_ip rd_ip = {0};
#if ENABLE_BGP_VNC
struct rd_vnc_eth rd_vnc_eth = {
0};
#endif
u_char *pnt;
pnt = rn->p.u.val;
/* Decode RD type. */
type = decode_rd_type(pnt);
/* Decode RD value. */
if (type == RD_TYPE_AS)
decode_rd_as(pnt + 2,
&rd_as);
else if (type == RD_TYPE_AS4)
decode_rd_as4(pnt + 2,
&rd_as);
else if (type == RD_TYPE_IP)
decode_rd_ip(pnt + 2,
&rd_ip);
#if ENABLE_BGP_VNC
else if (type
== RD_TYPE_VNC_ETH)
decode_rd_vnc_eth(
pnt,
&rd_vnc_eth);
#endif
if (use_json) {
char buffer[BUFSIZ];
if (type == RD_TYPE_AS
|| type == RD_TYPE_AS4)
sprintf(buffer,
"%u:%d",
rd_as.as,
rd_as.val);
else if (type
== RD_TYPE_IP)
sprintf(buffer,
"%s:%d",
inet_ntoa(
rd_ip.ip),
rd_ip.val);
json_object_string_add(
json_nroute,
"routeDistinguisher",
buffer);
} else {
vty_out(vty,
"Route Distinguisher: ");
if (type == RD_TYPE_AS
|| type == RD_TYPE_AS4)
vty_out(vty,
"%u:%d",
rd_as.as,
rd_as.val);
else if (type
== RD_TYPE_IP)
vty_out(vty,
"%s:%d",
inet_ntoa(
rd_ip.ip),
rd_ip.val);
#if ENABLE_BGP_VNC
else if (
type
== RD_TYPE_VNC_ETH)
vty_out(vty,
"%u:%02x:%02x:%02x:%02x:%02x:%02x",
rd_vnc_eth
.local_nve_id,
rd_vnc_eth
.macaddr
.octet[0],
rd_vnc_eth
.macaddr
.octet[1],
rd_vnc_eth
.macaddr
.octet[2],
rd_vnc_eth
.macaddr
.octet[3],
rd_vnc_eth
.macaddr
.octet[4],
rd_vnc_eth
.macaddr
.octet[5]);
#endif
vty_out(vty, "\n");
}
rd_header = 0;
}
if (tags)
route_vty_out_tag(vty, &rm->p,
ri, 0,
SAFI_MPLS_VPN,
json_array);
else
route_vty_out(vty, &rm->p, ri,
0, SAFI_MPLS_VPN,
json_array);
output_count++;
}
if (use_json) {
struct prefix *p;
char buf_a[BUFSIZ];
char buf_b[BUFSIZ];
p = &rm->p;
sprintf(buf_a, "%s/%d",
inet_ntop(p->family,
&p->u.prefix, buf_b,
BUFSIZ),
p->prefixlen);
json_object_object_add(
json_mroute, buf_a, json_array);
}
}
if (use_json) {
struct prefix *p;
char buf_a[BUFSIZ];
char buf_b[BUFSIZ];
p = &rn->p;
sprintf(buf_a, "%s/%d",
inet_ntop(p->family, &p->u.prefix,
buf_b, BUFSIZ),
p->prefixlen);
json_object_object_add(json_nroute, buf_a,
json_mroute);
}
}
}
if (use_json) {
json_object_object_add(json, "routes", json_nroute);
vty_out(vty, "%s\n", json_object_to_json_string_ext(
json, JSON_C_TO_STRING_PRETTY));
json_object_free(json);
} else {
if (output_count == 0)
vty_out(vty, "No prefixes displayed, %ld exist\n",
total_count);
else
vty_out(vty,
"\nDisplayed %ld routes and %ld total paths\n",
output_count, total_count);
}
return CMD_SUCCESS;
} }
DEFUN (show_bgp_ip_vpn_all_rd, DEFUN (show_bgp_ip_vpn_all_rd,
show_bgp_ip_vpn_all_rd_cmd, show_bgp_ip_vpn_all_rd_cmd,
"show bgp "BGP_AFI_CMD_STR" vpn all [rd ASN:NN_OR_IP-ADDRESS:NN] [json]", "show bgp "BGP_AFI_CMD_STR" vpn all [rd ASN:NN_OR_IP-ADDRESS:NN] [json]",
SHOW_STR SHOW_STR
IP_STR
BGP_STR BGP_STR
BGP_VPNVX_HELP_STR BGP_VPNVX_HELP_STR
"Display VPN NLRI specific information\n" "Display VPN NLRI specific information\n"
"Display VPN NLRI specific information\n"
"Display information for a route distinguisher\n" "Display information for a route distinguisher\n"
"VPN Route Distinguisher\n" "VPN Route Distinguisher\n"
JSON_STR) JSON_STR)
{ {
int idx_rd = 5;
int ret; int ret;
struct prefix_rd prd; struct prefix_rd prd;
afi_t afi; afi_t afi;
int idx = 0; int idx = 0;
if (argv_find_and_parse_afi(argv, argc, &idx, &afi)) { if (argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
if (argc >= 7 && argv[idx_rd]->arg) { if (argv_find(argv, argc, "rd", &idx)) {
ret = str2prefix_rd(argv[idx_rd]->arg, &prd); ret = str2prefix_rd(argv[idx+1]->arg, &prd);
if (!ret) { if (!ret) {
vty_out(vty, vty_out(vty,
"%% Malformed Route Distinguisher\n"); "%% Malformed Route Distinguisher\n");
@ -668,9 +407,21 @@ DEFUN (show_bgp_ip_vpn_all_rd,
return CMD_SUCCESS; return CMD_SUCCESS;
} }
ALIAS(show_bgp_ip_vpn_all_rd,
show_bgp_ip_vpn_rd_cmd,
"show bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN [json]",
SHOW_STR
BGP_STR
BGP_VPNVX_HELP_STR
"Display VPN NLRI specific information\n"
"Display information for a route distinguisher\n"
"VPN Route Distinguisher\n"
JSON_STR)
#ifdef KEEP_OLD_VPN_COMMANDS
DEFUN (show_ip_bgp_vpn_rd, DEFUN (show_ip_bgp_vpn_rd,
show_ip_bgp_vpn_rd_cmd, show_ip_bgp_vpn_rd_cmd,
"show [ip] bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN", "show ip bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN",
SHOW_STR SHOW_STR
IP_STR IP_STR
BGP_STR BGP_STR
@ -697,7 +448,6 @@ DEFUN (show_ip_bgp_vpn_rd,
return CMD_SUCCESS; return CMD_SUCCESS;
} }
#ifdef KEEP_OLD_VPN_COMMANDS
DEFUN (show_ip_bgp_vpn_all, DEFUN (show_ip_bgp_vpn_all,
show_ip_bgp_vpn_all_cmd, show_ip_bgp_vpn_all_cmd,
"show [ip] bgp <vpnv4|vpnv6>", "show [ip] bgp <vpnv4|vpnv6>",
@ -1055,8 +805,9 @@ void bgp_mplsvpn_init(void)
install_element(BGP_VPNV6_NODE, &no_vpnv6_network_cmd); install_element(BGP_VPNV6_NODE, &no_vpnv6_network_cmd);
install_element(VIEW_NODE, &show_bgp_ip_vpn_all_rd_cmd); install_element(VIEW_NODE, &show_bgp_ip_vpn_all_rd_cmd);
install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_cmd); install_element(VIEW_NODE, &show_bgp_ip_vpn_rd_cmd);
#ifdef KEEP_OLD_VPN_COMMANDS #ifdef KEEP_OLD_VPN_COMMANDS
install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_cmd);
install_element(VIEW_NODE, &show_ip_bgp_vpn_all_cmd); install_element(VIEW_NODE, &show_ip_bgp_vpn_all_cmd);
install_element(VIEW_NODE, &show_ip_bgp_vpn_all_tags_cmd); install_element(VIEW_NODE, &show_ip_bgp_vpn_all_tags_cmd);
install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_tags_cmd); install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_tags_cmd);

View File

@ -6500,7 +6500,15 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo,
/* Print attribute */ /* Print attribute */
attr = binfo->attr; attr = binfo->attr;
if (attr) { if (!attr) {
if (json_paths)
json_object_array_add(json_paths, json_path);
else
vty_out(vty, "\n");
return;
}
/* /*
* For ENCAP and EVPN routes, nexthop address family is not * For ENCAP and EVPN routes, nexthop address family is not
* neccessarily the same as the prefix address family. * neccessarily the same as the prefix address family.
@ -6513,35 +6521,50 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo,
*/ */
if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) { if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) {
char buf[BUFSIZ]; char buf[BUFSIZ];
char nexthop[128];
int af = NEXTHOP_FAMILY(attr->mp_nexthop_len); int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
switch (af) { switch (af) {
case AF_INET: case AF_INET:
vty_out(vty, "%s", sprintf(nexthop, "%s",
inet_ntop(af, inet_ntop(af, &attr->mp_nexthop_global_in,
&attr->mp_nexthop_global_in,
buf, BUFSIZ)); buf, BUFSIZ));
break; break;
case AF_INET6: case AF_INET6:
vty_out(vty, "%s", sprintf(nexthop, "%s",
inet_ntop(af, &attr->mp_nexthop_global, inet_ntop(af, &attr->mp_nexthop_global,
buf, BUFSIZ)); buf, BUFSIZ));
break; break;
default: default:
vty_out(vty, "?"); sprintf(nexthop, "?");
break; break;
} }
if (json_paths) {
json_nexthop_global = json_object_new_object();
json_object_string_add(json_nexthop_global,
"afi",
(af == AF_INET) ?
"ip" : "ipv6");
json_object_string_add(json_nexthop_global,
(af == AF_INET) ?
"ip" : "ipv6",
nexthop);
json_object_boolean_true_add(json_nexthop_global,
"used");
} else
vty_out(vty, "%s", nexthop);
} else if (safi == SAFI_EVPN) { } else if (safi == SAFI_EVPN) {
if (json_paths) { if (json_paths) {
json_nexthop_global = json_object_new_object(); json_nexthop_global = json_object_new_object();
json_object_string_add( json_object_string_add(json_nexthop_global, "ip",
json_nexthop_global, "ip",
inet_ntoa(attr->nexthop)); inet_ntoa(attr->nexthop));
json_object_string_add(json_nexthop_global, json_object_string_add(json_nexthop_global,
"afi", "ipv4"); "afi", "ipv4");
json_object_boolean_true_add( json_object_boolean_true_add(json_nexthop_global,
json_nexthop_global, "used"); "used");
} else } else
vty_out(vty, "%-16s", inet_ntoa(attr->nexthop)); vty_out(vty, "%-16s", inet_ntoa(attr->nexthop));
} }
@ -6553,19 +6576,18 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo,
if ((safi == SAFI_MPLS_VPN) if ((safi == SAFI_MPLS_VPN)
|| (safi == SAFI_EVPN)) || (safi == SAFI_EVPN))
json_object_string_add( json_object_string_add(json_nexthop_global,
json_nexthop_global, "ip", "ip",
inet_ntoa( inet_ntoa(attr->mp_nexthop_global_in));
attr->mp_nexthop_global_in));
else else
json_object_string_add( json_object_string_add(json_nexthop_global,
json_nexthop_global, "ip", "ip",
inet_ntoa(attr->nexthop)); inet_ntoa(attr->nexthop));
json_object_string_add(json_nexthop_global, json_object_string_add(json_nexthop_global,
"afi", "ipv4"); "afi", "ipv4");
json_object_boolean_true_add( json_object_boolean_true_add(json_nexthop_global,
json_nexthop_global, "used"); "used");
} else { } else {
if ((safi == SAFI_MPLS_VPN) if ((safi == SAFI_MPLS_VPN)
|| (safi == SAFI_EVPN)) || (safi == SAFI_EVPN))
@ -6586,8 +6608,7 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo,
if (json_paths) { if (json_paths) {
json_nexthop_global = json_object_new_object(); json_nexthop_global = json_object_new_object();
json_object_string_add( json_object_string_add(json_nexthop_global, "ip",
json_nexthop_global, "ip",
inet_ntop(AF_INET6, inet_ntop(AF_INET6,
&attr->mp_nexthop_global, buf, &attr->mp_nexthop_global, buf,
BUFSIZ)); BUFSIZ));
@ -6667,10 +6688,8 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo,
" "); " ");
} }
} else { } else {
len = vty_out( len = vty_out(vty, "%s",
vty, "%s", inet_ntop(AF_INET6,
inet_ntop(
AF_INET6,
&attr->mp_nexthop_global, &attr->mp_nexthop_global,
buf, BUFSIZ)); buf, BUFSIZ));
len = 16 - len; len = 16 - len;
@ -6732,13 +6751,6 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo,
bgp_origin_long_str[attr->origin]); bgp_origin_long_str[attr->origin]);
else else
vty_out(vty, "%s", bgp_origin_str[attr->origin]); vty_out(vty, "%s", bgp_origin_str[attr->origin]);
} else {
if (json_paths)
json_object_string_add(json_path, "alert",
"No attributes");
else
vty_out(vty, "No attributes to print\n");
}
if (json_paths) { if (json_paths) {
if (json_nexthop_global || json_nexthop_ll) { if (json_nexthop_global || json_nexthop_ll) {
@ -8122,23 +8134,29 @@ static int bgp_show_community(struct vty *vty, struct bgp *bgp,
const char *comstr, int exact, afi_t afi, const char *comstr, int exact, afi_t afi,
safi_t safi); safi_t safi);
static int bgp_show_table(struct vty *vty, struct bgp *bgp,
static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
struct bgp_table *table, enum bgp_show_type type, struct bgp_table *table, enum bgp_show_type type,
void *output_arg, u_char use_json) void *output_arg, u_char use_json,
char *rd, int is_last,
unsigned long *output_cum, unsigned long *total_cum)
{ {
struct bgp_info *ri; struct bgp_info *ri;
struct bgp_node *rn; struct bgp_node *rn;
int header = 1; int header = 1;
int display; int display;
unsigned long output_count; unsigned long output_count = 0;
unsigned long total_count; unsigned long total_count = 0;
struct prefix *p; struct prefix *p;
char buf[BUFSIZ]; char buf[BUFSIZ];
char buf2[BUFSIZ]; char buf2[BUFSIZ];
json_object *json_paths = NULL; json_object *json_paths = NULL;
int first = 1; int first = 1;
if (use_json) { if (output_cum && *output_cum != 0)
header = 0;
if (use_json && header) {
vty_out(vty, vty_out(vty,
"{ \"vrfId\": %d, \"vrfName\": \"%s\", \"tableVersion\": %" PRId64 "{ \"vrfId\": %d, \"vrfName\": \"%s\", \"tableVersion\": %" PRId64
", \"routerId\": \"%s\", \"routes\": { ", ", \"routerId\": \"%s\", \"routes\": { ",
@ -8146,20 +8164,23 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp,
bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT ? "Default" bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT ? "Default"
: bgp->name, : bgp->name,
table->version, inet_ntoa(bgp->router_id)); table->version, inet_ntoa(bgp->router_id));
if (rd)
vty_out(vty, " \"routeDistinguishers\" : {");
json_paths = json_object_new_object(); json_paths = json_object_new_object();
} }
/* This is first entry point, so reset total line. */ if (use_json && rd) {
output_count = 0; vty_out(vty, " \"%s\" : { ", rd);
total_count = 0; }
/* Start processing of routes. */ /* Start processing of routes. */
for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
if (rn->info != NULL) { if (rn->info == NULL)
continue;
display = 0; display = 0;
if (!first && use_json) { if (!first && use_json)
vty_out(vty, ","); vty_out(vty, ",");
}
if (use_json) if (use_json)
json_paths = json_object_new_array(); json_paths = json_object_new_array();
else else
@ -8192,8 +8213,7 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp,
if (type == bgp_show_type_filter_list) { if (type == bgp_show_type_filter_list) {
struct as_list *as_list = output_arg; struct as_list *as_list = output_arg;
if (as_list_apply(as_list, if (as_list_apply(as_list, ri->attr->aspath)
ri->attr->aspath)
!= AS_FILTER_PERMIT) != AS_FILTER_PERMIT)
continue; continue;
} }
@ -8220,15 +8240,14 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp,
if (ri->peer == NULL if (ri->peer == NULL
|| ri->peer->su_remote == NULL || ri->peer->su_remote == NULL
|| !sockunion_same( || !sockunion_same(ri->peer->su_remote,
ri->peer->su_remote, su)) su))
continue; continue;
} }
if (type == bgp_show_type_cidr_only) { if (type == bgp_show_type_cidr_only) {
u_int32_t destination; u_int32_t destination;
destination = destination = ntohl(rn->p.u.prefix4.s_addr);
ntohl(rn->p.u.prefix4.s_addr);
if (IN_CLASSC(destination) if (IN_CLASSC(destination)
&& rn->p.prefixlen == 24) && rn->p.prefixlen == 24)
continue; continue;
@ -8253,8 +8272,7 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp,
struct community *com = output_arg; struct community *com = output_arg;
if (!ri->attr->community if (!ri->attr->community
|| !community_match( || !community_match(ri->attr->community,
ri->attr->community,
com)) com))
continue; continue;
} }
@ -8262,14 +8280,12 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp,
struct community *com = output_arg; struct community *com = output_arg;
if (!ri->attr->community if (!ri->attr->community
|| !community_cmp( || !community_cmp(ri->attr->community,
ri->attr->community,
com)) com))
continue; continue;
} }
if (type == bgp_show_type_community_list) { if (type == bgp_show_type_community_list) {
struct community_list *list = struct community_list *list = output_arg;
output_arg;
if (!community_list_match( if (!community_list_match(
ri->attr->community, list)) ri->attr->community, list))
@ -8277,8 +8293,7 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp,
} }
if (type if (type
== bgp_show_type_community_list_exact) { == bgp_show_type_community_list_exact) {
struct community_list *list = struct community_list *list = output_arg;
output_arg;
if (!community_list_exact_match( if (!community_list_exact_match(
ri->attr->community, list)) ri->attr->community, list))
@ -8288,14 +8303,12 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp,
struct lcommunity *lcom = output_arg; struct lcommunity *lcom = output_arg;
if (!ri->attr->lcommunity if (!ri->attr->lcommunity
|| !lcommunity_match( || !lcommunity_match(ri->attr->lcommunity,
ri->attr->lcommunity,
lcom)) lcom))
continue; continue;
} }
if (type == bgp_show_type_lcommunity_list) { if (type == bgp_show_type_lcommunity_list) {
struct community_list *list = struct community_list *list = output_arg;
output_arg;
if (!lcommunity_list_match( if (!lcommunity_list_match(
ri->attr->lcommunity, list)) ri->attr->lcommunity, list))
@ -8307,10 +8320,8 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp,
} }
if (type == bgp_show_type_dampend_paths if (type == bgp_show_type_dampend_paths
|| type == bgp_show_type_damp_neighbor) { || type == bgp_show_type_damp_neighbor) {
if (!CHECK_FLAG(ri->flags, if (!CHECK_FLAG(ri->flags, BGP_INFO_DAMPED)
BGP_INFO_DAMPED) || CHECK_FLAG(ri->flags, BGP_INFO_HISTORY))
|| CHECK_FLAG(ri->flags,
BGP_INFO_HISTORY))
continue; continue;
} }
@ -8324,59 +8335,71 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp,
vty_out(vty, BGP_SHOW_OCODE_HEADER); vty_out(vty, BGP_SHOW_OCODE_HEADER);
if (type == bgp_show_type_dampend_paths if (type == bgp_show_type_dampend_paths
|| type == bgp_show_type_damp_neighbor) || type == bgp_show_type_damp_neighbor)
vty_out(vty, vty_out(vty, BGP_SHOW_DAMP_HEADER);
BGP_SHOW_DAMP_HEADER);
else if ( else if (
type == bgp_show_type_flap_statistics type == bgp_show_type_flap_statistics
|| type == bgp_show_type_flap_neighbor) || type == bgp_show_type_flap_neighbor)
vty_out(vty, vty_out(vty, BGP_SHOW_FLAP_HEADER);
BGP_SHOW_FLAP_HEADER);
else else
vty_out(vty, BGP_SHOW_HEADER); vty_out(vty, BGP_SHOW_HEADER);
header = 0; header = 0;
} }
if (rd != NULL && !display && !output_count) {
if (!use_json)
vty_out(vty,
"Route Distinguisher: %s\n",
rd);
}
if (type == bgp_show_type_dampend_paths if (type == bgp_show_type_dampend_paths
|| type == bgp_show_type_damp_neighbor) || type == bgp_show_type_damp_neighbor)
damp_route_vty_out( damp_route_vty_out(vty, &rn->p, ri, display,
vty, &rn->p, ri, display, safi, use_json,
SAFI_UNICAST, use_json,
json_paths); json_paths);
else if (type == bgp_show_type_flap_statistics else if (type == bgp_show_type_flap_statistics
|| type == bgp_show_type_flap_neighbor) || type == bgp_show_type_flap_neighbor)
flap_route_vty_out( flap_route_vty_out(vty, &rn->p, ri, display,
vty, &rn->p, ri, display, safi, use_json,
SAFI_UNICAST, use_json,
json_paths); json_paths);
else else
route_vty_out(vty, &rn->p, ri, display, route_vty_out(vty, &rn->p, ri, display,
SAFI_UNICAST, json_paths); safi, json_paths);
display++; display++;
} }
if (display) { if (display) {
output_count++; output_count++;
if (use_json) { if (!use_json)
continue;
p = &rn->p; p = &rn->p;
sprintf(buf2, "%s/%d", sprintf(buf2, "%s/%d",
inet_ntop(p->family, inet_ntop(p->family, &p->u.prefix,
&p->u.prefix, buf, buf, BUFSIZ),
BUFSIZ),
p->prefixlen); p->prefixlen);
vty_out(vty, "\"%s\": ", buf2); vty_out(vty, "\"%s\": ", buf2);
vty_out(vty, "%s", vty_out(vty, "%s",
json_object_to_json_string( json_object_to_json_string(json_paths));
json_paths));
json_object_free(json_paths); json_object_free(json_paths);
first = 0; first = 0;
} }
} }
}
if (output_cum) {
output_count += *output_cum;
*output_cum = output_count;
}
if (total_cum) {
total_count += *total_cum;
*total_cum = total_count;
}
if (use_json) { if (use_json) {
json_object_free(json_paths); json_object_free(json_paths);
if (is_last)
vty_out(vty, " } }\n"); vty_out(vty, " } }\n");
else
vty_out(vty, " }, ");
} else { } else {
if (is_last) {
/* No route is displayed */ /* No route is displayed */
if (output_count == 0) { if (output_count == 0) {
if (type == bgp_show_type_normal) if (type == bgp_show_type_normal)
@ -8388,10 +8411,43 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp,
"\nDisplayed %ld routes and %ld total paths\n", "\nDisplayed %ld routes and %ld total paths\n",
output_count, total_count); output_count, total_count);
} }
}
return CMD_SUCCESS; return CMD_SUCCESS;
} }
int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
struct bgp_table *table, struct prefix_rd *prd_match,
enum bgp_show_type type, void *output_arg,
u_char use_json)
{
struct bgp_node *rn, *next;
unsigned long output_cum = 0;
unsigned long total_cum = 0;
for (rn = bgp_table_top(table); rn; rn = next) {
next = bgp_route_next(rn);
if (prd_match && memcmp(rn->p.u.val, prd_match->val, 8) != 0)
continue;
if (rn->info != NULL) {
struct prefix_rd prd;
char rd[BUFSIZ];
memcpy(&prd, &(rn->p), sizeof(struct prefix_rd));
if (prefix_rd2str(&prd, rd, BUFSIZ) == NULL)
sprintf(rd,
"Unknown Type: %u",
decode_rd_type(prd.val));
bgp_show_table(vty, bgp, safi, rn->info, type,
output_arg, use_json,
rd, next == NULL,
&output_cum, &total_cum);
}
}
if (use_json)
vty_out(vty, " } }");
return CMD_SUCCESS;
}
static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
enum bgp_show_type type, void *output_arg, u_char use_json) enum bgp_show_type type, void *output_arg, u_char use_json)
{ {
@ -8409,18 +8465,18 @@ static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
return CMD_WARNING; return CMD_WARNING;
} }
table = bgp->rib[afi][safi];
/* use MPLS and ENCAP specific shows until they are merged */ /* use MPLS and ENCAP specific shows until they are merged */
if (safi == SAFI_MPLS_VPN) { if (safi == SAFI_MPLS_VPN) {
return bgp_show_mpls_vpn(vty, afi, NULL, type, output_arg, 0, return bgp_show_table_rd(vty, bgp, safi, table, NULL, type,
use_json); output_arg, use_json);
} }
/* labeled-unicast routes live in the unicast table */ /* labeled-unicast routes live in the unicast table */
else if (safi == SAFI_LABELED_UNICAST) else if (safi == SAFI_LABELED_UNICAST)
safi = SAFI_UNICAST; safi = SAFI_UNICAST;
table = bgp->rib[afi][safi]; return bgp_show_table(vty, bgp, safi, table, type, output_arg, use_json,
NULL, 1, NULL, NULL);
return bgp_show_table(vty, bgp, table, type, output_arg, use_json);
} }
static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi, static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
@ -9090,11 +9146,6 @@ DEFUN (show_ip_bgp_json,
return bgp_show(vty, bgp, afi, safi, return bgp_show(vty, bgp, afi, safi,
bgp_show_type_community_all, NULL, uj); bgp_show_type_community_all, NULL, uj);
} }
if (safi == SAFI_MPLS_VPN)
return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_normal,
NULL, 0, uj);
else
return bgp_show(vty, bgp, afi, safi, sh_type, NULL, uj); return bgp_show(vty, bgp, afi, safi, sh_type, NULL, uj);
} }

View File

@ -442,4 +442,8 @@ extern void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
struct prefix *p, struct bgp_info *binfo, struct prefix *p, struct bgp_info *binfo,
afi_t afi, safi_t safi, afi_t afi, safi_t safi,
json_object *json_paths); json_object *json_paths);
extern int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
struct bgp_table *table, struct prefix_rd *prd,
enum bgp_show_type type, void *output_arg,
u_char use_json);
#endif /* _QUAGGA_BGP_ROUTE_H */ #endif /* _QUAGGA_BGP_ROUTE_H */

View File

@ -9868,17 +9868,13 @@ static int bgp_show_neighbor_vty(struct vty *vty, const char *name,
/* "show [ip] bgp neighbors" commands. */ /* "show [ip] bgp neighbors" commands. */
DEFUN (show_ip_bgp_neighbors, DEFUN (show_ip_bgp_neighbors,
show_ip_bgp_neighbors_cmd, show_ip_bgp_neighbors_cmd,
"show [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6|vpnv4 <all|rd ASN:NN_OR_IP-ADDRESS:NN>>] neighbors [<A.B.C.D|X:X::X:X|WORD>] [json]", "show [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6>] neighbors [<A.B.C.D|X:X::X:X|WORD>] [json]",
SHOW_STR SHOW_STR
IP_STR IP_STR
BGP_STR BGP_STR
BGP_INSTANCE_HELP_STR BGP_INSTANCE_HELP_STR
"Address Family\n" "Address Family\n"
"Address Family\n" "Address Family\n"
"Address Family\n"
"Display information about all VPNv4 NLRIs\n"
"Display information for a route distinguisher\n"
"VPN Route Distinguisher\n"
"Detailed information on TCP and BGP neighbor connections\n" "Detailed information on TCP and BGP neighbor connections\n"
"Neighbor to display information about\n" "Neighbor to display information about\n"
"Neighbor to display information about\n" "Neighbor to display information about\n"