From 4933168df31b88c24f03b467cae81a06b784813d Mon Sep 17 00:00:00 2001 From: Matus Fabian Date: Thu, 1 Dec 2016 01:32:03 -0800 Subject: snat: fix 1:1 NAT with multiple workers Assign worker when static mapping is created. Change-Id: I204e486e2ba5d1ef8e357759c35ba92a25a9a097 Signed-off-by: Matus Fabian --- plugins/snat-plugin/snat/out2in.c | 17 ++++++++++--- plugins/snat-plugin/snat/snat.c | 29 ++++++++++++++++++++++ vnet/etc/scripts/snat_static | 44 ++++++++++++++++++++++++++++++++++ vnet/etc/scripts/snat_static_with_port | 44 ++++++++++++++++++++++++++++++++++ 4 files changed, 131 insertions(+), 3 deletions(-) create mode 100644 vnet/etc/scripts/snat_static create mode 100644 vnet/etc/scripts/snat_static_with_port 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 -- cgit 1.2.3-korg