aboutsummaryrefslogtreecommitdiff
path: root/sys/netinet/tcp_usrreq.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet/tcp_usrreq.c')
-rw-r--r--sys/netinet/tcp_usrreq.c120
1 files changed, 107 insertions, 13 deletions
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
index fbc204097b25..98c934955121 100644
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -146,7 +146,7 @@ tcp_bblog_pru(struct tcpcb *tp, uint32_t pru, int error)
}
/*
- * TCP attaches to socket via pru_attach(), reserving space,
+ * TCP attaches to socket via pr_attach(), reserving space,
* and an internet control block.
*/
static int
@@ -164,7 +164,7 @@ tcp_usr_attach(struct socket *so, int proto, struct thread *td)
goto out;
so->so_rcv.sb_flags |= SB_AUTOSIZE;
- so->so_snd.sb_flags |= SB_AUTOSIZE;
+ so->so_snd.sb_flags |= (SB_AUTOLOWAT | SB_AUTOSIZE);
error = in_pcballoc(so, &V_tcbinfo);
if (error)
goto out;
@@ -523,7 +523,7 @@ tcp_usr_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
}
if ((error = prison_remote_ip4(td->td_ucred, &sinp->sin_addr)) != 0)
goto out;
- if (SOLISTENING(so) || so->so_options & SO_REUSEPORT_LB) {
+ if (SOLISTENING(so)) {
error = EOPNOTSUPP;
goto out;
}
@@ -590,7 +590,7 @@ tcp6_usr_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
error = EAFNOSUPPORT;
goto out;
}
- if (SOLISTENING(so) || so->so_options & SO_REUSEPORT_LB) {
+ if (SOLISTENING(so)) {
error = EOPNOTSUPP;
goto out;
}
@@ -907,8 +907,8 @@ out:
/*
* Do a send by putting data in output queue and updating urgent
* marker if URG set. Possibly send more data. Unlike the other
- * pru_*() routines, the mbuf chains are our responsibility. We
- * must either enqueue them or free them. The other pru_* routines
+ * pr_*() routines, the mbuf chains are our responsibility. We
+ * must either enqueue them or free them. The other pr_*() routines
* generally are caller-frees.
*/
static int
@@ -1419,6 +1419,7 @@ struct protosw tcp_protosw = {
.pr_rcvd = tcp_usr_rcvd,
.pr_rcvoob = tcp_usr_rcvoob,
.pr_send = tcp_usr_send,
+ .pr_sendfile_wait = sendfile_wait_generic,
.pr_ready = tcp_usr_ready,
.pr_shutdown = tcp_usr_shutdown,
.pr_sockaddr = in_getsockaddr,
@@ -1447,6 +1448,7 @@ struct protosw tcp6_protosw = {
.pr_rcvd = tcp_usr_rcvd,
.pr_rcvoob = tcp_usr_rcvoob,
.pr_send = tcp_usr_send,
+ .pr_sendfile_wait = sendfile_wait_generic,
.pr_ready = tcp_usr_ready,
.pr_shutdown = tcp_usr_shutdown,
.pr_sockaddr = in6_mapped_sockaddr,
@@ -1476,6 +1478,8 @@ tcp_connect(struct tcpcb *tp, struct sockaddr_in *sin, struct thread *td)
(SS_ISCONNECTING | SS_ISCONNECTED | SS_ISDISCONNECTING |
SS_ISDISCONNECTED)) != 0))
return (EISCONN);
+ if (__predict_false((so->so_options & SO_REUSEPORT_LB) != 0))
+ return (EOPNOTSUPP);
INP_HASH_WLOCK(&V_tcbinfo);
error = in_pcbconnect(inp, sin, td->td_ucred);
@@ -1516,8 +1520,11 @@ tcp6_connect(struct tcpcb *tp, struct sockaddr_in6 *sin6, struct thread *td)
INP_WLOCK_ASSERT(inp);
if (__predict_false((so->so_state &
- (SS_ISCONNECTING | SS_ISCONNECTED)) != 0))
+ (SS_ISCONNECTING | SS_ISCONNECTED | SS_ISDISCONNECTING |
+ SS_ISDISCONNECTED)) != 0))
return (EISCONN);
+ if (__predict_false((so->so_options & SO_REUSEPORT_LB) != 0))
+ return (EOPNOTSUPP);
INP_HASH_WLOCK(&V_tcbinfo);
error = in6_pcbconnect(inp, sin6, td->td_ucred, true);
@@ -1761,9 +1768,9 @@ tcp_ctloutput_set(struct inpcb *inp, struct sockopt *sopt)
/*
* Release the ref count the lookup
* acquired.
- */
+ */
refcount_release(&blk->tfb_refcnt);
- /*
+ /*
* Now there is a chance that the
* init() function mucked with some
* things before it failed, such as
@@ -1793,7 +1800,7 @@ tcp_ctloutput_set(struct inpcb *inp, struct sockopt *sopt)
* new one already.
*/
refcount_release(&tp->t_fb->tfb_refcnt);
- /*
+ /*
* Set in the new stack.
*/
tp->t_fb = blk;
@@ -1927,7 +1934,7 @@ tcp_set_cc_mod(struct inpcb *inp, struct sockopt *sopt)
CC_LIST_RUNLOCK();
return(ESRCH);
}
- /*
+ /*
* With a reference the algorithm cannot be removed
* so we hold a reference through the change process.
*/
@@ -3044,7 +3051,44 @@ db_print_toobflags(char t_oobflags)
}
static void
-db_print_tcpcb(struct tcpcb *tp, const char *name, int indent)
+db_print_bblog_state(int state)
+{
+ switch (state) {
+ case TCP_LOG_STATE_RATIO_OFF:
+ db_printf("TCP_LOG_STATE_RATIO_OFF");
+ break;
+ case TCP_LOG_STATE_CLEAR:
+ db_printf("TCP_LOG_STATE_CLEAR");
+ break;
+ case TCP_LOG_STATE_OFF:
+ db_printf("TCP_LOG_STATE_OFF");
+ break;
+ case TCP_LOG_STATE_TAIL:
+ db_printf("TCP_LOG_STATE_TAIL");
+ break;
+ case TCP_LOG_STATE_HEAD:
+ db_printf("TCP_LOG_STATE_HEAD");
+ break;
+ case TCP_LOG_STATE_HEAD_AUTO:
+ db_printf("TCP_LOG_STATE_HEAD_AUTO");
+ break;
+ case TCP_LOG_STATE_CONTINUAL:
+ db_printf("TCP_LOG_STATE_CONTINUAL");
+ break;
+ case TCP_LOG_STATE_TAIL_AUTO:
+ db_printf("TCP_LOG_STATE_TAIL_AUTO");
+ break;
+ case TCP_LOG_VIA_BBPOINTS:
+ db_printf("TCP_LOG_STATE_BBPOINTS");
+ break;
+ default:
+ db_printf("UNKNOWN(%d)", state);
+ break;
+ }
+}
+
+static void
+db_print_tcpcb(struct tcpcb *tp, const char *name, int indent, bool show_bblog)
{
db_print_indent(indent);
@@ -3154,18 +3198,68 @@ db_print_tcpcb(struct tcpcb *tp, const char *name, int indent)
db_print_indent(indent);
db_printf("t_rttlow: %d rfbuf_ts: %u rfbuf_cnt: %d\n",
tp->t_rttlow, tp->rfbuf_ts, tp->rfbuf_cnt);
+
+ db_print_indent(indent);
+ db_printf("t_fb.tfb_tcp_block_name: %s\n", tp->t_fb->tfb_tcp_block_name);
+
+ db_print_indent(indent);
+ db_printf("t_cc.name: %s\n", tp->t_cc->name);
+
+ db_print_indent(indent);
+ db_printf("_t_logstate: %d (", tp->_t_logstate);
+ db_print_bblog_state(tp->_t_logstate);
+ db_printf(")\n");
+
+ db_print_indent(indent);
+ db_printf("t_lognum: %d t_loglimit: %d t_logsn: %u\n",
+ tp->t_lognum, tp->t_loglimit, tp->t_logsn);
+
+ if (show_bblog) {
+#ifdef TCP_BLACKBOX
+ db_print_bblog_entries(&tp->t_logs, indent);
+#else
+ db_print_indent(indent);
+ db_printf("BBLog not supported\n");
+#endif
+ }
}
DB_SHOW_COMMAND(tcpcb, db_show_tcpcb)
{
struct tcpcb *tp;
+ bool show_bblog;
if (!have_addr) {
db_printf("usage: show tcpcb <addr>\n");
return;
}
+ show_bblog = strchr(modif, 'b') != NULL;
tp = (struct tcpcb *)addr;
- db_print_tcpcb(tp, "tcpcb", 0);
+ db_print_tcpcb(tp, "tcpcb", 0, show_bblog);
+}
+
+DB_SHOW_ALL_COMMAND(tcpcbs, db_show_all_tcpcbs)
+{
+ VNET_ITERATOR_DECL(vnet_iter);
+ struct inpcb *inp;
+ bool only_locked, show_bblog;
+
+ only_locked = strchr(modif, 'l') != NULL;
+ show_bblog = strchr(modif, 'b') != NULL;
+ VNET_FOREACH(vnet_iter) {
+ CURVNET_SET(vnet_iter);
+ CK_LIST_FOREACH(inp, &V_tcbinfo.ipi_listhead, inp_list) {
+ if (only_locked &&
+ inp->inp_lock.rw_lock == RW_UNLOCKED)
+ continue;
+ db_print_tcpcb(intotcpcb(inp), "tcpcb", 0, show_bblog);
+ if (db_pager_quit)
+ break;
+ }
+ CURVNET_RESTORE();
+ if (db_pager_quit)
+ break;
+ }
}
#endif