X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Ftcp%2Ftcp.c;h=915675c11ed654ac36167ed2905740a522c2306d;hb=cbe25aab3be72154f2c706c39eeba6a77f34450f;hp=86e5d949bd1079a9716e9e7813609f900b2a69b9;hpb=bbcfaac9571004d87998684c123354667b726532;p=vpp.git diff --git a/src/vnet/tcp/tcp.c b/src/vnet/tcp/tcp.c index 86e5d949bd1..915675c11ed 100644 --- a/src/vnet/tcp/tcp.c +++ b/src/vnet/tcp/tcp.c @@ -23,9 +23,8 @@ #include #include #include -#include +#include #include -#include tcp_main_t tcp_main; @@ -360,6 +359,7 @@ tcp_connection_reset (tcp_connection_t * tc) * cleanly close the connection */ tcp_timer_set (tc, TCP_TIMER_WAITCLOSE, tcp_cfg.closewait_time); session_transport_reset_notify (&tc->connection); + tcp_cong_recovery_off (tc); tcp_connection_set_state (tc, TCP_STATE_CLOSED); session_transport_closed_notify (&tc->connection); break; @@ -370,6 +370,7 @@ tcp_connection_reset (tcp_connection_t * tc) case TCP_STATE_LAST_ACK: tcp_connection_timers_reset (tc); tcp_timer_set (tc, TCP_TIMER_WAITCLOSE, tcp_cfg.closewait_time); + tcp_cong_recovery_off (tc); /* Make sure we mark the session as closed. In some states we may * be still trying to send data */ tcp_connection_set_state (tc, TCP_STATE_CLOSED); @@ -489,6 +490,7 @@ tcp_session_reset (u32 conn_index, u32 thread_index) session_transport_closed_notify (&tc->connection); tcp_send_reset (tc); tcp_connection_timers_reset (tc); + tcp_cong_recovery_off (tc); tcp_connection_set_state (tc, TCP_STATE_CLOSED); tcp_timer_update (tc, TCP_TIMER_WAITCLOSE, tcp_cfg.cleanup_time); } @@ -702,6 +704,9 @@ tcp_init_snd_vars (tcp_connection_t * tc) tc->snd_nxt = tc->iss + 1; tc->snd_una_max = tc->snd_nxt; tc->srtt = 100; /* 100 ms */ + + if (!tcp_cfg.csum_offload) + tc->cfg_flags |= TCP_CFG_F_NO_CSUM_OFFLOAD; } void @@ -1015,6 +1020,8 @@ format_tcp_vars (u8 * s, va_list * args) tc->rto, tc->rto_boff, tc->srtt, tc->mrtt_us * 1000, tc->rttvar, tc->rtt_ts); s = format (s, " rtt_seq %u\n", tc->rtt_seq - tc->iss); + s = format (s, " next_node %u opaque 0x%x\n", tc->next_node_index, + tc->next_node_opaque); s = format (s, " cong: %U", format_tcp_congestion, tc); if (tc->state >= TCP_STATE_ESTABLISHED) @@ -1391,33 +1398,33 @@ tcp_connection_tx_pacer_update (tcp_connection_t * tc) if (!transport_connection_is_tx_paced (&tc->connection)) return; + f64 srtt = clib_min ((f64) tc->srtt * TCP_TICK, tc->mrtt_us); + transport_connection_tx_pacer_update (&tc->connection, - tcp_cc_get_pacing_rate (tc)); + tcp_cc_get_pacing_rate (tc), + srtt * CLIB_US_TIME_FREQ); } void tcp_connection_tx_pacer_reset (tcp_connection_t * tc, u32 window, u32 start_bucket) { - tcp_worker_ctx_t *wrk = tcp_get_worker (tc->c_thread_index); f64 srtt = clib_min ((f64) tc->srtt * TCP_TICK, tc->mrtt_us); - u64 last_time = wrk->vm->clib_time.last_cpu_time; - transport_connection_tx_pacer_reset (&tc->connection, window / srtt, - start_bucket, last_time); + transport_connection_tx_pacer_reset (&tc->connection, + tcp_cc_get_pacing_rate (tc), + start_bucket, + srtt * CLIB_US_TIME_FREQ); } static void -tcp_timer_waitclose_handler (u32 conn_index) +tcp_timer_waitclose_handler (u32 conn_index, u32 thread_index) { - u32 thread_index = vlib_get_thread_index (); tcp_connection_t *tc; tc = tcp_connection_get (conn_index, thread_index); if (!tc) return; - tc->timers[TCP_TIMER_WAITCLOSE] = TCP_TIMER_HANDLE_INVALID; - switch (tc->state) { case TCP_STATE_CLOSE_WAIT: @@ -1490,19 +1497,38 @@ static timer_expiration_handler *timer_expiration_handlers[TCP_N_TIMERS] = static void tcp_expired_timers_dispatch (u32 * expired_timers) { - int i; + u32 thread_index = vlib_get_thread_index (); u32 connection_index, timer_id; + tcp_connection_t *tc; + int i; + /* + * Invalidate all timer handles before dispatching. This avoids dangling + * index references to timer wheel pool entries that have been freed. + */ for (i = 0; i < vec_len (expired_timers); i++) { - /* Get session index and timer id */ connection_index = expired_timers[i] & 0x0FFFFFFF; timer_id = expired_timers[i] >> 28; + if (timer_id != TCP_TIMER_RETRANSMIT_SYN) + tc = tcp_connection_get (connection_index, thread_index); + else + tc = tcp_half_open_connection_get (connection_index); + TCP_EVT (TCP_EVT_TIMER_POP, connection_index, timer_id); - /* Handle expiration */ - (*timer_expiration_handlers[timer_id]) (connection_index); + tc->timers[timer_id] = TCP_TIMER_HANDLE_INVALID; + } + + /* + * Dispatch expired timers + */ + for (i = 0; i < vec_len (expired_timers); i++) + { + connection_index = expired_timers[i] & 0x0FFFFFFF; + timer_id = expired_timers[i] >> 28; + (*timer_expiration_handlers[timer_id]) (connection_index, thread_index); } } @@ -1649,6 +1675,7 @@ tcp_configuration_init (void) tcp_cfg.initial_cwnd_multiplier = 0; tcp_cfg.enable_tx_pacing = 1; tcp_cfg.allow_tso = 0; + tcp_cfg.csum_offload = 1; tcp_cfg.cc_algo = TCP_CC_NEWRENO; tcp_cfg.rwnd_min_update_ack = 1; @@ -1758,10 +1785,26 @@ tcp_config_fn (vlib_main_t * vm, unformat_input_t * input) ; else if (unformat (input, "max-rx-fifo %U", unformat_memory_size, &memory_size)) - tcp_cfg.max_rx_fifo = memory_size; + { + if (memory_size >= 0x100000000) + { + return clib_error_return + (0, "max-rx-fifo %llu (0x%llx) too large", memory_size, + memory_size); + } + tcp_cfg.max_rx_fifo = memory_size; + } else if (unformat (input, "min-rx-fifo %U", unformat_memory_size, &memory_size)) - tcp_cfg.min_rx_fifo = memory_size; + { + if (memory_size >= 0x100000000) + { + return clib_error_return + (0, "min-rx-fifo %llu (0x%llx) too large", memory_size, + memory_size); + } + tcp_cfg.min_rx_fifo = memory_size; + } else if (unformat (input, "mtu %u", &tcp_cfg.default_mtu)) ; else if (unformat (input, "rwnd-min-update-ack %d", @@ -1774,6 +1817,8 @@ tcp_config_fn (vlib_main_t * vm, unformat_input_t * input) tcp_cfg.enable_tx_pacing = 0; else if (unformat (input, "tso")) tcp_cfg.allow_tso = 1; + else if (unformat (input, "no-csum-offload")) + tcp_cfg.csum_offload = 0; else if (unformat (input, "cc-algo %U", unformat_tcp_cc_algo, &tcp_cfg.cc_algo)) ; @@ -1817,7 +1862,6 @@ tcp_configure_v4_source_address_range (vlib_main_t * vm, ip4_address_t * start, ip4_address_t * end, u32 table_id) { - vnet_main_t *vnm = vnet_get_main (); u32 start_host_byte_order, end_host_byte_order; fib_prefix_t prefix; fib_node_index_t fei; @@ -1853,12 +1897,12 @@ tcp_configure_v4_source_address_range (vlib_main_t * vm, sw_if_index = fib_entry_get_resolving_interface (fei); /* Configure proxy arp across the range */ - rv = vnet_proxy_arp_add_del (start, end, fib_index, 0 /* is_del */ ); + rv = ip4_neighbor_proxy_add (fib_index, start, end); if (rv) return rv; - rv = vnet_proxy_arp_enable_disable (vnm, sw_if_index, 1); + rv = ip4_neighbor_proxy_enable (sw_if_index); if (rv) return rv; @@ -1943,7 +1987,7 @@ tcp_configure_v6_source_address_range (vlib_main_t * vm, return VNET_API_ERROR_NO_MATCHING_INTERFACE; /* Add a proxy neighbor discovery entry for this address */ - ip6_neighbor_proxy_add_del (sw_if_index, start, 0 /* is_del */ ); + ip6_neighbor_proxy_add (sw_if_index, start); /* Add a receive adjacency for this address */ receive_dpo_add_or_lock (DPO_PROTO_IP6, ~0 /* sw_if_index */ ,