IP6 forward: Add ND route when next-hop is unknown link local 56/1856/4
authorPierre Pfister <ppfister@cisco.com>
Tue, 5 Jul 2016 14:36:26 +0000 (15:36 +0100)
committerDamjan Marion <dmarion.lists@gmail.com>
Wed, 20 Jul 2016 11:35:37 +0000 (11:35 +0000)
Indirect routes have been recently added. When the next-hop is not known,
an indirect route is automatically installed instead. But it makes no
sense to add an indirect route for a link-local next-hop addresses.

Instead, it may make sense to add an ND entry to the
yet-to-be-met neighbor.

Also corrected some indentation.

Change-Id: Ia83c9cd1feafac742680745e82c6faf9f2e1e536
Signed-off-by: Pierre Pfister <ppfister@cisco.com>
vnet/vnet/ip/ip6_forward.c

index c581a9b..80156e0 100644 (file)
@@ -358,25 +358,36 @@ ip6_route_get_next_hop_adj (ip6_main_t * im,
       kv.key[0] = next_hop->as_u64[0];
       kv.key[1] = next_hop->as_u64[1];
       kv.key[2] = ((u64)((fib - im->fibs))<<32) | 128;
-
+after_nd:
       if (BV(clib_bihash_search)(&im->ip6_lookup_table, &kv, &value) < 0)
         {
-         ip_adjacency_t * adj;
-         nh_adj_index = ip6_fib_lookup_with_table (im, fib_index, next_hop);
-         adj = ip_get_adjacency (lm, nh_adj_index);
-         /* if ND interface adjacencty is present, we need to
-            install ND adjaceny for specific next hop */
-         if (adj->lookup_next_index == IP_LOOKUP_NEXT_ARP &&
-             adj->arp.next_hop.ip6.as_u64[0] == 0 &&
-             adj->arp.next_hop.ip6.as_u64[1] == 0)
-           {
+          ip_adjacency_t * adj;
+          nh_adj_index = ip6_fib_lookup_with_table (im, fib_index, next_hop);
+          adj = ip_get_adjacency (lm, nh_adj_index);
+          /* if ND interface adjacencty is present, we need to
+           install ND adjaceny for specific next hop */
+          if (adj->lookup_next_index == IP_LOOKUP_NEXT_ARP &&
+              adj->arp.next_hop.ip6.as_u64[0] == 0 &&
+              adj->arp.next_hop.ip6.as_u64[1] == 0)
+            {
               nh_adj_index = vnet_ip6_neighbor_glean_add(fib_index, next_hop);
-           }
-       }
+            }
+          else if (next_hop->as_u8[0] == 0xfe)
+            {
+              //Next hop is link-local. No indirect in this case.
+              //Let's add it as a possible neighbor on this interface
+              ip6_address_t null_addr= {};
+              ip6_add_del_route_next_hop (im, IP6_ROUTE_FLAG_ADD,
+                                          next_hop, 128,
+                                          &null_addr, next_hop_sw_if_index,
+                                          1, ~0, fib_index);
+              goto after_nd;
+            }
+        }
       else
         {
-         nh_adj_index = value.value;
-       }
+          nh_adj_index = value.value;
+        }
     }
 
   return (nh_adj_index);