summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatus Fabian <matfabia@cisco.com>2016-12-01 01:32:03 -0800
committerDamjan Marion <dmarion.lists@gmail.com>2016-12-02 14:42:26 +0000
commit4933168df31b88c24f03b467cae81a06b784813d (patch)
tree643266e220280a61974bb8b059236ffbaaa0173e
parentdcbc86a8afd3b928ffe5bd5a5d15da31ee762b4f (diff)
snat: fix 1:1 NAT with multiple workers
Assign worker when static mapping is created. Change-Id: I204e486e2ba5d1ef8e357759c35ba92a25a9a097 Signed-off-by: Matus Fabian <matfabia@cisco.com>
-rw-r--r--plugins/snat-plugin/snat/out2in.c17
-rw-r--r--plugins/snat-plugin/snat/snat.c29
-rw-r--r--vnet/etc/scripts/snat_static44
-rw-r--r--vnet/etc/scripts/snat_static_with_port44
4 files changed, 131 insertions, 3 deletions
diff --git a/plugins/snat-plugin/snat/out2in.c b/plugins/snat-plugin/snat/out2in.c
index 13e596b9a0d..f1f4159cdce 100644
--- a/plugins/snat-plugin/snat/out2in.c
+++ b/plugins/snat-plugin/snat/out2in.c
@@ -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;
diff --git a/plugins/snat-plugin/snat/snat.c b/plugins/snat-plugin/snat/snat.c
index 02077c329f0..d0bcabb73d1 100644
--- a/plugins/snat-plugin/snat/snat.c
+++ b/plugins/snat-plugin/snat/snat.c
@@ -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
index 00000000000..8fe48bffaaa
--- /dev/null
+++ b/vnet/etc/scripts/snat_static
@@ -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
index 00000000000..f646145a5bf
--- /dev/null
+++ b/vnet/etc/scripts/snat_static_with_port
@@ -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