NAT: VPP-1537 IPFIX per worker processing
[vpp.git] / src / plugins / nat / nat44_classify.c
index 0e9863c..ed0c37e 100644 (file)
@@ -31,7 +31,10 @@ 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 +96,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;
@@ -213,8 +217,8 @@ 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];
@@ -324,8 +328,8 @@ nat44_classify_node_fn_inline (vlib_main_t * vm,
                  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];
@@ -361,12 +365,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 +384,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,6 +408,13 @@ 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;
 }