mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-06 14:29:47 +00:00
bgpd: Fixing "show bgp l2vpn evpn neighbors x.x.x.x advertised-routes json
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: https://github.com/FRRouting/frr/pull/5078 Crash issue: https://github.com/FRRouting/frr/issues/5010 Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
This commit is contained in:
parent
5c256b572c
commit
dc387b0fea
@ -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_status = NULL;
|
||||||
json_object *json_net = NULL;
|
json_object *json_net = NULL;
|
||||||
char buff[BUFSIZ];
|
char buff[BUFSIZ];
|
||||||
char buf2[BUFSIZ];
|
|
||||||
/* Route status display. */
|
/* Route status display. */
|
||||||
if (use_json) {
|
if (use_json) {
|
||||||
json_status = json_object_new_object();
|
json_status = json_object_new_object();
|
||||||
@ -7530,12 +7530,18 @@ void route_vty_out_tmp(struct vty *vty, struct prefix *p, struct attr *attr,
|
|||||||
|
|
||||||
/* print prefix and mask */
|
/* print prefix and mask */
|
||||||
if (use_json) {
|
if (use_json) {
|
||||||
json_object_string_add(
|
if (safi == SAFI_EVPN)
|
||||||
json_net, "addrPrefix",
|
bgp_evpn_route2json((struct prefix_evpn *)p, json_net);
|
||||||
inet_ntop(p->family, &p->u.prefix, buff, BUFSIZ));
|
else if (p->family == AF_INET || p->family == AF_INET6) {
|
||||||
json_object_int_add(json_net, "prefixLen", p->prefixlen);
|
json_object_string_add(
|
||||||
prefix2str(p, buf2, PREFIX_STRLEN);
|
json_net, "addrPrefix",
|
||||||
json_object_string_add(json_net, "network", buf2);
|
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
|
} else
|
||||||
route_vty_out_route(p, vty, NULL);
|
route_vty_out_route(p, vty, NULL);
|
||||||
|
|
||||||
@ -7544,10 +7550,8 @@ void route_vty_out_tmp(struct vty *vty, struct prefix *p, struct attr *attr,
|
|||||||
if (use_json) {
|
if (use_json) {
|
||||||
if (p->family == AF_INET
|
if (p->family == AF_INET
|
||||||
&& (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
|
&& (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
|
||||||
|| safi == SAFI_EVPN
|
|
||||||
|| !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
|
|| !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
|
||||||
if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
|
if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
|
||||||
|| safi == SAFI_EVPN)
|
|
||||||
json_object_string_add(
|
json_object_string_add(
|
||||||
json_net, "nextHop",
|
json_net, "nextHop",
|
||||||
inet_ntoa(
|
inet_ntoa(
|
||||||
@ -7565,7 +7569,11 @@ void route_vty_out_tmp(struct vty *vty, struct prefix *p, struct attr *attr,
|
|||||||
inet_ntop(AF_INET6,
|
inet_ntop(AF_INET6,
|
||||||
&attr->mp_nexthop_global, buf,
|
&attr->mp_nexthop_global, buf,
|
||||||
BUFSIZ));
|
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
|
if (attr->flag
|
||||||
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
|
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
|
||||||
@ -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_boolean_true_add(json_status, ">");
|
||||||
json_object_object_add(json_net, "appliedStatusSymbols",
|
json_object_object_add(json_net, "appliedStatusSymbols",
|
||||||
json_status);
|
json_status);
|
||||||
char buf_cut[BUFSIZ];
|
|
||||||
|
|
||||||
prefix2str(p, buf_cut, PREFIX_STRLEN);
|
prefix2str(p, buff, PREFIX_STRLEN);
|
||||||
json_object_object_add(json_ar, buf_cut, json_net);
|
json_object_object_add(json_ar, buff, json_net);
|
||||||
} else
|
} else
|
||||||
vty_out(vty, "\n");
|
vty_out(vty, "\n");
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include "bgpd/bgp_attr.h"
|
#include "bgpd/bgp_attr.h"
|
||||||
#include "bgpd/bgp_mplsvpn.h"
|
#include "bgpd/bgp_mplsvpn.h"
|
||||||
#include "bgpd/bgp_vpn.h"
|
#include "bgpd/bgp_vpn.h"
|
||||||
|
#include "bgpd/bgp_updgrp.h"
|
||||||
|
|
||||||
int show_adj_route_vpn(struct vty *vty, struct peer *peer,
|
int show_adj_route_vpn(struct vty *vty, struct peer *peer,
|
||||||
struct prefix_rd *prd, afi_t afi, safi_t safi,
|
struct prefix_rd *prd, afi_t afi, safi_t safi,
|
||||||
@ -38,14 +39,15 @@ int show_adj_route_vpn(struct vty *vty, struct peer *peer,
|
|||||||
struct bgp_table *table;
|
struct bgp_table *table;
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
struct bgp_node *rm;
|
struct bgp_node *rm;
|
||||||
struct bgp_path_info *path;
|
|
||||||
int rd_header;
|
int rd_header;
|
||||||
int header = 1;
|
int header = 1;
|
||||||
json_object *json = NULL;
|
json_object *json = NULL;
|
||||||
json_object *json_scode = NULL;
|
json_object *json_scode = NULL;
|
||||||
json_object *json_ocode = NULL;
|
json_object *json_ocode = NULL;
|
||||||
|
json_object *json_adv = NULL;
|
||||||
json_object *json_routes = NULL;
|
json_object *json_routes = NULL;
|
||||||
json_object *json_array = NULL;
|
char rd_str[BUFSIZ];
|
||||||
|
unsigned long output_count = 0;
|
||||||
|
|
||||||
bgp = bgp_get_default();
|
bgp = bgp_get_default();
|
||||||
if (bgp == NULL) {
|
if (bgp == NULL) {
|
||||||
@ -59,8 +61,8 @@ int show_adj_route_vpn(struct vty *vty, struct peer *peer,
|
|||||||
if (use_json) {
|
if (use_json) {
|
||||||
json_scode = json_object_new_object();
|
json_scode = json_object_new_object();
|
||||||
json_ocode = json_object_new_object();
|
json_ocode = json_object_new_object();
|
||||||
json_routes = json_object_new_object();
|
|
||||||
json = 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, "suppressed", "s");
|
||||||
json_object_string_add(json_scode, "damped", "d");
|
json_object_string_add(json_scode, "damped", "d");
|
||||||
@ -83,16 +85,25 @@ int show_adj_route_vpn(struct vty *vty, struct peer *peer,
|
|||||||
if (table == NULL)
|
if (table == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (use_json)
|
|
||||||
json_array = json_object_new_array();
|
|
||||||
else
|
|
||||||
json_array = NULL;
|
|
||||||
|
|
||||||
rd_header = 1;
|
rd_header = 1;
|
||||||
|
memset(rd_str, 0, sizeof(rd_str));
|
||||||
|
|
||||||
for (rm = bgp_table_top(table); rm; rm = bgp_route_next(rm)) {
|
for (rm = bgp_table_top(table); rm; rm = bgp_route_next(rm)) {
|
||||||
path = bgp_node_get_bgp_path_info(rm);
|
struct bgp_adj_out *adj = NULL;
|
||||||
if (path == 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;
|
continue;
|
||||||
|
|
||||||
if (header) {
|
if (header) {
|
||||||
@ -102,6 +113,13 @@ int show_adj_route_vpn(struct vty *vty, struct peer *peer,
|
|||||||
json_object_string_add(
|
json_object_string_add(
|
||||||
json, "bgpLocalRouterId",
|
json, "bgpLocalRouterId",
|
||||||
inet_ntoa(bgp->router_id));
|
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,
|
json_object_object_add(json,
|
||||||
"bgpStatusCodes",
|
"bgpStatusCodes",
|
||||||
json_scode);
|
json_scode);
|
||||||
@ -112,6 +130,9 @@ int show_adj_route_vpn(struct vty *vty, struct peer *peer,
|
|||||||
vty_out(vty,
|
vty_out(vty,
|
||||||
"BGP table version is 0, local router ID is %s\n",
|
"BGP table version is 0, local router ID is %s\n",
|
||||||
inet_ntoa(bgp->router_id));
|
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,
|
vty_out(vty,
|
||||||
"Status codes: s suppressed, d damped, h history, * valid, > best, i - internal\n");
|
"Status codes: s suppressed, d damped, h history, * valid, > best, i - internal\n");
|
||||||
vty_out(vty,
|
vty_out(vty,
|
||||||
@ -146,18 +167,19 @@ int show_adj_route_vpn(struct vty *vty, struct peer *peer,
|
|||||||
decode_rd_vnc_eth(pnt, &rd_vnc_eth);
|
decode_rd_vnc_eth(pnt, &rd_vnc_eth);
|
||||||
#endif
|
#endif
|
||||||
if (use_json) {
|
if (use_json) {
|
||||||
char buffer[BUFSIZ];
|
json_routes = json_object_new_object();
|
||||||
|
|
||||||
if (type == RD_TYPE_AS
|
if (type == RD_TYPE_AS
|
||||||
|| type == RD_TYPE_AS4)
|
|| type == RD_TYPE_AS4)
|
||||||
sprintf(buffer, "%u:%d",
|
sprintf(rd_str, "%u:%d",
|
||||||
rd_as.as, rd_as.val);
|
rd_as.as, rd_as.val);
|
||||||
else if (type == RD_TYPE_IP)
|
else if (type == RD_TYPE_IP)
|
||||||
sprintf(buffer, "%s:%d",
|
sprintf(rd_str, "%s:%d",
|
||||||
inet_ntoa(rd_ip.ip),
|
inet_ntoa(rd_ip.ip),
|
||||||
rd_ip.val);
|
rd_ip.val);
|
||||||
json_object_string_add(
|
json_object_string_add(
|
||||||
json_routes,
|
json_routes,
|
||||||
"routeDistinguisher", buffer);
|
"rd", rd_str);
|
||||||
} else {
|
} else {
|
||||||
vty_out(vty, "Route Distinguisher: ");
|
vty_out(vty, "Route Distinguisher: ");
|
||||||
|
|
||||||
@ -192,24 +214,25 @@ int show_adj_route_vpn(struct vty *vty, struct peer *peer,
|
|||||||
}
|
}
|
||||||
rd_header = 0;
|
rd_header = 0;
|
||||||
}
|
}
|
||||||
if (use_json) {
|
route_vty_out_tmp(vty, &rm->p, attr,
|
||||||
char buf[BUFSIZ];
|
safi, use_json,
|
||||||
|
json_routes);
|
||||||
prefix2str(&rm->p, buf, sizeof(buf));
|
output_count++;
|
||||||
json_object_object_add(json_routes, buf,
|
|
||||||
json_array);
|
|
||||||
} else {
|
|
||||||
route_vty_out_tmp(vty, &rm->p, path->attr,
|
|
||||||
safi, use_json,
|
|
||||||
json_array);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (use_json)
|
||||||
|
json_object_object_add(json_adv, rd_str, json_routes);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (use_json) {
|
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(
|
vty_out(vty, "%s\n", json_object_to_json_string_ext(
|
||||||
json, JSON_C_TO_STRING_PRETTY));
|
json, JSON_C_TO_STRING_PRETTY));
|
||||||
json_object_free(json);
|
json_object_free(json);
|
||||||
}
|
} else
|
||||||
|
vty_out(vty, "\nTotal number of prefixes %ld\n", output_count);
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user