39#include "opt_tcpdebug.h"
43#include <sys/kernel.h>
47#include <sys/protosw.h>
49#include <sys/socket.h>
50#include <sys/socketvar.h>
51#include <sys/sysctl.h>
56#include <net/rss_config.h>
58#include <net/netisr.h>
66#include <netinet6/in6_pcb.h>
77#include <netinet6/tcp6_var.h>
86 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
88 "minimum persistence interval");
92 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
94 "maximum persistence interval");
98 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
100 "time to establish connection");
104 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
106 "time before keepalive probes begin");
110 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
112 "time between keepalive probes");
116 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
118 "Time before a delayed ACK is sent");
122 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_VNET,
123 &VNET_NAME(tcp_msl), 0, sysctl_msec_to_ticks,
"I",
124 "Maximum segment lifetime");
128 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
130 "Initial Retransmission Timeout");
134 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
136 "Minimum Retransmission Timeout");
140 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
142 "Retransmission Timer Slop");
145SYSCTL_INT(_net_inet_tcp, OID_AUTO, always_keepalive, CTLFLAG_VNET|CTLFLAG_RW,
146 &VNET_NAME(tcp_always_keepalive) , 0,
147 "Assume SO_KEEPALIVE on all TCP connections");
150SYSCTL_INT(_net_inet_tcp, OID_AUTO, fast_finwait2_recycle, CTLFLAG_RW,
152 "Recycle closed FIN_WAIT_2 connections faster");
156 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
158 "FIN-WAIT2 timeout");
162 "Number of keepalive probes to send");
168SYSCTL_INT(_net_inet_tcp, OID_AUTO, rexmit_drop_options, CTLFLAG_RW,
170 "Drop TCP options from 3rd and later retransmitted SYN");
173SYSCTL_INT(_net_inet_tcp, OID_AUTO, pmtud_blackhole_detection,
174 CTLFLAG_RW|CTLFLAG_VNET,
175 &VNET_NAME(tcp_pmtud_blackhole_detect), 0,
176 "Path MTU Discovery Black Hole Detection Enabled");
180SYSCTL_INT(_net_inet_tcp, OID_AUTO, pmtud_blackhole_mss,
181 CTLFLAG_RW|CTLFLAG_VNET,
182 &VNET_NAME(tcp_pmtud_blackhole_mss), 0,
183 "Path MTU Discovery Black Hole Detection lowered MSS");
188SYSCTL_INT(_net_inet_tcp, OID_AUTO, v6pmtud_blackhole_mss,
189 CTLFLAG_RW|CTLFLAG_VNET,
190 &VNET_NAME(tcp_v6pmtud_blackhole_mss), 0,
191 "Path MTU Discovery IPv6 Black Hole Detection lowered MSS");
216 if (cpuid == NETISR_CPUID_NONE)
227 if (! CPU_ABSENT(cpuid))
243 VNET_ITERATOR_DECL(vnet_iter);
245 VNET_LIST_RLOCK_NOSLEEP();
246 VNET_FOREACH(vnet_iter) {
247 CURVNET_SET(vnet_iter);
251 VNET_LIST_RUNLOCK_NOSLEEP();
255 { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 512, 512, 512 };
266 struct epoch_tracker et;
267 struct tcpcb *tp = xtp;
272 KASSERT(inp != NULL, (
"%s: tp %p tp->t_inpcb == NULL", __func__, tp));
289 (void) tcp_output_unlock(tp);
297 if (inp && tp != NULL)
304 struct tcpcb *tp = xtp;
306 struct epoch_tracker et;
314 KASSERT(inp != NULL, (
"%s: tp %p tp->t_inpcb == NULL", __func__, tp));
330 (
"%s: tp %p tcpcb can't be stopped here", __func__, tp));
379 struct tcpcb *tp = xtp;
382 struct epoch_tracker et;
390 KASSERT(inp != NULL, (
"%s: tp %p tp->t_inpcb == NULL", __func__, tp));
405 (
"%s: tp %p tcpcb can't be stopped here", __func__, tp));
434 inp->
inp_socket->so_options & SO_KEEPALIVE) &&
455 &t_template->
tt_t, (
struct mbuf *)NULL,
458 free(t_template, M_TEMP);
495 struct tcpcb *tp = xtp;
497 struct epoch_tracker et;
506 KASSERT(inp != NULL, (
"%s: tp %p tp->t_inpcb == NULL", __func__, tp));
521 (
"%s: tp %p tcpcb can't be stopped here", __func__, tp));
560 outrv = tcp_output_nodrop(tp);
568 (void) tcp_unlock_or_drop(tp, outrv);
577 struct tcpcb *tp = xtp;
581 struct epoch_tracker et;
589 KASSERT(inp != NULL, (
"%s: tp %p tp->t_inpcb == NULL", __func__, tp));
604 (
"%s: tp %p tcpcb can't be stopped here", __func__, tp));
647 tp->
t_flags &= ~TF_WASFRECOVERY;
651 tp->
t_flags &= ~TF_WASCRECOVERY;
702 if (tp->
t_maxseg > V_tcp_v6mssdflt &&
753 TCPSTAT_INC(tcps_pmtud_blackhole_activated_min_mss);
756#if defined(INET6) && defined(INET)
773 TCPSTAT_INC(tcps_pmtud_blackhole_activated_min_mss);
780 if (
CC_ALGO(tp)->conn_init != NULL)
792 tp->
t_flags2 &= ~TF2_PLPMTU_BLACKHOLE;
799 if (
CC_ALGO(tp)->conn_init != NULL)
840 outrv = tcp_output_nodrop(tp);
847 (void) tcp_unlock_or_drop(tp, outrv);
856 struct callout *t_callout;
857 callout_func_t *f_callout;
869 switch (timer_type) {
895 panic(
"tp %p bad timer_type %#x", tp, timer_type);
898 callout_stop(t_callout);
900 callout_reset_on(t_callout, delta, f_callout, tp, cpu);
907 struct callout *t_callout;
909 switch (timer_type) {
929 panic(
"tp %p bad timer_type %#x", tp, timer_type);
931 return callout_active(t_callout);
945 struct callout *t_callout;
948 switch (timer_type) {
970 panic(
"tp:%p bad timer_type 0x%x", tp, timer_type);
973 return (callout_stop(t_callout));
979 switch (timer_type) {
1035 panic(
"tp:%p bad timer_type 0x%x", tp, timer_type);
1044 struct epoch_tracker et;
1046 tp = (
struct tcpcb *)ptp;
1048 NET_EPOCH_ENTER(et);
1050 KASSERT(inp != NULL, (
"%s: tp %p tp->t_inpcb == NULL",
1054 (
"%s: tcpcb has to be stopped here", __func__));
1065 struct callout *t_callout;
1068 switch (timer_type) {
1093 panic(
"tp %p bad timer_type %#x", tp, timer_type);
#define TCP_PROBE2(probe, arg0, arg1)
void in_losing(struct inpcb *inp)
struct socket * inp_socket
void(* tfb_tcp_timer_stop)(struct tcpcb *, uint32_t)
int(* tfb_tcp_timer_active)(struct tcpcb *, uint32_t)
void(* tfb_tcp_rexmit_tmr)(struct tcpcb *)
void(* tfb_tcp_timer_activate)(struct tcpcb *, uint32_t, u_int)
struct callout tt_persist
struct tcp_timer * t_timers
u_int t_pmtud_saved_maxseg
uint32_t snd_ssthresh_prev
struct tcp_function_block * t_fb
void tcp_trace(short act, short ostate, struct tcpcb *tp, void *ipgen, struct tcphdr *th, int req)
#define TCPS_SYN_RECEIVED
#define TCPS_HAVEESTABLISHED(s)
#define TCP_LOG_EVENT(tp, th, rxbuf, txbuf, eventid, errornum, len, stackinfo, th_hostorder)
void tcp_setpersist(struct tcpcb *tp)
void tcp_free_sackholes(struct tcpcb *tp)
struct tcpcb * tcp_drop(struct tcpcb *tp, int errno)
struct tcpcb * tcp_close(struct tcpcb *tp)
void tcp_respond(struct tcpcb *tp, void *ipgen, struct tcphdr *th, struct mbuf *m, tcp_seq ack, tcp_seq seq, int flags)
bool tcp_freecb(struct tcpcb *tp)
struct tcptemp * tcpip_maketemplate(struct inpcb *inp)
void tcp_timer_persist(void *xtp)
void tcp_timer_rexmt(void *xtp)
SYSCTL_INT(_net_inet_tcp, OID_AUTO, always_keepalive, CTLFLAG_VNET|CTLFLAG_RW, &VNET_NAME(tcp_always_keepalive), 0, "Assume SO_KEEPALIVE on all TCP connections")
void tcp_timer_keep(void *xtp)
SYSCTL_PROC(_net_inet_tcp, OID_AUTO, persmin, CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_NEEDGIANT, &tcp_persmin, 0, sysctl_msec_to_ticks, "I", "minimum persistence interval")
static void tcp_timer_discard(void *ptp)
void tcp_timer_stop(struct tcpcb *tp, uint32_t timer_type)
void tcp_timer_2msl(void *xtp)
int tcp_timer_active(struct tcpcb *tp, uint32_t timer_type)
void tcp_timer_delack(void *xtp)
int inp_to_cpuid(struct inpcb *inp)
int tcp_backoff[TCP_MAXRXTSHIFT+1]
static int per_cpu_timers
int tcp_timer_suspend(struct tcpcb *tp, uint32_t timer_type)
void tcp_inpinfo_lock_del(struct inpcb *inp, struct tcpcb *tp)
int tcp_rexmit_drop_options
void tcp_timer_activate(struct tcpcb *tp, uint32_t timer_type, u_int delta)
int tcp_fast_finwait2_recycle
void tcp_timers_unsuspend(struct tcpcb *tp, uint32_t timer_type)
VNET_DEFINE(int, tcp_msl)
#define V_tcp_always_keepalive
#define V_tcp_pmtud_blackhole_detect
#define V_tcp_pmtud_blackhole_mss
struct tcptw * tcp_tw_2msl_scan(int reuse)
#define TCPT_RANGESET(tv, value, tvmin, tvmax)
#define V_tcp_v6pmtud_blackhole_mss
#define TCP_RTT_INVALIDATE
#define TF2_PLPMTU_MAXSEGSNT
#define IN_CONGRECOVERY(t_flags)
#define IN_FASTRECOVERY(t_flags)
#define TCPCTL_DELACKTIME
#define TF2_PLPMTU_BLACKHOLE
#define TCPSTAT_INC(name)