ip-neighbor: Allow to replace dynamic entry
[vpp.git] / src / vnet / ip-neighbor / ip_neighbor.c
index a0179f7..4111b02 100644 (file)
@@ -141,6 +141,8 @@ ip_neighbor_list_remove (ip_neighbor_t * ipn)
       elt = pool_elt_at_index (ip_neighbor_elt_pool, ipn->ipn_elt);
 
       clib_llist_remove (ip_neighbor_elt_pool, ipne_anchor, elt);
+
+      ipn->ipn_elt = ~0;
     }
 }
 
@@ -492,6 +494,17 @@ ip_neighbor_add (const ip46_address_t * ip,
          return -2;
        }
 
+      /* A dynamic entry can become static, but not vice-versa.
+       * i.e. since if it was programmed by the CP then it must
+       * be removed by the CP */
+      if ((flags & IP_NEIGHBOR_FLAG_STATIC) &&
+         !(ipn->ipn_flags & IP_NEIGHBOR_FLAG_STATIC))
+       {
+         ip_neighbor_list_remove (ipn);
+         ipn->ipn_flags |= IP_NEIGHBOR_FLAG_STATIC;
+         ipn->ipn_flags &= ~IP_NEIGHBOR_FLAG_DYNAMIC;
+       }
+
       /*
        * prevent a DoS attack from the data-plane that
        * spams us with no-op updates to the MAC address
@@ -503,17 +516,6 @@ ip_neighbor_add (const ip46_address_t * ip,
        }
 
       mac_address_copy (&ipn->ipn_mac, mac);
-
-      /* A dynamic entry can become static, but not vice-versa.
-       * i.e. since if it was programmed by the CP then it must
-       * be removed by the CP */
-      if ((flags & IP_NEIGHBOR_FLAG_STATIC) &&
-         !(ipn->ipn_flags & IP_NEIGHBOR_FLAG_STATIC))
-       {
-         ip_neighbor_list_remove (ipn);
-         ipn->ipn_flags |= IP_NEIGHBOR_FLAG_STATIC;
-         ipn->ipn_flags &= ~IP_NEIGHBOR_FLAG_DYNAMIC;
-       }
     }
   else
     {
@@ -821,12 +823,11 @@ ip_neighbor_entries (u32 sw_if_index, ip46_type_t type)
   /* *INDENT-OFF* */
   pool_foreach (ipn, ip_neighbor_pool,
   ({
-    if (sw_if_index != ~0 &&
-        ipn->ipn_key->ipnk_sw_if_index != sw_if_index &&
+    if ((sw_if_index == ~0 ||
+        ipn->ipn_key->ipnk_sw_if_index == sw_if_index) &&
         (IP46_TYPE_ANY == type ||
-         (ipn->ipn_key->ipnk_type == type)))
-      continue;
-    vec_add1 (ipnis, ip_neighbor_get_index(ipn));
+         ipn->ipn_key->ipnk_type == type))
+       vec_add1 (ipnis, ip_neighbor_get_index(ipn));
   }));
 
   /* *INDENT-ON* */