Remove c-11 memcpy checks from perf-critical code
[vpp.git] / src / vnet / ethernet / arp.c
index f7d8ff8..549e05d 100644 (file)
@@ -26,6 +26,7 @@
 #include <vnet/adj/adj_nbr.h>
 #include <vnet/adj/adj_mcast.h>
 #include <vnet/mpls/mpls.h>
+#include <vnet/l2/feat_bitmap.h>
 
 /**
  * @file
@@ -357,8 +358,9 @@ arp_nbr_probe (ip_adjacency_t * adj)
 
   hi = vnet_get_sup_hw_interface (vnm, adj->rewrite_header.sw_if_index);
 
-  clib_memcpy (h->ip4_over_ethernet[0].ethernet,
-              hi->hw_address, sizeof (h->ip4_over_ethernet[0].ethernet));
+  clib_memcpy_fast (h->ip4_over_ethernet[0].ethernet,
+                   hi->hw_address,
+                   sizeof (h->ip4_over_ethernet[0].ethernet));
 
   h->ip4_over_ethernet[0].ip4 = src[0];
   h->ip4_over_ethernet[1].ip4 = adj->sub_type.nbr.next_hop.ip4;
@@ -556,7 +558,7 @@ arp_adj_fib_add (ethernet_arp_ip4_entry_t * e, u32 fib_index)
   fib_table_lock (fib_index, FIB_PROTOCOL_IP4, FIB_SOURCE_ADJ);
 }
 
-void
+static void
 arp_adj_fib_remove (ethernet_arp_ip4_entry_t * e, u32 fib_index)
 {
   if (FIB_NODE_INDEX_INVALID != e->fib_entry_index)
@@ -608,7 +610,7 @@ force_reuse_arp_entry (void)
   arp_adj_fib_remove
     (e, ip4_fib_table_get_index_for_sw_if_index (e->sw_if_index));
   adj_nbr_walk_nh4 (e->sw_if_index,
-                   &e->ip4_address, arp_mk_incomplete_walk, NULL);
+                   &e->ip4_address, arp_mk_incomplete_walk, e);
   return e;
 }
 
@@ -673,8 +675,8 @@ vnet_arp_set_ip4_over_ethernet_internal (vnet_main_t * vnm,
       e->sw_if_index = sw_if_index;
       e->ip4_address = a->ip4;
       e->fib_entry_index = FIB_NODE_INDEX_INVALID;
-      clib_memcpy (e->ethernet_address,
-                  a->ethernet, sizeof (e->ethernet_address));
+      clib_memcpy_fast (e->ethernet_address,
+                       a->ethernet, sizeof (e->ethernet_address));
 
       if (!is_no_fib_entry)
        {
@@ -701,8 +703,8 @@ vnet_arp_set_ip4_over_ethernet_internal (vnet_main_t * vnm,
        }
 
       /* Update ethernet address. */
-      clib_memcpy (e->ethernet_address, a->ethernet,
-                  sizeof (e->ethernet_address));
+      clib_memcpy_fast (e->ethernet_address, a->ethernet,
+                       sizeof (e->ethernet_address));
     }
 
   /* Update time stamp and flags. */
