X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Ftcp%2Ftcp.c;h=e4335e067692f062d87e2447ffd2a31dc0c8a461;hb=1e8d949781a44846dabbf56e1aab80bbf4cc8d59;hp=2ac938a1b1e03427704f1e2a0f902d2be8d0859b;hpb=999840cf805f26a490e8e6b8acc1fe7a7c21a181;p=vpp.git diff --git a/src/vnet/tcp/tcp.c b/src/vnet/tcp/tcp.c index 2ac938a1b1e..e4335e06769 100644 --- a/src/vnet/tcp/tcp.c +++ b/src/vnet/tcp/tcp.c @@ -208,10 +208,14 @@ tcp_half_open_connection_del (tcp_connection_t * tc) int tcp_half_open_connection_cleanup (tcp_connection_t * tc) { + tcp_worker_ctx_t *wrk; + /* Make sure this is the owning thread */ if (tc->c_thread_index != vlib_get_thread_index ()) return 1; - tcp_timer_reset (tc, TCP_TIMER_RETRANSMIT_SYN); + + wrk = tcp_get_worker (tc->c_thread_index); + tcp_timer_reset (&wrk->timer_wheel, tc, TCP_TIMER_RETRANSMIT_SYN); tcp_half_open_connection_del (tc); return 0; } @@ -354,6 +358,8 @@ tcp_program_cleanup (tcp_worker_ctx_t * wrk, tcp_connection_t * tc) void tcp_connection_close (tcp_connection_t * tc) { + tcp_worker_ctx_t *wrk = tcp_get_worker (tc->c_thread_index); + TCP_EVT (TCP_EVT_CLOSE, tc); /* Send/Program FIN if needed and switch state */ @@ -368,7 +374,8 @@ tcp_connection_close (tcp_connection_t * tc) tcp_connection_timers_reset (tc); tcp_send_fin (tc); tcp_connection_set_state (tc, TCP_STATE_FIN_WAIT_1); - tcp_timer_update (tc, TCP_TIMER_WAITCLOSE, tcp_cfg.finwait1_time); + tcp_timer_update (&wrk->timer_wheel, tc, TCP_TIMER_WAITCLOSE, + tcp_cfg.finwait1_time); break; case TCP_STATE_ESTABLISHED: /* If closing with unread data, reset the connection */ @@ -379,7 +386,7 @@ tcp_connection_close (tcp_connection_t * tc) tcp_connection_set_state (tc, TCP_STATE_CLOSED); session_transport_closed_notify (&tc->connection); tcp_program_cleanup (tcp_get_worker (tc->c_thread_index), tc); - tcp_worker_stats_inc (tc->c_thread_index, rst_unread, 1); + tcp_worker_stats_inc (wrk, rst_unread, 1); break; } if (!transport_max_tx_dequeue (&tc->connection)) @@ -390,7 +397,8 @@ tcp_connection_close (tcp_connection_t * tc) /* Set a timer in case the peer stops responding. Otherwise the * connection will be stuck here forever. */ ASSERT (tc->timers[TCP_TIMER_WAITCLOSE] == TCP_TIMER_HANDLE_INVALID); - tcp_timer_set (tc, TCP_TIMER_WAITCLOSE, tcp_cfg.finwait1_time); + tcp_timer_set (&wrk->timer_wheel, tc, TCP_TIMER_WAITCLOSE, + tcp_cfg.finwait1_time); break; case TCP_STATE_CLOSE_WAIT: if (!transport_max_tx_dequeue (&tc->connection)) @@ -398,13 +406,15 @@ tcp_connection_close (tcp_connection_t * tc) tcp_send_fin (tc); tcp_connection_timers_reset (tc); tcp_connection_set_state (tc, TCP_STATE_LAST_ACK); - tcp_timer_update (tc, TCP_TIMER_WAITCLOSE, tcp_cfg.lastack_time); + tcp_timer_update (&wrk->timer_wheel, tc, TCP_TIMER_WAITCLOSE, + tcp_cfg.lastack_time); } else tc->flags |= TCP_CONN_FINPNDG; break; case TCP_STATE_FIN_WAIT_1: - tcp_timer_update (tc, TCP_TIMER_WAITCLOSE, tcp_cfg.finwait1_time); + tcp_timer_update (&wrk->timer_wheel, tc, TCP_TIMER_WAITCLOSE, + tcp_cfg.finwait1_time); break; case TCP_STATE_CLOSED: /* Cleanup should've been programmed already */ @@ -469,11 +479,11 @@ tcp_connection_timers_init (tcp_connection_t * tc) void tcp_connection_timers_reset (tcp_connection_t * tc) { + tcp_worker_ctx_t *wrk = tcp_get_worker (tc->c_thread_index); int i; + for (i = 0; i < TCP_N_TIMERS; i++) - { - tcp_timer_reset (tc, i); - } + tcp_timer_reset (&wrk->timer_wheel, tc, i); } #if 0 @@ -728,10 +738,7 @@ tcp_alloc_custom_local_endpoint (tcp_main_t * tm, ip46_address_t * lcl_addr, } port = transport_alloc_local_port (TRANSPORT_PROTO_TCP, lcl_addr); if (port < 1) - { - clib_warning ("Failed to allocate src port"); - return -1; - } + return SESSION_E_NOPORT; *lcl_port = port; return 0; } @@ -757,7 +764,20 @@ tcp_session_open (transport_endpoint_cfg_t * rmt) rmt, &lcl_addr, &lcl_port); if (rv) - return -1; + { + if (rv != SESSION_E_PORTINUSE) + return rv; + + if (session_lookup_connection (rmt->fib_index, &lcl_addr, &rmt->ip, + lcl_port, rmt->port, TRANSPORT_PROTO_UDP, + rmt->is_ip4)) + return SESSION_E_PORTINUSE; + + /* 5-tuple is available so increase lcl endpoint refcount and proceed + * with connection allocation */ + transport_share_local_endpoint (TRANSPORT_PROTO_UDP, &lcl_addr, + lcl_port); + } /* * Create connection and send SYN @@ -956,7 +976,7 @@ tcp_timer_waitclose_handler (tcp_connection_t * tc) tcp_connection_set_state (tc, TCP_STATE_CLOSED); session_transport_closed_notify (&tc->connection); tcp_program_cleanup (wrk, tc); - tcp_workerp_stats_inc (wrk, to_closewait, 1); + tcp_worker_stats_inc (wrk, to_closewait, 1); break; } @@ -969,8 +989,9 @@ tcp_timer_waitclose_handler (tcp_connection_t * tc) session_transport_closed_notify (&tc->connection); /* Make sure we don't wait in LAST ACK forever */ - tcp_timer_set (tc, TCP_TIMER_WAITCLOSE, tcp_cfg.lastack_time); - tcp_workerp_stats_inc (wrk, to_closewait2, 1); + tcp_timer_set (&wrk->timer_wheel, tc, TCP_TIMER_WAITCLOSE, + tcp_cfg.lastack_time); + tcp_worker_stats_inc (wrk, to_closewait2, 1); /* Don't delete the connection yet */ break; @@ -992,21 +1013,21 @@ tcp_timer_waitclose_handler (tcp_connection_t * tc) tcp_program_cleanup (wrk, tc); } session_transport_closed_notify (&tc->connection); - tcp_workerp_stats_inc (wrk, to_finwait1, 1); + tcp_worker_stats_inc (wrk, to_finwait1, 1); break; case TCP_STATE_LAST_ACK: tcp_connection_timers_reset (tc); tcp_connection_set_state (tc, TCP_STATE_CLOSED); session_transport_closed_notify (&tc->connection); tcp_program_cleanup (wrk, tc); - tcp_workerp_stats_inc (wrk, to_lastack, 1); + tcp_worker_stats_inc (wrk, to_lastack, 1); break; case TCP_STATE_CLOSING: tcp_connection_timers_reset (tc); tcp_connection_set_state (tc, TCP_STATE_CLOSED); session_transport_closed_notify (&tc->connection); tcp_program_cleanup (wrk, tc); - tcp_workerp_stats_inc (wrk, to_closing, 1); + tcp_worker_stats_inc (wrk, to_closing, 1); break; case TCP_STATE_FIN_WAIT_2: tcp_send_reset (tc); @@ -1014,7 +1035,7 @@ tcp_timer_waitclose_handler (tcp_connection_t * tc) tcp_connection_set_state (tc, TCP_STATE_CLOSED); session_transport_closed_notify (&tc->connection); tcp_program_cleanup (wrk, tc); - tcp_workerp_stats_inc (wrk, to_finwait2, 1); + tcp_worker_stats_inc (wrk, to_finwait2, 1); break; case TCP_STATE_TIME_WAIT: tcp_connection_set_state (tc, TCP_STATE_CLOSED); @@ -1186,7 +1207,7 @@ tcp_expired_timers_dispatch (u32 * expired_timers) wrk = tcp_get_worker (thread_index); n_expired = vec_len (expired_timers); - tcp_workerp_stats_inc (wrk, timer_expirations, n_expired); + tcp_worker_stats_inc (wrk, timer_expirations, n_expired); n_left = clib_fifo_elts (wrk->pending_timers); /*