IP-neighbor: add and delete internal API 76/14776/4
authorNeale Ranns <neale.ranns@cisco.com>
Fri, 7 Sep 2018 18:04:52 +0000 (11:04 -0700)
committerDamjan Marion <dmarion@me.com>
Thu, 13 Sep 2018 00:32:57 +0000 (00:32 +0000)
Change-Id: I4d1ab5ff0c8f0756e91bf63e045f88513bb7d039
Signed-off-by: Neale Ranns <neale.ranns@cisco.com>
src/vnet/ip/ip6_neighbor.c
src/vnet/ip/ip6_neighbor.h
src/vnet/ip/ip6_packet.h
src/vnet/ip/ip_api.c
src/vnet/ip/ip_neighbor.c
src/vnet/ip/ip_neighbor.h

index a54f9e9..8466ba7 100755 (executable)
@@ -414,8 +414,9 @@ static void ip6_neighbor_set_unset_rpc_callback
 static void set_unset_ip6_neighbor_rpc
   (vlib_main_t * vm,
    u32 sw_if_index,
-   ip6_address_t * a, u8 * link_layer_address, int is_add, int is_static,
-   int is_no_fib_entry)
+   const ip6_address_t * a,
+   const u8 * link_layer_address,
+   int is_add, int is_static, int is_no_fib_entry)
 {
   ip6_neighbor_set_unset_rpc_args_t args;
   void vl_api_rpc_call_main_thread (void *fp, u8 * data, u32 data_length);
@@ -772,8 +773,8 @@ force_reuse_neighbor_entry (void)
 int
 vnet_set_ip6_ethernet_neighbor (vlib_main_t * vm,
                                u32 sw_if_index,
-                               ip6_address_t * a,
-                               u8 * link_layer_address,
+                               const ip6_address_t * a,
+                               const u8 * link_layer_address,
                                uword n_bytes_link_layer_address,
                                int is_static, int is_no_fib_entry)
 {
@@ -895,7 +896,7 @@ check_customers:
          pool_put (nm->pending_resolutions, pr);
        }
 
-      mhash_unset (&nm->pending_resolutions_by_address, a, 0);
+      mhash_unset (&nm->pending_resolutions_by_address, (void *) a, 0);
     }
 
   /* Customer(s) requesting ND event for this address? */
@@ -914,7 +915,8 @@ check_customers:
          /* Call the user's data callback, return 1 to suppress dup events */
          if (fp)
            rv =
-             (*fp) (mc->data, link_layer_address, sw_if_index, &ip6a_zero);
+             (*fp) (mc->data, (u8 *) link_layer_address, sw_if_index,
+                    &ip6a_zero);
          /*
           * Signal the resolver process, as long as the user
           * says they want to be notified
@@ -931,10 +933,7 @@ check_customers:
 
 int
 vnet_unset_ip6_ethernet_neighbor (vlib_main_t * vm,
-                                 u32 sw_if_index,
-                                 ip6_address_t * a,
-                                 u8 * link_layer_address,
-                                 uword n_bytes_link_layer_address)
+                                 u32 sw_if_index, const ip6_address_t * a)
 {
   ip6_neighbor_main_t *nm = &ip6_neighbor_main;
   ip6_neighbor_key_t k;
@@ -944,7 +943,7 @@ vnet_unset_ip6_ethernet_neighbor (vlib_main_t * vm,
 
   if (vlib_get_thread_index ())
     {
-      set_unset_ip6_neighbor_rpc (vm, sw_if_index, a, link_layer_address,
+      set_unset_ip6_neighbor_rpc (vm, sw_if_index, a, NULL,
                                  0 /* unset */ , 0, 0);
       return 0;
     }
@@ -983,8 +982,7 @@ static void ip6_neighbor_set_unset_rpc_callback
                                    a->link_layer_address, 6, a->is_static,
                                    a->is_no_fib_entry);
   else
-    vnet_unset_ip6_ethernet_neighbor (vm, a->sw_if_index, &a->addr,
-                                     a->link_layer_address, 6);
+    vnet_unset_ip6_ethernet_neighbor (vm, a->sw_if_index, &a->addr);
 }
 
 static int
@@ -1122,8 +1120,7 @@ set_ip6_neighbor (vlib_main_t * vm,
                                    mac_address, sizeof (mac_address),
                                    is_static, is_no_fib_entry);
   else
-    vnet_unset_ip6_ethernet_neighbor (vm, sw_if_index, &addr,
-                                     mac_address, sizeof (mac_address));
+    vnet_unset_ip6_ethernet_neighbor (vm, sw_if_index, &addr);
   return 0;
 }
 
