]> git.puffer.fish Git - mirror/frr.git/commitdiff
Allow for more than 1 NH recursion level
authorßingen <bingen@voltanet.io>
Tue, 27 Jun 2017 10:49:49 +0000 (12:49 +0200)
committerßingen <bingen@voltanet.io>
Wed, 28 Jun 2017 19:32:18 +0000 (21:32 +0200)
Before, only one level of recursive resolution was supported.

Signed-off-by: ßingen <bingen@voltanet.io>
lib/nexthop.c
lib/nexthop.h
tests/lib/test_nexthop_iter.c
zebra/rib.h
zebra/rt_netlink.c
zebra/rt_socket.c
zebra/zebra_fpm_netlink.c
zebra/zebra_rib.c
zebra/zebra_rnh.c
zebra/zebra_vty.c

index 725b52c0529a0686bb3ca57c00c3e08517a80f25..948baca1985d23543a38da63694c0c4c19d72a02 100644 (file)
@@ -135,7 +135,7 @@ nexthop_add (struct nexthop **target, struct nexthop *nexthop)
 }
 
 void
-copy_nexthops (struct nexthop **tnh, struct nexthop *nh)
+copy_nexthops (struct nexthop **tnh, struct nexthop *nh, struct nexthop *rparent)
 {
   struct nexthop *nexthop;
   struct nexthop *nh1;
@@ -150,11 +150,12 @@ copy_nexthops (struct nexthop **tnh, struct nexthop *nh)
       memcpy(&(nexthop->src), &(nh->src), sizeof(union g_addr));
       if (nh->nh_label)
         nexthop_add_labels (nexthop, nh->nh_label_type,
-                           nh->nh_label->num_labels, &nh->nh_label->label[0]);
+                nh->nh_label->num_labels, &nh->nh_label->label[0]);
+      nexthop->rparent = rparent;
       nexthop_add(tnh, nexthop);
 
       if (CHECK_FLAG(nh1->flags, NEXTHOP_FLAG_RECURSIVE))
-       copy_nexthops(&nexthop->resolved, nh1->resolved);
+        copy_nexthops(&nexthop->resolved, nh1->resolved, nexthop);
     }
 }
 
index 8c9c801c91eb244e8f9ae0f0f3e99b9da261cb95..f48c41dc55d256088d19f9d20bc508022df7f4ac 100644 (file)
@@ -81,8 +81,10 @@ struct nexthop
    * If the nexthop struct needs to be resolved recursively,
    * NEXTHOP_FLAG_RECURSIVE will be set in flags and the nexthops
    * obtained by recursive resolution will be added to `resolved'.
-   * Only one level of recursive resolution is currently supported. */
+   */
   struct nexthop *resolved;
+  /* Recursive parent */
+  struct nexthop *rparent;
 
   /* Type of label(s), if any */
   enum lsp_types_t nh_label_type;
@@ -107,7 +109,7 @@ nh_resolve_via_default(int family)
 struct nexthop *nexthop_new (void);
 void nexthop_add (struct nexthop **target, struct nexthop *nexthop);
 
-void copy_nexthops (struct nexthop **tnh, struct nexthop *nh);
+void copy_nexthops (struct nexthop **tnh, struct nexthop *nh, struct nexthop *rparent);
 void nexthop_free (struct nexthop *nexthop);
 void nexthops_free (struct nexthop *nexthop);
 
index 77515386c7e8248c1a423ecac278a742a233ac33..6c8ffb8da189f4bfa62a1ae87f8740438d9f6f76 100644 (file)
@@ -173,13 +173,12 @@ nexthop_chain_free(struct nexthop_chain *nc)
 static void
 nexthop_chain_verify_iter(struct nexthop_chain *nc)
 {
-  struct nexthop *nh, *tnh;
-  int recursing;
+  struct nexthop *nh;
   char *repr = NULL;
 
-  for (ALL_NEXTHOPS_RO(nc->head, nh, tnh, recursing))
+  for (ALL_NEXTHOPS_RO(nc->head, nh))
     {
-      if (recursing)
+      if (nh->rparent)
         str_appendf(&repr, "  %p\n", nh);
       else
         str_appendf(&repr, "%p\n", nh);
index 88f2bf39abc24e25a81af7fdcc59aa081cd9307f..e4e2c454864d5b709c3e0fde8e04f9cdc7727244 100644 (file)
@@ -197,32 +197,24 @@ typedef struct rib_dest_t_
  * Iteration check: Check that the `nexthop' pointer is not NULL.
  *
  * Iteration step: This is the tricky part. Check if `nexthop' has
- * NEXTHOP_FLAG_RECURSIVE set. If yes, this implies that `nexthop' is in
- * the top level chain and has at least one nexthop attached to
- * `nexthop->resolved'. As we want to descend into `nexthop->resolved',
- * set `recursing' to 1 and set `nexthop' to `nexthop->resolved'.
- * `tnexthop' is left alone in that case so we can remember which nexthop
- * in the top level chain we are currently handling.
+ * NEXTHOP_FLAG_RECURSIVE set. If yes, this implies that `nexthop' has
+ * at least one nexthop attached to `nexthop->resolved'.
  *
  * If NEXTHOP_FLAG_RECURSIVE is not set, `nexthop' will progress in its
