summaryrefslogtreecommitdiffstats
path: root/src/plugins/nat/out2in.c
diff options
context:
space:
mode:
authorMatus Fabian <matfabia@cisco.com>2018-10-19 04:01:19 -0700
committerMatus Fabian <matfabia@cisco.com>2018-10-19 04:01:19 -0700
commitda41d729b9339528b6c9bd1e859792303d15eb78 (patch)
tree116fe56e60da986d7258d298d9ba70406e3f3f16 /src/plugins/nat/out2in.c
parent2f6d7bb93c157b874efb79a2d1583a4c368bf89a (diff)
NAT44: fix ICMP virtual fragmentation reassembly (VPP-1466)
Change-Id: I8006bca02948d9121f474a3d14f0576747bb3c51 Signed-off-by: Matus Fabian <matfabia@cisco.com>
Diffstat (limited to 'src/plugins/nat/out2in.c')
-rwxr-xr-xsrc/plugins/nat/out2in.c58
1 files changed, 40 insertions, 18 deletions
diff --git a/src/plugins/nat/out2in.c b/src/plugins/nat/out2in.c
index eeecf165264..c4d1fbf6900 100755
--- a/src/plugins/nat/out2in.c
+++ b/src/plugins/nat/out2in.c
@@ -775,17 +775,17 @@ snat_out2in_node_fn (vlib_main_t * vm,
goto trace0;
}
- if (PREDICT_FALSE (proto0 == SNAT_PROTOCOL_ICMP))
+ if (PREDICT_FALSE (ip4_is_fragment (ip0)))
{
- next0 = icmp_out2in_slow_path
- (sm, b0, ip0, icmp0, sw_if_index0, rx_fib_index0, node,
- next0, now, thread_index, &s0);
+ next0 = SNAT_OUT2IN_NEXT_REASS;
goto trace0;
}
- if (PREDICT_FALSE (ip4_is_fragment (ip0)))
+ if (PREDICT_FALSE (proto0 == SNAT_PROTOCOL_ICMP))
{
- next0 = SNAT_OUT2IN_NEXT_REASS;
+ next0 = icmp_out2in_slow_path
+ (sm, b0, ip0, icmp0, sw_if_index0, rx_fib_index0, node,
+ next0, now, thread_index, &s0);
goto trace0;
}
@@ -936,17 +936,17 @@ snat_out2in_node_fn (vlib_main_t * vm,
goto trace1;
}
- if (PREDICT_FALSE (proto1 == SNAT_PROTOCOL_ICMP))
+ if (PREDICT_FALSE (ip4_is_fragment (ip1)))
{
- next1 = icmp_out2in_slow_path
- (sm, b1, ip1, icmp1, sw_if_index1, rx_fib_index1, node,
- next1, now, thread_index, &s1);
+ next1 = SNAT_OUT2IN_NEXT_REASS;
goto trace1;
}
- if (PREDICT_FALSE (ip4_is_fragment (ip1)))
+ if (PREDICT_FALSE (proto1 == SNAT_PROTOCOL_ICMP))
{
- next1 = SNAT_OUT2IN_NEXT_REASS;
+ next1 = icmp_out2in_slow_path
+ (sm, b1, ip1, icmp1, sw_if_index1, rx_fib_index1, node,
+ next1, now, thread_index, &s1);
goto trace1;
}
@@ -1134,17 +1134,17 @@ snat_out2in_node_fn (vlib_main_t * vm,
goto trace00;
}
- if (PREDICT_FALSE (proto0 == SNAT_PROTOCOL_ICMP))
+ if (PREDICT_FALSE (ip4_is_fragment (ip0)))
{
- next0 = icmp_out2in_slow_path
- (sm, b0, ip0, icmp0, sw_if_index0, rx_fib_index0, node,
- next0, now, thread_index, &s0);
+ next0 = SNAT_OUT2IN_NEXT_REASS;
goto trace00;
}
- if (PREDICT_FALSE (ip4_is_fragment (ip0)))
+ if (PREDICT_FALSE (proto0 == SNAT_PROTOCOL_ICMP))
{
- next0 = SNAT_OUT2IN_NEXT_REASS;
+ next0 = icmp_out2in_slow_path
+ (sm, b0, ip0, icmp0, sw_if_index0, rx_fib_index0, node,
+ next0, now, thread_index, &s0);
goto trace00;
}
@@ -1336,6 +1336,7 @@ nat44_out2in_reass_node_fn (vlib_main_t * vm,
nat_reass_ip4_t *reass0;
udp_header_t *udp0;
tcp_header_t *tcp0;
+ icmp46_header_t *icmp0;
snat_session_key_t key0, sm0;
clib_bihash_kv_8_8_t kv0, value0;
snat_session_t *s0 = 0;
@@ -1369,6 +1370,7 @@ nat44_out2in_reass_node_fn (vlib_main_t * vm,
ip0 = (ip4_header_t *) vlib_buffer_get_current (b0);
udp0 = ip4_next_header (ip0);
tcp0 = (tcp_header_t *) udp0;
+ icmp0 = (icmp46_header_t *) udp0;
proto0 = ip_proto_to_snat_proto (ip0->protocol);
reass0 = nat_ip4_reass_find_or_create (ip0->src_address,
@@ -1387,6 +1389,26 @@ nat44_out2in_reass_node_fn (vlib_main_t * vm,
if (PREDICT_FALSE (ip4_is_first_fragment (ip0)))
{
+ if (PREDICT_FALSE (proto0 == SNAT_PROTOCOL_ICMP))
+ {
+ next0 = icmp_out2in_slow_path
+ (sm, b0, ip0, icmp0, sw_if_index0, rx_fib_index0, node,
+ next0, now, thread_index, &s0);
+
+ if (PREDICT_TRUE (next0 != SNAT_OUT2IN_NEXT_DROP))
+ {
+ if (s0)
+ reass0->sess_index = s0 - per_thread_data->sessions;
+ else
+ reass0->flags |= NAT_REASS_FLAG_ED_DONT_TRANSLATE;
+ reass0->thread_index = thread_index;
+ nat_ip4_reass_get_frags (reass0,
+ &fragments_to_loopback);
+ }
+
+ goto trace0;
+ }
+
key0.addr = ip0->dst_address;
key0.port = udp0->dst_port;
key0.protocol = proto0;