From: Daniel Walton <[email protected]>

Paths with global and link-local nexthops should be considered for multipath

Signed-off-by: Daniel Walton <[email protected]>
---
 bgpd/bgp_mpath.c | 55 ++++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 38 insertions(+), 17 deletions(-)

diff --git a/bgpd/bgp_mpath.c b/bgpd/bgp_mpath.c
index 5590b05..92532f7 100644
--- a/bgpd/bgp_mpath.c
+++ b/bgpd/bgp_mpath.c
@@ -113,29 +113,50 @@ bgp_info_nexthop_cmp (struct bgp_info *bi1, struct 
bgp_info *bi2)
 
   compare = IPV4_ADDR_CMP (&bi1->attr->nexthop, &bi2->attr->nexthop);
 
-  if (!compare && ae1 && ae2 && (ae1->mp_nexthop_len == ae2->mp_nexthop_len))
+  if (!compare && ae1 && ae2)
     {
-      switch (ae1->mp_nexthop_len)
+      if (ae1->mp_nexthop_len == ae2->mp_nexthop_len)
         {
-        case 4:
-        case 12:
-          compare = IPV4_ADDR_CMP (&ae1->mp_nexthop_global_in,
-                                   &ae2->mp_nexthop_global_in);
-          break;
+          switch (ae1->mp_nexthop_len)
+            {
+            case 4:
+            case 12:
+              compare = IPV4_ADDR_CMP (&ae1->mp_nexthop_global_in,
+                                       &ae2->mp_nexthop_global_in);
+              break;
 #ifdef HAVE_IPV6
-        case 16:
-          compare = IPV6_ADDR_CMP (&ae1->mp_nexthop_global,
-                                   &ae2->mp_nexthop_global);
-          break;
-        case 32:
+            case 16:
+              compare = IPV6_ADDR_CMP (&ae1->mp_nexthop_global,
+                                       &ae2->mp_nexthop_global);
+              break;
+            case 32:
+              compare = IPV6_ADDR_CMP (&ae1->mp_nexthop_global,
+                                       &ae2->mp_nexthop_global);
+              if (!compare)
+                compare = IPV6_ADDR_CMP (&ae1->mp_nexthop_local,
+                                         &ae2->mp_nexthop_local);
+              break;
+#endif /* HAVE_IPV6 */
+            }
+        }
+
+#ifdef HAVE_IPV6
+      /* This can happen if one IPv6 peer sends you global and link-local
+       * nexthops but another IPv6 peer only sends you global
+       */
+      else if (ae1->mp_nexthop_len == 16 || ae1->mp_nexthop_len == 32)
+        {
           compare = IPV6_ADDR_CMP (&ae1->mp_nexthop_global,
                                    &ae2->mp_nexthop_global);
           if (!compare)
-            compare = IPV6_ADDR_CMP (&ae1->mp_nexthop_local,
-                                     &ae2->mp_nexthop_local);
-          break;
-#endif /* HAVE_IPV6 */
+            {
+              if (ae1->mp_nexthop_len < ae2->mp_nexthop_len)
+                compare = -1;
+              else
+                compare = 1;
+            }
         }
+#endif /* HAVE_IPV6 */
     }
 
   return compare;
@@ -403,7 +424,7 @@ bgp_info_mpath_update (struct bgp_node *rn, struct bgp_info 
*new_best,
   struct listnode *mp_node, *mp_next_node;
   struct bgp_info *cur_mpath, *new_mpath, *next_mpath, *prev_mpath;
   int mpath_changed, debug;
-  char pfx_buf[INET_ADDRSTRLEN], nh_buf[2][INET_ADDRSTRLEN];
+  char pfx_buf[INET6_ADDRSTRLEN], nh_buf[2][INET6_ADDRSTRLEN];
 
   mpath_changed = 0;
   maxpaths = BGP_DEFAULT_MAXPATHS;
-- 
1.9.1


_______________________________________________
Quagga-dev mailing list
[email protected]
https://lists.quagga.net/mailman/listinfo/quagga-dev

Reply via email to