mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-13 19:39:28 +00:00
bgpd: when showing routes, add nexthop vrf and announce-self flag
As part of recent vpn-vrf leaking changes, it is now possible for a route to refer to a nexthop in a different vrf. There is also a new route flag that means "when announcing this route, indicate myself as the next-hop." route_vty_out(): nexthops are appended with: "@VRFID" (where VRFID is the numerical vrf id) when different from the route's vrf; "<" when the route's BGP_INFO_ANNC_NH_SELF is set This change also shows the route table's vrf id in the table header. route_vty_out_detail(): show nexthop's vrf and announce-nh-self flag if appropriate. Both functions are also augmented to add json elements nhVrfId, nhVrfName, and announceNexthopSelf as appropriate. The intent of these changes is to make it easier to understand/debug the relationship between a route and its nexthops. Signed-off-by: G. Paul Ziemba <paulz@labn.net>
This commit is contained in:
parent
d90b2b73cb
commit
9df8b37c72
173
bgpd/bgp_route.c
173
bgpd/bgp_route.c
@ -99,6 +99,8 @@ static const struct message bgp_pmsi_tnltype_str[] = {
|
||||
{0}
|
||||
};
|
||||
|
||||
#define VRFID_NONE_STR "-"
|
||||
|
||||
struct bgp_node *bgp_afi_node_get(struct bgp_table *table, afi_t afi,
|
||||
safi_t safi, struct prefix *p,
|
||||
struct prefix_rd *prd)
|
||||
@ -6471,6 +6473,13 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo,
|
||||
json_object *json_nexthops = NULL;
|
||||
json_object *json_nexthop_global = NULL;
|
||||
json_object *json_nexthop_ll = NULL;
|
||||
char vrf_id_str[VRF_NAMSIZ] = {0};
|
||||
bool nexthop_self = CHECK_FLAG(binfo->flags, BGP_INFO_ANNC_NH_SELF)
|
||||
? true
|
||||
: false;
|
||||
bool nexthop_othervrf = false;
|
||||
vrf_id_t nexthop_vrfid;
|
||||
const char *nexthop_vrfname = "Default";
|
||||
|
||||
if (json_paths)
|
||||
json_path = json_object_new_object();
|
||||
@ -6499,6 +6508,39 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo,
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If vrf id of nexthop is different from that of prefix,
|
||||
* set up printable string to append
|
||||
*/
|
||||
if (binfo->extra && binfo->extra->bgp_orig) {
|
||||
const char *self = "";
|
||||
|
||||
if (nexthop_self)
|
||||
self = "<";
|
||||
|
||||
nexthop_othervrf = true;
|
||||
nexthop_vrfid = binfo->extra->bgp_orig->vrf_id;
|
||||
|
||||
if (binfo->extra->bgp_orig->vrf_id == VRF_UNKNOWN)
|
||||
snprintf(vrf_id_str, sizeof(vrf_id_str),
|
||||
"@%s%s", VRFID_NONE_STR, self);
|
||||
else
|
||||
snprintf(vrf_id_str, sizeof(vrf_id_str), "@%u%s",
|
||||
binfo->extra->bgp_orig->vrf_id, self);
|
||||
|
||||
if (binfo->extra->bgp_orig->inst_type !=
|
||||
BGP_INSTANCE_TYPE_DEFAULT)
|
||||
|
||||
nexthop_vrfname = binfo->extra->bgp_orig->name;
|
||||
} else {
|
||||
const char *self = "";
|
||||
|
||||
if (nexthop_self)
|
||||
self = "<";
|
||||
|
||||
snprintf(vrf_id_str, sizeof(vrf_id_str), "%s", self);
|
||||
}
|
||||
|
||||
/*
|
||||
* For ENCAP and EVPN routes, nexthop address family is not
|
||||
* neccessarily the same as the prefix address family.
|
||||
@ -6541,7 +6583,7 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo,
|
||||
json_object_boolean_true_add(json_nexthop_global,
|
||||
"used");
|
||||
} else
|
||||
vty_out(vty, "%s", nexthop);
|
||||
vty_out(vty, "%s%s", nexthop, vrf_id_str);
|
||||
} else if (safi == SAFI_EVPN) {
|
||||
if (json_paths) {
|
||||
json_nexthop_global = json_object_new_object();
|
||||
@ -6553,7 +6595,8 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo,
|
||||
json_object_boolean_true_add(json_nexthop_global,
|
||||
"used");
|
||||
} else
|
||||
vty_out(vty, "%-16s", inet_ntoa(attr->nexthop));
|
||||
vty_out(vty, "%-16s%s", inet_ntoa(attr->nexthop),
|
||||
vrf_id_str);
|
||||
} else if (safi == SAFI_FLOWSPEC) {
|
||||
if (attr->nexthop.s_addr != 0) {
|
||||
if (json_paths) {
|
||||
@ -6587,11 +6630,17 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo,
|
||||
json_object_boolean_true_add(json_nexthop_global,
|
||||
"used");
|
||||
} else {
|
||||
char buf[BUFSIZ];
|
||||
|
||||
if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_EVPN))
|
||||
vty_out(vty, "%-16s",
|
||||
inet_ntoa(attr->mp_nexthop_global_in));
|
||||
snprintf(buf, sizeof(buf), "%s%s",
|
||||
inet_ntoa(attr->mp_nexthop_global_in),
|
||||
vrf_id_str);
|
||||
else
|
||||
vty_out(vty, "%-16s", inet_ntoa(attr->nexthop));
|
||||
snprintf(buf, sizeof(buf), "%s%s",
|
||||
inet_ntoa(attr->nexthop),
|
||||
vrf_id_str);
|
||||
vty_out(vty, "%-16s", buf);
|
||||
}
|
||||
}
|
||||
|
||||
@ -6658,11 +6707,12 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo,
|
||||
vty_out(vty, "%*s", len, " ");
|
||||
} else {
|
||||
len = vty_out(
|
||||
vty, "%s",
|
||||
vty, "%s%s",
|
||||
inet_ntop(
|
||||
AF_INET6,
|
||||
&attr->mp_nexthop_local,
|
||||
buf, BUFSIZ));
|
||||
buf, BUFSIZ),
|
||||
vrf_id_str);
|
||||
len = 16 - len;
|
||||
|
||||
if (len < 1)
|
||||
@ -6672,10 +6722,11 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo,
|
||||
}
|
||||
} else {
|
||||
len = vty_out(
|
||||
vty, "%s",
|
||||
vty, "%s%s",
|
||||
inet_ntop(AF_INET6,
|
||||
&attr->mp_nexthop_global, buf,
|
||||
BUFSIZ));
|
||||
BUFSIZ),
|
||||
vrf_id_str);
|
||||
len = 16 - len;
|
||||
|
||||
if (len < 1)
|
||||
@ -6733,6 +6784,21 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo,
|
||||
else
|
||||
vty_out(vty, "%s", bgp_origin_str[attr->origin]);
|
||||
|
||||
if (json_paths) {
|
||||
if (nexthop_self)
|
||||
json_object_boolean_true_add(json_path,
|
||||
"announceNexthopSelf");
|
||||
if (nexthop_othervrf) {
|
||||
json_object_string_add(json_path, "nhVrfName",
|
||||
nexthop_vrfname);
|
||||
|
||||
json_object_int_add(json_path, "nhVrfId",
|
||||
((nexthop_vrfid == VRF_UNKNOWN)
|
||||
? -1
|
||||
: (int)nexthop_vrfid));
|
||||
}
|
||||
}
|
||||
|
||||
if (json_paths) {
|
||||
if (json_nexthop_global || json_nexthop_ll) {
|
||||
json_nexthops = json_object_new_array();
|
||||
@ -7333,6 +7399,9 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct prefix *p,
|
||||
int addpath_capable;
|
||||
int has_adj;
|
||||
unsigned int first_as;
|
||||
bool nexthop_self = CHECK_FLAG(binfo->flags, BGP_INFO_ANNC_NH_SELF)
|
||||
? true
|
||||
: false;
|
||||
|
||||
if (json_paths) {
|
||||
json_path = json_object_new_object();
|
||||
@ -7636,6 +7705,49 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct prefix *p,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Note when vrfid of nexthop is different from that of prefix
|
||||
*/
|
||||
if (binfo->extra && binfo->extra->bgp_orig) {
|
||||
vrf_id_t nexthop_vrfid = binfo->extra->bgp_orig->vrf_id;
|
||||
|
||||
if (json_paths) {
|
||||
const char *vn;
|
||||
|
||||
if (binfo->extra->bgp_orig->inst_type ==
|
||||
BGP_INSTANCE_TYPE_DEFAULT)
|
||||
|
||||
vn = "Default";
|
||||
else
|
||||
vn = binfo->extra->bgp_orig->name;
|
||||
|
||||
json_object_string_add(json_path, "nhVrfName",
|
||||
vn);
|
||||
|
||||
if (nexthop_vrfid == VRF_UNKNOWN) {
|
||||
json_object_int_add(json_path,
|
||||
"nhVrfId", -1);
|
||||
} else {
|
||||
json_object_int_add(json_path,
|
||||
"nhVrfId", (int)nexthop_vrfid);
|
||||
}
|
||||
} else {
|
||||
if (nexthop_vrfid == VRF_UNKNOWN)
|
||||
vty_out(vty, " vrf ?");
|
||||
else
|
||||
vty_out(vty, " vrf %u", nexthop_vrfid);
|
||||
}
|
||||
}
|
||||
|
||||
if (nexthop_self) {
|
||||
if (json_paths) {
|
||||
json_object_boolean_true_add(json_path,
|
||||
"announceNexthopSelf");
|
||||
} else {
|
||||
vty_out(vty, " announce-nh-self");
|
||||
}
|
||||
}
|
||||
|
||||
if (!json_paths)
|
||||
vty_out(vty, "\n");
|
||||
|
||||
@ -8333,10 +8445,16 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
|
||||
|
||||
if (!use_json && header) {
|
||||
vty_out(vty, "BGP table version is %" PRIu64
|
||||
", local router ID is %s\n",
|
||||
", local router ID is %s, vrf id ",
|
||||
table->version,
|
||||
inet_ntoa(bgp->router_id));
|
||||
if (bgp->vrf_id == VRF_UNKNOWN)
|
||||
vty_out(vty, "%s", VRFID_NONE_STR);
|
||||
else
|
||||
vty_out(vty, "%u", bgp->vrf_id);
|
||||
vty_out(vty, "\n");
|
||||
vty_out(vty, BGP_SHOW_SCODE_HEADER);
|
||||
vty_out(vty, BGP_SHOW_NCODE_HEADER);
|
||||
vty_out(vty, BGP_SHOW_OCODE_HEADER);
|
||||
if (type == bgp_show_type_dampend_paths
|
||||
|| type == bgp_show_type_damp_neighbor)
|
||||
@ -10146,9 +10264,15 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
|
||||
"0.0.0.0");
|
||||
} else {
|
||||
vty_out(vty, "BGP table version is %" PRIu64
|
||||
", local router ID is %s\n",
|
||||
", local router ID is %s, vrf id ",
|
||||
table->version, inet_ntoa(bgp->router_id));
|
||||
if (bgp->vrf_id == VRF_UNKNOWN)
|
||||
vty_out(vty, "%s", VRFID_NONE_STR);
|
||||
else
|
||||
vty_out(vty, "%u", bgp->vrf_id);
|
||||
vty_out(vty, "\n");
|
||||
vty_out(vty, BGP_SHOW_SCODE_HEADER);
|
||||
vty_out(vty, BGP_SHOW_NCODE_HEADER);
|
||||
vty_out(vty, BGP_SHOW_OCODE_HEADER);
|
||||
|
||||
vty_out(vty, "Originating default network 0.0.0.0\n\n");
|
||||
@ -10179,11 +10303,20 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
|
||||
json_ocode);
|
||||
} else {
|
||||
vty_out(vty,
|
||||
"BGP table version is 0, local router ID is %s\n",
|
||||
"BGP table version is 0, local router ID is %s, vrf id ",
|
||||
inet_ntoa(
|
||||
bgp->router_id));
|
||||
bgp->router_id));
|
||||
if (bgp->vrf_id == VRF_UNKNOWN)
|
||||
vty_out(vty, "%s",
|
||||
VRFID_NONE_STR);
|
||||
else
|
||||
vty_out(vty, "%u",
|
||||
bgp->vrf_id);
|
||||
vty_out(vty, "\n");
|
||||
vty_out(vty,
|
||||
BGP_SHOW_SCODE_HEADER);
|
||||
vty_out(vty,
|
||||
BGP_SHOW_NCODE_HEADER);
|
||||
vty_out(vty,
|
||||
BGP_SHOW_OCODE_HEADER);
|
||||
}
|
||||
@ -10237,12 +10370,24 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
|
||||
} else {
|
||||
vty_out(vty,
|
||||
"BGP table version is %" PRIu64
|
||||
", local router ID is %s\n",
|
||||
", local router ID is %s, vrf id ",
|
||||
table->version,
|
||||
inet_ntoa(
|
||||
bgp->router_id));
|
||||
if (bgp->vrf_id ==
|
||||
VRF_UNKNOWN)
|
||||
vty_out(vty,
|
||||
"%s",
|
||||
VRFID_NONE_STR);
|
||||
else
|
||||
vty_out(vty,
|
||||
"%u",
|
||||
bgp->vrf_id);
|
||||
vty_out(vty, "\n");
|
||||
vty_out(vty,
|
||||
BGP_SHOW_SCODE_HEADER);
|
||||
vty_out(vty,
|
||||
BGP_SHOW_NCODE_HEADER);
|
||||
vty_out(vty,
|
||||
BGP_SHOW_OCODE_HEADER);
|
||||
}
|
||||
|
@ -54,10 +54,11 @@ enum bgp_show_type {
|
||||
|
||||
|
||||
#define BGP_SHOW_SCODE_HEADER \
|
||||
"Status codes: s suppressed, d damped, " \
|
||||
"Status codes: s suppressed, d damped, " \
|
||||
"h history, * valid, > best, = multipath,\n" \
|
||||
" i internal, r RIB-failure, S Stale, R Removed\n"
|
||||
#define BGP_SHOW_OCODE_HEADER "Origin codes: i - IGP, e - EGP, ? - incomplete\n\n"
|
||||
" i internal, r RIB-failure, S Stale, R Removed\n"
|
||||
#define BGP_SHOW_OCODE_HEADER "Origin codes: i - IGP, e - EGP, ? - incomplete\n\n"
|
||||
#define BGP_SHOW_NCODE_HEADER "Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self\n"
|
||||
#define BGP_SHOW_HEADER " Network Next Hop Metric LocPrf Weight Path\n"
|
||||
|
||||
/* Maximum number of labels we can process or send with a prefix. We
|
||||
|
Loading…
Reference in New Issue
Block a user