nat: fix counters increment for output feature
[vpp.git] / src / plugins / nat / nat44-ed / nat44_ed_in2out.c
index f7257db..79c03bd 100644 (file)
@@ -326,7 +326,7 @@ nat44_ed_external_sm_lookup (snat_main_t *sm, ip4_address_t match_addr,
   if (dport)
     {
       /* Address only mapping doesn't change port */
-      *dport = is_addr_only_static_mapping (m) ? match_port : m->local_port;
+      *dport = is_sm_addr_only (m->flags) ? match_port : m->local_port;
     }
   return 1;
 }
@@ -342,7 +342,7 @@ slow_path_ed (vlib_main_t *vm, snat_main_t *sm, vlib_buffer_t *b,
   ip4_address_t outside_addr;
   u16 outside_port;
   u32 outside_fib_index;
-  u8 is_identity_nat;
+  u8 is_identity_nat = 0;
 
   u32 nat_proto = ip_proto_to_nat_proto (proto);
   snat_session_t *s = NULL;
@@ -350,17 +350,6 @@ slow_path_ed (vlib_main_t *vm, snat_main_t *sm, vlib_buffer_t *b,
   ip4_address_t daddr = r_addr;
   u16 dport = r_port;
 
-  if (PREDICT_TRUE (nat_proto == NAT_PROTOCOL_TCP))
-    {
-      if (PREDICT_FALSE
-         (!tcp_flags_is_init
-          (vnet_buffer (b)->ip.reass.icmp_type_or_tcp_flags)))
-       {
-         b->error = node->errors[NAT_IN2OUT_ED_ERROR_NON_SYN];
-         return NAT_NEXT_DROP;
-       }
-    }
-
   if (PREDICT_FALSE
       (nat44_ed_maximum_sessions_exceeded (sm, rx_fib_index, thread_index)))
     {
@@ -402,13 +391,22 @@ slow_path_ed (vlib_main_t *vm, snat_main_t *sm, vlib_buffer_t *b,
     }
   else
     {
+      if (PREDICT_FALSE (is_identity_nat))
+       {
+         *sessionp = NULL;
+         return next;
+       }
       is_sm = 1;
     }
 
-  if (PREDICT_FALSE (is_sm && is_identity_nat))
+  if (PREDICT_TRUE (nat_proto == NAT_PROTOCOL_TCP))
     {
-      *sessionp = NULL;
-      return next;
+      if (PREDICT_FALSE (!tcp_flags_is_init (
+           vnet_buffer (b)->ip.reass.icmp_type_or_tcp_flags)))
+       {
+         b->error = node->errors[NAT_IN2OUT_ED_ERROR_NON_SYN];
+         return NAT_NEXT_DROP;
+       }
     }
 
   s = nat_ed_session_alloc (sm, thread_index, now, proto);
@@ -990,7 +988,9 @@ nat44_ed_in2out_fast_path_node_fn_inline (vlib_main_t *vm,
   while (n_left_from > 0)
     {
       vlib_buffer_t *b0;
-      u32 sw_if_index0, rx_fib_index0, iph_offset0 = 0;
+      u32 rx_sw_if_index0, rx_fib_index0, iph_offset0 = 0;
+      u32 tx_sw_if_index0;
+      u32 cntr_sw_if_index0;
       nat_protocol_t proto0;
       ip4_header_t *ip0;
       snat_session_t *s0 = 0;
@@ -1012,7 +1012,7 @@ nat44_ed_in2out_fast_path_node_fn_inline (vlib_main_t *vm,
 
          vlib_prefetch_buffer_header (p2, LOAD);
 
-         CLIB_PREFETCH (p2->data, CLIB_CACHE_LINE_BYTES, LOAD);
+         clib_prefetch_load (p2->data);
        }
 
       if (is_output_feature)
@@ -1025,9 +1025,12 @@ nat44_ed_in2out_fast_path_node_fn_inline (vlib_main_t *vm,
       ip0 =
        (ip4_header_t *) ((u8 *) vlib_buffer_get_current (b0) + iph_offset0);
 
-      sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
-      rx_fib_index0 =
-       fib_table_get_index_for_sw_if_index (FIB_PROTOCOL_IP4, sw_if_index0);
+      rx_sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
+      tx_sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_TX];
+      cntr_sw_if_index0 =
+       is_output_feature ? tx_sw_if_index0 : rx_sw_if_index0;
+      rx_fib_index0 = fib_table_get_index_for_sw_if_index (FIB_PROTOCOL_IP4,
+                                                          rx_sw_if_index0);
       lookup.fib_index = rx_fib_index0;
 
       if (PREDICT_FALSE (!is_output_feature && ip0->ttl == 1))
@@ -1179,16 +1182,18 @@ nat44_ed_in2out_fast_path_node_fn_inline (vlib_main_t *vm,
          nat_free_session_data (sm, s0, thread_index, 0);
          nat_ed_session_delete (sm, s0, thread_index, 1);
          next[0] = NAT_NEXT_DROP;
+         b0->error = node->errors[NAT_IN2OUT_ED_ERROR_TRNSL_FAILED];
          goto trace0;
        }
 
       if (NAT_ED_TRNSL_ERR_SUCCESS !=
          (translation_error = nat_6t_flow_buf_translate_i2o (
-            sm, b0, ip0, f, proto0, is_output_feature)))
+            vm, sm, b0, ip0, f, proto0, is_output_feature)))
        {
          nat_free_session_data (sm, s0, thread_index, 0);
          nat_ed_session_delete (sm, s0, thread_index, 1);
          next[0] = NAT_NEXT_DROP;
+         b0->error = node->errors[NAT_IN2OUT_ED_ERROR_TRNSL_FAILED];
          goto trace0;
        }
 
@@ -1196,20 +1201,20 @@ nat44_ed_in2out_fast_path_node_fn_inline (vlib_main_t *vm,
        {
        case NAT_PROTOCOL_TCP:
          vlib_increment_simple_counter (&sm->counters.fastpath.in2out.tcp,
-                                        thread_index, sw_if_index0, 1);
+                                        thread_index, cntr_sw_if_index0, 1);
          nat44_set_tcp_session_state_i2o (sm, now, s0, b0, thread_index);
          break;
        case NAT_PROTOCOL_UDP:
          vlib_increment_simple_counter (&sm->counters.fastpath.in2out.udp,
-                                        thread_index, sw_if_index0, 1);
+                                        thread_index, cntr_sw_if_index0, 1);
          break;
        case NAT_PROTOCOL_ICMP:
          vlib_increment_simple_counter (&sm->counters.fastpath.in2out.icmp,
-                                        thread_index, sw_if_index0, 1);
+                                        thread_index, cntr_sw_if_index0, 1);
          break;
        case NAT_PROTOCOL_OTHER:
          vlib_increment_simple_counter (&sm->counters.fastpath.in2out.other,
-                                        thread_index, sw_if_index0, 1);
+                                        thread_index, cntr_sw_if_index0, 1);
          break;
        }
 
