nat: cleanup & reorganization
[vpp.git] / src / plugins / nat / in2out_ed.c
index 0c65a50..5973d36 100644 (file)
 
 #include <vlib/vlib.h>
 #include <vnet/vnet.h>
-#include <vnet/pg/pg.h>
 #include <vnet/ip/ip.h>
 #include <vnet/ethernet/ethernet.h>
 #include <vnet/fib/ip4_fib.h>
-#include <vnet/udp/udp.h>
+#include <vnet/udp/udp_local.h>
 #include <vppinfra/error.h>
 #include <nat/nat.h>
-#include <nat/nat_ipfix_logging.h>
+#include <nat/lib/ipfix_logging.h>
 #include <nat/nat_inlines.h>
 #include <nat/nat44/inlines.h>
-#include <nat/nat_syslog.h>
+#include <nat/lib/nat_syslog.h>
 #include <nat/nat_ha.h>
 #include <nat/nat44/ed_inlines.h>
 #include <nat/lib/nat_inlines.h>
@@ -119,13 +118,13 @@ nat44_i2o_ed_is_idle_session_cb (clib_bihash_kv_16_8_t * kv, void *arg)
       if (snat_is_unk_proto_session (s))
        goto delete;
 
-      snat_ipfix_logging_nat44_ses_delete (ctx->thread_index,
-                                          s->in2out.addr.as_u32,
-                                          s->out2in.addr.as_u32,
-                                          s->nat_proto,
-                                          s->in2out.port,
-                                          s->out2in.port,
-                                          s->in2out.fib_index);
+      nat_ipfix_logging_nat44_ses_delete (ctx->thread_index,
+                                         s->in2out.addr.as_u32,
+                                         s->out2in.addr.as_u32,
+                                         s->nat_proto,
+                                         s->in2out.port,
+                                         s->out2in.port,
+                                         s->in2out.fib_index);
 
       nat_syslog_nat44_sdel (s->user_index, s->in2out.fib_index,
                             &s->in2out.addr, s->in2out.port,
@@ -285,7 +284,7 @@ nat_ed_alloc_addr_and_port (snat_main_t * sm, u32 rx_fib_index,
 #undef _
 
   /* Totally out of translations to use... */
-  snat_ipfix_logging_addresses_exhausted (thread_index, 0);
+  nat_ipfix_logging_addresses_exhausted (thread_index, 0);
   return 1;
 }
 
@@ -370,7 +369,7 @@ slow_path_ed (snat_main_t * sm,
   /* First try to match static mapping by local address and port */
   if (snat_static_mapping_match
       (sm, l_addr, l_port, rx_fib_index, nat_proto, &sm_addr, &sm_port,
-       &sm_fib_index, 0, 0, 0, &lb, 0, &identity_nat))
+       &sm_fib_index, 0, 0, 0, &lb, 0, &identity_nat, 0))
     {
       s = nat_ed_session_alloc (sm, thread_index, now, proto);
       ASSERT (s);
@@ -469,12 +468,12 @@ slow_path_ed (snat_main_t * sm,
   *sessionp = s;
 
   /* log NAT event */
-  snat_ipfix_logging_nat44_ses_create (thread_index,
-                                      s->in2out.addr.as_u32,
-                                      s->out2in.addr.as_u32,
-                                      s->nat_proto,
-                                      s->in2out.port,
-                                      s->out2in.port, s->in2out.fib_index);
+  nat_ipfix_logging_nat44_ses_create (thread_index,
+                                     s->in2out.addr.as_u32,
+                                     s->out2in.addr.as_u32,
+                                     s->nat_proto,
+                                     s->in2out.port,
+                                     s->out2in.port, s->in2out.fib_index);
 
   nat_syslog_nat44_sadd (s->user_index, s->in2out.fib_index,
                         &s->in2out.addr, s->in2out.port,
@@ -488,6 +487,8 @@ slow_path_ed (snat_main_t * sm,
               &s->ext_host_nat_addr, s->ext_host_nat_port,
               s->nat_proto, s->in2out.fib_index, s->flags, thread_index, 0);
 
+  per_vrf_sessions_register_session (s, thread_index);
+
   return next;
 }
 
@@ -512,7 +513,7 @@ nat44_ed_not_translate (snat_main_t * sm, vlib_node_runtime_t * node,
       if (!snat_static_mapping_match
          (sm, ip->dst_address, udp->dst_port, sm->outside_fib_index, proto,
           &placeholder_addr, &placeholder_port, &placeholder_fib_index, 1, 0,
-          0, 0, 0, 0))
+          0, 0, 0, 0, 0))
        return 0;
     }
   else