@@ -928,7 +930,8 @@ arp_unnumbered (vlib_buffer_t * p0,
 
 static u32
 arp_learn (vnet_main_t * vnm,
-          ethernet_arp_main_t * am, u32 sw_if_index, void *addr)
+          ethernet_arp_main_t * am, u32 sw_if_index,
+          const ethernet_arp_ip4_over_ethernet_address_t * addr)
 {
   vnet_arp_set_ip4_over_ethernet (vnm, sw_if_index, addr, 0, 0);
   return (ETHERNET_ARP_ERROR_l3_src_address_learned);
@@ -964,12 +967,13 @@ arp_input (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
          vnet_hw_interface_t *hw_if0;
          ethernet_arp_header_t *arp0;
          ethernet_header_t *eth_rx, *eth_tx;
-         ip4_address_t *if_addr0, proxy_src;
+         const ip4_address_t *if_addr0;
+         ip4_address_t proxy_src;
          u32 pi0, error0, next0, sw_if_index0, conn_sw_if_index0, fib_index0;
          u8 is_request0, dst_is_local0, is_unnum0, is_vrrp_reply0;
          ethernet_proxy_arp_t *pa;
          fib_node_index_t dst_fei, src_fei;
-         fib_prefix_t pfx0;
+         const fib_prefix_t *pfx0;
          fib_entry_flag_t src_flags, dst_flags;
          u8 *rewrite0, rewrite0_len;
 
@@ -1041,9 +1045,9 @@ arp_input (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
             * to reach us, they only affect how we reach the sender.
             */
            fib_entry_t *src_fib_entry;
+           const fib_prefix_t *pfx;
            fib_entry_src_t *src;
            fib_source_t source;
-           fib_prefix_t pfx;
            int attached;
            int mask;
 
@@ -1106,8 +1110,8 @@ arp_input (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
                /*
                 * shorter mask lookup for the next iteration.
                 */
-               fib_entry_get_prefix (src_fei, &pfx);
-               mask = pfx.fp_len - 1;
+               pfx = fib_entry_get_prefix (src_fei);
+               mask = pfx->fp_len - 1;
 
                /*
                 * continue until we hit the default route or we find
@@ -1165,8 +1169,8 @@ arp_input (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
            }
 
          dst_is_local0 = (FIB_ENTRY_FLAG_LOCAL & dst_flags);
-         fib_entry_get_prefix (dst_fei, &pfx0);
-         if_addr0 = &pfx0.fp_addr.ip4;
+         pfx0 = fib_entry_get_prefix (dst_fei);
+         if_addr0 = &pfx0->fp_addr.ip4;
 
          is_vrrp_reply0 =
            ((arp0->opcode ==
@@ -1235,8 +1239,8 @@ arp_input (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
 
          arp0->ip4_over_ethernet[1] = arp0->ip4_over_ethernet[0];
 
-         clib_memcpy (arp0->ip4_over_ethernet[0].ethernet,
-                      hw_if0->hw_address, 6);
+         clib_memcpy_fast (arp0->ip4_over_ethernet[0].ethernet,
+                           hw_if0->hw_address, 6);
          clib_mem_unaligned (&arp0->ip4_over_ethernet[0].ip4.data_u32, u32) =
            if_addr0->data_u32;
 
@@ -1246,7 +1250,7 @@ arp_input (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
          /* the rx nd tx ethernet headers wil overlap in the case
           * when we received a tagged VLAN=0 packet, but we are sending
           * back untagged */
-         clib_memcpy (eth_tx, rewrite0, vec_len (rewrite0));
+         clib_memcpy_fast (eth_tx, rewrite0, vec_len (rewrite0));
          vec_free (rewrite0);
 
          if (NULL == pa)
@@ -1545,59 +1549,16 @@ ip4_set_arp_limit (u32 arp_limit)
  */
 int
 vnet_arp_unset_ip4_over_ethernet (vnet_main_t * vnm,
-                                 u32 sw_if_index, void *a_arg)
+                                 u32 sw_if_index,
+                                 const
+                                 ethernet_arp_ip4_over_ethernet_address_t *
+                                 a)
 {
-  ethernet_arp_ip4_over_ethernet_address_t *a = a_arg;
   vnet_arp_set_ip4_over_ethernet_rpc_args_t args;
 
   args.sw_if_index = sw_if_index;
   args.flags = ETHERNET_ARP_ARGS_REMOVE;
-  clib_memcpy (&args.a, a, sizeof (*a));
-
-  vl_api_rpc_call_main_thread (set_ip4_over_ethernet_rpc_callback,
-                              (u8 *) & args, sizeof (args));
-  return 0;
-}
-
-/**
- * @brief Internally generated event to flush the ARP cache on an
- * interface state change event.
- * A flush will remove dynamic ARP entries, and for statics remove the MAC
- * address from the corresponding adjacencies.
- */
-static int
-vnet_arp_flush_ip4_over_ethernet (vnet_main_t * vnm,
-                                 u32 sw_if_index, void *a_arg)
-{
-  ethernet_arp_ip4_over_ethernet_address_t *a = a_arg;
-  vnet_arp_set_ip4_over_ethernet_rpc_args_t args;
-
-  args.sw_if_index = sw_if_index;
-  args.flags = ETHERNET_ARP_ARGS_FLUSH;
-  clib_memcpy (&args.a, a, sizeof (*a));
-
-  vl_api_rpc_call_main_thread (set_ip4_over_ethernet_rpc_callback,
-                              (u8 *) & args, sizeof (args));
-  return 0;
-}
-
-/**
- * @brief Internally generated event to populate the ARP cache on an
- * interface state change event.
- * For static entries this will re-source the adjacencies.
- *
- * @param sw_if_index The interface on which the ARP entires are acted
- */
-static int
-vnet_arp_populate_ip4_over_ethernet (vnet_main_t * vnm,
-                                    u32 sw_if_index, void *a_arg)
-{
-  ethernet_arp_ip4_over_ethernet_address_t *a = a_arg;
-  vnet_arp_set_ip4_over_ethernet_rpc_args_t args;
-
-  args.sw_if_index = sw_if_index;
-  args.flags = ETHERNET_ARP_ARGS_POPULATE;
-  clib_memcpy (&args.a, a, sizeof (*a));
+  clib_memcpy_fast (&args.a, a, sizeof (*a));
 
   vl_api_rpc_call_main_thread (set_ip4_over_ethernet_rpc_callback,
                               (u8 *) & args, sizeof (args));
@@ -1609,9 +1570,9 @@ vnet_arp_populate_ip4_over_ethernet (vnet_main_t * vnm,
  * @param sw_if_index The interface on which the ARP entires are acted
  */
 static int
-vnet_arp_wc_publish (u32 sw_if_index, void *a_arg)
+vnet_arp_wc_publish (u32 sw_if_index,
+                    const ethernet_arp_ip4_over_ethernet_address_t * a)
 {
-  ethernet_arp_ip4_over_ethernet_address_t *a = a_arg;
   vnet_arp_set_ip4_over_ethernet_rpc_args_t args = {
     .flags = ETHERNET_ARP_ARGS_WC_PUB,
     .sw_if_index = sw_if_index,
@@ -1650,6 +1611,49 @@ wc_arp_set_publisher_node (uword node_index, uword event_type)
   am->wc_ip4_arp_publisher_et = event_type;
 }
 
+static void
+arp_entry_free (ethernet_arp_interface_t * eai, ethernet_arp_ip4_entry_t * e);
+
+static int
+vnet_arp_flush_ip4_over_ethernet_internal (vnet_main_t * vnm,
+                                          vnet_arp_set_ip4_over_ethernet_rpc_args_t
+                                          * args)
+{
+  ethernet_arp_main_t *am = &ethernet_arp_main;
+  ethernet_arp_ip4_entry_t *e;
+  ethernet_arp_interface_t *eai;
+
+  if (vec_len (am->ethernet_arp_by_sw_if_index) <= args->sw_if_index)
+    return 0;
+
+  eai = &am->ethernet_arp_by_sw_if_index[args->sw_if_index];
+
+  e = arp_entry_find (eai, &args->a.ip4);
+
+  if (NULL != e)
+    {
+      adj_nbr_walk_nh4 (e->sw_if_index,
+                       &e->ip4_address, arp_mk_incomplete_walk, e);
+
+      /*
+       * The difference between flush and unset, is that an unset
+       * means delete for static and dynamic entries. A flush
+       * means delete only for dynamic. Flushing is what the DP
+       * does in response to interface events. unset is only done
+       * by the control plane.
+       */
+      if (e->flags & ETHERNET_ARP_IP4_ENTRY_FLAG_STATIC)
+       {
+         e->flags &= ~ETHERNET_ARP_IP4_ENTRY_FLAG_DYNAMIC;
+       }
+      else if (e->flags & ETHERNET_ARP_IP4_ENTRY_FLAG_DYNAMIC)
+       {
+         arp_entry_free (eai, e);
+       }
+    }
+  return (0);
+}
+
 /*
  * arp_add_del_interface_address
  *
@@ -1696,14 +1700,17 @@ arp_add_del_interface_address (ip4_main_t * im,
 
       for (i = 0; i < vec_len (to_delete); i++)
        {
-         ethernet_arp_ip4_over_ethernet_address_t delme;
          e = pool_elt_at_index (am->ip4_entry_pool, to_delete[i]);
 
-         clib_memcpy (&delme.ethernet, e->ethernet_address, 6);
-         delme.ip4.as_u32 = e->ip4_address.as_u32;
+         vnet_arp_set_ip4_over_ethernet_rpc_args_t delme = {
+           .a.ip4.as_u32 = e->ip4_address.as_u32,
+           .sw_if_index = e->sw_if_index,
+           .flags = ETHERNET_ARP_ARGS_FLUSH,
+         };
+         clib_memcpy_fast (&delme.a.ethernet, e->ethernet_address, 6);
 
-         vnet_arp_flush_ip4_over_ethernet (vnet_get_main (),
-                                           e->sw_if_index, &delme);
+         vnet_arp_flush_ip4_over_ethernet_internal (vnet_get_main (),
+                                                    &delme);
        }
 
       vec_free (to_delete);
@@ -1831,52 +1838,13 @@ vnet_arp_unset_ip4_over_ethernet_internal (vnet_main_t * vnm,
   if (NULL != e)
     {
       adj_nbr_walk_nh4 (e->sw_if_index,
-                       &e->ip4_address, arp_mk_incomplete_walk, NULL);
+                       &e->ip4_address, arp_mk_incomplete_walk, e);
       arp_entry_free (eai, e);
     }
 
   return 0;
 }
 
-static int
-vnet_arp_flush_ip4_over_ethernet_internal (vnet_main_t * vnm,
-                                          vnet_arp_set_ip4_over_ethernet_rpc_args_t
-                                          * args)
-{
-  ethernet_arp_main_t *am = &ethernet_arp_main;
-  ethernet_arp_ip4_entry_t *e;
-  ethernet_arp_interface_t *eai;
-
-  if (vec_len (am->ethernet_arp_by_sw_if_index) <= args->sw_if_index)
-    return 0;
-
-  eai = &am->ethernet_arp_by_sw_if_index[args->sw_if_index];
-
-  e = arp_entry_find (eai, &args->a.ip4);
-
-  if (NULL != e)
-    {
-      adj_nbr_walk_nh4 (e->sw_if_index,
-                       &e->ip4_address, arp_mk_incomplete_walk, e);
-
-      /*
-       * The difference between flush and unset, is that an unset
-       * means delete for static and dynamic entries. A flush
-       * means delete only for dynamic. Flushing is what the DP
-       * does in response to interface events. unset is only done
-       * by the control plane.
-       */
-      if (e->flags & ETHERNET_ARP_IP4_ENTRY_FLAG_STATIC)
-       {
-         e->flags &= ~ETHERNET_ARP_IP4_ENTRY_FLAG_DYNAMIC;
-       }
-      else if (e->flags & ETHERNET_ARP_IP4_ENTRY_FLAG_DYNAMIC)
-       {
-         arp_entry_free (eai, e);
-       }
-    }
-  return (0);
-}
 
 static int
 vnet_arp_populate_ip4_over_ethernet_internal (vnet_main_t * vnm,
@@ -1928,36 +1896,40 @@ ethernet_arp_sw_interface_up_down (vnet_main_t * vnm,
 {
   ethernet_arp_main_t *am = &ethernet_arp_main;
   ethernet_arp_ip4_entry_t *e;
-  u32 i, *to_delete = 0;
+  u32 i, *to_update = 0;
 
   /* *INDENT-OFF* */
   pool_foreach (e, am->ip4_entry_pool,
   ({
     if (e->sw_if_index == sw_if_index)
-      vec_add1 (to_delete,
+      vec_add1 (to_update,
                e - am->ip4_entry_pool);
   }));
   /* *INDENT-ON* */
 
-  for (i = 0; i < vec_len (to_delete); i++)
+  for (i = 0; i < vec_len (to_update); i++)
     {
-      ethernet_arp_ip4_over_ethernet_address_t delme;
-      e = pool_elt_at_index (am->ip4_entry_pool, to_delete[i]);
+      e = pool_elt_at_index (am->ip4_entry_pool, to_update[i]);
 
-      clib_memcpy (&delme.ethernet, e->ethernet_address, 6);
-      delme.ip4.as_u32 = e->ip4_address.as_u32;
+      vnet_arp_set_ip4_over_ethernet_rpc_args_t update_me = {
+       .a.ip4.as_u32 = e->ip4_address.as_u32,
+       .sw_if_index = e->sw_if_index,
+      };
+
+      clib_memcpy_fast (&update_me.a.ethernet, e->ethernet_address, 6);
 
       if (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP)
        {
-         vnet_arp_populate_ip4_over_ethernet (vnm, e->sw_if_index, &delme);
+         update_me.flags = ETHERNET_ARP_ARGS_POPULATE;
+         vnet_arp_populate_ip4_over_ethernet_internal (vnm, &update_me);
        }
       else
        {
-         vnet_arp_flush_ip4_over_ethernet (vnm, e->sw_if_index, &delme);
+         update_me.flags = ETHERNET_ARP_ARGS_FLUSH;
+         vnet_arp_flush_ip4_over_ethernet_internal (vnm, &update_me);
        }
-
     }
-  vec_free (to_delete);
+  vec_free (to_update);
 
   return 0;
 }
@@ -1989,17 +1961,17 @@ increment_ip4_and_mac_address (ethernet_arp_ip4_over_ethernet_address_t * a)
 
 int
 vnet_arp_set_ip4_over_ethernet (vnet_main_t * vnm,
-                               u32 sw_if_index, void *a_arg,
-                               int is_static, int is_no_fib_entry)
+                               u32 sw_if_index,
+                               const ethernet_arp_ip4_over_ethernet_address_t
+                               * a, int is_static, int is_no_fib_entry)
 {
-  ethernet_arp_ip4_over_ethernet_address_t *a = a_arg;
   vnet_arp_set_ip4_over_ethernet_rpc_args_t args;
 
   args.sw_if_index = sw_if_index;
   args.is_static = is_static;
   args.is_no_fib_entry = is_no_fib_entry;
   args.flags = 0;
-  clib_memcpy (&args.a, a, sizeof (*a));
+  clib_memcpy_fast (&args.a, a, sizeof (*a));
 
   vl_api_rpc_call_main_thread (set_ip4_over_ethernet_rpc_callback,
                               (u8 *) & args, sizeof (args));
@@ -2373,7 +2345,8 @@ arp_term_l2bd (vlib_main_t * vm,
            {
              u8 *t0 = vlib_add_trace (vm, node, p0,
                                       sizeof (ethernet_arp_input_trace_t));
-             clib_memcpy (t0, l3h0, sizeof (ethernet_arp_input_trace_t));
+             clib_memcpy_fast (t0, l3h0,
+                               sizeof (ethernet_arp_input_trace_t));
            }
 
          error0 = 0;
@@ -2439,9 +2412,9 @@ arp_term_l2bd (vlib_main_t * vm,
          arp0->opcode = clib_host_to_net_u16 (ETHERNET_ARP_OPCODE_reply);
          arp0->ip4_over_ethernet[1] = arp0->ip4_over_ethernet[0];
          arp0->ip4_over_ethernet[0].ip4.as_u32 = ip0;
-         clib_memcpy (arp0->ip4_over_ethernet[0].ethernet, macp0, 6);
-         clib_memcpy (eth0->dst_address, eth0->src_address, 6);
-         clib_memcpy (eth0->src_address, macp0, 6);
+         clib_memcpy_fast (arp0->ip4_over_ethernet[0].ethernet, macp0, 6);
+         clib_memcpy_fast (eth0->dst_address, eth0->src_address, 6);
+         clib_memcpy_fast (eth0->src_address, macp0, 6);
          n_replies_sent += 1;
 
        output_response:
@@ -2606,10 +2579,10 @@ send_ip4_garp_w_addr (vlib_main_t * vm,
       if (!h)
        return;
 
-      clib_memcpy (h->ip4_over_ethernet[0].ethernet, hi->hw_address,
-                  sizeof (h->ip4_over_ethernet[0].ethernet));
-      clib_memcpy (h->ip4_over_ethernet[1].ethernet, hi->hw_address,
-                  sizeof (h->ip4_over_ethernet[1].ethernet));
+      clib_memcpy_fast (h->ip4_over_ethernet[0].ethernet, hi->hw_address,
+                       sizeof (h->ip4_over_ethernet[0].ethernet));
+      clib_memcpy_fast (h->ip4_over_ethernet[1].ethernet, hi->hw_address,
+                       sizeof (h->ip4_over_ethernet[1].ethernet));
       h->ip4_over_ethernet[0].ip4 = ip4_addr[0];
       h->ip4_over_ethernet[1].ip4 = ip4_addr[0];
 
@@ -2621,7 +2594,7 @@ send_ip4_garp_w_addr (vlib_main_t * vm,
       rewrite_len = vec_len (rewrite);
       vlib_buffer_advance (b, -rewrite_len);
       ethernet_header_t *e = vlib_buffer_get_current (b);
-      clib_memcpy (e->dst_address, rewrite, rewrite_len);
+      clib_memcpy_fast (e->dst_address, rewrite, rewrite_len);
       vec_free (rewrite);
 
       /* Send GARP packet out the specified interface */