@@ -1227,7 +1232,7 @@ nat44_ed_in2out_fast_path_node_fn_inline (vlib_main_t *vm,
        {
          nat_in2out_ed_trace_t *t =
            vlib_add_trace (vm, node, b0, sizeof (*t));
-         t->sw_if_index = sw_if_index0;
+         t->sw_if_index = rx_sw_if_index0;
          t->next_index = next[0];
          t->is_slow_path = 0;
          t->translation_error = translation_error;
@@ -1250,7 +1255,7 @@ nat44_ed_in2out_fast_path_node_fn_inline (vlib_main_t *vm,
       if (next[0] == NAT_NEXT_DROP)
        {
          vlib_increment_simple_counter (&sm->counters.fastpath.in2out.drops,
-                                        thread_index, sw_if_index0, 1);
+                                        thread_index, cntr_sw_if_index0, 1);
        }
 
       n_left_from--;
@@ -1285,7 +1290,9 @@ nat44_ed_in2out_slow_path_node_fn_inline (vlib_main_t *vm,
   while (n_left_from > 0)
     {
       vlib_buffer_t *b0;
-      u32 sw_if_index0, rx_fib_index0, iph_offset0 = 0;
+      u32 rx_sw_if_index0, rx_fib_index0, iph_offset0 = 0;
+      u32 tx_sw_if_index0;
+      u32 cntr_sw_if_index0;
       nat_protocol_t proto0;
       ip4_header_t *ip0;
       udp_header_t *udp0;
@@ -1304,9 +1311,12 @@ nat44_ed_in2out_slow_path_node_fn_inline (vlib_main_t *vm,
       ip0 = (ip4_header_t *) ((u8 *) vlib_buffer_get_current (b0) +
                              iph_offset0);
 
-      sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
-      rx_fib_index0 =
-       fib_table_get_index_for_sw_if_index (FIB_PROTOCOL_IP4, sw_if_index0);
+      rx_sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
+      tx_sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_TX];
+      cntr_sw_if_index0 =
+       is_output_feature ? tx_sw_if_index0 : rx_sw_if_index0;
+      rx_fib_index0 = fib_table_get_index_for_sw_if_index (FIB_PROTOCOL_IP4,
+                                                          rx_sw_if_index0);
 
       if (PREDICT_FALSE (!is_output_feature && ip0->ttl == 1))
        {
@@ -1332,31 +1342,39 @@ nat44_ed_in2out_slow_path_node_fn_inline (vlib_main_t *vm,
          if (NAT_NEXT_DROP != next[0] && s0 &&
              NAT_ED_TRNSL_ERR_SUCCESS !=
                (translation_error = nat_6t_flow_buf_translate_i2o (
-                  sm, b0, ip0, &s0->i2o, proto0, is_output_feature)))
+                  vm, sm, b0, ip0, &s0->i2o, proto0, is_output_feature)))
            {
+             nat_free_session_data (sm, s0, thread_index, 0);
+             nat_ed_session_delete (sm, s0, thread_index, 1);
+             next[0] = NAT_NEXT_DROP;
+             b0->error = node->errors[NAT_IN2OUT_ED_ERROR_TRNSL_FAILED];
              goto trace0;
            }
 
          vlib_increment_simple_counter (&sm->counters.slowpath.in2out.other,
-                                        thread_index, sw_if_index0, 1);
+                                        thread_index, cntr_sw_if_index0, 1);
          goto trace0;
        }
 
       if (PREDICT_FALSE (proto0 == NAT_PROTOCOL_ICMP))
        {
          next[0] = icmp_in2out_ed_slow_path (
-           sm, b0, ip0, icmp0, sw_if_index0, rx_fib_index0, node, next[0],
+           sm, b0, ip0, icmp0, rx_sw_if_index0, rx_fib_index0, node, next[0],
            now, thread_index, proto0, &s0, is_multi_worker);
          if (NAT_NEXT_DROP != next[0] && s0 &&
              NAT_ED_TRNSL_ERR_SUCCESS !=
                (translation_error = nat_6t_flow_buf_translate_i2o (
-                  sm, b0, ip0, &s0->i2o, proto0, is_output_feature)))
+                  vm, sm, b0, ip0, &s0->i2o, proto0, is_output_feature)))
            {
+             nat_free_session_data (sm, s0, thread_index, 0);
+             nat_ed_session_delete (sm, s0, thread_index, 1);
+             next[0] = NAT_NEXT_DROP;
+             b0->error = node->errors[NAT_IN2OUT_ED_ERROR_TRNSL_FAILED];
              goto trace0;
            }
 
          vlib_increment_simple_counter (&sm->counters.slowpath.in2out.icmp,
-                                        thread_index, sw_if_index0, 1);
+                                        thread_index, cntr_sw_if_index0, 1);
          goto trace0;
        }
 
