From: Matus Fabian Date: Fri, 11 May 2018 05:48:53 +0000 (-0700) Subject: NAT44: delete closed TCP session (VPP-1274) X-Git-Tag: v18.07-rc1~343 X-Git-Url: https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commitdiff_plain;h=17e5cfbe8d9b1f47b18eb1a43976fe322e3987a2 NAT44: delete closed TCP session (VPP-1274) Change-Id: Id25b447bddccb7b321123e4abc4134e7261a0807 Signed-off-by: Matus Fabian --- diff --git a/src/plugins/nat/in2out.c b/src/plugins/nat/in2out.c index d3369b6b49c..4a0d2653a81 100755 --- a/src/plugins/nat/in2out.c +++ b/src/plugins/nat/in2out.c @@ -535,7 +535,8 @@ nat_not_translate_output_feature_fwd (snat_main_t * sm, ip4_header_t * ip, if (ip->protocol == IP_PROTOCOL_TCP) { tcp_header_t *tcp = ip4_next_header(ip); - nat44_set_tcp_session_state (sm, s, tcp, thread_index); + if (nat44_set_tcp_session_state (sm, s, tcp, thread_index)) + return 1; } /* Per-user LRU list maintenance */ clib_dlist_remove (tsm->list_pool, s->per_user_index); @@ -1376,7 +1377,10 @@ snat_in2out_lb (snat_main_t *sm, if (is_fwd_bypass_session (s)) { if (ip->protocol == IP_PROTOCOL_TCP) - nat44_set_tcp_session_state (sm, s, tcp, thread_index); + { + if (nat44_set_tcp_session_state (sm, s, tcp, thread_index)) + return 0; + } /* Per-user LRU list maintenance */ clib_dlist_remove (tsm->list_pool, s->per_user_index); clib_dlist_addtail (tsm->list_pool, s->per_user_list_head_index, @@ -1450,6 +1454,9 @@ snat_in2out_lb (snat_main_t *sm, s->ext_host_addr.as_u32, ip4_header_t, dst_address); ip->checksum = ip_csum_fold (sum); + if (vnet_buffer(b)->sw_if_index[VLIB_TX] == ~0) + vnet_buffer(b)->sw_if_index[VLIB_TX] = sm->outside_fib_index; + if (PREDICT_TRUE(proto == SNAT_PROTOCOL_TCP)) { old_port = tcp->src_port; @@ -1470,7 +1477,8 @@ snat_in2out_lb (snat_main_t *sm, ip->dst_address.as_u32 = s->ext_host_addr.as_u32; } tcp->checksum = ip_csum_fold(sum); - nat44_set_tcp_session_state (sm, s, tcp, thread_index); + if (nat44_set_tcp_session_state (sm, s, tcp, thread_index)) + return s; } else { @@ -1483,9 +1491,6 @@ snat_in2out_lb (snat_main_t *sm, udp->checksum = 0; } - if (vnet_buffer(b)->sw_if_index[VLIB_TX] == ~0) - vnet_buffer(b)->sw_if_index[VLIB_TX] = sm->outside_fib_index; - /* Accounting */ s->last_heard = now; s->total_pkts++; @@ -1729,7 +1734,8 @@ snat_in2out_node_fn_inline (vlib_main_t * vm, ip4_header_t /* cheat */, length /* changed member */); tcp0->checksum = ip_csum_fold(sum0); - nat44_set_tcp_session_state (sm, s0, tcp0, thread_index); + if (nat44_set_tcp_session_state (sm, s0, tcp0, thread_index)) + goto trace00; } else { @@ -1922,7 +1928,8 @@ snat_in2out_node_fn_inline (vlib_main_t * vm, ip4_header_t /* cheat */, length /* changed member */); tcp1->checksum = ip_csum_fold(sum1); - nat44_set_tcp_session_state (sm, s1, tcp1, thread_index); + if (nat44_set_tcp_session_state (sm, s1, tcp1, thread_index)) + goto trace01; } else { @@ -2152,7 +2159,8 @@ snat_in2out_node_fn_inline (vlib_main_t * vm, ip4_header_t /* cheat */, length /* changed member */); tcp0->checksum = ip_csum_fold(sum0); - nat44_set_tcp_session_state (sm, s0, tcp0, thread_index); + if (nat44_set_tcp_session_state (sm, s0, tcp0, thread_index)) + goto trace0; } else { @@ -2669,6 +2677,10 @@ nat44_in2out_reass_node_fn (vlib_main_t * vm, src_address /* changed member */); ip0->checksum = ip_csum_fold (sum0); + /* Hairpinning */ + nat44_reass_hairpinning (sm, b0, ip0, s0->out2in.port, + s0->ext_host_port, proto0); + if (PREDICT_FALSE (ip4_is_first_fragment (ip0))) { if (PREDICT_TRUE(proto0 == SNAT_PROTOCOL_TCP)) @@ -2685,7 +2697,8 @@ nat44_in2out_reass_node_fn (vlib_main_t * vm, ip4_header_t /* cheat */, length /* changed member */); tcp0->checksum = ip_csum_fold(sum0); - nat44_set_tcp_session_state (sm, s0, tcp0, thread_index); + if (nat44_set_tcp_session_state (sm, s0, tcp0, thread_index)) + goto trace0; } else { @@ -2695,10 +2708,6 @@ nat44_in2out_reass_node_fn (vlib_main_t * vm, } } - /* Hairpinning */ - nat44_reass_hairpinning (sm, b0, ip0, s0->out2in.port, - s0->ext_host_port, proto0); - /* Accounting */ s0->last_heard = now; s0->total_pkts++; diff --git a/src/plugins/nat/nat.h b/src/plugins/nat/nat.h index 61d26b2076c..78b7962b83e 100644 --- a/src/plugins/nat/nat.h +++ b/src/plugins/nat/nat.h @@ -687,6 +687,33 @@ user_session_increment(snat_main_t *sm, snat_user_t *u, u8 is_static) } always_inline void +nat44_delete_session(snat_main_t * sm, snat_session_t * ses, u32 thread_index) +{ + snat_main_per_thread_data_t *tsm = vec_elt_at_index (sm->per_thread_data, + thread_index); + clib_bihash_kv_8_8_t kv, value; + snat_user_key_t u_key; + snat_user_t *u; + u_key.addr = ses->in2out.addr; + u_key.fib_index = ses->in2out.fib_index; + kv.key = u_key.as_u64; + if (!clib_bihash_search_8_8 (&tsm->user_hash, &kv, &value)) + { + u = pool_elt_at_index (tsm->users, value.value); + if (snat_is_session_static(ses)) + u->nstaticsessions--; + else + u->nsessions--; + } + clib_dlist_remove (tsm->list_pool, ses->per_user_index); + pool_put_index (tsm->list_pool, ses->per_user_index); + pool_put (tsm->sessions, ses); +} + +/** \brief Set TCP session stet. + @return 1 if session was closed, otherwise 0 +*/ +always_inline int nat44_set_tcp_session_state(snat_main_t * sm, snat_session_t * ses, tcp_header_t * tcp, u32 thread_index) { @@ -704,7 +731,11 @@ nat44_set_tcp_session_state(snat_main_t * sm, snat_session_t * ses, { nat_free_session_data (sm, ses, thread_index); ses->state = SNAT_SESSION_TCP_CLOSED; + nat44_delete_session (sm, ses, thread_index); + return 1; } + + return 0; } #endif /* __included_snat_h__ */ diff --git a/src/plugins/nat/out2in.c b/src/plugins/nat/out2in.c index c0f5a3c835a..6bc25b8cc22 100755 --- a/src/plugins/nat/out2in.c +++ b/src/plugins/nat/out2in.c @@ -410,7 +410,8 @@ create_bypass_for_fwd(snat_main_t * sm, ip4_header_t * ip, u32 rx_fib_index, if (ip->protocol == IP_PROTOCOL_TCP) { tcp_header_t *tcp = ip4_next_header(ip); - nat44_set_tcp_session_state (sm, s, tcp, thread_index); + if (nat44_set_tcp_session_state (sm, s, tcp, thread_index)) + return; } /* Per-user LRU list maintenance */ clib_dlist_remove (tsm->list_pool, s->per_user_index); @@ -1043,6 +1044,8 @@ snat_out2in_lb (snat_main_t *sm, src_address); ip->checksum = ip_csum_fold (sum); + vnet_buffer(b)->sw_if_index[VLIB_TX] = s->in2out.fib_index; + if (PREDICT_TRUE(proto == SNAT_PROTOCOL_TCP)) { old_port = tcp->dst_port; @@ -1063,7 +1066,8 @@ snat_out2in_lb (snat_main_t *sm, ip->src_address.as_u32 = s->ext_host_nat_addr.as_u32; } tcp->checksum = ip_csum_fold(sum); - nat44_set_tcp_session_state (sm, s, tcp, thread_index); + if (nat44_set_tcp_session_state (sm, s, tcp, thread_index)) + return s; } else { @@ -1076,8 +1080,6 @@ snat_out2in_lb (snat_main_t *sm, udp->checksum = 0; } - vnet_buffer(b)->sw_if_index[VLIB_TX] = s->in2out.fib_index; - /* Accounting */ s->last_heard = now; s->total_pkts++; @@ -1306,7 +1308,8 @@ snat_out2in_node_fn (vlib_main_t * vm, ip4_header_t /* cheat */, length /* changed member */); tcp0->checksum = ip_csum_fold(sum0); - nat44_set_tcp_session_state (sm, s0, tcp0, thread_index); + if (nat44_set_tcp_session_state (sm, s0, tcp0, thread_index)) + goto trace0; } else { @@ -1485,7 +1488,8 @@ snat_out2in_node_fn (vlib_main_t * vm, ip4_header_t /* cheat */, length /* changed member */); tcp1->checksum = ip_csum_fold(sum1); - nat44_set_tcp_session_state (sm, s1, tcp1, thread_index); + if (nat44_set_tcp_session_state (sm, s1, tcp1, thread_index)) + goto trace1; } else { @@ -1700,7 +1704,8 @@ snat_out2in_node_fn (vlib_main_t * vm, ip4_header_t /* cheat */, length /* changed member */); tcp0->checksum = ip_csum_fold(sum0); - nat44_set_tcp_session_state (sm, s0, tcp0, thread_index); + if (nat44_set_tcp_session_state (sm, s0, tcp0, thread_index)) + goto trace00; } else { @@ -1969,7 +1974,8 @@ nat44_out2in_reass_node_fn (vlib_main_t * vm, ip4_header_t /* cheat */, length /* changed member */); tcp0->checksum = ip_csum_fold(sum0); - nat44_set_tcp_session_state (sm, s0, tcp0, thread_index); + if (nat44_set_tcp_session_state (sm, s0, tcp0, thread_index)) + goto trace0; } else { diff --git a/test/test_nat.py b/test/test_nat.py index 7c841f515c4..c2e36be7697 100644 --- a/test/test_nat.py +++ b/test/test_nat.py @@ -4208,7 +4208,7 @@ class TestNAT44(MethodHolder): self.initiate_tcp_session(self.pg0, self.pg1) sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0) - self.assertEqual(len(sessions) - start_sessnum, 2) + self.assertEqual(len(sessions) - start_sessnum, 1) except: self.logger.error("TCP session termination failed") raise @@ -4271,7 +4271,7 @@ class TestNAT44(MethodHolder): self.initiate_tcp_session(self.pg0, self.pg1) sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0) - self.assertEqual(len(sessions) - start_sessnum, 2) + self.assertEqual(len(sessions) - start_sessnum, 1) except: self.logger.error("TCP session termination failed") raise @@ -4333,7 +4333,7 @@ class TestNAT44(MethodHolder): self.initiate_tcp_session(self.pg0, self.pg1) sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0) - self.assertEqual(len(sessions) - start_sessnum, 2) + self.assertEqual(len(sessions) - start_sessnum, 1) except: self.logger.error("TCP session termination failed") raise