VPP-446: 1:1 SNAT Inside overlapping interfaces 94/3294/2
authorMatus Fabian <matfabia@cisco.com>
Thu, 6 Oct 2016 11:28:29 +0000 (04:28 -0700)
committerOle Trøan <otroan@employees.org>
Thu, 13 Oct 2016 09:54:52 +0000 (09:54 +0000)
Change-Id: Idabf89bd27ee95769da16331a6bd1439497b2765
Signed-off-by: Matus Fabian <matfabia@cisco.com>
plugins/snat-plugin/snat/in2out.c
plugins/snat-plugin/snat/out2in.c
plugins/snat-plugin/snat/snat.c
plugins/snat-plugin/snat/snat.h

index 25dad93..9a4aeb0 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <vnet/ip/ip.h>
 #include <vnet/ethernet/ethernet.h>
+#include <vnet/fib/ip4_fib.h>
 #include <snat/snat.h>
 
 #include <vppinfra/hash.h>
@@ -1004,7 +1005,8 @@ static inline u32 icmp_in2out_static_map (snat_main_t *sm,
                                           icmp46_header_t * icmp0,
                                           u32 sw_if_index0,
                                           vlib_node_runtime_t * node,
-                                          u32 next0)
+                                          u32 next0,
+                                          u32 rx_fib_index0)
 {
   snat_session_key_t key0, sm0;
   icmp_echo_header_t *echo0;
@@ -1017,6 +1019,7 @@ static inline u32 icmp_in2out_static_map (snat_main_t *sm,
 
   key0.addr = ip0->src_address;
   key0.port = echo0->identifier;
+  key0.fib_index = rx_fib_index0;
   
   if (snat_static_mapping_match(sm, key0, &sm0, 0))
     {
@@ -1106,6 +1109,7 @@ snat_in2out_fast_static_map_fn (vlib_main_t * vm,
           icmp46_header_t * icmp0;
           snat_session_key_t key0, sm0;
           u32 proto0;
+          u32 rx_fib_index0;
 
           /* speculatively enqueue b0 to the current next frame */
          bi0 = from[0];
@@ -1124,6 +1128,7 @@ snat_in2out_fast_static_map_fn (vlib_main_t * vm,
           icmp0 = (icmp46_header_t *) udp0;
 
           sw_if_index0 = vnet_buffer(b0)->sw_if_index[VLIB_RX];
+         rx_fib_index0 = ip4_fib_table_get_index_for_sw_if_index(sw_if_index0);
 
           proto0 = ~0;
           proto0 = (ip0->protocol == IP_PROTOCOL_UDP)
@@ -1155,12 +1160,13 @@ snat_in2out_fast_static_map_fn (vlib_main_t * vm,
                 goto trace0;
 
               next0 = icmp_in2out_static_map
-                (sm, b0, ip0, icmp0, sw_if_index0, node, next0);
+                (sm, b0, ip0, icmp0, sw_if_index0, node, next0, rx_fib_index0);
               goto trace0;
             }
 
           key0.addr = ip0->src_address;
           key0.port = udp0->src_port;
+          key0.fib_index = rx_fib_index0;
 
           if (snat_static_mapping_match(sm, key0, &sm0, 0))
             {
index b3497c4..7601eb8 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <vnet/ip/ip.h>
 #include <vnet/ethernet/ethernet.h>
+#include <vnet/fib/ip4_fib.h>
 #include <snat/snat.h>
 
 #include <vppinfra/hash.h>
@@ -778,7 +779,8 @@ static inline u32 icmp_out2in_fast (snat_main_t *sm,
                                     icmp46_header_t * icmp0,
                                     u32 sw_if_index0,
                                     vlib_node_runtime_t * node,
-                                    u32 next0)
+                                    u32 next0,
+                                    u32 rx_fib_index0)
 {
   snat_session_key_t key0, sm0;
   icmp_echo_header_t *echo0;
@@ -791,6 +793,7 @@ static inline u32 icmp_out2in_fast (snat_main_t *sm,
 
   key0.addr = ip0->dst_address;
   key0.port = echo0->identifier;
+  key0.fib_index = rx_fib_index0;
 
   if (snat_static_mapping_match(sm, key0, &sm0, 1))
     {
@@ -879,6 +882,7 @@ snat_out2in_fast_node_fn (vlib_main_t * vm,
           icmp46_header_t * icmp0;
           snat_session_key_t key0, sm0;
           u32 proto0;
+          u32 rx_fib_index0;
 
           /* speculatively enqueue b0 to the current next frame */
          bi0 = from[0];
@@ -896,6 +900,7 @@ snat_out2in_fast_node_fn (vlib_main_t * vm,
           icmp0 = (icmp46_header_t *) udp0;
 
           sw_if_index0 = vnet_buffer(b0)->sw_if_index[VLIB_RX];
+         rx_fib_index0 = ip4_fib_table_get_index_for_sw_if_index(sw_if_index0);
 
          vnet_get_config_data (&cm->config_main,
                                 &b0->current_config_index,
@@ -915,12 +920,13 @@ snat_out2in_fast_node_fn (vlib_main_t * vm,
           if (PREDICT_FALSE (proto0 == SNAT_PROTOCOL_ICMP))
             {
               next0 = icmp_out2in_fast
-                (sm, b0, ip0, icmp0, sw_if_index0, node, next0);
+                (sm, b0, ip0, icmp0, sw_if_index0, node, next0, rx_fib_index0);
               goto trace00;
             }
 
           key0.addr = ip0->dst_address;
           key0.port = udp0->dst_port;
+          key0.fib_index = rx_fib_index0;
 
           if (snat_static_mapping_match(sm, key0, &sm0, 1))
             {
index 8360db5..8490bd8 100644 (file)
@@ -321,9 +321,18 @@ int snat_add_static_mapping(ip4_address_t l_addr, ip4_address_t e_addr,
   uword * p;
   int i;
 
+  /* If outside FIB index is not resolved yet */
+  if (sm->outside_fib_index == ~0)
+    {
+      p = hash_get (sm->ip4_main->fib_index_by_table_id, sm->outside_vrf_id);
+      if (!p)
+        return VNET_API_ERROR_NO_SUCH_FIB;
+      sm->outside_fib_index = p[0];
+    }
+
   m_key.addr = e_addr;
   m_key.port = addr_only ? 0 : e_port;
-  m_key.pad = 0;
+  m_key.fib_index = sm->outside_fib_index;
   kv.key = m_key.as_u64;
   if (clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value))
     m = 0;
@@ -360,15 +369,6 @@ int snat_add_static_mapping(ip4_address_t l_addr, ip4_address_t e_addr,
           vrf_id = sm->inside_vrf_id;
         }
 
-      /* If outside FIB index is not resolved yet */
-      if (sm->outside_fib_index == ~0)
-        {
-          p = hash_get (sm->ip4_main->fib_index_by_table_id, sm->outside_vrf_id);
-          if (!p)
-            return VNET_API_ERROR_NO_SUCH_FIB;
-          sm->outside_fib_index = p[0];
-        }
-
       /* Find external address in allocated addresses and reserve port for
          address and port pair mapping when dynamic translations enabled */
       if (!addr_only && !(sm->static_mapping_only))
@@ -409,13 +409,14 @@ int snat_add_static_mapping(ip4_address_t l_addr, ip4_address_t e_addr,
 
       m_key.addr = m->local_addr;
       m_key.port = m->local_port;
-      m_key.pad = 0;
+      m_key.fib_index = m->fib_index;
       kv.key = m_key.as_u64;
       kv.value = m - sm->static_mappings;
       clib_bihash_add_del_8_8(&sm->static_mapping_by_local, &kv, 1);
 
       m_key.addr = m->external_addr;
       m_key.port = m->external_port;
+      m_key.fib_index = sm->outside_fib_index;
       kv.key = m_key.as_u64;
       kv.value = m - sm->static_mappings;
       clib_bihash_add_del_8_8(&sm->static_mapping_by_external, &kv, 1);
@@ -444,12 +445,13 @@ int snat_add_static_mapping(ip4_address_t l_addr, ip4_address_t e_addr,
 
       m_key.addr = m->local_addr;
       m_key.port = m->local_port;
-      m_key.pad = 0;
+      m_key.fib_index = m->fib_index;
       kv.key = m_key.as_u64;
       clib_bihash_add_del_8_8(&sm->static_mapping_by_local, &kv, 0);
 
       m_key.addr = m->external_addr;
       m_key.port = m->external_port;
+      m_key.fib_index = sm->outside_fib_index;
       kv.key = m_key.as_u64;
       clib_bihash_add_del_8_8(&sm->static_mapping_by_external, &kv, 0);
 
@@ -967,7 +969,7 @@ int snat_static_mapping_match (snat_main_t * sm,
 
   m_key.addr = match.addr;
   m_key.port = clib_net_to_host_u16 (match.port);
-  m_key.pad = 0;
+  m_key.fib_index = match.fib_index;
 
   kv.key = m_key.as_u64;
 
index 823b860..531da28 100644 (file)
@@ -62,7 +62,7 @@ typedef struct {
     {
       ip4_address_t addr;
       u16 port;
-      u16 pad;
+      u16 fib_index;
     };
     u64 as_u64;
   };