ip: fix probing of already resolved destinations (VPP-998) 08/8608/3
authorFlorin Coras <fcoras@cisco.com>
Sun, 1 Oct 2017 23:18:42 +0000 (19:18 -0400)
committerNeale Ranns <nranns@cisco.com>
Tue, 3 Oct 2017 14:58:12 +0000 (14:58 +0000)
Change-Id: I3e6276e6829dfee5a7aeae1b4ab4c3d2f2e932a4
Signed-off-by: Florin Coras <fcoras@cisco.com>
src/vnet/ethernet/arp.c
src/vnet/ip/ip4_forward.c
src/vnet/ip/ip6_forward.c
src/vnet/ip/ip6_neighbor.c

index 120a276..52b13e0 100644 (file)
@@ -615,7 +615,7 @@ vnet_arp_set_ip4_over_ethernet_internal (vnet_main_t * vnm,
        */
       if (0 == memcmp (e->ethernet_address,
                       a->ethernet, sizeof (e->ethernet_address)))
-       return -1;
+       goto check_customers;
 
       /* Update time stamp and ethernet address. */
       clib_memcpy (e->ethernet_address, a->ethernet,
@@ -630,6 +630,7 @@ vnet_arp_set_ip4_over_ethernet_internal (vnet_main_t * vnm,
 
   adj_nbr_walk_nh4 (sw_if_index, &e->ip4_address, arp_mk_complete_walk, e);
 
+check_customers:
   /* Customer(s) waiting for this address to be resolved? */
   p = hash_get (am->pending_resolutions_by_address, a->ip4.as_u32);
   if (p)
index 0a34497..58cfd18 100755 (executable)
@@ -2257,14 +2257,6 @@ ip4_probe_neighbor (vlib_main_t * vm, ip4_address_t * dst, u32 sw_if_index)
         sw_if_index);
     }
 
-  ip46_address_t nh = {
-    .ip4 = *dst,
-  };
-
-  ai = adj_nbr_add_or_lock (FIB_PROTOCOL_IP4,
-                           VNET_LINK_IP4, &nh, sw_if_index);
-  adj = adj_get (ai);
-
   h = vlib_packet_template_get_packet (vm,
                                       &im->ip4_arp_request_packet_template,
                                       &bi);
@@ -2288,6 +2280,22 @@ ip4_probe_neighbor (vlib_main_t * vm, ip4_address_t * dst, u32 sw_if_index)
   vnet_buffer (b)->sw_if_index[VLIB_RX] =
     vnet_buffer (b)->sw_if_index[VLIB_TX] = sw_if_index;
 
+  ip46_address_t nh = {
+    .ip4 = *dst,
+  };
+
+  ai = adj_nbr_add_or_lock (FIB_PROTOCOL_IP4,
+                           VNET_LINK_IP4, &nh, sw_if_index);
+  adj = adj_get (ai);
+
+  /* Peer has been previously resolved, retrieve glean adj instead */
+  if (adj->lookup_next_index == IP_LOOKUP_NEXT_REWRITE)
+    {
+      adj_unlock (ai);
+      ai = adj_glean_add_or_lock (FIB_PROTOCOL_IP4, sw_if_index, &nh);
+      adj = adj_get (ai);
+    }
+
   /* Add encapsulation string for software interface (e.g. ethernet header). */
   vnet_rewrite_one_header (adj[0], h, sizeof (ethernet_header_t));
   vlib_buffer_advance (b, -adj->rewrite_header.data_bytes);
index bb4893a..54582d3 100644 (file)
@@ -2041,6 +2041,14 @@ ip6_probe_neighbor (vlib_main_t * vm, ip6_address_t * dst, u32 sw_if_index)
                            VNET_LINK_IP6, &nh, sw_if_index);
   adj = adj_get (ai);
 
+  /* Peer has been previously resolved, retrieve glean adj instead */
+  if (adj->lookup_next_index == IP_LOOKUP_NEXT_REWRITE)
+    {
+      adj_unlock (ai);
+      ai = adj_glean_add_or_lock (FIB_PROTOCOL_IP6, sw_if_index, &nh);
+      adj = adj_get (ai);
+    }
+
   vnet_rewrite_one_header (adj[0], h, sizeof (ethernet_header_t));
   vlib_buffer_advance (b, -adj->rewrite_header.data_bytes);
 
index 1908a67..d549ac3 100644 (file)
@@ -723,7 +723,7 @@ vnet_set_ip6_ethernet_neighbor (vlib_main_t * vm,
        */
       if (0 == memcmp (n->link_layer_address,
                       link_layer_address, n_bytes_link_layer_address))
-       return -1;
+       goto check_customers;
 
       clib_memcpy (n->link_layer_address,
                   link_layer_address, n_bytes_link_layer_address);
@@ -739,6 +739,7 @@ vnet_set_ip6_ethernet_neighbor (vlib_main_t * vm,
   adj_nbr_walk_nh6 (sw_if_index,
                    &n->key.ip6_address, ip6_nd_mk_complete_walk, n);
 
+check_customers:
   /* Customer(s) waiting for this address to be resolved? */
   p = mhash_get (&nm->pending_resolutions_by_address, a);
   if (p)