bgpd: unify 'show bgp' with RD with normal unicast bgp show

Signed-off-by: Lou Berger <lberger@labn.net>
This commit is contained in:
Lou Berger 2017-09-28 18:51:31 -04:00 committed by Donald Sharp
parent ad183f047c
commit 1ae44dfcba
3 changed files with 88 additions and 297 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,256 +365,9 @@ 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,

View file

@ -8122,23 +8122,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\": { ",
@ -8149,10 +8155,6 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp,
json_paths = json_object_new_object(); json_paths = json_object_new_object();
} }
/* This is first entry point, so reset total line. */
output_count = 0;
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) {
@ -8335,22 +8337,29 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp,
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);
else
vty_out(vty, "rd:\"%s\",", 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_UNICAST, use_json, safi, 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_UNICAST, use_json, safi, 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++;
} }
@ -8373,10 +8382,22 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp,
} }
} }
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 +8409,41 @@ 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);
}
}
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 +8461,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 +9142,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 */