]> git.proxmox.com Git - mirror_frr.git/commitdiff
bgpd: when showing routes, add nexthop vrf and announce-self flag
authorG. Paul Ziemba <paulz@labn.net>
Mon, 9 Apr 2018 20:28:11 +0000 (13:28 -0700)
committerG. Paul Ziemba <paulz@labn.net>
Sat, 28 Apr 2018 00:34:43 +0000 (17:34 -0700)
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>
bgpd/bgp_route.c
bgpd/bgp_route.h

index 90fa39b44543ba50eff6f4a4769359c25f6003ba..299486128c8c2bcfc12dd20d8818ddde057d8088 100644 (file)
@@ -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);
                                                }
index 1e788b00f163daa12e6ac452839a56d925bd7068..89b8eb70cd1475932d16369afba521751831f505 100644 (file)
@@ -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