@@ -564,9 +565,7 @@ nat_not_translate_output_feature_fwd (snat_main_t * sm, ip4_header_t * ip,
        {
          if (ip->protocol == IP_PROTOCOL_TCP)
            {
-             if (nat44_set_tcp_session_state_i2o
-                 (sm, now, s, b, thread_index))
-               return 1;
+             nat44_set_tcp_session_state_i2o (sm, now, s, b, thread_index);
            }
          /* Accounting */
          nat44_session_update_counters (s, now,
@@ -886,6 +885,8 @@ nat44_ed_in2out_unknown_proto (snat_main_t * sm,
                  s - tsm->sessions);
       if (clib_bihash_add_del_16_8 (&sm->out2in_ed, &s_kv, 1))
        nat_elog_notice ("out2in key add failed");
+
+      per_vrf_sessions_register_session (s, thread_index);
     }
 
   /* Update IP checksum */
@@ -960,7 +961,6 @@ nat44_ed_in2out_fast_path_node_fn_inline (vlib_main_t * vm,
 
       if (is_output_feature)
        {
-         vnet_feature_next (&vnet_buffer2 (b0)->nat.arc_next, b0);
          iph_offset0 = vnet_buffer (b0)->ip.reass.save_rewrite_length;
        }
 
@@ -1024,11 +1024,20 @@ nat44_ed_in2out_fast_path_node_fn_inline (vlib_main_t * vm,
        pool_elt_at_index (tsm->sessions,
                           ed_value_get_session_index (&value0));
 
+      if (PREDICT_FALSE (per_vrf_sessions_is_expired (s0, thread_index)))
+       {
+         // session is closed, go slow path
+         nat_free_session_data (sm, s0, thread_index, 0);
+         nat_ed_session_delete (sm, s0, thread_index, 1);
+         next[0] = NAT_NEXT_OUT2IN_ED_SLOW_PATH;
+         goto trace0;
+       }
+
       if (s0->tcp_closed_timestamp)
        {
          if (now >= s0->tcp_closed_timestamp)
            {
-             // session is closed, go slow path
+             // session is closed, go slow path, freed in slow path
              next[0] = def_slow;
            }
          else
@@ -1103,8 +1112,7 @@ nat44_ed_in2out_fast_path_node_fn_inline (vlib_main_t * vm,
            }
          vlib_increment_simple_counter (&sm->counters.fastpath.in2out_ed.tcp,
                                         thread_index, sw_if_index0, 1);
-         if (nat44_set_tcp_session_state_i2o (sm, now, s0, b0, thread_index))
-           goto trace0;
+         nat44_set_tcp_session_state_i2o (sm, now, s0, b0, thread_index);
        }
       else if (!vnet_buffer (b0)->ip.reass.is_non_first_fragment
               && udp0->checksum)
@@ -1389,8 +1397,7 @@ nat44_ed_in2out_slow_path_node_fn_inline (vlib_main_t * vm,
            }
          vlib_increment_simple_counter (&sm->counters.slowpath.in2out_ed.tcp,
                                         thread_index, sw_if_index0, 1);
-         if (nat44_set_tcp_session_state_i2o (sm, now, s0, b0, thread_index))
-           goto trace0;
+         nat44_set_tcp_session_state_i2o (sm, now, s0, b0, thread_index);
        }
       else if (!vnet_buffer (b0)->ip.reass.is_non_first_fragment
               && udp0->checksum)
@@ -1573,6 +1580,13 @@ VLIB_NODE_FN (nat_pre_in2out_node)
                                 NAT_NEXT_IN2OUT_ED_FAST_PATH);
 }
 
+VLIB_NODE_FN (nat_pre_in2out_output_node)
+  (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
+{
+  return nat_pre_node_fn_inline (vm, node, frame,
+                                NAT_NEXT_IN2OUT_ED_OUTPUT_FAST_PATH);
+}
+
 /* *INDENT-OFF* */
 VLIB_REGISTER_NODE (nat_pre_in2out_node) = {
   .name = "nat-pre-in2out",
@@ -1582,6 +1596,15 @@ VLIB_REGISTER_NODE (nat_pre_in2out_node) = {
   .type = VLIB_NODE_TYPE_INTERNAL,
   .n_errors = 0,
 };
+
+VLIB_REGISTER_NODE (nat_pre_in2out_output_node) = {
+  .name = "nat-pre-in2out-output",
+  .vector_size = sizeof (u32),
+  .sibling_of = "nat-default",
+  .format_trace = format_nat_pre_trace,
+  .type = VLIB_NODE_TYPE_INTERNAL,
+  .n_errors = 0,
+};
 /* *INDENT-ON* */
 
 /*