@@ -1386,8 +1404,7 @@ nat44_ed_in2out_slow_path_node_fn_inline (vlib_main_t *vm,
              if (PREDICT_FALSE (nat44_ed_not_translate_output_feature (
                    sm, b0, ip0, vnet_buffer (b0)->ip.reass.l4_src_port,
                    vnet_buffer (b0)->ip.reass.l4_dst_port, thread_index,
-                   sw_if_index0, vnet_buffer (b0)->sw_if_index[VLIB_TX], now,
-                   is_multi_worker)))
+                   rx_sw_if_index0, tx_sw_if_index0, now, is_multi_worker)))
                goto trace0;
 
              /*
@@ -1404,8 +1421,8 @@ nat44_ed_in2out_slow_path_node_fn_inline (vlib_main_t *vm,
          else
            {
              if (PREDICT_FALSE (nat44_ed_not_translate (
-                   vm, sm, node, sw_if_index0, b0, ip0, proto0, rx_fib_index0,
-                   thread_index)))
+                   vm, sm, node, rx_sw_if_index0, b0, ip0, proto0,
+                   rx_fib_index0, thread_index)))
                goto trace0;
            }
 
@@ -1427,24 +1444,25 @@ nat44_ed_in2out_slow_path_node_fn_inline (vlib_main_t *vm,
 
       if (NAT_ED_TRNSL_ERR_SUCCESS !=
          (translation_error = nat_6t_flow_buf_translate_i2o (
-            sm, b0, ip0, &s0->i2o, proto0, is_output_feature)))
+            vm, sm, b0, ip0, &s0->i2o, proto0, is_output_feature)))
        {
          nat_free_session_data (sm, s0, thread_index, 0);
          nat_ed_session_delete (sm, s0, thread_index, 1);
-         s0 = NULL;
+         next[0] = NAT_NEXT_DROP;
+         b0->error = node->errors[NAT_IN2OUT_ED_ERROR_TRNSL_FAILED];
          goto trace0;
        }
 
       if (PREDICT_TRUE (proto0 == NAT_PROTOCOL_TCP))
        {
          vlib_increment_simple_counter (&sm->counters.slowpath.in2out.tcp,
-                                        thread_index, sw_if_index0, 1);
+                                        thread_index, cntr_sw_if_index0, 1);
          nat44_set_tcp_session_state_i2o (sm, now, s0, b0, thread_index);
        }
       else
        {
          vlib_increment_simple_counter (&sm->counters.slowpath.in2out.udp,
-                                        thread_index, sw_if_index0, 1);
+                                        thread_index, cntr_sw_if_index0, 1);
        }
 
       /* Accounting */
@@ -1460,7 +1478,7 @@ nat44_ed_in2out_slow_path_node_fn_inline (vlib_main_t *vm,
        {
          nat_in2out_ed_trace_t *t =
            vlib_add_trace (vm, node, b0, sizeof (*t));
-         t->sw_if_index = sw_if_index0;
+         t->sw_if_index = rx_sw_if_index0;
          t->next_index = next[0];
          t->is_slow_path = 1;
          t->translation_error = translation_error;
@@ -1483,7 +1501,7 @@ nat44_ed_in2out_slow_path_node_fn_inline (vlib_main_t *vm,
       if (next[0] == NAT_NEXT_DROP)
        {
          vlib_increment_simple_counter (&sm->counters.slowpath.in2out.drops,
-                                        thread_index, sw_if_index0, 1);
+                                        thread_index, cntr_sw_if_index0, 1);
        }
 
       n_left_from--;