From 9b8cb5082471dd670066b8ba2872ffbcc35a87f8 Mon Sep 17 00:00:00 2001 From: Elias Rudberg Date: Fri, 4 Dec 2020 19:32:55 +0100 Subject: nat: avoid hairpinning infinite loop problem Fix in nat44 hairpinning code to check if anything was actually changed in the snat_hairpinning() routine, and return 0 if nothing changed. This helps avoid an infinite loop repeating the three nodes nat44-hairpinning-->ip4-lookup-->ip4-local in case there was no change. Also add a corresponding test case. Type: fix Signed-off-by: Elias Rudberg Change-Id: I95f48476bd002ac4c6789afe504681f1963e5d38 Signed-off-by: Elias Rudberg --- src/plugins/nat/nat44_hairpinning.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src/plugins/nat/nat44_hairpinning.c') diff --git a/src/plugins/nat/nat44_hairpinning.c b/src/plugins/nat/nat44_hairpinning.c index 9eadcf30832..2859046ae05 100644 --- a/src/plugins/nat/nat44_hairpinning.c +++ b/src/plugins/nat/nat44_hairpinning.c @@ -108,6 +108,7 @@ snat_hairpinning (vlib_main_t * vm, vlib_node_runtime_t * node, ip4_address_t sm0_addr; u16 sm0_port; u32 sm0_fib_index; + u32 old_sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_TX]; /* Check if destination is static mappings */ if (!snat_static_mapping_match (sm, ip0->dst_address, udp0->dst_port, sm->outside_fib_index, proto0, @@ -159,6 +160,17 @@ snat_hairpinning (vlib_main_t * vm, vlib_node_runtime_t * node, vnet_buffer (b0)->sw_if_index[VLIB_TX] = s0->in2out.fib_index; } + /* Check if anything has changed and if not, then return 0. This + helps avoid infinite loop, repeating the three nodes + nat44-hairpinning-->ip4-lookup-->ip4-local, in case nothing has + changed. */ + old_dst_addr0 = ip0->dst_address.as_u32; + old_dst_port0 = tcp0->dst; + if (new_dst_addr0 == old_dst_addr0 + && new_dst_port0 == old_dst_port0 + && vnet_buffer (b0)->sw_if_index[VLIB_TX] == old_sw_if_index) + return 0; + /* Destination is behind the same NAT, use internal address and port */ if (new_dst_addr0) { -- cgit 1.2.3-korg