nat: elog rewrite for multi-worker support
[vpp.git] / src / plugins / nat / nat44_classify.c
index 0e9863c..aa2bf73 100644 (file)
 #include <nat/nat_reass.h>
 #include <nat/nat_inlines.h>
 
-vlib_node_registration_t nat44_classify_node;
-vlib_node_registration_t nat44_ed_classify_node;
-vlib_node_registration_t nat44_det_classify_node;
-vlib_node_registration_t nat44_handoff_classify_node;
-
 #define foreach_nat44_classify_error                      \
 _(MAX_REASS, "Maximum reassemblies exceeded")             \
-_(MAX_FRAG, "Maximum fragments per reassembly exceeded")
+_(MAX_FRAG, "Maximum fragments per reassembly exceeded")  \
+_(NEXT_IN2OUT, "next in2out")                             \
+_(NEXT_OUT2IN, "next out2in")                             \
+_(FRAG_CACHED, "fragment cached")
 
 typedef enum
 {
@@ -93,6 +91,7 @@ nat44_classify_node_fn_inline (vlib_main_t * vm,
   snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
   u32 *fragments_to_drop = 0;
   u32 *fragments_to_loopback = 0;
+  u32 next_in2out = 0, next_out2in = 0, frag_cached = 0;
 
   from = vlib_frame_vector_args (frame);
   n_left_from = frame->n_vectors;
@@ -155,7 +154,7 @@ nat44_classify_node_fn_inline (vlib_main_t * vm,
                          next0 = NAT44_CLASSIFY_NEXT_DROP;
                          b0->error =
                            node->errors[NAT44_CLASSIFY_ERROR_MAX_REASS];
-                         nat_log_notice ("maximum reassemblies exceeded");
+                         nat_elog_notice ("maximum reassemblies exceeded");
                          goto enqueue0;
                        }
                      if (!clib_bihash_search_16_8 (&tsm->in2out_ed, &ed_kv0,
@@ -205,7 +204,7 @@ nat44_classify_node_fn_inline (vlib_main_t * vm,
                      next0 = NAT44_CLASSIFY_NEXT_DROP;
                      b0->error =
                        node->errors[NAT44_CLASSIFY_ERROR_MAX_REASS];
-                     nat_log_notice ("maximum reassemblies exceeded");
+                     nat_elog_notice ("maximum reassemblies exceeded");
                      goto enqueue0;
                    }
                  /* check if first fragment has arrived */
@@ -213,12 +212,12 @@ nat44_classify_node_fn_inline (vlib_main_t * vm,
                      !(reass0->flags & NAT_REASS_FLAG_CLASSIFY_ED_CONTINUE))
                    {
                      /* first fragment still hasn't arrived, cache this fragment */
-                     if (nat_ip4_reass_add_fragment (reass0, bi0,
-                                                     &fragments_to_drop))
+                     if (nat_ip4_reass_add_fragment
+                         (thread_index, reass0, bi0, &fragments_to_drop))
                        {
                          b0->error =
                            node->errors[NAT44_CLASSIFY_ERROR_MAX_FRAG];
-                         nat_log_notice
+                         nat_elog_notice
                            ("maximum fragments per reassembly exceeded");
                          next0 = NAT44_CLASSIFY_NEXT_DROP;
                          goto enqueue0;
@@ -289,7 +288,7 @@ nat44_classify_node_fn_inline (vlib_main_t * vm,
                          next0 = NAT44_CLASSIFY_NEXT_DROP;
                          b0->error =
                            node->errors[NAT44_CLASSIFY_ERROR_MAX_REASS];
-                         nat_log_notice ("maximum reassemblies exceeded");
+                         nat_elog_notice ("maximum reassemblies exceeded");
                          goto enqueue0;
                        }
                      /* save classification for future fragments and set past
@@ -318,18 +317,18 @@ nat44_classify_node_fn_inline (vlib_main_t * vm,
                      next0 = NAT44_CLASSIFY_NEXT_DROP;
                      b0->error =
                        node->errors[NAT44_CLASSIFY_ERROR_MAX_REASS];
-                     nat_log_notice ("maximum reassemblies exceeded");
+                     nat_elog_notice ("maximum reassemblies exceeded");
                      goto enqueue0;
                    }
                  if (reass0->classify_next == NAT_REASS_IP4_CLASSIFY_NONE)
                    /* first fragment still hasn't arrived */
                    {
-                     if (nat_ip4_reass_add_fragment (reass0, bi0,
-                                                     &fragments_to_drop))
+                     if (nat_ip4_reass_add_fragment
+                         (thread_index, reass0, bi0, &fragments_to_drop))
                        {
                          b0->error =
                            node->errors[NAT44_CLASSIFY_ERROR_MAX_FRAG];
-                         nat_log_notice
+                         nat_elog_notice
                            ("maximum fragments per reassembly exceeded");
                          next0 = NAT44_CLASSIFY_NEXT_DROP;
                          goto enqueue0;
@@ -361,12 +360,18 @@ nat44_classify_node_fn_inline (vlib_main_t * vm,
            {
              n_left_to_next++;
              to_next--;
+             frag_cached++;
            }
          else
-           /* verify speculative enqueue, maybe switch current next frame */
-           vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
-                                            to_next, n_left_to_next,
-                                            bi0, next0);
+           {
+             next_in2out += next0 == NAT44_CLASSIFY_NEXT_IN2OUT;
+             next_out2in += next0 == NAT44_CLASSIFY_NEXT_OUT2IN;
+
+             /* verify speculative enqueue, maybe switch current next frame */
+             vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
+                                              to_next, n_left_to_next,
+                                              bi0, next0);
+           }
 
          if (n_left_from == 0 && vec_len (fragments_to_loopback))
            {
@@ -374,17 +379,16 @@ nat44_classify_node_fn_inline (vlib_main_t * vm,
              u32 len = vec_len (fragments_to_loopback);
              if (len <= VLIB_FRAME_SIZE)
                {
-                 clib_memcpy (from, fragments_to_loopback,
-                              sizeof (u32) * len);
+                 clib_memcpy_fast (from, fragments_to_loopback,
+                                   sizeof (u32) * len);
                  n_left_from = len;
                  vec_reset_length (fragments_to_loopback);
                }
              else
                {
-                 clib_memcpy (from,
-                              fragments_to_loopback + (len -
-                                                       VLIB_FRAME_SIZE),
-                              sizeof (u32) * VLIB_FRAME_SIZE);
+                 clib_memcpy_fast (from, fragments_to_loopback +
+                                   (len - VLIB_FRAME_SIZE),
+                                   sizeof (u32) * VLIB_FRAME_SIZE);
                  n_left_from = VLIB_FRAME_SIZE;
                  _vec_len (fragments_to_loopback) = len - VLIB_FRAME_SIZE;
                }
@@ -399,19 +403,25 @@ nat44_classify_node_fn_inline (vlib_main_t * vm,
 
   vec_free (fragments_to_drop);
 
+  vlib_node_increment_counter (vm, node->node_index,
+                              NAT44_CLASSIFY_ERROR_NEXT_IN2OUT, next_in2out);
+  vlib_node_increment_counter (vm, node->node_index,
+                              NAT44_CLASSIFY_ERROR_NEXT_OUT2IN, next_out2in);
+  vlib_node_increment_counter (vm, node->node_index,
+                              NAT44_CLASSIFY_ERROR_FRAG_CACHED, frag_cached);
+
   return frame->n_vectors;
 }
 
-static uword
-nat44_classify_node_fn (vlib_main_t * vm,
-                       vlib_node_runtime_t * node, vlib_frame_t * frame)
+VLIB_NODE_FN (nat44_classify_node) (vlib_main_t * vm,
+                                   vlib_node_runtime_t * node,
+                                   vlib_frame_t * frame)
 {
   return nat44_classify_node_fn_inline (vm, node, frame, 0);
 }
 
 /* *INDENT-OFF* */
 VLIB_REGISTER_NODE (nat44_classify_node) = {
-  .function = nat44_classify_node_fn,
   .name = "nat44-classify",
   .vector_size = sizeof (u32),
   .format_trace = format_nat44_classify_trace,
@@ -427,17 +437,15 @@ VLIB_REGISTER_NODE (nat44_classify_node) = {
 };
 /* *INDENT-ON* */
 
-VLIB_NODE_FUNCTION_MULTIARCH (nat44_classify_node, nat44_classify_node_fn);
-static uword
-nat44_ed_classify_node_fn (vlib_main_t * vm,
-                          vlib_node_runtime_t * node, vlib_frame_t * frame)
+VLIB_NODE_FN (nat44_ed_classify_node) (vlib_main_t * vm,
+                                      vlib_node_runtime_t * node,
+                                      vlib_frame_t * frame)
 {
   return nat44_classify_node_fn_inline (vm, node, frame, 1);
 }
 
 /* *INDENT-OFF* */
 VLIB_REGISTER_NODE (nat44_ed_classify_node) = {
-  .function = nat44_ed_classify_node_fn,
   .name = "nat44-ed-classify",
   .vector_size = sizeof (u32),
   .format_trace = format_nat44_classify_trace,
@@ -451,19 +459,15 @@ VLIB_REGISTER_NODE (nat44_ed_classify_node) = {
 };
 /* *INDENT-ON* */
 
-VLIB_NODE_FUNCTION_MULTIARCH (nat44_ed_classify_node,
-                             nat44_ed_classify_node_fn);
-
-static uword
-nat44_det_classify_node_fn (vlib_main_t * vm,
-                           vlib_node_runtime_t * node, vlib_frame_t * frame)
+VLIB_NODE_FN (nat44_det_classify_node) (vlib_main_t * vm,
+                                       vlib_node_runtime_t * node,
+                                       vlib_frame_t * frame)
 {
   return nat44_classify_node_fn_inline (vm, node, frame, 0);
 }
 
 /* *INDENT-OFF* */
 VLIB_REGISTER_NODE (nat44_det_classify_node) = {
-  .function = nat44_det_classify_node_fn,
   .name = "nat44-det-classify",
   .vector_size = sizeof (u32),
   .format_trace = format_nat44_classify_trace,
@@ -477,20 +481,15 @@ VLIB_REGISTER_NODE (nat44_det_classify_node) = {
 };
 /* *INDENT-ON* */
 
-VLIB_NODE_FUNCTION_MULTIARCH (nat44_det_classify_node,
-                             nat44_det_classify_node_fn);
-
-static uword
-nat44_handoff_classify_node_fn (vlib_main_t * vm,
-                               vlib_node_runtime_t * node,
-                               vlib_frame_t * frame)
+VLIB_NODE_FN (nat44_handoff_classify_node) (vlib_main_t * vm,
+                                           vlib_node_runtime_t * node,
+                                           vlib_frame_t * frame)
 {
   return nat44_classify_node_fn_inline (vm, node, frame, 0);
 }
 
 /* *INDENT-OFF* */
 VLIB_REGISTER_NODE (nat44_handoff_classify_node) = {
-  .function = nat44_handoff_classify_node_fn,
   .name = "nat44-handoff-classify",
   .vector_size = sizeof (u32),
   .format_trace = format_nat44_classify_trace,
@@ -503,8 +502,6 @@ VLIB_REGISTER_NODE (nat44_handoff_classify_node) = {
   },
 };
 
-VLIB_NODE_FUNCTION_MULTIARCH (nat44_handoff_classify_node,
-                              nat44_handoff_classify_node_fn);
 /* *INDENT-ON* */
 
 /*