diff options
author | Juraj Sloboda <jsloboda@cisco.com> | 2017-04-05 15:59:21 +0200 |
---|---|---|
committer | Damjan Marion <dmarion.lists@gmail.com> | 2017-04-12 17:17:18 +0000 |
commit | 30d857cd07785461f993ec4a935d99af75673f4a (patch) | |
tree | 11495b013158a4a44dbfee58c1f5ce71f46b658d /src/plugins/snat | |
parent | 6fb41fa52b559d2f6dda02d8739bcd54fbeb6c4f (diff) |
Handle multiple flows with the same client port in deterministic NAT
Handle situation when client tries to connect to multiple hosts/ports
from the same client port. Extend matching to include remote host/port
when searching for existing session and create session for each flow
even when originating from the same client port.
Change-Id: I4f54ded930e59e7196843c6bc1d2d2386c57cd3c
Signed-off-by: Juraj Sloboda <jsloboda@cisco.com>
Diffstat (limited to 'src/plugins/snat')
-rw-r--r-- | src/plugins/snat/in2out.c | 28 | ||||
-rw-r--r-- | src/plugins/snat/snat_det.h | 10 |
2 files changed, 23 insertions, 15 deletions
diff --git a/src/plugins/snat/in2out.c b/src/plugins/snat/in2out.c index 1e8e14484c3..5a2e2b7f2c3 100644 --- a/src/plugins/snat/in2out.c +++ b/src/plugins/snat/in2out.c @@ -1613,11 +1613,12 @@ snat_det_in2out_node_fn (vlib_main_t * vm, snat_det_forward(dm0, &ip0->src_address, &new_addr0, &lo_port0); - ses0 = snat_det_find_ses_by_in(dm0, &ip0->src_address, tcp0->src); + key0.ext_host_addr = ip0->dst_address; + key0.ext_host_port = tcp0->dst; + + ses0 = snat_det_find_ses_by_in(dm0, &ip0->src_address, tcp0->src, key0); if (PREDICT_FALSE(!ses0)) { - key0.ext_host_addr = ip0->dst_address; - key0.ext_host_port = tcp0->dst; for (i0 = 0; i0 < dm0->ports_per_host; i0++) { key0.out_port = clib_host_to_net_u16 (lo_port0 + @@ -1757,11 +1758,12 @@ snat_det_in2out_node_fn (vlib_main_t * vm, snat_det_forward(dm1, &ip1->src_address, &new_addr1, &lo_port1); - ses1 = snat_det_find_ses_by_in(dm1, &ip1->src_address, tcp1->src); + key1.ext_host_addr = ip1->dst_address; + key1.ext_host_port = tcp1->dst; + + ses1 = snat_det_find_ses_by_in(dm1, &ip1->src_address, tcp1->src, key1); if (PREDICT_FALSE(!ses1)) { - key1.ext_host_addr = ip1->dst_address; - key1.ext_host_port = tcp1->dst; for (i1 = 0; i1 < dm1->ports_per_host; i1++) { key1.out_port = clib_host_to_net_u16 (lo_port1 + @@ -1937,11 +1939,12 @@ snat_det_in2out_node_fn (vlib_main_t * vm, snat_det_forward(dm0, &ip0->src_address, &new_addr0, &lo_port0); - ses0 = snat_det_find_ses_by_in(dm0, &ip0->src_address, tcp0->src); + key0.ext_host_addr = ip0->dst_address; + key0.ext_host_port = tcp0->dst; + + ses0 = snat_det_find_ses_by_in(dm0, &ip0->src_address, tcp0->src, key0); if (PREDICT_FALSE(!ses0)) { - key0.ext_host_addr = ip0->dst_address; - key0.ext_host_port = tcp0->dst; for (i0 = 0; i0 < dm0->ports_per_host; i0++) { key0.out_port = clib_host_to_net_u16 (lo_port0 + @@ -2171,7 +2174,10 @@ u32 icmp_match_in2out_det(snat_main_t *sm, vlib_node_runtime_t *node, snat_det_forward(dm0, &in_addr, &new_addr0, &lo_port0); - ses0 = snat_det_find_ses_by_in(dm0, &in_addr, in_port); + key0.ext_host_addr = ip0->dst_address; + key0.ext_host_port = 0; + + ses0 = snat_det_find_ses_by_in(dm0, &in_addr, in_port, key0); if (PREDICT_FALSE(!ses0)) { if (PREDICT_FALSE(snat_not_translate_fast(sm, node, sw_if_index0, ip0, @@ -2186,8 +2192,6 @@ u32 icmp_match_in2out_det(snat_main_t *sm, vlib_node_runtime_t *node, next0 = SNAT_IN2OUT_NEXT_DROP; goto out; } - key0.ext_host_addr = ip0->dst_address; - key0.ext_host_port = 0; for (i0 = 0; i0 < dm0->ports_per_host; i0++) { key0.out_port = clib_host_to_net_u16 (lo_port0 + diff --git a/src/plugins/snat/snat_det.h b/src/plugins/snat/snat_det.h index 42ce87608b5..45e36829a20 100644 --- a/src/plugins/snat/snat_det.h +++ b/src/plugins/snat/snat_det.h @@ -125,16 +125,20 @@ snat_det_get_ses_by_out (snat_det_map_t * dm, ip4_address_t * in_addr, } always_inline snat_det_session_t * -snat_det_find_ses_by_in (snat_det_map_t * dm, - ip4_address_t * in_addr, u16 in_port) +snat_det_find_ses_by_in (snat_det_map_t * dm, ip4_address_t * in_addr, + u16 in_port, snat_det_out_key_t out_key) { + snat_det_session_t *ses; u32 user_offset; u16 i; user_offset = snat_det_user_ses_offset (in_addr, dm->in_plen); for (i = 0; i < SNAT_DET_SES_PER_USER; i++) { - if (dm->sessions[i + user_offset].in_port == in_port) + ses = &dm->sessions[i + user_offset]; + if (ses->in_port == in_port && + ses->out.ext_host_addr.as_u32 == out_key.ext_host_addr.as_u32 && + ses->out.ext_host_port == out_key.ext_host_port) return &dm->sessions[i + user_offset]; } |