@@ -4928,8 +4925,7 @@ ip6_neighbor_proxy_add_del (u32 sw_if_index, ip6_address_t * addr, u8 is_del)
                                   sw_if_index,
                                   ~0, 1, FIB_ROUTE_PATH_FLAG_NONE);
       /* flush the ND cache of this address if it's there */
-      vnet_unset_ip6_ethernet_neighbor (vlib_get_main (),
-                                       sw_if_index, addr, NULL, 0);
+      vnet_unset_ip6_ethernet_neighbor (vlib_get_main (), sw_if_index, addr);
     }
   else
     {
index b346563..3256ba7 100644 (file)
@@ -75,18 +75,15 @@ extern void vnet_register_ip6_neighbor_resolution_event (vnet_main_t * vnm,
 
 extern int vnet_set_ip6_ethernet_neighbor (vlib_main_t * vm,
                                           u32 sw_if_index,
-                                          ip6_address_t * a,
-                                          u8 * link_layer_address,
+                                          const ip6_address_t * a,
+                                          const u8 * link_layer_address,
                                           uword n_bytes_link_layer_address,
                                           int is_static,
                                           int is_no_fib_entry);
 
 extern int vnet_unset_ip6_ethernet_neighbor (vlib_main_t * vm,
                                             u32 sw_if_index,
-                                            ip6_address_t * a,
-                                            u8 * link_layer_address,
-                                            uword
-                                            n_bytes_link_layer_address);
+                                            const ip6_address_t * a);
 
 extern int ip6_neighbor_proxy_add_del (u32 sw_if_index,
                                       ip6_address_t * addr, u8 is_add);
index 6207400..ea2fa15 100644 (file)
@@ -93,6 +93,8 @@ typedef CLIB_PACKED (union {
 #define ip46_address_is_zero(ip46)     (((ip46)->as_u64[0] == 0) && ((ip46)->as_u64[1] == 0))
 #define ip46_address_is_equal(a1, a2)  (((a1)->as_u64[0] == (a2)->as_u64[0]) \
                                          && ((a1)->as_u64[1] == (a2)->as_u64[1]))
+#define ip46_address_initializer {{{ 0 }}}
+
 static_always_inline void
 ip46_address_copy (ip46_address_t * dst, const ip46_address_t * src)
 {
@@ -100,7 +102,12 @@ ip46_address_copy (ip46_address_t * dst, const ip46_address_t * src)
   dst->as_u64[1] = src->as_u64[1];
 }
 
-#define ip46_address_initializer {{{ 0 }}}
+static_always_inline void
+ip46_address_set_ip6 (ip46_address_t * dst, const ip6_address_t * src)
+{
+  dst->as_u64[0] = src->as_u64[0];
+  dst->as_u64[1] = src->as_u64[1];
+}
 
 always_inline ip46_address_t
 to_ip46 (u32 is_ipv6, u8 * buf)
index 31b7e40..431a777 100644 (file)
@@ -653,48 +653,31 @@ static void
 vl_api_ip_neighbor_add_del_t_handler (vl_api_ip_neighbor_add_del_t * mp,
                                      vlib_main_t * vm)
 {
+  ip46_address_t ip = ip46_address_initializer;
   vl_api_ip_neighbor_add_del_reply_t *rmp;
-  vnet_main_t *vnm = vnet_get_main ();
+  ip_neighbor_flags_t flags;
   int rv = 0;
 
   VALIDATE_SW_IF_INDEX (mp);
 
   stats_dslock_with_hint (1 /* release hint */ , 7 /* tag */ );
 
-  /*
-   * there's no validation here of the ND/ARP entry being added.
-   * The expectation is that the FIB will ensure that nothing bad
-   * will come of adding bogus entries.
-   */
+  flags = IP_NEIGHBOR_FLAG_NODE;
+  if (mp->is_static)
+    flags |= IP_NEIGHBOR_FLAG_STATIC;
+  if (mp->is_no_adj_fib)
+    flags |= IP_NEIGHBOR_FLAG_NO_ADJ_FIB;
+
   if (mp->is_ipv6)
-    {
-      if (mp->is_add)
-       rv = vnet_set_ip6_ethernet_neighbor
-         (vm, ntohl (mp->sw_if_index),
-          (ip6_address_t *) (mp->dst_address),
-          mp->mac_address, sizeof (mp->mac_address), mp->is_static,
-          mp->is_no_adj_fib);
-      else
-       rv = vnet_unset_ip6_ethernet_neighbor
-         (vm, ntohl (mp->sw_if_index),
-          (ip6_address_t *) (mp->dst_address),
-          mp->mac_address, sizeof (mp->mac_address));
-    }
+    clib_memcpy (&ip.ip6, mp->dst_address, 16);
   else
-    {
-      ethernet_arp_ip4_over_ethernet_address_t a;
-
-      clib_memcpy (&a.ethernet, mp->mac_address, 6);
-      clib_memcpy (&a.ip4, mp->dst_address, 4);
+    clib_memcpy (&ip.ip4, mp->dst_address, 4);
 
-      if (mp->is_add)
-       rv = vnet_arp_set_ip4_over_ethernet (vnm, ntohl (mp->sw_if_index),
-                                            &a, mp->is_static,
-                                            mp->is_no_adj_fib);
-      else
-       rv =
-         vnet_arp_unset_ip4_over_ethernet (vnm, ntohl (mp->sw_if_index), &a);
-    }
+  if (mp->is_add)
+    rv = ip_neighbor_add (&ip, mp->is_ipv6, mp->mac_address,
+                         ntohl (mp->sw_if_index), flags);
+  else
+    rv = ip_neighbor_del (&ip, mp->is_ipv6, ntohl (mp->sw_if_index));
 
   stats_dsunlock ();
 
index 8043765..2edd737 100644 (file)
@@ -47,6 +47,69 @@ typedef struct
 
 static ip_neighbor_scan_config_t ip_neighbor_scan_conf;
 
+int
+ip_neighbor_add (const ip46_address_t * ip,
+                u8 is_ip6,
+                const u8 * mac, u32 sw_if_index, ip_neighbor_flags_t flags)
+{
+  int rv;
+
+  /*
+   * there's no validation here of the ND/ARP entry being added.
+   * The expectation is that the FIB will ensure that nothing bad
+   * will come of adding bogus entries.
+   */
+  if (is_ip6)
+    {
+      rv = vnet_set_ip6_ethernet_neighbor (vlib_get_main (),
+                                          sw_if_index, &ip->ip6, mac, 6,
+                                          (flags & IP_NEIGHBOR_FLAG_STATIC),
+                                          (flags &
+                                           IP_NEIGHBOR_FLAG_NO_ADJ_FIB));
+
+    }
+  else
+    {
+      ethernet_arp_ip4_over_ethernet_address_t a = {
+       .ip4 = ip->ip4,
+      };
+
+      clib_memcpy (&a.ethernet, mac, 6);
+
+      rv = vnet_arp_set_ip4_over_ethernet (vnet_get_main (),
+                                          sw_if_index,
+                                          &a,
+                                          (flags & IP_NEIGHBOR_FLAG_STATIC),
+                                          (flags &
+                                           IP_NEIGHBOR_FLAG_NO_ADJ_FIB));
+    }
+
+  return (rv);
+}
+
+int
+ip_neighbor_del (const ip46_address_t * ip, u8 is_ip6, u32 sw_if_index)
+{
+  int rv;
+
+  if (is_ip6)
+    {
+      rv = vnet_unset_ip6_ethernet_neighbor (vlib_get_main (),
+                                            sw_if_index, &ip->ip6);
+    }
+  else
+    {
+      ethernet_arp_ip4_over_ethernet_address_t a = {
+       .ip4 = ip->ip4,
+      };
+
+      rv =
+       vnet_arp_unset_ip4_over_ethernet (vnet_get_main (), sw_if_index, &a);
+    }
+
+  return (rv);
+}
+
 void
 ip_neighbor_scan_enable_disable (ip_neighbor_scan_arg_t * arg)
 {
@@ -134,8 +197,7 @@ ip_neighbor_scan (vlib_main_t * vm, f64 start_time, u32 start_idx,
          else
            {
              vnet_unset_ip6_ethernet_neighbor
-               (vm, n6->key.sw_if_index, &n6->key.ip6_address,
-                n6->link_layer_address, 6);
+               (vm, n6->key.sw_if_index, &n6->key.ip6_address);
            }
        }
       else if (delta >= cfg->scan_interval)
index d2790bc..b865862 100644 (file)
@@ -35,6 +35,21 @@ typedef struct
 
 void ip_neighbor_scan_enable_disable (ip_neighbor_scan_arg_t * arg);
 
+typedef enum ip_neighbor_flags_t_
+{
+  IP_NEIGHBOR_FLAG_NODE = 0,
+  IP_NEIGHBOR_FLAG_STATIC = (1 << 0),
+  IP_NEIGHBOR_FLAG_NO_ADJ_FIB = (1 << 1),
+} ip_neighbor_flags_t;
+
+extern int ip_neighbor_add (const ip46_address_t * ip,
+                           u8 is_ip6,
+                           const u8 * mac,
+                           u32 sw_if_index, ip_neighbor_flags_t flags);
+
+extern int ip_neighbor_del (const ip46_address_t * ip,
+                           u8 is_ip6, u32 sw_if_index);
+
 #endif /* included_ip_neighbor_h */
 
 /*