Remove c-11 memcpy checks from perf-critical code
[vpp.git] / src / plugins / ioam / export-common / ioam_export.h
index e6ab034..672576e 100644 (file)
@@ -20,8 +20,9 @@
 #include <vnet/ip/ip_packet.h>
 #include <vnet/ip/ip4_packet.h>
 #include <vnet/ip/ip6_packet.h>
-#include <vnet/ip/udp.h>
-#include <vnet/flow/ipfix_packet.h>
+#include <vnet/ip/ip6_hop_by_hop.h>
+#include <vnet/udp/udp.h>
+#include <vnet/ipfix-export/ipfix_packet.h>
 
 #include <vppinfra/pool.h>
 #include <vppinfra/hash.h>
@@ -32,6 +33,8 @@
 
 typedef struct ioam_export_buffer
 {
+  /** Required for pool_get_aligned */
+  CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
   /* Allocated buffer */
   u32 buffer_index;
   u64 touched_at;
@@ -43,6 +46,7 @@ typedef struct
 {
   /* API message ID base */
   u16 msg_id_base;
+  u16 set_id;
 
   /* TODO: to support multiple collectors all this has to be grouped and create a vector here */
   u8 *record_header;
@@ -67,17 +71,13 @@ typedef struct
   /* convenience */
   vlib_main_t *vlib_main;
   vnet_main_t *vnet_main;
-  u32 ip4_lookup_node_index;
+  ethernet_main_t *ethernet_main;
+  u32 next_node_index;
 
   uword my_hbh_slot;
   u32 export_process_node_index;
 } ioam_export_main_t;
 
-ioam_export_main_t ioam_export_main;
-ioam_export_main_t vxlan_gpe_ioam_export_main;
-
-extern vlib_node_registration_t export_node;
-extern vlib_node_registration_t vxlan_export_node;
 
 #define DEFAULT_EXPORT_SIZE (3 * CLIB_CACHE_LINE_BYTES)
 /*
@@ -86,6 +86,24 @@ extern vlib_node_registration_t vxlan_export_node;
  */
 #define DEFAULT_EXPORT_RECORDS 7
 
+inline static void
+ioam_export_set_next_node (ioam_export_main_t * em, u8 * next_node_name)
+{
+  vlib_node_t *next_node;
+
+  next_node = vlib_get_node_by_name (em->vlib_main, next_node_name);
+  em->next_node_index = next_node->index;
+}
+
+inline static void
+ioam_export_reset_next_node (ioam_export_main_t * em)
+{
+  vlib_node_t *next_node;
+
+  next_node = vlib_get_node_by_name (em->vlib_main, (u8 *) "ip4-lookup");
+  em->next_node_index = next_node->index;
+}
+
 always_inline ioam_export_buffer_t *
 ioam_export_get_my_buffer (ioam_export_main_t * em, u32 thread_id)
 {
@@ -99,7 +117,7 @@ ioam_export_get_my_buffer (ioam_export_main_t * em, u32 thread_id)
 inline static int
 ioam_export_buffer_add_header (ioam_export_main_t * em, vlib_buffer_t * b0)
 {
-  clib_memcpy (b0->data, em->record_header, vec_len (em->record_header));
+  clib_memcpy_fast (b0->data, em->record_header, vec_len (em->record_header));
   b0->current_data = 0;
   b0->current_length = vec_len (em->record_header);
   b0->flags |= VLIB_BUFFER_TOTAL_LENGTH_VALID;
@@ -154,15 +172,13 @@ ioam_export_thread_buffer_init (ioam_export_main_t * em, vlib_main_t * vm)
   int no_of_threads = vec_len (vlib_worker_threads);
   int i;
   ioam_export_buffer_t *eb = 0;
-  vlib_node_t *ip4_lookup_node;
 
   pool_alloc_aligned (em->buffer_pool,
                      no_of_threads - 1, CLIB_CACHE_LINE_BYTES);
   vec_validate_aligned (em->buffer_per_thread,
                        no_of_threads - 1, CLIB_CACHE_LINE_BYTES);
   vec_validate_aligned (em->lockp, no_of_threads - 1, CLIB_CACHE_LINE_BYTES);
-  ip4_lookup_node = vlib_get_node_by_name (vm, (u8 *) "ip4-lookup");
-  em->ip4_lookup_node_index = ip4_lookup_node->index;
+
   if (!em->buffer_per_thread || !em->buffer_pool || !em->lockp)
     {
       return (-1);
@@ -171,7 +187,7 @@ ioam_export_thread_buffer_init (ioam_export_main_t * em, vlib_main_t * vm)
     {
       eb = 0;
       pool_get_aligned (em->buffer_pool, eb, CLIB_CACHE_LINE_BYTES);
-      memset (eb, 0, sizeof (*eb));
+      clib_memset (eb, 0, sizeof (*eb));
       em->buffer_per_thread[i] = eb - em->buffer_pool;
       if (ioam_export_init_buffer (em, vm, eb) != 1)
        {
@@ -180,12 +196,13 @@ ioam_export_thread_buffer_init (ioam_export_main_t * em, vlib_main_t * vm)
        }
       em->lockp[i] = clib_mem_alloc_aligned (CLIB_CACHE_LINE_BYTES,
                                             CLIB_CACHE_LINE_BYTES);
-      memset ((void *) em->lockp[i], 0, CLIB_CACHE_LINE_BYTES);
+      clib_memset ((void *) em->lockp[i], 0, CLIB_CACHE_LINE_BYTES);
     }
   return (1);
 }
 
 #define IPFIX_IOAM_EXPORT_ID 272
+#define IPFIX_VXLAN_IOAM_EXPORT_ID 273
 
 /* Used to build the rewrite */
 /* data set packet */
@@ -241,8 +258,8 @@ ioam_export_header_create (ioam_export_main_t * em,
   ip->protocol = IP_PROTOCOL_UDP;
   ip->src_address.as_u32 = src_address->as_u32;
   ip->dst_address.as_u32 = collector_address->as_u32;
-  udp->src_port = clib_host_to_net_u16 (4939 /* $$FIXME */ );
-  udp->dst_port = clib_host_to_net_u16 (4939);
+  udp->src_port = clib_host_to_net_u16 (UDP_DST_PORT_ipfix);
+  udp->dst_port = clib_host_to_net_u16 (UDP_DST_PORT_ipfix);
   /* FIXUP: UDP length */
   udp->length = clib_host_to_net_u16 (vec_len (rewrite) +
                                      (DEFAULT_EXPORT_RECORDS *
@@ -253,7 +270,7 @@ ioam_export_header_create (ioam_export_main_t * em,
   h->domain_id = clib_host_to_net_u32 (em->domain_id);
 
   /*FIXUP: Setid length in octets if records exported are not default */
-  s->set_id_length = ipfix_set_id_length (IPFIX_IOAM_EXPORT_ID,
+  s->set_id_length = ipfix_set_id_length (em->set_id,
                                          (sizeof (*s) +
                                           (DEFAULT_EXPORT_RECORDS *
                                            DEFAULT_EXPORT_SIZE)));
@@ -309,11 +326,10 @@ ioam_export_send_buffer (ioam_export_main_t * em, vlib_main_t * vm,
   /* FIXUP: lengths if different from default */
   if (PREDICT_FALSE (eb->records_in_this_buffer != DEFAULT_EXPORT_RECORDS))
     {
-      s->set_id_length =
-       ipfix_set_id_length (IPFIX_IOAM_EXPORT_ID /* set_id */ ,
-                            b0->current_length - (sizeof (*ip) +
-                                                  sizeof (*udp) +
-                                                  sizeof (*h)));
+      s->set_id_length = ipfix_set_id_length (em->set_id /* set_id */ ,
+                                             b0->current_length -
+                                             (sizeof (*ip) + sizeof (*udp) +
+                                              sizeof (*h)));
       h->version_length =
        version_length (b0->current_length - (sizeof (*ip) + sizeof (*udp)));
       sum0 = ip->checksum;
@@ -328,12 +344,12 @@ ioam_export_send_buffer (ioam_export_main_t * em, vlib_main_t * vm,
 
   /* Enqueue pkts to ip4-lookup */
 
-  nf = vlib_get_frame_to_node (vm, em->ip4_lookup_node_index);
+  nf = vlib_get_frame_to_node (vm, em->next_node_index);
   nf->n_vectors = 0;
   to_next = vlib_frame_vector_args (nf);
   nf->n_vectors = 1;
   to_next[0] = eb->buffer_index;
-  vlib_put_frame_to_node (vm, em->ip4_lookup_node_index, nf);
+  vlib_put_frame_to_node (vm, em->next_node_index, nf);
   return (1);
 
 }
@@ -396,7 +412,7 @@ ioam_export_process_common (ioam_export_main_t * em, vlib_main_t * vm,
            {
              pool_get_aligned (em->buffer_pool, new_eb,
                                CLIB_CACHE_LINE_BYTES);
-             memset (new_eb, 0, sizeof (*new_eb));
+             clib_memset (new_eb, 0, sizeof (*new_eb));
              if (ioam_export_init_buffer (em, vm, new_eb) == 1)
                {
                  new_pool_index = new_eb - em->buffer_pool;
@@ -420,11 +436,11 @@ ioam_export_process_common (ioam_export_main_t * em, vlib_main_t * vm,
           */
          for (i = 0; i < vec_len (thread_index); i++)
            {
-             while (__sync_lock_test_and_set (em->lockp[thread_index[i]], 1))
+             while (clib_atomic_test_and_set (em->lockp[thread_index[i]]))
                ;
              em->buffer_per_thread[thread_index[i]] =
                vec_pop (vec_buffer_indices);
-             *em->lockp[thread_index[i]] = 0;
+             clib_atomic_release (em->lockp[thread_index[i]]);
            }
 
          /* Send the buffers */
@@ -452,7 +468,7 @@ ioam_export_process_common (ioam_export_main_t * em, vlib_main_t * vm,
   return 0;                    /* not so much */
 }
 
-#define ioam_export_node_common(EM, VM, N, F, HTYPE, L, V, NEXT)               \
+#define ioam_export_node_common(EM, VM, N, F, HTYPE, L, V, NEXT, FIXUP_FUNC)   \
 do {                                                                           \
   u32 n_left_from, *from, *to_next;                                            \
   export_next_t next_index;                                                    \
@@ -463,8 +479,8 @@ do {                                                                           \
   from = vlib_frame_vector_args (F);                                           \
   n_left_from = (F)->n_vectors;                                                \
   next_index = (N)->cached_next_index;                                         \
-  while (__sync_lock_test_and_set ((EM)->lockp[(VM)->cpu_index], 1));          \
-  my_buf = ioam_export_get_my_buffer (EM, (VM)->cpu_index);                    \
+  while (clib_atomic_test_and_set ((EM)->lockp[(VM)->thread_index]));         \
+  my_buf = ioam_export_get_my_buffer (EM, (VM)->thread_index);                 \
   my_buf->touched_at = vlib_time_now (VM);                                     \
   while (n_left_from > 0)                                                      \
     {                                                                          \
@@ -510,6 +526,7 @@ do {                                                                           \
          ip_len1 =                                                            \
            ip_len1 > DEFAULT_EXPORT_SIZE ? DEFAULT_EXPORT_SIZE : ip_len1;     \
          copy3cachelines (eb0->data + eb0->current_length, ip0, ip_len0);     \
+         FIXUP_FUNC(eb0, p0);                                                 \
          eb0->current_length += DEFAULT_EXPORT_SIZE;                          \
          my_buf->records_in_this_buffer++;                                    \
          if (my_buf->records_in_this_buffer >= DEFAULT_EXPORT_RECORDS)        \
@@ -522,6 +539,7 @@ do {                                                                           \
          if (PREDICT_FALSE (eb0 == 0))                                        \
            goto NO_BUFFER1;                                                   \
          copy3cachelines (eb0->data + eb0->current_length, ip1, ip_len1);     \
+         FIXUP_FUNC(eb0, p1);                                                 \
          eb0->current_length += DEFAULT_EXPORT_SIZE;                          \
          my_buf->records_in_this_buffer++;                                    \
          if (my_buf->records_in_this_buffer >= DEFAULT_EXPORT_RECORDS)        \
@@ -578,6 +596,7 @@ do {                                                                           \
          ip_len0 =                                                            \
            ip_len0 > DEFAULT_EXPORT_SIZE ? DEFAULT_EXPORT_SIZE : ip_len0;     \
          copy3cachelines (eb0->data + eb0->current_length, ip0, ip_len0);     \
+         FIXUP_FUNC(eb0, p0);                                                 \
          eb0->current_length += DEFAULT_EXPORT_SIZE;                          \
          my_buf->records_in_this_buffer++;                                    \
          if (my_buf->records_in_this_buffer >= DEFAULT_EXPORT_RECORDS)        \
@@ -603,7 +622,7 @@ do {                                                                           \
     }                                                                          \
   vlib_node_increment_counter (VM, export_node.index,                          \
                               EXPORT_ERROR_RECORDED, pkts_recorded);          \
-  *(EM)->lockp[(VM)->cpu_index] = 0;                                           \
+  *(EM)->lockp[(VM)->thread_index] = 0;                                        \
 } while(0)
 
 #endif /* __included_ioam_export_h__ */