aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/snat-plugin/snat
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 /plugins/snat-plugin/snat
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>
Diffstat (limited to 'plugins/snat-plugin/snat')
-rw-r--r--plugins/snat-plugin/snat/out2in.c17
-rw-r--r--plugins/snat-plugin/snat/snat.c29
2 files changed, 43 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
{