diff options
Diffstat (limited to 'sys/netinet/tcp_subr.c')
-rw-r--r-- | sys/netinet/tcp_subr.c | 99 |
1 files changed, 72 insertions, 27 deletions
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c index fd3ea2d..f94e290 100644 --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -119,6 +119,7 @@ int tcp_v6mssdflt = TCP6_MSS; static int sysctl_net_inet_tcp_mss_check(SYSCTL_HANDLER_ARGS) { + INIT_VNET_INET(TD_TO_VNET(curthread)); int error, new; new = V_tcp_mssdflt; @@ -140,6 +141,7 @@ SYSCTL_PROC(_net_inet_tcp, TCPCTL_MSSDFLT, mssdflt, CTLTYPE_INT|CTLFLAG_RW, static int sysctl_net_inet_tcp_mss_v6_check(SYSCTL_HANDLER_ARGS) { + INIT_VNET_INET6(TD_TO_VNET(curthread)); int error, new; new = V_tcp_v6mssdflt; @@ -167,12 +169,13 @@ SYSCTL_PROC(_net_inet_tcp, TCPCTL_V6MSSDFLT, v6mssdflt, CTLTYPE_INT|CTLFLAG_RW, * checking. This setting prevents us from sending too small packets. */ int tcp_minmss = TCP_MINMSS; -SYSCTL_INT(_net_inet_tcp, OID_AUTO, minmss, CTLFLAG_RW, - &tcp_minmss , 0, "Minmum TCP Maximum Segment Size"); +SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_tcp, OID_AUTO, minmss, + CTLFLAG_RW, tcp_minmss , 0, "Minmum TCP Maximum Segment Size"); int tcp_do_rfc1323 = 1; -SYSCTL_INT(_net_inet_tcp, TCPCTL_DO_RFC1323, rfc1323, CTLFLAG_RW, - &tcp_do_rfc1323, 0, "Enable rfc1323 (high performance TCP) extensions"); +SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_tcp, TCPCTL_DO_RFC1323, rfc1323, + CTLFLAG_RW, tcp_do_rfc1323, 0, + "Enable rfc1323 (high performance TCP) extensions"); static int tcp_log_debug = 0; SYSCTL_INT(_net_inet_tcp, OID_AUTO, log_debug, CTLFLAG_RW, @@ -183,21 +186,21 @@ SYSCTL_INT(_net_inet_tcp, OID_AUTO, tcbhashsize, CTLFLAG_RDTUN, &tcp_tcbhashsize, 0, "Size of TCP control-block hashtable"); static int do_tcpdrain = 1; -SYSCTL_INT(_net_inet_tcp, OID_AUTO, do_tcpdrain, CTLFLAG_RW, - &do_tcpdrain, 0, +SYSCTL_INT(_net_inet_tcp, OID_AUTO, do_tcpdrain, CTLFLAG_RW, &do_tcpdrain, 0, "Enable tcp_drain routine for extra help when low on mbufs"); -SYSCTL_INT(_net_inet_tcp, OID_AUTO, pcbcount, CTLFLAG_RD, - &tcbinfo.ipi_count, 0, "Number of active PCBs"); +SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_tcp, OID_AUTO, pcbcount, + CTLFLAG_RD, tcbinfo.ipi_count, 0, "Number of active PCBs"); static int icmp_may_rst = 1; -SYSCTL_INT(_net_inet_tcp, OID_AUTO, icmp_may_rst, CTLFLAG_RW, - &icmp_may_rst, 0, +SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_tcp, OID_AUTO, icmp_may_rst, + CTLFLAG_RW, icmp_may_rst, 0, "Certain ICMP unreachable messages may abort connections in SYN_SENT"); static int tcp_isn_reseed_interval = 0; -SYSCTL_INT(_net_inet_tcp, OID_AUTO, isn_reseed_interval, CTLFLAG_RW, - &tcp_isn_reseed_interval, 0, "Seconds between reseeding of ISN secret"); +SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_tcp, OID_AUTO, isn_reseed_interval, + CTLFLAG_RW, tcp_isn_reseed_interval, 0, + "Seconds between reseeding of ISN secret"); /* * TCP bandwidth limiting sysctls. Note that the default lower bound of @@ -208,8 +211,9 @@ SYSCTL_NODE(_net_inet_tcp, OID_AUTO, inflight, CTLFLAG_RW, 0, "TCP inflight data limiting"); static int tcp_inflight_enable = 1; -SYSCTL_INT(_net_inet_tcp_inflight, OID_AUTO, enable, CTLFLAG_RW, - &tcp_inflight_enable, 0, "Enable automatic TCP inflight data limiting"); +SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_tcp_inflight, OID_AUTO, enable, + CTLFLAG_RW, tcp_inflight_enable, 0, + "Enable automatic TCP inflight data limiting"); static int tcp_inflight_debug = 0; SYSCTL_INT(_net_inet_tcp_inflight, OID_AUTO, debug, CTLFLAG_RW, @@ -221,16 +225,17 @@ SYSCTL_PROC(_net_inet_tcp_inflight, OID_AUTO, rttthresh, CTLTYPE_INT|CTLFLAG_RW, "RTT threshold below which inflight will deactivate itself"); static int tcp_inflight_min = 6144; -SYSCTL_INT(_net_inet_tcp_inflight, OID_AUTO, min, CTLFLAG_RW, - &tcp_inflight_min, 0, "Lower-bound for TCP inflight window"); +SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_tcp_inflight, OID_AUTO, min, + CTLFLAG_RW, tcp_inflight_min, 0, "Lower-bound for TCP inflight window"); static int tcp_inflight_max = TCP_MAXWIN << TCP_MAX_WINSHIFT; -SYSCTL_INT(_net_inet_tcp_inflight, OID_AUTO, max, CTLFLAG_RW, - &tcp_inflight_max, 0, "Upper-bound for TCP inflight window"); +SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_tcp_inflight, OID_AUTO, max, + CTLFLAG_RW, tcp_inflight_max, 0, "Upper-bound for TCP inflight window"); static int tcp_inflight_stab = 20; -SYSCTL_INT(_net_inet_tcp_inflight, OID_AUTO, stab, CTLFLAG_RW, - &tcp_inflight_stab, 0, "Inflight Algorithm Stabilization 20 = 2 packets"); +SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_tcp_inflight, OID_AUTO, stab, + CTLFLAG_RW, tcp_inflight_stab, 0, + "Inflight Algorithm Stabilization 20 = 2 packets"); uma_zone_t sack_hole_zone; @@ -291,6 +296,7 @@ tcp_inpcb_init(void *mem, int size, int flags) void tcp_init(void) { + INIT_VNET_INET(curvnet); int hashsize = TCBHASHSIZE; tcp_delacktime = TCPTV_DELACK; @@ -450,6 +456,7 @@ void tcp_respond(struct tcpcb *tp, void *ipgen, struct tcphdr *th, struct mbuf *m, tcp_seq ack, tcp_seq seq, int flags) { + INIT_VNET_INET(curvnet); int tlen; int win = 0; struct ip *ip; @@ -620,6 +627,7 @@ tcp_respond(struct tcpcb *tp, void *ipgen, struct tcphdr *th, struct mbuf *m, struct tcpcb * tcp_newtcpcb(struct inpcb *inp) { + INIT_VNET_INET(inp->inp_vnet); struct tcpcb_mem *tm; struct tcpcb *tp; #ifdef INET6 @@ -683,6 +691,7 @@ tcp_newtcpcb(struct inpcb *inp) struct tcpcb * tcp_drop(struct tcpcb *tp, int errno) { + INIT_VNET_INET(tp->t_inpcb->inp_vnet); struct socket *so = tp->t_inpcb->inp_socket; INP_INFO_WLOCK_ASSERT(&V_tcbinfo); @@ -703,6 +712,7 @@ tcp_drop(struct tcpcb *tp, int errno) void tcp_discardcb(struct tcpcb *tp) { + INIT_VNET_INET(tp->t_vnet); struct tseg_qent *q; struct inpcb *inp = tp->t_inpcb; struct socket *so = inp->inp_socket; @@ -804,6 +814,7 @@ tcp_discardcb(struct tcpcb *tp) struct tcpcb * tcp_close(struct tcpcb *tp) { + INIT_VNET_INET(tp->t_inpcb->inp_vnet); struct inpcb *inp = tp->t_inpcb; struct socket *so; @@ -835,8 +846,15 @@ tcp_close(struct tcpcb *tp) void tcp_drain(void) { + VNET_ITERATOR_DECL(vnet_iter); - if (do_tcpdrain) { + if (!do_tcpdrain) + return; + + VNET_LIST_RLOCK(); + VNET_FOREACH(vnet_iter) { + CURVNET_SET(vnet_iter); + INIT_VNET_INET(vnet_iter); struct inpcb *inpb; struct tcpcb *tcpb; struct tseg_qent *te; @@ -868,7 +886,9 @@ tcp_drain(void) INP_WUNLOCK(inpb); } INP_INFO_RUNLOCK(&V_tcbinfo); + CURVNET_RESTORE(); } + VNET_LIST_RUNLOCK(); } /* @@ -926,6 +946,7 @@ tcp_notify(struct inpcb *inp, int error) static int tcp_pcblist(SYSCTL_HANDLER_ARGS) { + INIT_VNET_INET(curvnet); int error, i, m, n, pcb_count; struct inpcb *inp, **inp_list; inp_gen_t gencnt; @@ -1062,6 +1083,7 @@ SYSCTL_PROC(_net_inet_tcp, TCPCTL_PCBLIST, pcblist, CTLFLAG_RD, 0, 0, static int tcp_getcred(SYSCTL_HANDLER_ARGS) { + INIT_VNET_INET(curvnet); struct xucred xuc; struct sockaddr_in addrs[2]; struct inpcb *inp; @@ -1104,6 +1126,8 @@ SYSCTL_PROC(_net_inet_tcp, OID_AUTO, getcred, static int tcp6_getcred(SYSCTL_HANDLER_ARGS) { + INIT_VNET_INET(curvnet); + INIT_VNET_INET6(curvnet); struct xucred xuc; struct sockaddr_in6 addrs[2]; struct inpcb *inp; @@ -1167,6 +1191,7 @@ SYSCTL_PROC(_net_inet6_tcp6, OID_AUTO, getcred, void tcp_ctlinput(int cmd, struct sockaddr *sa, void *vip) { + INIT_VNET_INET(curvnet); struct ip *ip = vip; struct tcphdr *th; struct in_addr faddr; @@ -1286,6 +1311,7 @@ tcp_ctlinput(int cmd, struct sockaddr *sa, void *vip) void tcp6_ctlinput(int cmd, struct sockaddr *sa, void *d) { + INIT_VNET_INET(curvnet); struct tcphdr th; struct inpcb *(*notify)(struct inpcb *, int) = tcp_notify; struct ip6_hdr *ip6; @@ -1414,6 +1440,7 @@ static MD5_CTX isn_ctx; tcp_seq tcp_new_isn(struct tcpcb *tp) { + INIT_VNET_INET(tp->t_vnet); u_int32_t md5_buffer[4]; tcp_seq new_isn; @@ -1464,15 +1491,24 @@ tcp_new_isn(struct tcpcb *tp) static void tcp_isn_tick(void *xtp) { + VNET_ITERATOR_DECL(vnet_iter); u_int32_t projected_offset; ISN_LOCK(); - projected_offset = V_isn_offset_old + ISN_BYTES_PER_SECOND / 100; - - if (SEQ_GT(projected_offset, V_isn_offset)) - V_isn_offset = projected_offset; - - V_isn_offset_old = V_isn_offset; + VNET_LIST_RLOCK(); + VNET_FOREACH(vnet_iter) { + CURVNET_SET(vnet_iter); /* XXX appease INVARIANTS */ + INIT_VNET_INET(curvnet); + projected_offset = + V_isn_offset_old + ISN_BYTES_PER_SECOND / 100; + + if (SEQ_GT(projected_offset, V_isn_offset)) + V_isn_offset = projected_offset; + + V_isn_offset_old = V_isn_offset; + CURVNET_RESTORE(); + } + VNET_LIST_RUNLOCK(); callout_reset(&isn_callout, hz/100, tcp_isn_tick, NULL); ISN_UNLOCK(); } @@ -1485,6 +1521,9 @@ tcp_isn_tick(void *xtp) struct inpcb * tcp_drop_syn_sent(struct inpcb *inp, int errno) { +#ifdef INVARIANTS + INIT_VNET_INET(inp->inp_vnet); +#endif struct tcpcb *tp; INP_INFO_WLOCK_ASSERT(&V_tcbinfo); @@ -1514,6 +1553,7 @@ tcp_drop_syn_sent(struct inpcb *inp, int errno) struct inpcb * tcp_mtudisc(struct inpcb *inp, int errno) { + INIT_VNET_INET(inp->inp_vnet); struct tcpcb *tp; struct socket *so; @@ -1720,6 +1760,7 @@ ipsec_hdrsiz_tcp(struct tcpcb *tp) void tcp_xmit_bandwidth_limit(struct tcpcb *tp, tcp_seq ack_seq) { + INIT_VNET_INET(tp->t_vnet); u_long bw; u_long bwnd; int save_ticks; @@ -2008,6 +2049,10 @@ tcp_signature_compute(struct mbuf *m, int _unused, int len, int optlen, static int sysctl_drop(SYSCTL_HANDLER_ARGS) { + INIT_VNET_INET(curvnet); +#ifdef INET6 + INIT_VNET_INET6(curvnet); +#endif /* addrs[0] is a foreign socket, addrs[1] is a local one. */ struct sockaddr_storage addrs[2]; struct inpcb *inp; |