nat: deal with flows instead of sessions
[vpp.git] / src / plugins / nat / nat44_classify.c
index b4645dc..85f8c64 100644 (file)
@@ -22,6 +22,7 @@
 #include <vnet/fib/ip4_fib.h>
 #include <nat/nat.h>
 #include <nat/nat_inlines.h>
+#include <nat/nat44/ed_inlines.h>
 
 #define foreach_nat44_classify_error                      \
 _(NEXT_IN2OUT, "next in2out")                             \
@@ -84,7 +85,6 @@ nat44_classify_node_fn_inline (vlib_main_t * vm,
   nat44_classify_next_t next_index;
   snat_main_t *sm = &snat_main;
   snat_static_mapping_t *m;
-  u32 *fragments_to_drop = 0;
   u32 next_in2out = 0, next_out2in = 0;
 
   from = vlib_frame_vector_args (frame);
@@ -104,7 +104,6 @@ nat44_classify_node_fn_inline (vlib_main_t * vm,
          u32 next0 = NAT44_CLASSIFY_NEXT_IN2OUT;
          ip4_header_t *ip0;
          snat_address_t *ap;
-         snat_session_key_t m_key0;
          clib_bihash_kv_8_8_t kv0, value0;
 
          /* speculatively enqueue b0 to the current next frame */
@@ -131,11 +130,7 @@ nat44_classify_node_fn_inline (vlib_main_t * vm,
 
          if (PREDICT_FALSE (pool_elts (sm->static_mappings)))
            {
-             m_key0.addr = ip0->dst_address;
-             m_key0.port = 0;
-             m_key0.protocol = 0;
-             m_key0.fib_index = 0;
-             kv0.key = m_key0.as_u64;
+             init_nat_k (&kv0, ip0->dst_address, 0, 0, 0);
              /* try to classify the fragment based on IP header alone */
              if (!clib_bihash_search_8_8 (&sm->static_mapping_by_external,
                                           &kv0, &value0))
@@ -145,10 +140,9 @@ nat44_classify_node_fn_inline (vlib_main_t * vm,
                    next0 = NAT44_CLASSIFY_NEXT_OUT2IN;
                  goto enqueue0;
                }
-             m_key0.port =
-               clib_net_to_host_u16 (vnet_buffer (b0)->ip.reass.l4_dst_port);
-             m_key0.protocol = ip_proto_to_snat_proto (ip0->protocol);
-             kv0.key = m_key0.as_u64;
+             init_nat_k (&kv0, ip0->dst_address,
+                         vnet_buffer (b0)->ip.reass.l4_dst_port, 0,
+                         ip_proto_to_nat_proto (ip0->protocol));
              if (!clib_bihash_search_8_8
                  (&sm->static_mapping_by_external, &kv0, &value0))
                {
@@ -180,11 +174,6 @@ nat44_classify_node_fn_inline (vlib_main_t * vm,
       vlib_put_next_frame (vm, node, next_index, n_left_to_next);
     }
 
-  nat_send_all_to_node (vm, fragments_to_drop, node, 0,
-                       NAT44_CLASSIFY_NEXT_DROP);
-
-  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,
@@ -201,7 +190,6 @@ nat44_handoff_classify_node_fn_inline (vlib_main_t * vm,
   nat44_classify_next_t next_index;
   snat_main_t *sm = &snat_main;
   snat_static_mapping_t *m;
-  u32 *fragments_to_drop = 0;
   u32 next_in2out = 0, next_out2in = 0;
 
   from = vlib_frame_vector_args (frame);
@@ -221,7 +209,6 @@ nat44_handoff_classify_node_fn_inline (vlib_main_t * vm,
          u32 next0 = NAT_NEXT_IN2OUT_CLASSIFY;
          ip4_header_t *ip0;
          snat_address_t *ap;
-         snat_session_key_t m_key0;
          clib_bihash_kv_8_8_t kv0, value0;
 
          /* speculatively enqueue b0 to the current next frame */
@@ -248,11 +235,7 @@ nat44_handoff_classify_node_fn_inline (vlib_main_t * vm,
 
          if (PREDICT_FALSE (pool_elts (sm->static_mappings)))
            {
-             m_key0.addr = ip0->dst_address;
-             m_key0.port = 0;
-             m_key0.protocol = 0;
-             m_key0.fib_index = 0;
-             kv0.key = m_key0.as_u64;
+             init_nat_k (&kv0, ip0->dst_address, 0, 0, 0);
              /* try to classify the fragment based on IP header alone */
              if (!clib_bihash_search_8_8 (&sm->static_mapping_by_external,
                                           &kv0, &value0))
@@ -262,10 +245,9 @@ nat44_handoff_classify_node_fn_inline (vlib_main_t * vm,
                    next0 = NAT_NEXT_OUT2IN_CLASSIFY;
                  goto enqueue0;
                }
-             m_key0.port =
-               clib_net_to_host_u16 (vnet_buffer (b0)->ip.reass.l4_dst_port);
-             m_key0.protocol = ip_proto_to_snat_proto (ip0->protocol);
-             kv0.key = m_key0.as_u64;
+             init_nat_k (&kv0, ip0->dst_address,
+                         vnet_buffer (b0)->ip.reass.l4_dst_port, 0,
+                         ip_proto_to_nat_proto (ip0->protocol));
              if (!clib_bihash_search_8_8
                  (&sm->static_mapping_by_external, &kv0, &value0))
                {
@@ -297,10 +279,6 @@ nat44_handoff_classify_node_fn_inline (vlib_main_t * vm,
       vlib_put_next_frame (vm, node, next_index, n_left_to_next);
     }
 
-  nat_send_all_to_node (vm, fragments_to_drop, node, 0, NAT_NEXT_DROP);
-
-  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,
@@ -317,9 +295,6 @@ nat44_ed_classify_node_fn_inline (vlib_main_t * vm,
   nat44_classify_next_t next_index;
   snat_main_t *sm = &snat_main;
   snat_static_mapping_t *m;
-  u32 thread_index = vm->thread_index;
-  snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
-  u32 *fragments_to_drop = 0;
   u32 next_in2out = 0, next_out2in = 0;
 
   from = vlib_frame_vector_args (frame);
@@ -340,7 +315,6 @@ nat44_ed_classify_node_fn_inline (vlib_main_t * vm,
          u32 sw_if_index0, rx_fib_index0;
          ip4_header_t *ip0;
          snat_address_t *ap;
-         snat_session_key_t m_key0;
          clib_bihash_kv_8_8_t kv0, value0;
          clib_bihash_kv_16_8_t ed_kv0, ed_value0;
 
@@ -366,15 +340,37 @@ nat44_ed_classify_node_fn_inline (vlib_main_t * vm,
              rx_fib_index0 =
                fib_table_get_index_for_sw_if_index (FIB_PROTOCOL_IP4,
                                                     sw_if_index0);
-             make_ed_kv (&ip0->src_address, &ip0->dst_address,
-                         ip0->protocol, rx_fib_index0,
-                         vnet_buffer (b0)->ip.reass.l4_src_port,
-                         vnet_buffer (b0)->ip.reass.l4_dst_port, ~0ULL,
-                         &ed_kv0);
+             init_ed_k (&ed_kv0, ip0->src_address,
+                        vnet_buffer (b0)->ip.reass.l4_src_port,
+                        ip0->dst_address,
+                        vnet_buffer (b0)->ip.reass.l4_dst_port,
+                        rx_fib_index0, ip0->protocol);
              /* process whole packet */
-             if (!clib_bihash_search_16_8
-                 (&tsm->in2out_ed, &ed_kv0, &ed_value0))
-               goto enqueue0;
+             if (!clib_bihash_search_16_8 (&sm->flow_hash, &ed_kv0,
+                                           &ed_value0))
+               {
+                 ASSERT (vm->thread_index ==
+                         ed_value_get_thread_index (&ed_value0));
+                 snat_main_per_thread_data_t *tsm =
+                   &sm->per_thread_data[vm->thread_index];
+                 snat_session_t *s = pool_elt_at_index (
+                   tsm->sessions, ed_value_get_session_index (&ed_value0));
+                 clib_bihash_kv_16_8_t i2o_kv;
+                 nat_6t_flow_to_ed_k (&i2o_kv, &s->i2o);
+                 vnet_buffer2 (b0)->nat.cached_session_index =
+                   ed_value_get_session_index (&ed_value0);
+                 if (i2o_kv.key[0] == ed_kv0.key[0] &&
+                     i2o_kv.key[1] == ed_kv0.key[1])
+                   {
+                     next0 = NAT_NEXT_IN2OUT_ED_FAST_PATH;
+                   }
+                 else
+                   {
+                     next0 = NAT_NEXT_OUT2IN_ED_FAST_PATH;
+                   }
+
+                 goto enqueue0;
+               }
              /* session doesn't exist so continue in code */
            }
 
@@ -391,11 +387,7 @@ nat44_ed_classify_node_fn_inline (vlib_main_t * vm,
 
          if (PREDICT_FALSE (pool_elts (sm->static_mappings)))
            {
-             m_key0.addr = ip0->dst_address;
-             m_key0.port = 0;
-             m_key0.protocol = 0;
-             m_key0.fib_index = 0;
-             kv0.key = m_key0.as_u64;
+             init_nat_k (&kv0, ip0->dst_address, 0, 0, 0);
              /* try to classify the fragment based on IP header alone */
              if (!clib_bihash_search_8_8 (&sm->static_mapping_by_external,
                                           &kv0, &value0))
@@ -405,10 +397,9 @@ nat44_ed_classify_node_fn_inline (vlib_main_t * vm,
                    next0 = NAT_NEXT_OUT2IN_ED_FAST_PATH;
                  goto enqueue0;
                }
-             m_key0.port =
-               clib_net_to_host_u16 (vnet_buffer (b0)->ip.reass.l4_dst_port);
-             m_key0.protocol = ip_proto_to_snat_proto (ip0->protocol);
-             kv0.key = m_key0.as_u64;
+             init_nat_k (&kv0, ip0->dst_address,
+                         vnet_buffer (b0)->ip.reass.l4_dst_port, 0,
+                         ip_proto_to_nat_proto (ip0->protocol));
              if (!clib_bihash_search_8_8
                  (&sm->static_mapping_by_external, &kv0, &value0))
                {
@@ -440,11 +431,6 @@ nat44_ed_classify_node_fn_inline (vlib_main_t * vm,
       vlib_put_next_frame (vm, node, next_index, n_left_to_next);
     }
 
-  nat_send_all_to_node (vm, fragments_to_drop, node, 0,
-                       NAT44_CLASSIFY_NEXT_DROP);
-
-  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,
@@ -493,28 +479,6 @@ VLIB_REGISTER_NODE (nat44_ed_classify_node) = {
 };
 /* *INDENT-ON* */
 
-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);
-}
-
-/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (nat44_det_classify_node) = {
-  .name = "nat44-det-classify",
-  .vector_size = sizeof (u32),
-  .format_trace = format_nat44_classify_trace,
-  .type = VLIB_NODE_TYPE_INTERNAL,
-  .n_next_nodes = NAT44_CLASSIFY_N_NEXT,
-  .next_nodes = {
-    [NAT44_CLASSIFY_NEXT_IN2OUT] = "nat44-det-in2out",
-    [NAT44_CLASSIFY_NEXT_OUT2IN] = "nat44-det-out2in",
-    [NAT44_CLASSIFY_NEXT_DROP] = "error-drop",
-  },
-};
-/* *INDENT-ON* */
-
 VLIB_NODE_FN (nat44_handoff_classify_node) (vlib_main_t * vm,
                                            vlib_node_runtime_t * node,
                                            vlib_frame_t * frame)