snat: fix 1:1 NAT with multiple workers
authorMatus Fabian <[email protected]>
Thu, 1 Dec 2016 09:32:03 +0000 (01:32 -0800)
committerDamjan Marion <[email protected]>
Fri, 2 Dec 2016 14:42:26 +0000 (14:42 +0000)
Assign worker when static mapping is created.

Change-Id: I204e486e2ba5d1ef8e357759c35ba92a25a9a097
Signed-off-by: Matus Fabian <[email protected]>
plugins/snat-plugin/snat/out2in.c
plugins/snat-plugin/snat/snat.c
vnet/etc/scripts/snat_static [new file with mode: 0644]
vnet/etc/scripts/snat_static_with_port [new file with mode: 0644]

index 13e596b..f1f4159 100644 (file)
@@ -877,9 +877,20 @@ snat_out2in_worker_handoff_fn (vlib_main_t * vm,
       /* Ever heard of of the "user" before? */
       if (clib_bihash_search_8_8 (&sm->worker_by_out, &kv0, &value0))
         {
-          /* No, assign next available worker (RR) */
-          next_worker_index = sm->first_worker_index +
-            sm->workers[sm->next_worker++ % vec_len (sm->workers)];
+          key0.port = 0;
+          kv0.key = key0.as_u64;
+
+          if (clib_bihash_search_8_8 (&sm->worker_by_out, &kv0, &value0))
+            {
+              /* No, assign next available worker (RR) */
+              next_worker_index = sm->first_worker_index +
+                sm->workers[sm->next_worker++ % vec_len (sm->workers)];
+            }
+          else
+            {
+              /* Static mapping without port */
+              next_worker_index = value0.value;
+            }
 
           /* Add to translated packets worker lookup */
           kv0.value = next_worker_index;
index 02077c3..d0bcabb 100644 (file)
@@ -440,6 +440,35 @@ int snat_add_static_mapping(ip4_address_t l_addr, ip4_address_t e_addr,
       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);
+
+      /* Assign worker */
+      if (sm->workers)
+        {
+          snat_user_key_t w_key0;
+          snat_static_mapping_key_t w_key1;
+
+          w_key0.addr = m->local_addr;
+          w_key0.fib_index = m->fib_index;
+          kv.key = w_key0.as_u64;
+
+          if (clib_bihash_search_8_8 (&sm->worker_by_in, &kv, &value))
+            {
+              kv.value = sm->first_worker_index +
+                sm->workers[sm->next_worker++ % vec_len (sm->workers)];
+
+              clib_bihash_add_del_8_8 (&sm->worker_by_in, &kv, 1);
+            }
+          else
+            {
+              kv.value = value.value;
+            }
+
+          w_key1.addr = m->external_addr;
+          w_key1.port = clib_host_to_net_u16 (m->external_port);
+          w_key1.fib_index = sm->outside_fib_index;
+          kv.key = w_key1.as_u64;
+          clib_bihash_add_del_8_8 (&sm->worker_by_out, &kv, 1);
+        }
     }
   else
     {
diff --git a/vnet/etc/scripts/snat_static b/vnet/etc/scripts/snat_static
new file mode 100644 (file)
index 0000000..8fe48bf
--- /dev/null
@@ -0,0 +1,44 @@
+create packet-generator interface pg0
+create packet-generator interface pg1
+
+packet-generator new {
+  name f1
+  limit 1000000
+  node ip4-input
+  size 64-64
+  no-recycle
+  worker 0
+  interface pg0
+  data {
+    UDP: 10.0.0.3 -> 172.16.1.2
+    UDP: 3000 -> 3001
+    length 128 checksum 0 incrementing 1
+  }
+}
+
+
+packet-generator new {
+  name f2
+  limit 1000000
+  node ip4-input
+  size 64-64
+  no-recycle
+  worker 1
+  interface pg1
+  data {
+    UDP: 172.16.1.2 -> 172.16.1.3
+    UDP: 3001 -> 3000
+    length 128 checksum 0 incrementing 1
+  }
+}
+
+snat add address 172.16.1.3
+snat add static mapping local 10.0.0.3 external 172.16.1.3
+set int ip address pg0 10.0.0.1/24
+set int ip address pg1 172.16.1.1/24
+set int state pg0 up
+set int state pg1 up
+set ip arp static pg0 10.0.0.3 abcd.abcd.abcd
+set ip arp static pg1 172.16.1.2 cdef.abcd.abcd
+set int snat in pg0 out pg1
+trace add pg-input 10
diff --git a/vnet/etc/scripts/snat_static_with_port b/vnet/etc/scripts/snat_static_with_port
new file mode 100644 (file)
index 0000000..f646145
--- /dev/null
@@ -0,0 +1,44 @@
+create packet-generator interface pg0
+create packet-generator interface pg1
+
+packet-generator new {
+  name f1
+  limit 1000000
+  node ip4-input
+  size 64-64
+  no-recycle
+  worker 0
+  interface pg0
+  data {
+    UDP: 10.0.0.3 -> 172.16.1.2
+    UDP: 3000 -> 3001
+    length 128 checksum 0 incrementing 1
+  }
+}
+
+
+packet-generator new {
+  name f2
+  limit 1000000
+  node ip4-input
+  size 64-64
+  no-recycle
+  worker 1
+  interface pg1
+  data {
+    UDP: 172.16.1.2 -> 172.16.1.3
+    UDP: 3001 -> 3000
+    length 128 checksum 0 incrementing 1
+  }
+}
+
+snat add address 172.16.1.3
+snat add static mapping local 10.0.0.3 3000 external 172.16.1.3 3000
+set int ip address pg0 10.0.0.1/24
+set int ip address pg1 172.16.1.1/24
+set int state pg0 up
+set int state pg1 up
+set ip arp static pg0 10.0.0.3 abcd.abcd.abcd
+set ip arp static pg1 172.16.1.2 cdef.abcd.abcd
+set int snat in pg0 out pg1
+trace add pg-input 10