Skip to content

Commit

Permalink
Fixing "show bgp l2vpn evpn neighbors x.x.x.x advertised-routes json
Browse files Browse the repository at this point in the history
Display output from adj_out instead of the rib table.

Also fixes crash for the json output. RCA: prefix is written to json object
using inet_ntop. But, this api returns null buffer for AF_EVPN address family
(it works only for AF_INET and AF_INET6).  This null buffer is then deref'd
by json-object-to string api.

Full output shown in PR: FRRouting#5078
Crash issue: FRRouting#5010

Signed-off-by: Lakshman Krishnamoorthy <[email protected]>
  • Loading branch information
lkrishnamoor committed Sep 27, 2019
1 parent 5c256b5 commit fabf464
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 40 deletions.
35 changes: 21 additions & 14 deletions bgpd/bgp_route.c
Original file line number Diff line number Diff line change
Expand Up @@ -7517,7 +7517,7 @@ void route_vty_out_tmp(struct vty *vty, struct prefix *p, struct attr *attr,
json_object *json_status = NULL;
json_object *json_net = NULL;
char buff[BUFSIZ];
char buf2[BUFSIZ];

/* Route status display. */
if (use_json) {
json_status = json_object_new_object();
Expand All @@ -7530,12 +7530,18 @@ void route_vty_out_tmp(struct vty *vty, struct prefix *p, struct attr *attr,

/* print prefix and mask */
if (use_json) {
json_object_string_add(
json_net, "addrPrefix",
inet_ntop(p->family, &p->u.prefix, buff, BUFSIZ));
json_object_int_add(json_net, "prefixLen", p->prefixlen);
prefix2str(p, buf2, PREFIX_STRLEN);
json_object_string_add(json_net, "network", buf2);
if (safi == SAFI_EVPN)
bgp_evpn_route2json((struct prefix_evpn *)p, json_net);
else if (p->family == AF_INET || p->family == AF_INET6) {
json_object_string_add(
json_net, "addrPrefix",
inet_ntop(p->family, &p->u.prefix, buff,
BUFSIZ));
json_object_int_add(json_net, "prefixLen",
p->prefixlen);
prefix2str(p, buff, PREFIX_STRLEN);
json_object_string_add(json_net, "network", buff);
}
} else
route_vty_out_route(p, vty, NULL);

Expand All @@ -7544,10 +7550,8 @@ void route_vty_out_tmp(struct vty *vty, struct prefix *p, struct attr *attr,
if (use_json) {
if (p->family == AF_INET
&& (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
|| safi == SAFI_EVPN
|| !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
|| safi == SAFI_EVPN)
if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
json_object_string_add(
json_net, "nextHop",
inet_ntoa(
Expand All @@ -7565,7 +7569,11 @@ void route_vty_out_tmp(struct vty *vty, struct prefix *p, struct attr *attr,
inet_ntop(AF_INET6,
&attr->mp_nexthop_global, buf,
BUFSIZ));
}
} else if (p->family == AF_EVPN &&
!BGP_ATTR_NEXTHOP_AFI_IP6(attr))
json_object_string_add(json_net,
"nextHop", inet_ntoa(
attr->mp_nexthop_global_in));

if (attr->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
Expand Down Expand Up @@ -7659,10 +7667,9 @@ void route_vty_out_tmp(struct vty *vty, struct prefix *p, struct attr *attr,
json_object_boolean_true_add(json_status, ">");
json_object_object_add(json_net, "appliedStatusSymbols",
json_status);
char buf_cut[BUFSIZ];

prefix2str(p, buf_cut, PREFIX_STRLEN);
json_object_object_add(json_ar, buf_cut, json_net);
prefix2str(p, buff, PREFIX_STRLEN);
json_object_object_add(json_ar, buff, json_net);
} else
vty_out(vty, "\n");
}
Expand Down
75 changes: 49 additions & 26 deletions bgpd/bgp_vpn.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "bgpd/bgp_attr.h"
#include "bgpd/bgp_mplsvpn.h"
#include "bgpd/bgp_vpn.h"
#include "bgpd/bgp_updgrp.h"

int show_adj_route_vpn(struct vty *vty, struct peer *peer,
struct prefix_rd *prd, afi_t afi, safi_t safi,
Expand All @@ -38,14 +39,15 @@ int show_adj_route_vpn(struct vty *vty, struct peer *peer,
struct bgp_table *table;
struct bgp_node *rn;
struct bgp_node *rm;
struct bgp_path_info *path;
int rd_header;
int header = 1;
json_object *json = NULL;
json_object *json_scode = NULL;
json_object *json_ocode = NULL;
json_object *json_adv = NULL;
json_object *json_routes = NULL;
json_object *json_array = NULL;
char rd_str[BUFSIZ];
unsigned long output_count = 0;

bgp = bgp_get_default();
if (bgp == NULL) {
Expand All @@ -59,8 +61,8 @@ int show_adj_route_vpn(struct vty *vty, struct peer *peer,
if (use_json) {
json_scode = json_object_new_object();
json_ocode = json_object_new_object();
json_routes = json_object_new_object();
json = json_object_new_object();
json_adv = json_object_new_object();

json_object_string_add(json_scode, "suppressed", "s");
json_object_string_add(json_scode, "damped", "d");
Expand All @@ -83,16 +85,25 @@ int show_adj_route_vpn(struct vty *vty, struct peer *peer,
if (table == NULL)
continue;

if (use_json)
json_array = json_object_new_array();
else
json_array = NULL;

rd_header = 1;
memset(rd_str, 0, sizeof(rd_str));

for (rm = bgp_table_top(table); rm; rm = bgp_route_next(rm)) {
path = bgp_node_get_bgp_path_info(rm);
if (path == NULL)
struct bgp_adj_out *adj = NULL;
struct attr *attr = NULL;
struct peer_af *paf = NULL;

RB_FOREACH (adj, bgp_adj_out_rb, &rm->adj_out)
SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
if (paf->peer != peer || !adj->attr)
continue;

attr = adj->attr;
break;
}

if (bgp_node_get_bgp_path_info(rm) == NULL)
continue;

if (header) {
Expand All @@ -102,6 +113,13 @@ int show_adj_route_vpn(struct vty *vty, struct peer *peer,
json_object_string_add(
json, "bgpLocalRouterId",
inet_ntoa(bgp->router_id));
json_object_int_add(
json,
"defaultLocPrf",
bgp->default_local_pref);
json_object_int_add(
json, "localAS",
bgp->as);
json_object_object_add(json,
"bgpStatusCodes",
json_scode);
Expand All @@ -112,6 +130,9 @@ int show_adj_route_vpn(struct vty *vty, struct peer *peer,
vty_out(vty,
"BGP table version is 0, local router ID is %s\n",
inet_ntoa(bgp->router_id));
vty_out(vty, "Default local pref %u, ",
bgp->default_local_pref);
vty_out(vty, "local AS %u\n", bgp->as);
vty_out(vty,
"Status codes: s suppressed, d damped, h history, * valid, > best, i - internal\n");
vty_out(vty,
Expand Down Expand Up @@ -146,18 +167,19 @@ int show_adj_route_vpn(struct vty *vty, struct peer *peer,
decode_rd_vnc_eth(pnt, &rd_vnc_eth);
#endif
if (use_json) {
char buffer[BUFSIZ];
json_routes = json_object_new_object();

if (type == RD_TYPE_AS
|| type == RD_TYPE_AS4)
sprintf(buffer, "%u:%d",
sprintf(rd_str, "%u:%d",
rd_as.as, rd_as.val);
else if (type == RD_TYPE_IP)
sprintf(buffer, "%s:%d",
sprintf(rd_str, "%s:%d",
inet_ntoa(rd_ip.ip),
rd_ip.val);
json_object_string_add(
json_routes,
"routeDistinguisher", buffer);
"rd", rd_str);
} else {
vty_out(vty, "Route Distinguisher: ");

Expand Down Expand Up @@ -192,24 +214,25 @@ int show_adj_route_vpn(struct vty *vty, struct peer *peer,
}
rd_header = 0;
}
if (use_json) {
char buf[BUFSIZ];

prefix2str(&rm->p, buf, sizeof(buf));
json_object_object_add(json_routes, buf,
json_array);
} else {
route_vty_out_tmp(vty, &rm->p, path->attr,
safi, use_json,
json_array);
}
route_vty_out_tmp(vty, &rm->p, attr,
safi, use_json,
json_routes);
output_count++;
}

if (use_json)
json_object_object_add(json_adv, rd_str, json_routes);
}

if (use_json) {
json_object_object_add(json, "routes", json_routes);
json_object_object_add(json, "advertisedRoutes", json_adv);
json_object_int_add(json,
"totalPrefixCounter", output_count);
vty_out(vty, "%s\n", json_object_to_json_string_ext(
json, JSON_C_TO_STRING_PRETTY));
json_object_free(json);
}
} else
vty_out(vty, "\nTotal number of prefixes %ld\n", output_count);

return CMD_SUCCESS;
}

0 comments on commit fabf464

Please sign in to comment.