diff options
author | Matus Fabian <matfabia@cisco.com> | 2018-01-30 03:04:17 -0800 |
---|---|---|
committer | Ole Trøan <otroan@employees.org> | 2018-01-31 17:28:55 +0000 |
commit | f7ad5cbe819533523169e8a88876b94b9f38789c (patch) | |
tree | 9e2776f7d7d1f22675bf67e12df066b149834a78 /src | |
parent | b793d097c55ef28787e8e7ca39039f5be498cbf7 (diff) |
NAT44: in2out output feature skip translation for already translated packets (VPP-1156)
Change-Id: I5395245c9e49f741a949ada1f725c34f9379c249
Signed-off-by: Matus Fabian <matfabia@cisco.com>
Diffstat (limited to 'src')
-rwxr-xr-x | src/plugins/nat/in2out.c | 87 | ||||
-rw-r--r-- | src/plugins/nat/nat.c | 2 |
2 files changed, 74 insertions, 15 deletions
diff --git a/src/plugins/nat/in2out.c b/src/plugins/nat/in2out.c index a453328c38f..003b1ad3858 100755 --- a/src/plugins/nat/in2out.c +++ b/src/plugins/nat/in2out.c @@ -252,6 +252,27 @@ snat_not_translate (snat_main_t * sm, vlib_node_runtime_t *node, rx_fib_index0); } +static inline int +nat_not_translate_output_feature (snat_main_t * sm, ip4_header_t * ip0, + u32 proto0, u32 thread_index) +{ + udp_header_t * udp0 = ip4_next_header (ip0); + snat_session_key_t key0; + clib_bihash_kv_8_8_t kv0, value0; + + key0.addr = ip0->src_address; + key0.port = udp0->src_port; + key0.protocol = proto0; + key0.fib_index = sm->outside_fib_index; + kv0.key = key0.as_u64; + + if (!clib_bihash_search_8_8 (&sm->per_thread_data[thread_index].out2in, &kv0, + &value0)) + return 1; + + return 0; +} + static u32 slow_path (snat_main_t *sm, vlib_buffer_t *b0, ip4_header_t * ip0, u32 rx_fib_index0, @@ -497,12 +518,23 @@ u32 icmp_match_in2out_slow(snat_main_t *sm, vlib_node_runtime_t *node, if (clib_bihash_search_8_8 (&sm->per_thread_data[thread_index].in2out, &kv0, &value0)) { - if (PREDICT_FALSE(snat_not_translate(sm, node, sw_if_index0, ip0, - IP_PROTOCOL_ICMP, rx_fib_index0, thread_index) && - vnet_buffer(b0)->sw_if_index[VLIB_TX] == ~0)) + if (vnet_buffer(b0)->sw_if_index[VLIB_TX] != ~0) { - dont_translate = 1; - goto out; + if (PREDICT_FALSE(nat_not_translate_output_feature(sm, + ip0, IP_PROTOCOL_ICMP, thread_index))) + { + dont_translate = 1; + goto out; + } + } + else + { + if (PREDICT_FALSE(snat_not_translate(sm, node, sw_if_index0, + ip0, IP_PROTOCOL_ICMP, rx_fib_index0, thread_index))) + { + dont_translate = 1; + goto out; + } } if (PREDICT_FALSE(icmp_is_error_message (icmp0))) @@ -1517,9 +1549,18 @@ snat_in2out_node_fn_inline (vlib_main_t * vm, { if (is_slow_path) { - if (PREDICT_FALSE(snat_not_translate(sm, node, sw_if_index0, - ip0, proto0, rx_fib_index0, thread_index)) && !is_output_feature) - goto trace00; + if (is_output_feature) + { + if (PREDICT_FALSE(nat_not_translate_output_feature(sm, + ip0, proto0, thread_index))) + goto trace00; + } + else + { + if (PREDICT_FALSE(snat_not_translate(sm, node, sw_if_index0, + ip0, proto0, rx_fib_index0, thread_index))) + goto trace00; + } next0 = slow_path (sm, b0, ip0, rx_fib_index0, &key0, &s0, node, next0, thread_index); @@ -1696,9 +1737,18 @@ snat_in2out_node_fn_inline (vlib_main_t * vm, { if (is_slow_path) { - if (PREDICT_FALSE(snat_not_translate(sm, node, sw_if_index1, - ip1, proto1, rx_fib_index1, thread_index)) && !is_output_feature) - goto trace01; + if (is_output_feature) + { + if (PREDICT_FALSE(nat_not_translate_output_feature(sm, + ip1, proto1, thread_index))) + goto trace00; + } + else + { + if (PREDICT_FALSE(snat_not_translate(sm, node, sw_if_index1, + ip1, proto1, rx_fib_index1, thread_index))) + goto trace01; + } next1 = slow_path (sm, b1, ip1, rx_fib_index1, &key1, &s1, node, next1, thread_index); @@ -1907,9 +1957,18 @@ snat_in2out_node_fn_inline (vlib_main_t * vm, { if (is_slow_path) { - if (PREDICT_FALSE(snat_not_translate(sm, node, sw_if_index0, - ip0, proto0, rx_fib_index0, thread_index)) && !is_output_feature) - goto trace0; + if (is_output_feature) + { + if (PREDICT_FALSE(nat_not_translate_output_feature(sm, + ip0, proto0, thread_index))) + goto trace0; + } + else + { + if (PREDICT_FALSE(snat_not_translate(sm, node, sw_if_index0, + ip0, proto0, rx_fib_index0, thread_index))) + goto trace0; + } next0 = slow_path (sm, b0, ip0, rx_fib_index0, &key0, &s0, node, next0, thread_index); diff --git a/src/plugins/nat/nat.c b/src/plugins/nat/nat.c index 38caae43376..ef740d9d12b 100644 --- a/src/plugins/nat/nat.c +++ b/src/plugins/nat/nat.c @@ -774,7 +774,7 @@ int snat_add_static_mapping(ip4_address_t l_addr, ip4_address_t e_addr, } } /* External address must be allocated */ - if (!a) + if (!a && (l_addr.as_u32 != e_addr.as_u32)) return VNET_API_ERROR_NO_SUCH_ENTRY; } |