diff options
author | Matus Fabian <matfabia@cisco.com> | 2018-10-19 04:01:19 -0700 |
---|---|---|
committer | Matus Fabian <matfabia@cisco.com> | 2018-10-19 04:01:19 -0700 |
commit | da41d729b9339528b6c9bd1e859792303d15eb78 (patch) | |
tree | 116fe56e60da986d7258d298d9ba70406e3f3f16 /src/plugins/nat/in2out.c | |
parent | 2f6d7bb93c157b874efb79a2d1583a4c368bf89a (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/in2out.c')
-rwxr-xr-x | src/plugins/nat/in2out.c | 48 |
1 files changed, 42 insertions, 6 deletions
diff --git a/src/plugins/nat/in2out.c b/src/plugins/nat/in2out.c index b99aef3944d..cb169814eac 100755 --- a/src/plugins/nat/in2out.c +++ b/src/plugins/nat/in2out.c @@ -952,8 +952,7 @@ snat_in2out_node_fn_inline (vlib_main_t * vm, } else { - if (PREDICT_FALSE - (proto0 == ~0 || proto0 == SNAT_PROTOCOL_ICMP)) + if (PREDICT_FALSE (proto0 == ~0)) { next0 = SNAT_IN2OUT_NEXT_SLOW_PATH; goto trace00; @@ -964,6 +963,12 @@ snat_in2out_node_fn_inline (vlib_main_t * vm, next0 = SNAT_IN2OUT_NEXT_REASS; goto trace00; } + + if (PREDICT_FALSE (proto0 == SNAT_PROTOCOL_ICMP)) + { + next0 = SNAT_IN2OUT_NEXT_SLOW_PATH; + goto trace00; + } } key0.addr = ip0->src_address; @@ -1131,8 +1136,7 @@ snat_in2out_node_fn_inline (vlib_main_t * vm, } else { - if (PREDICT_FALSE - (proto1 == ~0 || proto1 == SNAT_PROTOCOL_ICMP)) + if (PREDICT_FALSE (proto1 == ~0)) { next1 = SNAT_IN2OUT_NEXT_SLOW_PATH; goto trace01; @@ -1143,6 +1147,12 @@ snat_in2out_node_fn_inline (vlib_main_t * vm, next1 = SNAT_IN2OUT_NEXT_REASS; goto trace01; } + + if (PREDICT_FALSE (proto1 == SNAT_PROTOCOL_ICMP)) + { + next1 = SNAT_IN2OUT_NEXT_SLOW_PATH; + goto trace01; + } } key1.addr = ip1->src_address; @@ -1346,8 +1356,7 @@ snat_in2out_node_fn_inline (vlib_main_t * vm, } else { - if (PREDICT_FALSE - (proto0 == ~0 || proto0 == SNAT_PROTOCOL_ICMP)) + if (PREDICT_FALSE (proto0 == ~0)) { next0 = SNAT_IN2OUT_NEXT_SLOW_PATH; goto trace0; @@ -1358,6 +1367,12 @@ snat_in2out_node_fn_inline (vlib_main_t * vm, next0 = SNAT_IN2OUT_NEXT_REASS; goto trace0; } + + if (PREDICT_FALSE (proto0 == SNAT_PROTOCOL_ICMP)) + { + next0 = SNAT_IN2OUT_NEXT_SLOW_PATH; + goto trace0; + } } key0.addr = ip0->src_address; @@ -1672,6 +1687,7 @@ nat44_in2out_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; clib_bihash_kv_8_8_t kv0, value0; snat_session_t *s0 = 0; @@ -1704,6 +1720,7 @@ nat44_in2out_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, @@ -1722,6 +1739,25 @@ nat44_in2out_reass_node_fn (vlib_main_t * vm, if (PREDICT_FALSE (ip4_is_first_fragment (ip0))) { + if (PREDICT_FALSE (proto0 == SNAT_PROTOCOL_ICMP)) + { + next0 = icmp_in2out_slow_path + (sm, b0, ip0, icmp0, sw_if_index0, rx_fib_index0, node, + next0, now, thread_index, &s0); + + if (PREDICT_TRUE (next0 != SNAT_IN2OUT_NEXT_DROP)) + { + if (s0) + reass0->sess_index = s0 - per_thread_data->sessions; + else + reass0->flags |= NAT_REASS_FLAG_ED_DONT_TRANSLATE; + nat_ip4_reass_get_frags (reass0, + &fragments_to_loopback); + } + + goto trace0; + } + key0.addr = ip0->src_address; key0.port = udp0->src_port; key0.protocol = proto0; |