From 182e37e33f80cc65f3cf27b69e74d855dd858a7e Mon Sep 17 00:00:00 2001 From: Matus Fabian Date: Tue, 14 Aug 2018 04:21:26 -0700 Subject: [PATCH] NAT44: fix next_src_nat (VPP-1384) Use rx_fib_index instead of sm->inside_fib_index for session lookup key. Change-Id: I2d6cce5b9376fa8ac4d75a9bbfa8498be0fd1493 Signed-off-by: Matus Fabian --- src/plugins/nat/out2in.c | 13 ++++++----- test/test_nat.py | 57 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 6 deletions(-) diff --git a/src/plugins/nat/out2in.c b/src/plugins/nat/out2in.c index 774ae67d50a..d30830812d8 100755 --- a/src/plugins/nat/out2in.c +++ b/src/plugins/nat/out2in.c @@ -1712,13 +1712,13 @@ icmp_get_ed_key(ip4_header_t *ip0, nat_ed_ses_key_t *p_key0) static int next_src_nat (snat_main_t * sm, ip4_header_t * ip, u8 proto, u16 src_port, - u16 dst_port, u32 thread_index) + u16 dst_port, u32 thread_index, u32 rx_fib_index) { clib_bihash_kv_16_8_t kv, value; snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index]; make_ed_kv (&kv, &ip->src_address, &ip->dst_address, proto, - sm->inside_fib_index, src_port, dst_port); + rx_fib_index, src_port, dst_port); if (!clib_bihash_search_16_8 (&tsm->in2out_ed, &kv, &value)) return 1; @@ -1870,7 +1870,8 @@ icmp_match_out2in_ed (snat_main_t * sm, vlib_node_runtime_t * node, else { dont_translate = 1; - if (next_src_nat(sm, ip, key.proto, key.l_port, key.r_port, thread_index)) + if (next_src_nat(sm, ip, key.proto, key.l_port, key.r_port, + thread_index, rx_fib_index)) { next = NAT44_ED_OUT2IN_NEXT_IN2OUT; goto out; @@ -2194,7 +2195,7 @@ nat44_ed_out2in_node_fn_inline (vlib_main_t * vm, { if (next_src_nat(sm, ip0, ip0->protocol, udp0->src_port, udp0->dst_port, - thread_index)) + thread_index, rx_fib_index0)) { next0 = NAT44_ED_OUT2IN_NEXT_IN2OUT; goto trace00; @@ -2397,7 +2398,7 @@ nat44_ed_out2in_node_fn_inline (vlib_main_t * vm, { if (next_src_nat(sm, ip1, ip1->protocol, udp1->src_port, udp1->dst_port, - thread_index)) + thread_index, rx_fib_index1)) { next1 = NAT44_ED_OUT2IN_NEXT_IN2OUT; goto trace01; @@ -2632,7 +2633,7 @@ nat44_ed_out2in_node_fn_inline (vlib_main_t * vm, { if (next_src_nat(sm, ip0, ip0->protocol, udp0->src_port, udp0->dst_port, - thread_index)) + thread_index, rx_fib_index0)) { next0 = NAT44_ED_OUT2IN_NEXT_IN2OUT; goto trace0; diff --git a/test/test_nat.py b/test/test_nat.py index 424b92c6e34..76cc7338c5a 100644 --- a/test/test_nat.py +++ b/test/test_nat.py @@ -3972,6 +3972,63 @@ class TestNAT44EndpointDependent(MethodHolder): self.logger.error(ppp("Unexpected or invalid packet:", p)) raise + def test_next_src_nat(self): + """ On way back forward packet to nat44-in2out node. """ + twice_nat_addr = '10.0.1.3' + external_port = 80 + local_port = 8080 + post_twice_nat_port = 0 + + self.vapi.nat44_forwarding_enable_disable(1) + self.nat44_add_address(twice_nat_addr, twice_nat=1) + self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4, + local_port, external_port, + proto=IP_PROTOS.tcp, out2in_only=1, + self_twice_nat=1, vrf_id=1) + self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index, + is_inside=0) + + p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) / + IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) / + TCP(sport=12345, dport=external_port)) + self.pg6.add_stream(p) + self.pg_enable_capture(self.pg_interfaces) + self.pg_start() + capture = self.pg6.get_capture(1) + p = capture[0] + try: + ip = p[IP] + tcp = p[TCP] + self.assertEqual(ip.src, twice_nat_addr) + self.assertNotEqual(tcp.sport, 12345) + post_twice_nat_port = tcp.sport + self.assertEqual(ip.dst, self.pg6.remote_ip4) + self.assertEqual(tcp.dport, local_port) + self.assert_packet_checksums_valid(p) + except: + self.logger.error(ppp("Unexpected or invalid packet:", p)) + raise + + p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) / + IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) / + TCP(sport=local_port, dport=post_twice_nat_port)) + self.pg6.add_stream(p) + self.pg_enable_capture(self.pg_interfaces) + self.pg_start() + capture = self.pg6.get_capture(1) + p = capture[0] + try: + ip = p[IP] + tcp = p[TCP] + self.assertEqual(ip.src, self.pg1.remote_ip4) + self.assertEqual(tcp.sport, external_port) + self.assertEqual(ip.dst, self.pg6.remote_ip4) + self.assertEqual(tcp.dport, 12345) + self.assert_packet_checksums_valid(p) + except: + self.logger.error(ppp("Unexpected or invalid packet:", p)) + raise + def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False, client_id=None): twice_nat_addr = '10.0.1.3' -- 2.16.6