- * current chain. If we are recursing, `nexthop' will be set to
- * `nexthop->next' and `tnexthop' will be left alone. If we are not
- * recursing, both `tnexthop' and `nexthop' will be set to `nexthop->next'
- * as we are progressing in the top level chain.
- *   If we encounter `nexthop->next == NULL', we will clear the `recursing'
- * flag as we arived either at the end of the resolved chain or at the end
- * of the top level chain. In both cases, we set `tnexthop' and `nexthop'
- * to `tnexthop->next', progressing to the next position in the top-level
- * chain and possibly to its end marked by NULL.
+ * current chain. In case its current chain end is reached, it will try
+ * to get up to the previous recursion level and progress there. Whenever
+ * a step forward in a chain is done, recursion will be checked again.
+ * In a nustshell, it's equivalent to a pre-traversal order assuming that
+ * left branch is 'resolved' and right branch is 'next':
+ * https://en.wikipedia.org/wiki/Tree_traversal#/media/File:Sorted_binary_tree_preorder.svg
  */
-#define ALL_NEXTHOPS_RO(head, nexthop, tnexthop, recursing) \
-  (tnexthop) = (nexthop) = (head), (recursing) = 0; \
-  (nexthop); \
-  (nexthop) = CHECK_FLAG((nexthop)->flags, NEXTHOP_FLAG_RECURSIVE) \
-    ? (((recursing) = 1), (nexthop)->resolved) \
-    : ((nexthop)->next ? ((recursing) ? (nexthop)->next \
-                                      : ((tnexthop) = (nexthop)->next)) \
-                       : (((recursing) = 0),((tnexthop) = (tnexthop)->next)))
+#define ALL_NEXTHOPS_RO(head, nexthop)                              \
+  (nexthop) = (head);                                               \
+  (nexthop);                                                        \
+  (nexthop) = CHECK_FLAG((nexthop)->flags, NEXTHOP_FLAG_RECURSIVE)  \
+    ? ((nexthop)->resolved)                                         \
+       : ((nexthop)->next ? (nexthop)->next                         \
+          : ((nexthop)->rparent ? (nexthop)->rparent->next : NULL))
 
 #if defined (HAVE_RTADV)
 /* Structure which hold status of router advertisement. */
index 0adbe2c27f8e2fb72f9f4f029b6ffc51c3d70765..87ead20e863739c6f9030a58ebd3d4a75e8542b3 100644 (file)
@@ -1190,8 +1190,7 @@ netlink_route_multipath (int cmd, struct prefix *p, struct prefix *src_p,
 {
   int bytelen;
   struct sockaddr_nl snl;
-  struct nexthop *nexthop = NULL, *tnexthop;
-  int recursing;
+  struct nexthop *nexthop = NULL;
   unsigned int nexthop_num;
   int discard;
   int family = PREFIX_FAMILY(p);
@@ -1283,7 +1282,7 @@ netlink_route_multipath (int cmd, struct prefix *p, struct prefix *src_p,
   if (discard)
     {
       if (cmd == RTM_NEWROUTE)
-        for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
+        for (ALL_NEXTHOPS_RO(re->nexthop, nexthop))
           {
             /* We shouldn't encounter recursive nexthops on discard routes,
              * but it is probably better to handle that case correctly anyway.
@@ -1297,7 +1296,7 @@ netlink_route_multipath (int cmd, struct prefix *p, struct prefix *src_p,
   /* Count overall nexthops so we can decide whether to use singlepath
    * or multipath case. */
   nexthop_num = 0;
-  for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
+  for (ALL_NEXTHOPS_RO(re->nexthop, nexthop))
     {
       if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
         continue;
@@ -1313,7 +1312,7 @@ netlink_route_multipath (int cmd, struct prefix *p, struct prefix *src_p,
   if (nexthop_num == 1 || multipath_num == 1)
     {
       nexthop_num = 0;
-      for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
+      for (ALL_NEXTHOPS_RO(re->nexthop, nexthop))
         {
           if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
             {
@@ -1354,7 +1353,7 @@ netlink_route_multipath (int cmd, struct prefix *p, struct prefix *src_p,
               || (cmd == RTM_DELROUTE
                   && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)))
             {
-              routedesc = recursing ? "recursive, 1 hop" : "single hop";
+              routedesc = nexthop->rparent ? "recursive, 1 hop" : "single hop";
 
               _netlink_route_debug(cmd, p, nexthop, routedesc, family, zvrf);
               _netlink_route_build_singlepath(routedesc, bytelen,
@@ -1384,7 +1383,7 @@ netlink_route_multipath (int cmd, struct prefix *p, struct prefix *src_p,
       rtnh = RTA_DATA (rta);
 
       nexthop_num = 0;
-      for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
+      for (ALL_NEXTHOPS_RO(re->nexthop, nexthop))
         {
           if (nexthop_num >= multipath_num)
             break;
@@ -1429,7 +1428,7 @@ netlink_route_multipath (int cmd, struct prefix *p, struct prefix *src_p,
               || (cmd == RTM_DELROUTE
                   && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)))
             {
-              routedesc = recursing ? "recursive, multihop" : "multihop";
+              routedesc = nexthop->rparent ? "recursive, multihop" : "multihop";
               nexthop_num++;
 
               _netlink_route_debug(cmd, p, nexthop,
index 9859a31627ee07d2367e0a14176072a747498101..caf4da257935677a02e1d1eeb836fee70f2ba70a 100644 (file)
@@ -80,8 +80,7 @@ kernel_rtm_ipv4 (int cmd, struct prefix *p, struct route_entry *re)
   struct sockaddr_mpls smpls;
 #endif
   union sockunion *smplsp = NULL;
-  struct nexthop *nexthop, *tnexthop;
-  int recursing;
+  struct nexthop *nexthop;
   int nexthop_num = 0;
   ifindex_t ifindex = 0;
   int gate = 0;
@@ -106,7 +105,7 @@ kernel_rtm_ipv4 (int cmd, struct prefix *p, struct route_entry *re)
 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
 
   /* Make gateway. */
-  for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
+  for (ALL_NEXTHOPS_RO(re->nexthop, nexthop))
     {
       if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
         continue;
@@ -266,8 +265,7 @@ kernel_rtm_ipv6 (int cmd, struct prefix *p, struct route_entry *re)
 {
   struct sockaddr_in6 *mask;
   struct sockaddr_in6 sin_dest, sin_mask, sin_gate;
-  struct nexthop *nexthop, *tnexthop;
-  int recursing;
+  struct nexthop *nexthop;
   int nexthop_num = 0;
   ifindex_t ifindex = 0;
   int gate = 0;
@@ -289,7 +287,7 @@ kernel_rtm_ipv6 (int cmd, struct prefix *p, struct route_entry *re)
 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
 
   /* Make gateway. */
-  for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
+  for (ALL_NEXTHOPS_RO(re->nexthop, nexthop))
     {
       if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
        continue;
index c5647debc3cd45054bc8b868ba2bde1f5b0210f9..a6c526ee6cec4f2bc473d8cd57fbb1a24fa237f2 100644 (file)
@@ -233,8 +233,7 @@ static int
 netlink_route_info_fill (netlink_route_info_t *ri, int cmd,
                         rib_dest_t *dest, struct route_entry *re)
 {
-  struct nexthop *nexthop, *tnexthop;
-  int recursing;
+  struct nexthop *nexthop;
   int discard;
 
   memset (ri, 0, sizeof (*ri));
@@ -286,7 +285,7 @@ netlink_route_info_fill (netlink_route_info_t *ri, int cmd,
   if (discard)
     return 1;
 
-  for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
+  for (ALL_NEXTHOPS_RO(re->nexthop, nexthop))
     {
       if (ri->num_nhs >= multipath_num)
         break;
@@ -299,7 +298,7 @@ netlink_route_info_fill (netlink_route_info_t *ri, int cmd,
           || (cmd == RTM_DELROUTE
               && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)))
         {
-          netlink_route_info_add_nh (ri, nexthop, recursing);
+          netlink_route_info_add_nh (ri, nexthop, (nexthop->rparent ? 1 : 0));
         }
     }
 
index c2af0a0d2250e8f2813e19c5f4a0e52e6540c64d..eed21254832fbc34199a012e48a2bc9b2e8743db 100644 (file)
@@ -209,9 +209,10 @@ route_entry_copy_nexthops (struct route_entry *re, struct nexthop *nh)
   if (nh->nh_label)
     nexthop_add_labels (nexthop, nh->nh_label_type, nh->nh_label->num_labels,
                         &nh->nh_label->label[0]);
+  nexthop->rparent = NULL;
   route_entry_nexthop_add(re, nexthop);
   if (CHECK_FLAG(nh->flags, NEXTHOP_FLAG_RECURSIVE))
-    copy_nexthops(&nexthop->resolved, nh->resolved);
+    copy_nexthops(&nexthop->resolved, nh->resolved, nexthop);
 }
 
 /* Delete specified nexthop from the list. */
@@ -389,6 +390,7 @@ nexthop_set_resolved (afi_t afi, struct nexthop *newhop, struct nexthop *nexthop
       resolved_hop->ifindex = newhop->ifindex;
     }
 
+  resolved_hop->rparent = nexthop;
   nexthop_add(&nexthop->resolved, resolved_hop);
 }
 
@@ -403,8 +405,7 @@ nexthop_active (afi_t afi, struct route_entry *re, struct nexthop *nexthop, int
   struct route_node *rn;
   struct route_entry *match;
   int resolved;
-  struct nexthop *newhop, *tnewhop;
-  int recursing = 0;
+  struct nexthop *newhop;
   struct interface *ifp;
 
   if ((nexthop->type == NEXTHOP_TYPE_IPV4) || nexthop->type == NEXTHOP_TYPE_IPV6)
@@ -528,7 +529,7 @@ nexthop_active (afi_t afi, struct route_entry *re, struct nexthop *nexthop, int
       else if (CHECK_FLAG (re->flags, ZEBRA_FLAG_INTERNAL))
        {
          resolved = 0;
-         for (newhop = match->nexthop; newhop; newhop = newhop->next)
+         for (ALL_NEXTHOPS_RO(match->nexthop, newhop))
            if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
                && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
              {
@@ -546,7 +547,7 @@ nexthop_active (afi_t afi, struct route_entry *re, struct nexthop *nexthop, int
       else if (re->type == ZEBRA_ROUTE_STATIC)
        {
          resolved = 0;
-         for (ALL_NEXTHOPS_RO(match->nexthop, newhop, tnewhop, recursing))
+         for (ALL_NEXTHOPS_RO(match->nexthop, newhop))
            if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
              {
                if (set)
@@ -577,8 +578,7 @@ rib_match (afi_t afi, safi_t safi, vrf_id_t vrf_id,
   struct route_table *table;
   struct route_node *rn;
   struct route_entry *match;
-  struct nexthop *newhop, *tnewhop;
-  int recursing;
+  struct nexthop *newhop;
 
   /* Lookup table.  */
   table = zebra_vrf_table (afi, safi, vrf_id);
@@ -628,7 +628,7 @@ rib_match (afi_t afi, safi_t safi, vrf_id_t vrf_id,
          if (match->type != ZEBRA_ROUTE_CONNECT)
            {
              int found = 0;
-             for (ALL_NEXTHOPS_RO(match->nexthop, newhop, tnewhop, recursing))
+             for (ALL_NEXTHOPS_RO(match->nexthop, newhop))
                if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
                  {
                    found = 1;
@@ -724,8 +724,7 @@ rib_lookup_ipv4 (struct prefix_ipv4 *p, vrf_id_t vrf_id)
   struct route_table *table;
   struct route_node *rn;
   struct route_entry *match;
-  struct nexthop *nexthop, *tnexthop;
-  int recursing;
+  struct nexthop *nexthop;
 
   /* Lookup table.  */
   table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
@@ -754,8 +753,8 @@ rib_lookup_ipv4 (struct prefix_ipv4 *p, vrf_id_t vrf_id)
 
   if (match->type == ZEBRA_ROUTE_CONNECT)
     return match;
-  
-  for (ALL_NEXTHOPS_RO(match->nexthop, nexthop, tnexthop, recursing))
+
+  for (ALL_NEXTHOPS_RO(match->nexthop, nexthop))
     if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
       return match;
 
@@ -781,8 +780,7 @@ rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate,
   struct route_table *table;
   struct route_node *rn;
   struct route_entry *match;
-  struct nexthop *nexthop, *tnexthop;
-  int recursing;
+  struct nexthop *nexthop;
   int nexthops_active;
 
   /* Lookup table.  */
@@ -818,7 +816,7 @@ rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate,
   
   /* Ok, we have a cood candidate, let's check it's nexthop list... */
   nexthops_active = 0;
-  for (ALL_NEXTHOPS_RO(match->nexthop, nexthop, tnexthop, recursing))
+  for (ALL_NEXTHOPS_RO(match->nexthop, nexthop))
     if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
       {
         nexthops_active = 1;
@@ -830,7 +828,7 @@ rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate,
             inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, gate_buf, INET_ADDRSTRLEN);
             inet_ntop (AF_INET, &sockunion2ip(qgate), qgate_buf, INET_ADDRSTRLEN);
             zlog_debug ("%s: qgate == %s, %s == %s", __func__,
-                        qgate_buf, recursing ? "rgate" : "gate", gate_buf);
+                        qgate_buf, nexthop->rparent ? "rgate" : "gate", gate_buf);
           }
       }
 
@@ -1025,13 +1023,12 @@ nexthop_active_update (struct route_node *rn, struct route_entry *re, int set)
 int
 zebra_rib_labeled_unicast (struct route_entry *re)
 {
-  struct nexthop *nexthop = NULL, *tnexthop;
-  int recursing;
+  struct nexthop *nexthop = NULL;
 
   if (re->type != ZEBRA_ROUTE_BGP)
     return 0;
 
-  for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
+  for (ALL_NEXTHOPS_RO(re->nexthop, nexthop))
     if (!nexthop->nh_label || !nexthop->nh_label->num_labels)
       return 0;
 
@@ -1045,9 +1042,8 @@ int
 rib_install_kernel (struct route_node *rn, struct route_entry *re, struct route_entry *old)
 {
   int ret = 0;
-  struct nexthop *nexthop, *tnexthop;
+  struct nexthop *nexthop;
   rib_table_info_t *info = srcdest_rnode_table_info(rn);
-  int recursing;
   struct prefix *p, *src_p;
   struct zebra_vrf *zvrf = vrf_info_lookup (re->vrf_id);
 
@@ -1055,7 +1051,7 @@ rib_install_kernel (struct route_node *rn, struct route_entry *re, struct route_
 
   if (info->safi != SAFI_UNICAST)
     {
-      for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
+      for (ALL_NEXTHOPS_RO(re->nexthop, nexthop))
         SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
       return ret;
     }
@@ -1071,7 +1067,7 @@ rib_install_kernel (struct route_node *rn, struct route_entry *re, struct route_
   /* If install succeeds, update FIB flag for nexthops. */
   if (!ret)
     {
-      for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
+      for (ALL_NEXTHOPS_RO(re->nexthop, nexthop))
         {
           if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
             continue;
@@ -1091,9 +1087,8 @@ int
 rib_uninstall_kernel (struct route_node *rn, struct route_entry *re)
 {
   int ret = 0;
-  struct nexthop *nexthop, *tnexthop;
+  struct nexthop *nexthop;
   rib_table_info_t *info = srcdest_rnode_table_info(rn);
-  int recursing;
   struct prefix *p, *src_p;
   struct zebra_vrf *zvrf = vrf_info_lookup (re->vrf_id);
 
@@ -1101,7 +1096,7 @@ rib_uninstall_kernel (struct route_node *rn, struct route_entry *re)
 
   if (info->safi != SAFI_UNICAST)
     {
-      for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
+      for (ALL_NEXTHOPS_RO(re->nexthop, nexthop))
         SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
       return ret;
     }
@@ -1114,7 +1109,7 @@ rib_uninstall_kernel (struct route_node *rn, struct route_entry *re)
   ret = kernel_route_rib (p, src_p, re, NULL);
   zvrf->removals++;
 
-  for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
+  for (ALL_NEXTHOPS_RO(re->nexthop, nexthop))
     UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
 
   return ret;
@@ -1284,8 +1279,7 @@ static void
 rib_process_update_fib (struct zebra_vrf *zvrf, struct route_node *rn,
                         struct route_entry *old, struct route_entry *new)
 {
-  struct nexthop *nexthop = NULL, *tnexthop;
-  int recursing;
+  struct nexthop *nexthop = NULL;
   int nh_active = 0;
   int installed = 1;
 
@@ -1403,7 +1397,7 @@ rib_process_update_fib (struct zebra_vrf *zvrf, struct route_node *rn,
         {
           int in_fib = 0;
 
-          for (ALL_NEXTHOPS_RO(new->nexthop, nexthop, tnexthop, recursing))
+          for (ALL_NEXTHOPS_RO(new->nexthop, nexthop))
             if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
               {
                 in_fib = 1;
@@ -1634,13 +1628,11 @@ rib_process (struct route_node *rn)
   /* Redistribute SELECTED entry */
   if (old_selected != new_selected || selected_changed)
     {
-      struct nexthop *nexthop, *tnexthop;
-      int recursing;
+      struct nexthop *nexthop;
 
       /* Check if we have a FIB route for the destination, otherwise,
        * don't redistribute it */
-      for (ALL_NEXTHOPS_RO(new_fib ? new_fib->nexthop : NULL, nexthop,
-                           tnexthop, recursing))
+      for (ALL_NEXTHOPS_RO(new_fib ? new_fib->nexthop : NULL, nexthop))
         {
           if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB))
             {
@@ -2141,8 +2133,7 @@ void _route_entry_dump (const char * func,
   bool is_srcdst = src_p && src_p->prefixlen;
   char straddr[PREFIX_STRLEN];
   char srcaddr[PREFIX_STRLEN];
-  struct nexthop *nexthop, *tnexthop;
-  int recursing;
+  struct nexthop *nexthop;
 
   zlog_debug ("%s: dumping RE entry %p for %s%s%s vrf %u", func, (const void *)re,
               prefix2str(pp, straddr, sizeof(straddr)),
@@ -2177,14 +2168,14 @@ void _route_entry_dump (const char * func,
     re->nexthop_active_num
   );
 
-  for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
+  for (ALL_NEXTHOPS_RO(re->nexthop, nexthop))
     {
       inet_ntop (p->family, &nexthop->gate, straddr, INET6_ADDRSTRLEN);
       zlog_debug
       (
         "%s: %s %s with flags %s%s%s",
         func,
-        (recursing ? "  NH" : "NH"),
+        (nexthop->rparent ? "  NH" : "NH"),
         straddr,
         (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE) ? "ACTIVE " : ""),
         (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? "FIB " : ""),
@@ -2391,8 +2382,7 @@ rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance,
   struct route_entry *re;
   struct route_entry *fib = NULL;
   struct route_entry *same = NULL;
-  struct nexthop *nexthop, *tnexthop;
-  int recursing;
+  struct nexthop *nexthop;
   char buf2[INET6_ADDRSTRLEN];
 
   assert(!src_p || afi == AFI_IP6);
@@ -2463,7 +2453,7 @@ rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance,
               same = re;
               break;
             }
-          for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
+          for (ALL_NEXTHOPS_RO(re->nexthop, nexthop))
             if (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate) ||
                IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate))
               {
index 66b1cc78ca6e57d1a44bf847aca19ad518ef93a3..352ac4f4cffd14f9b3a37adca437290d6da7416f 100644 (file)
@@ -420,12 +420,11 @@ zebra_rnh_eval_import_check_entry (vrf_id_t vrfid, int family, int force,
   struct zserv *client;
   char bufn[INET6_ADDRSTRLEN];
   struct listnode *node;
-  struct nexthop *nexthop, *tnexthop;
-  int recursing;
+  struct nexthop *nexthop;
 
   if (re && (rnh->state == NULL))
     {
-      for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
+      for (ALL_NEXTHOPS_RO(re->nexthop, nexthop))
         if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
           {
             state_changed = 1;
index 88778e491ba96764e649e0294e86c25d85b2830e..a19859440a9ccc738f0e22918f3e95279f96d513 100644 (file)
@@ -648,8 +648,7 @@ static void
 vty_show_ip_route_detail (struct vty *vty, struct route_node *rn, int mcast)
 {
   struct route_entry *re;
-  struct nexthop *nexthop, *tnexthop;
-  int recursing;
+  struct nexthop *nexthop;
   char buf[SRCDEST2STR_BUFFER];
   struct zebra_vrf *zvrf;
 
@@ -720,13 +719,13 @@ vty_show_ip_route_detail (struct vty *vty, struct route_node *rn, int mcast)
          vty_out (vty, " ago%s", VTY_NEWLINE);
        }
 
-      for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
-       {
+      for (ALL_NEXTHOPS_RO(re->nexthop, nexthop))
+    {
           char addrstr[32];
 
          vty_out (vty, "  %c%s",
-                  CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? '*' : ' ',
-                  recursing ? "  " : "");
+              CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? '*' : ' ',
+              nexthop->rparent ? "  " : "");
 
          switch (nexthop->type)
            {
@@ -806,8 +805,7 @@ static void
 vty_show_ip_route (struct vty *vty, struct route_node *rn, struct route_entry *re,
                    json_object *json)
 {
-  struct nexthop *nexthop, *tnexthop;
-  int recursing;
+  struct nexthop *nexthop;
   int len = 0;
   char buf[SRCDEST2STR_BUFFER];
   json_object *json_nexthops = NULL;
@@ -868,7 +866,7 @@ vty_show_ip_route (struct vty *vty, struct route_node *rn, struct route_entry *r
           json_object_string_add(json_route, "uptime", buf);
         }
 
-      for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
+      for (ALL_NEXTHOPS_RO(re->nexthop, nexthop))
         {
           json_nexthop = json_object_new_object();
 
@@ -962,7 +960,7 @@ vty_show_ip_route (struct vty *vty, struct route_node *rn, struct route_entry *r
     }
 
   /* Nexthop information. */
-  for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
+  for (ALL_NEXTHOPS_RO(re->nexthop, nexthop))
     {
       if (nexthop == re->nexthop)
        {
@@ -985,9 +983,9 @@ vty_show_ip_route (struct vty *vty, struct route_node *rn, struct route_entry *r
        }
       else
        vty_out (vty, "  %c%*c",
-                CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
-                ? '*' : ' ',
-                len - 3 + (2 * recursing), ' ');
+            CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
+            ? '*' : ' ',
+            len - 3 + (2 * (nexthop->rparent ? 1 : 0)), ' ');
 
       switch (nexthop->type)
        {