summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_route.c
diff options
context:
space:
mode:
authorG. Paul Ziemba <paulz@labn.net>2018-04-09 22:28:11 +0200
committerG. Paul Ziemba <paulz@labn.net>2018-04-28 02:34:43 +0200
commit9df8b37c72854fc965c452d17ef38bf4aae8dfee (patch)
tree71c930db8c2329a2dafc4817cd49f75ffeabd679 /bgpd/bgp_route.c
parentMerge pull request #2125 from qlyoung/fix-gcc-build-command-graph (diff)
downloadfrr-9df8b37c72854fc965c452d17ef38bf4aae8dfee.tar.xz
frr-9df8b37c72854fc965c452d17ef38bf4aae8dfee.zip
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>
Diffstat (limited to 'bgpd/bgp_route.c')
-rw-r--r--bgpd/bgp_route.c173
1 files changed, 159 insertions, 14 deletions
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 90fa39b44..299486128 100644
--- a/bgpd/bgp_route.c
+++ b/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();
@@ -6500,6 +6509,39 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo,
}
/*
+ * 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.
* Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
@@ -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)
@@ -6734,6 +6785,21 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo,
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,12 +10303,21 @@ 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);
}
header1 = 0;
@@ -10237,13 +10370,25 @@ 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);
}
header1 = 0;