Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F159785333
D56186.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
56 KB
Referenced Files
None
Subscribers
None
D56186.diff
View Options
diff --git a/sys/dev/cxgbe/crypto/t6_kern_tls.c b/sys/dev/cxgbe/crypto/t6_kern_tls.c
--- a/sys/dev/cxgbe/crypto/t6_kern_tls.c
+++ b/sys/dev/cxgbe/crypto/t6_kern_tls.c
@@ -458,15 +458,15 @@
}
inp = params->tls.inp;
+ tp = intotcpcb(inp);
INP_RLOCK(inp);
- if (inp->inp_flags & INP_DROPPED) {
+ if (tp->t_flags & TF_DISCONNECTED) {
INP_RUNLOCK(inp);
error = ECONNRESET;
goto failed;
}
tlsp->inp = inp;
- tp = intotcpcb(inp);
if (tp->t_flags & TF_REQ_TSTMP) {
tlsp->using_timestamps = true;
if ((tp->ts_offset & 0xfffffff) != 0) {
@@ -501,7 +501,7 @@
goto failed;
}
- if (inp->inp_flags & INP_DROPPED) {
+ if (tp->t_flags & TF_DISCONNECTED) {
INP_RUNLOCK(inp);
error = ECONNRESET;
goto failed;
diff --git a/sys/dev/cxgbe/crypto/t7_kern_tls.c b/sys/dev/cxgbe/crypto/t7_kern_tls.c
--- a/sys/dev/cxgbe/crypto/t7_kern_tls.c
+++ b/sys/dev/cxgbe/crypto/t7_kern_tls.c
@@ -246,7 +246,7 @@
inp = params->tls.inp;
INP_RLOCK(inp);
- if (inp->inp_flags & INP_DROPPED) {
+ if (intotcpcb(inp)->t_flags & TF_DISCONNECTED) {
INP_RUNLOCK(inp);
error = ECONNRESET;
goto failed;
diff --git a/sys/dev/cxgbe/cxgbei/cxgbei.c b/sys/dev/cxgbe/cxgbei/cxgbei.c
--- a/sys/dev/cxgbe/cxgbei/cxgbei.c
+++ b/sys/dev/cxgbe/cxgbei/cxgbei.c
@@ -499,10 +499,11 @@
toep->ofld_rxq->rx_iscsi_ddp_octets += ip->ip_data_len;
}
+ tp = intotcpcb(inp);
INP_WLOCK(inp);
- if (__predict_false(inp->inp_flags & INP_DROPPED)) {
- CTR4(KTR_CXGBE, "%s: tid %u, rx (%d bytes), inp_flags 0x%x",
- __func__, tid, pdu_len, inp->inp_flags);
+ if (__predict_false(tp->t_flags & TF_DISCONNECTED)) {
+ CTR4(KTR_CXGBE, "%s: tid %u, rx (%d bytes), t_flags 0x%x",
+ __func__, tid, pdu_len, tp->t_flags);
INP_WUNLOCK(inp);
icl_cxgbei_conn_pdu_free(NULL, ip);
toep->ulpcb2 = NULL;
@@ -513,7 +514,6 @@
* T6+ does not report data PDUs received via DDP without F
* set. This can result in gaps in the TCP sequence space.
*/
- tp = intotcpcb(inp);
MPASS(chip_id(sc) >= CHELSIO_T6 || icp->icp_seq == tp->rcv_nxt);
tp->rcv_nxt = icp->icp_seq + pdu_len;
tp->t_rcvtime = ticks;
@@ -652,10 +652,11 @@
toep->ofld_rxq->rx_iscsi_data_digest_errors++;
}
+ tp = intotcpcb(inp);
INP_WLOCK(inp);
- if (__predict_false(inp->inp_flags & INP_DROPPED)) {
- CTR4(KTR_CXGBE, "%s: tid %u, rx (%d bytes), inp_flags 0x%x",
- __func__, tid, pdu_len, inp->inp_flags);
+ if (__predict_false(tp->t_flags & TF_DISCONNECTED)) {
+ CTR4(KTR_CXGBE, "%s: tid %u, rx (%d bytes), t_flags 0x%x",
+ __func__, tid, pdu_len, tp->t_flags);
INP_WUNLOCK(inp);
icl_cxgbei_conn_pdu_free(NULL, ip);
toep->ulpcb2 = NULL;
@@ -663,8 +664,6 @@
return (0);
}
- tp = intotcpcb(inp);
-
/*
* If icc is NULL, the connection is being closed in
* icl_cxgbei_conn_close(), just drop this data.
diff --git a/sys/dev/cxgbe/cxgbei/icl_cxgbei.c b/sys/dev/cxgbe/cxgbei/icl_cxgbei.c
--- a/sys/dev/cxgbe/cxgbei/icl_cxgbei.c
+++ b/sys/dev/cxgbe/cxgbei/icl_cxgbei.c
@@ -434,6 +434,7 @@
struct toepcb *toep = icc->toep;
struct socket *so = ic->ic_socket;
struct inpcb *inp = sotoinpcb(so);
+ struct tcpcb *tp = intotcpcb(inp);
struct icl_pdu *ip;
struct mbuf *m;
struct mbufq mq;
@@ -476,7 +477,7 @@
INP_WLOCK(inp);
ICL_CONN_UNLOCK(ic);
- if (__predict_false(inp->inp_flags & INP_DROPPED) ||
+ if (__predict_false(tp->t_flags & TF_DISCONNECTED) ||
__predict_false((toep->flags & TPF_ATTACHED) == 0)) {
mbufq_drain(&mq);
} else {
@@ -1080,7 +1081,7 @@
inp = sotoinpcb(so);
INP_WLOCK(inp);
tp = intotcpcb(inp);
- if (inp->inp_flags & INP_DROPPED) {
+ if (tp->t_flags & TF_DISCONNECTED) {
INP_WUNLOCK(inp);
error = ENOTCONN;
goto out;
@@ -1334,6 +1335,7 @@
struct cxgbei_ddp_state *ddp;
struct ppod_reservation *prsv;
struct inpcb *inp;
+ struct tcpcb *tp;
struct mbufq mq;
uint32_t itt;
int rc = 0;
@@ -1421,8 +1423,9 @@
* detached already.
*/
inp = sotoinpcb(ic->ic_socket);
+ tp = intotcpcb(inp);
INP_WLOCK(inp);
- if ((inp->inp_flags & INP_DROPPED) != 0) {
+ if ((tp->t_flags & TF_DISCONNECTED) != 0) {
INP_WUNLOCK(inp);
mbufq_drain(&mq);
t4_free_page_pods(prsv);
@@ -1497,6 +1500,7 @@
struct ppod_reservation *prsv;
struct ctl_sg_entry *sgl, sg_entry;
struct inpcb *inp;
+ struct tcpcb *tp;
struct mbufq mq;
int sg_entries = ctsio->kern_sg_entries;
uint32_t ttt;
@@ -1597,9 +1601,10 @@
return (ECONNRESET);
}
inp = sotoinpcb(ic->ic_socket);
+ tp = intotcpcb(inp);
INP_WLOCK(inp);
ICL_CONN_UNLOCK(ic);
- if ((inp->inp_flags & INP_DROPPED) != 0) {
+ if ((tp->t_flags & TF_DISCONNECTED) != 0) {
INP_WUNLOCK(inp);
mbufq_drain(&mq);
t4_free_page_pods(prsv);
diff --git a/sys/dev/cxgbe/iw_cxgbe/qp.c b/sys/dev/cxgbe/iw_cxgbe/qp.c
--- a/sys/dev/cxgbe/iw_cxgbe/qp.c
+++ b/sys/dev/cxgbe/iw_cxgbe/qp.c
@@ -64,7 +64,7 @@
#include "iw_cxgbe.h"
#include "user.h"
-static int creds(struct toepcb *toep, struct inpcb *inp, size_t wrsize);
+static int creds(struct toepcb *toep, struct tcpcb *tp, size_t wrsize);
static int max_fr_immd = T4_MAX_FR_IMMD;//SYSCTL parameter later...
static int alloc_ird(struct c4iw_dev *dev, u32 ird)
@@ -1149,7 +1149,7 @@
term->ecode = qhp->attr.ecode;
} else
build_term_codes(err_cqe, &term->layer_etype, &term->ecode);
- ret = creds(toep, inp, sizeof(*wqe));
+ ret = creds(toep, tp, sizeof(*wqe));
if (ret) {
free_wrqe(wr);
return;
@@ -1253,8 +1253,7 @@
int ret;
struct wrqe *wr;
struct socket *so = ep->com.so;
- struct inpcb *inp = sotoinpcb(so);
- struct tcpcb *tp = intotcpcb(inp);
+ struct tcpcb *tp = intotcpcb(sotoinpcb(so));
struct toepcb *toep = tp->t_toe;
KASSERT(rhp == qhp->rhp && ep == qhp->ep, ("%s: EDOOFUS", __func__));
@@ -1277,7 +1276,7 @@
c4iw_init_wr_wait(&ep->com.wr_wait);
- ret = creds(toep, inp, sizeof(*wqe));
+ ret = creds(toep, tp, sizeof(*wqe));
if (ret) {
free_wrqe(wr);
return ret;
@@ -1315,14 +1314,14 @@
}
static int
-creds(struct toepcb *toep, struct inpcb *inp, size_t wrsize)
+creds(struct toepcb *toep, struct tcpcb *tp, size_t wrsize)
{
struct ofld_tx_sdesc *txsd;
CTR3(KTR_IW_CXGBE, "%s:creB %p %u", __func__, toep , wrsize);
- INP_WLOCK(inp);
- if ((inp->inp_flags & INP_DROPPED) != 0) {
- INP_WUNLOCK(inp);
+ INP_WLOCK(tptoinpcb(tp));
+ if (tp->t_flags & TF_DISCONNECTED) {
+ INP_WUNLOCK(tptoinpcb(tp));
return (EINVAL);
}
txsd = &toep->txsd[toep->txsd_pidx];
@@ -1336,7 +1335,7 @@
if (__predict_false(++toep->txsd_pidx == toep->txsd_total))
toep->txsd_pidx = 0;
toep->txsd_avail--;
- INP_WUNLOCK(inp);
+ INP_WUNLOCK(tptoinpcb(tp));
CTR5(KTR_IW_CXGBE, "%s:creE %p %u %u %u", __func__, toep ,
txsd->tx_credits, toep->tx_credits, toep->txsd_pidx);
return (0);
@@ -1351,8 +1350,7 @@
struct c4iw_rdev *rdev = &qhp->rhp->rdev;
struct adapter *sc = rdev->adap;
struct socket *so = ep->com.so;
- struct inpcb *inp = sotoinpcb(so);
- struct tcpcb *tp = intotcpcb(inp);
+ struct tcpcb *tp = intotcpcb(sotoinpcb(so));
struct toepcb *toep = tp->t_toe;
CTR5(KTR_IW_CXGBE, "%s qhp %p qid 0x%x ep %p tid %u", __func__, qhp,
@@ -1416,7 +1414,7 @@
c4iw_init_wr_wait(&ep->com.wr_wait);
- ret = creds(toep, inp, sizeof(*wqe));
+ ret = creds(toep, tp, sizeof(*wqe));
if (ret) {
free_wrqe(wr);
free_ird(rhp, qhp->attr.max_ird);
diff --git a/sys/dev/cxgbe/nvmf/nvmf_che.c b/sys/dev/cxgbe/nvmf/nvmf_che.c
--- a/sys/dev/cxgbe/nvmf/nvmf_che.c
+++ b/sys/dev/cxgbe/nvmf/nvmf_che.c
@@ -555,6 +555,7 @@
struct toepcb *toep = qp->toep;
struct socket *so = qp->so;
struct inpcb *inp = sotoinpcb(so);
+ struct tcpcb *tp = intotcpcb(inp);
struct mbufq mq;
int error;
@@ -568,7 +569,7 @@
goto error;
INP_WLOCK(inp);
- if ((inp->inp_flags & INP_DROPPED) != 0) {
+ if ((tp->t_flags & TF_DISCONNECTED) != 0) {
INP_WUNLOCK(inp);
error = ECONNRESET;
goto error;
@@ -862,12 +863,13 @@
struct epoch_tracker et;
struct socket *so = qp->so;
struct inpcb *inp = sotoinpcb(so);
+ struct tcpcb *tp = intotcpcb(inp);
struct toepcb *toep = qp->toep;
CURVNET_SET(so->so_vnet);
NET_EPOCH_ENTER(et);
INP_WLOCK(inp);
- if (__predict_false(inp->inp_flags & INP_DROPPED) ||
+ if (__predict_false(tp->t_flags & TF_DISCONNECTED) ||
__predict_false((toep->flags & TPF_ATTACHED) == 0)) {
m_freem(m);
} else {
@@ -2052,10 +2054,11 @@
("%s: payload length mismatch", __func__));
inp = toep->inp;
+ tp = intotcpcb(inp);
INP_WLOCK(inp);
- if (inp->inp_flags & INP_DROPPED) {
- CTR(KTR_CXGBE, "%s: tid %u, rx (%d bytes), inp_flags 0x%x",
- __func__, tid, len, inp->inp_flags);
+ if (tp->t_flags & TF_DISCONNECTED) {
+ CTR(KTR_CXGBE, "%s: tid %u, rx (%d bytes), t_flags 0x%x",
+ __func__, tid, len, tp->t_flags);
INP_WUNLOCK(inp);
m_freem(m);
return (0);
@@ -2070,7 +2073,6 @@
mbufq_enqueue(&qp->rx_data, m);
SOCKBUF_UNLOCK(&so->so_rcv);
- tp = intotcpcb(inp);
tp->t_rcvtime = ticks;
#ifdef VERBOSE_TRACES
@@ -2092,6 +2094,7 @@
struct nvmf_che_qpair *qp = toep->ulpcb;
struct socket *so = qp->so;
struct inpcb *inp = toep->inp;
+ struct tcpcb *tp = intotcpcb(inp);
u_int hlen __diagused;
bool empty;
@@ -2107,9 +2110,9 @@
("%s: payload length mismatch", __func__));
INP_WLOCK(inp);
- if (inp->inp_flags & INP_DROPPED) {
- CTR(KTR_CXGBE, "%s: tid %u, rx (hlen %u), inp_flags 0x%x",
- __func__, tid, hlen, inp->inp_flags);
+ if (tp->t_flags & TF_DISCONNECTED) {
+ CTR(KTR_CXGBE, "%s: tid %u, rx (hlen %u), t_flags 0x%x",
+ __func__, tid, hlen, tp->t_flags);
INP_WUNLOCK(inp);
m_freem(m);
return (0);
@@ -2505,7 +2508,7 @@
inp = sotoinpcb(so);
INP_WLOCK(inp);
tp = intotcpcb(inp);
- if (inp->inp_flags & INP_DROPPED) {
+ if (tp->t_flags & TF_DISCONNECTED) {
INP_WUNLOCK(inp);
free(qp->fl_cid_set, M_NVMF_CHE);
free(qp->fl_cids, M_NVMF_CHE);
diff --git a/sys/dev/cxgbe/tom/t4_connect.c b/sys/dev/cxgbe/tom/t4_connect.c
--- a/sys/dev/cxgbe/tom/t4_connect.c
+++ b/sys/dev/cxgbe/tom/t4_connect.c
@@ -78,6 +78,7 @@
u_int atid = G_TID_TID(ntohl(cpl->tos_atid));
struct toepcb *toep = lookup_atid(sc, atid);
struct inpcb *inp = toep->inp;
+ struct tcpcb *tp = intotcpcb(inp);
KASSERT(m == NULL, ("%s: wasn't expecting payload", __func__));
KASSERT(toep->tid == atid, ("%s: toep tid/atid mismatch", __func__));
@@ -95,7 +96,7 @@
toep->ctrlq = &sc->sge.ctrlq[toep->params.ctrlq_idx];
}
- if (inp->inp_flags & INP_DROPPED) {
+ if (tp->t_flags & TF_DISCONNECTED) {
/* socket closed by the kernel before hw told us it connected */
diff --git a/sys/dev/cxgbe/tom/t4_cpl_io.c b/sys/dev/cxgbe/tom/t4_cpl_io.c
--- a/sys/dev/cxgbe/tom/t4_cpl_io.c
+++ b/sys/dev/cxgbe/tom/t4_cpl_io.c
@@ -245,13 +245,13 @@
struct cpl_abort_req *req;
int tid = toep->tid;
struct inpcb *inp = toep->inp;
- struct tcpcb *tp = intotcpcb(inp); /* don't use if INP_DROPPED */
+ struct tcpcb *tp = intotcpcb(inp);
INP_WLOCK_ASSERT(inp);
CTR6(KTR_CXGBE, "%s: tid %d (%s), toep_flags 0x%x, inp_flags 0x%x%s",
__func__, toep->tid,
- inp->inp_flags & INP_DROPPED ? "inp dropped" :
+ tp->t_flags & TF_DISCONNECTED ? "TCP disconnected" :
tcpstates[tp->t_state],
toep->flags, inp->inp_flags,
toep->flags & TPF_ABORT_SHUTDOWN ?
@@ -273,7 +273,7 @@
req = wrtod(wr);
INIT_TP_WR_MIT_CPL(req, CPL_ABORT_REQ, tid);
- if (inp->inp_flags & INP_DROPPED)
+ if (tp->t_flags & TF_DISCONNECTED)
req->rsvd0 = htobe32(snd_nxt);
else
req->rsvd0 = htobe32(tp->snd_nxt);
@@ -284,7 +284,7 @@
* XXX: What's the correct way to tell that the inp hasn't been detached
* from its socket? Should I even be flushing the snd buffer here?
*/
- if ((inp->inp_flags & INP_DROPPED) == 0) {
+ if ((tp->t_flags & TF_DISCONNECTED) == 0) {
struct socket *so = inp->inp_socket;
if (so != NULL) /* because I'm not sure. See comment above */
@@ -1588,8 +1588,8 @@
struct toepcb *toep = tp->t_toe;
INP_WLOCK_ASSERT(inp);
- KASSERT((inp->inp_flags & INP_DROPPED) == 0,
- ("%s: inp %p dropped.", __func__, inp));
+ KASSERT((tp->t_flags & TF_DISCONNECTED) == 0,
+ ("%s: tcpcb %p disconnected", __func__, tp));
KASSERT(toep != NULL, ("%s: toep is NULL", __func__));
t4_push_data(sc, toep, 0);
@@ -1607,8 +1607,8 @@
struct toepcb *toep = tp->t_toe;
INP_WLOCK_ASSERT(inp);
- KASSERT((inp->inp_flags & INP_DROPPED) == 0,
- ("%s: inp %p dropped.", __func__, inp));
+ KASSERT((tp->t_flags & TF_DISCONNECTED) == 0,
+ ("%s: tcpcb %p disconnected", __func__, tp));
KASSERT(toep != NULL, ("%s: toep is NULL", __func__));
toep->flags |= TPF_SEND_FIN;
@@ -1628,8 +1628,8 @@
struct toepcb *toep = tp->t_toe;
INP_WLOCK_ASSERT(inp);
- KASSERT((inp->inp_flags & INP_DROPPED) == 0,
- ("%s: inp %p dropped.", __func__, inp));
+ KASSERT((tp->t_flags & TF_DISCONNECTED) == 0,
+ ("%s: tcpcb %p disconnected", __func__, tp));
KASSERT(toep != NULL, ("%s: toep is NULL", __func__));
/* hmmmm */
@@ -1921,7 +1921,7 @@
}
toep->flags |= TPF_ABORT_SHUTDOWN;
- if ((inp->inp_flags & INP_DROPPED) == 0) {
+ if ((tp->t_flags & TF_DISCONNECTED) == 0) {
struct socket *so = inp->inp_socket;
if (so != NULL)
@@ -2010,17 +2010,16 @@
m_adj(m, sizeof(*cpl));
len = m->m_pkthdr.len;
+ tp = intotcpcb(inp);
INP_WLOCK(inp);
- if (inp->inp_flags & INP_DROPPED) {
- CTR4(KTR_CXGBE, "%s: tid %u, rx (%d bytes), inp_flags 0x%x",
- __func__, tid, len, inp->inp_flags);
+ if (tp->t_flags & TF_DISCONNECTED) {
+ CTR4(KTR_CXGBE, "%s: tid %u, rx (%d bytes), t_flags 0x%x",
+ __func__, tid, len, tp->t_flags);
INP_WUNLOCK(inp);
m_freem(m);
return (0);
}
- tp = intotcpcb(inp);
-
if (__predict_false(ulp_mode(toep) == ULP_MODE_TLS &&
toep->flags & TPF_TLS_RECEIVE)) {
/* Received "raw" data on a TLS socket. */
@@ -2170,6 +2169,7 @@
}
inp = toep->inp;
+ tp = intotcpcb(inp);
KASSERT(opcode == CPL_FW4_ACK,
("%s: unexpected opcode 0x%x", __func__, opcode));
@@ -2183,10 +2183,8 @@
return (0);
}
- KASSERT((inp->inp_flags & INP_DROPPED) == 0,
- ("%s: inp_flags 0x%x", __func__, inp->inp_flags));
-
- tp = intotcpcb(inp);
+ KASSERT((tp->t_flags & TF_DISCONNECTED) == 0,
+ ("%s: t_flags 0x%x", __func__, tp->t_flags));
if (cpl->flags & CPL_FW4_ACK_FLAGS_SEQVAL) {
tcp_seq snd_una = be32toh(cpl->snd_una);
@@ -2627,8 +2625,9 @@
/* Inlined tcp_usr_send(). */
inp = toep->inp;
+ tp = intotcpcb(inp);
INP_WLOCK(inp);
- if (inp->inp_flags & INP_DROPPED) {
+ if (tp->t_flags & TF_DISCONNECTED) {
INP_WUNLOCK(inp);
SOCK_IO_SEND_UNLOCK(so);
error = ECONNRESET;
@@ -2642,8 +2641,7 @@
sbappendstream(sb, m, 0);
m = NULL;
- if (!(inp->inp_flags & INP_DROPPED)) {
- tp = intotcpcb(inp);
+ if (!(tp->t_flags & TF_DISCONNECTED)) {
if (moretocome)
tp->t_flags |= TF_MORETOCOME;
error = tcp_output(tp);
diff --git a/sys/dev/cxgbe/tom/t4_ddp.c b/sys/dev/cxgbe/tom/t4_ddp.c
--- a/sys/dev/cxgbe/tom/t4_ddp.c
+++ b/sys/dev/cxgbe/tom/t4_ddp.c
@@ -641,8 +641,8 @@
uint32_t report = be32toh(ddp_report);
unsigned int db_idx;
struct inpcb *inp = toep->inp;
+ struct tcpcb *tp = intotcpcb(inp);
struct ddp_buffer *db;
- struct tcpcb *tp;
struct socket *so;
struct sockbuf *sb;
struct kaiocb *job;
@@ -664,13 +664,13 @@
db = &toep->ddp.db[db_idx];
job = db->job;
- if (__predict_false(inp->inp_flags & INP_DROPPED)) {
+ if (__predict_false(tp->t_flags & TF_DISCONNECTED)) {
/*
* This can happen due to an administrative tcpdrop(8).
* Just fail the request with ECONNRESET.
*/
- CTR5(KTR_CXGBE, "%s: tid %u, seq 0x%x, len %d, inp_flags 0x%x",
- __func__, toep->tid, be32toh(rcv_nxt), len, inp->inp_flags);
+ CTR5(KTR_CXGBE, "%s: tid %u, seq 0x%x, len %d, t_flags 0x%x",
+ __func__, toep->tid, be32toh(rcv_nxt), len, tp->t_flags);
if (aio_clear_cancel_function(job))
ddp_complete_one(job, ECONNRESET);
goto completed;
@@ -859,7 +859,7 @@
{
uint32_t report = be32toh(ddp_report);
struct inpcb *inp = toep->inp;
- struct tcpcb *tp;
+ struct tcpcb *tp = intotcpcb(inp);
struct socket *so;
struct sockbuf *sb;
struct ddp_buffer *db;
@@ -881,20 +881,18 @@
toep->ddp.active_id, toep->tid));
db = &toep->ddp.db[db_idx];
- if (__predict_false(inp->inp_flags & INP_DROPPED)) {
+ if (__predict_false(tp->t_flags & TF_DISCONNECTED)) {
/*
* This can happen due to an administrative tcpdrop(8).
* Just ignore the received data.
*/
- CTR5(KTR_CXGBE, "%s: tid %u, seq 0x%x, len %d, inp_flags 0x%x",
- __func__, toep->tid, be32toh(rcv_nxt), len, inp->inp_flags);
+ CTR5(KTR_CXGBE, "%s: tid %u, seq 0x%x, len %d, t_flags 0x%x",
+ __func__, toep->tid, be32toh(rcv_nxt), len, tp->t_flags);
if (invalidated)
complete_ddp_buffer(toep, db, db_idx);
goto out;
}
- tp = intotcpcb(inp);
-
/*
* For RX_DDP_COMPLETE, len will be zero and rcv_nxt is the
* sequence number of the next byte to receive. The length of
diff --git a/sys/dev/cxgbe/tom/t4_listen.c b/sys/dev/cxgbe/tom/t4_listen.c
--- a/sys/dev/cxgbe/tom/t4_listen.c
+++ b/sys/dev/cxgbe/tom/t4_listen.c
@@ -886,6 +886,7 @@
unsigned int status = cpl->status;
struct listen_ctx *lctx = lookup_stid(sc, stid);
struct inpcb *inp = lctx->inp;
+ struct tcpcb *tp = intotcpcb(inp);
#ifdef INVARIANTS
unsigned int opcode = G_CPL_OPCODE(be32toh(OPCODE_TID(cpl)));
#endif
@@ -911,13 +912,13 @@
* If the inp has been dropped (listening socket closed) then
* listen_stop must have run and taken the inp out of the hash.
*/
- if (inp->inp_flags & INP_DROPPED) {
+ if (tp->t_flags & TF_DISCONNECTED) {
KASSERT(listen_hash_del(sc, inp) == NULL,
("%s: inp %p still in listen hash", __func__, inp));
}
#endif
- if (inp->inp_flags & INP_DROPPED && status != CPL_ERR_NONE) {
+ if (tp->t_flags & TF_DISCONNECTED && status != CPL_ERR_NONE) {
if (release_lctx(sc, lctx) != NULL)
INP_WUNLOCK(inp);
return (status);
@@ -928,7 +929,7 @@
* it has started the hardware listener. Stop it; the lctx will be
* released in do_close_server_rpl.
*/
- if (inp->inp_flags & INP_DROPPED) {
+ if (tp->t_flags & TF_DISCONNECTED) {
destroy_server(sc, lctx);
INP_WUNLOCK(inp);
return (status);
@@ -1336,6 +1337,7 @@
unsigned int tid = GET_TID(cpl);
struct listen_ctx *lctx = lookup_stid(sc, stid);
struct inpcb *inp;
+ struct tcpcb *tp;
struct socket *so;
struct in_conninfo inc;
struct tcphdr th;
@@ -1477,10 +1479,11 @@
}
inp = lctx->inp; /* listening socket, not owned by TOE */
+ tp = intotcpcb(inp);
INP_RLOCK(inp);
/* Don't offload if the listening socket has closed */
- if (__predict_false(inp->inp_flags & INP_DROPPED)) {
+ if (__predict_false(tp->t_flags & TF_DISCONNECTED)) {
INP_RUNLOCK(inp);
NET_EPOCH_EXIT(et);
REJECT_PASS_ACCEPT_REQ(false);
@@ -1622,6 +1625,7 @@
struct synq_entry *synqe = lookup_tid(sc, tid);
struct listen_ctx *lctx = synqe->lctx;
struct inpcb *inp = lctx->inp, *new_inp;
+ struct tcpcb *tp = intotcpcb(inp);
struct socket *so;
struct tcphdr th;
struct tcpopt to;
@@ -1653,7 +1657,7 @@
KASSERT(vi->adapter == sc,
("%s: vi %p, sc %p mismatch", __func__, vi, sc));
- if (__predict_false(inp->inp_flags & INP_DROPPED)) {
+ if (__predict_false(tp->t_flags & TF_DISCONNECTED)) {
reset:
send_abort_rpl_synqe(TOEDEV(ifp), synqe, CPL_ABORT_SEND_RST);
INP_WUNLOCK(inp);
diff --git a/sys/dev/cxgbe/tom/t4_tls.c b/sys/dev/cxgbe/tom/t4_tls.c
--- a/sys/dev/cxgbe/tom/t4_tls.c
+++ b/sys/dev/cxgbe/tom/t4_tls.c
@@ -762,7 +762,7 @@
unsigned int tid = GET_TID(cpl);
struct toepcb *toep = lookup_tid(sc, tid);
struct inpcb *inp = toep->inp;
- struct tcpcb *tp;
+ struct tcpcb *tp = intotcpcb(inp);
int len;
/* XXX: Should this match do_rx_data instead? */
@@ -781,9 +781,9 @@
("%s: payload length mismatch", __func__));
INP_WLOCK(inp);
- if (inp->inp_flags & INP_DROPPED) {
- CTR4(KTR_CXGBE, "%s: tid %u, rx (%d bytes), inp_flags 0x%x",
- __func__, tid, len, inp->inp_flags);
+ if (tp->t_flags & TF_DISCONNECTED) {
+ CTR4(KTR_CXGBE, "%s: tid %u, rx (%d bytes), t_flags 0x%x",
+ __func__, tid, len, tp->t_flags);
INP_WUNLOCK(inp);
m_freem(m);
return (0);
@@ -803,7 +803,6 @@
#endif
}
- tp = intotcpcb(inp);
tp->t_rcvtime = ticks;
#ifdef VERBOSE_TRACES
@@ -824,7 +823,7 @@
unsigned int tid = GET_TID(cpl);
struct toepcb *toep = lookup_tid(sc, tid);
struct inpcb *inp = toep->inp;
- struct tcpcb *tp;
+ struct tcpcb *tp = intotcpcb(inp);
struct socket *so;
struct sockbuf *sb;
struct mbuf *tls_data;
@@ -851,9 +850,9 @@
("%s: payload length mismatch", __func__));
INP_WLOCK(inp);
- if (inp->inp_flags & INP_DROPPED) {
- CTR4(KTR_CXGBE, "%s: tid %u, rx (%d bytes), inp_flags 0x%x",
- __func__, tid, len, inp->inp_flags);
+ if (tp->t_flags & TF_DISCONNECTED) {
+ CTR4(KTR_CXGBE, "%s: tid %u, rx (%d bytes), t_flags 0x%x",
+ __func__, tid, len, tp->t_flags);
INP_WUNLOCK(inp);
m_freem(m);
return (0);
@@ -862,7 +861,6 @@
pdu_length = G_CPL_RX_TLS_CMP_PDULENGTH(be32toh(cpl->pdulength_length));
so = inp_inpcbtosocket(inp);
- tp = intotcpcb(inp);
#ifdef VERBOSE_TRACES
CTR6(KTR_CXGBE, "%s: tid %u PDU len %d len %d seq %u, rcv_nxt %u",
diff --git a/sys/dev/cxgbe/tom/t4_tom.c b/sys/dev/cxgbe/tom/t4_tom.c
--- a/sys/dev/cxgbe/tom/t4_tom.c
+++ b/sys/dev/cxgbe/tom/t4_tom.c
@@ -1830,7 +1830,7 @@
INP_WLOCK(inp);
tp = intotcpcb(inp);
toep->flags |= TPF_ABORT_SHUTDOWN;
- if ((inp->inp_flags & INP_DROPPED) == 0) {
+ if ((tp->t_flags & TF_DISCONNECTED) == 0) {
struct socket *so = inp->inp_socket;
if (so != NULL)
@@ -2283,8 +2283,8 @@
struct find_offload_adapter_data *fa = arg;
struct socket *so = fa->so;
struct tom_data *td = sc->tom_softc;
- struct tcpcb *tp;
- struct inpcb *inp;
+ struct inpcb *inp = sotoinpcb(so);
+ struct tcpcb *tp = intotcpcb(inp);
/* Non-TCP were filtered out earlier. */
MPASS(so->so_proto->pr_protocol == IPPROTO_TCP);
@@ -2295,10 +2295,8 @@
if (td == NULL)
return; /* TOE not enabled on this adapter. */
- inp = sotoinpcb(so);
INP_WLOCK(inp);
- if ((inp->inp_flags & INP_DROPPED) == 0) {
- tp = intotcpcb(inp);
+ if ((tp->t_flags & TF_DISCONNECTED) == 0) {
if (tp->t_flags & TF_TOE && tp->tod == &td->tod)
fa->sc = sc; /* Found. */
}
diff --git a/sys/kern/uipc_ktls.c b/sys/kern/uipc_ktls.c
--- a/sys/kern/uipc_ktls.c
+++ b/sys/kern/uipc_ktls.c
@@ -870,21 +870,15 @@
static int
ktls_try_toe(struct socket *so, struct ktls_session *tls, int direction)
{
- struct inpcb *inp;
- struct tcpcb *tp;
+ struct inpcb *inp = sotoinpcb(so);
+ struct tcpcb *tp = intotcpcb(inp);
int error;
- inp = so->so_pcb;
INP_WLOCK(inp);
- if (inp->inp_flags & INP_DROPPED) {
- INP_WUNLOCK(inp);
- return (ECONNRESET);
- }
- if (inp->inp_socket == NULL) {
+ if (tp->t_flags & TF_DISCONNECTED) {
INP_WUNLOCK(inp);
return (ECONNRESET);
}
- tp = intotcpcb(inp);
if (!(tp->t_flags & TF_TOE)) {
INP_WUNLOCK(inp);
return (EOPNOTSUPP);
@@ -923,19 +917,14 @@
union if_snd_tag_alloc_params params;
struct ifnet *ifp;
struct nhop_object *nh;
- struct tcpcb *tp;
+ struct tcpcb *tp = intotcpcb(inp);
int error;
INP_RLOCK(inp);
- if (inp->inp_flags & INP_DROPPED) {
+ if (tp->t_flags & TF_DISCONNECTED) {
INP_RUNLOCK(inp);
return (ECONNRESET);
}
- if (inp->inp_socket == NULL) {
- INP_RUNLOCK(inp);
- return (ECONNRESET);
- }
- tp = intotcpcb(inp);
/*
* Check administrative controls on ifnet TLS to determine if
@@ -1027,11 +1016,7 @@
return (ENXIO);
INP_RLOCK(inp);
- if (inp->inp_flags & INP_DROPPED) {
- INP_RUNLOCK(inp);
- return (ECONNRESET);
- }
- if (inp->inp_socket == NULL) {
+ if (intotcpcb(inp)->t_flags & TF_DISCONNECTED) {
INP_RUNLOCK(inp);
return (ECONNRESET);
}
@@ -1506,23 +1491,15 @@
int
ktls_get_rx_sequence(struct inpcb *inp, uint32_t *tcpseq, uint64_t *tlsseq)
{
- struct socket *so;
- struct tcpcb *tp;
+ struct socket *so = inp->inp_socket;
+ struct tcpcb *tp = intotcpcb(inp);
INP_RLOCK(inp);
- so = inp->inp_socket;
- if (__predict_false(so == NULL)) {
- INP_RUNLOCK(inp);
- return (EINVAL);
- }
- if (inp->inp_flags & INP_DROPPED) {
+ if (tp->t_flags & TF_DISCONNECTED) {
INP_RUNLOCK(inp);
return (ECONNRESET);
}
- tp = intotcpcb(inp);
- MPASS(tp != NULL);
-
SOCKBUF_LOCK(&so->so_rcv);
*tcpseq = tp->rcv_nxt - so->so_rcv.sb_tlscc;
*tlsseq = so->so_rcv.sb_tls_seqno;
@@ -1697,7 +1674,7 @@
ifp = NULL;
INP_RLOCK(inp);
- if (inp->inp_flags & INP_DROPPED) {
+ if (intotcpcb(inp)->t_flags & TF_DISCONNECTED) {
INP_RUNLOCK(inp);
goto out;
}
@@ -1818,8 +1795,8 @@
} else {
NET_EPOCH_ENTER(et);
INP_WLOCK(inp);
- if (!(inp->inp_flags & INP_DROPPED)) {
- tp = intotcpcb(inp);
+ tp = intotcpcb(inp);
+ if (!(tp->t_flags & TF_DISCONNECTED)) {
CURVNET_SET(inp->inp_vnet);
tp = tcp_drop(tp, ECONNABORTED);
CURVNET_RESTORE();
@@ -2461,26 +2438,19 @@
{
union if_snd_tag_modify_params params;
struct m_snd_tag *mst;
- struct inpcb *inp;
- struct tcpcb *tp;
+ struct inpcb *inp = sotoinpcb(so);
+ struct tcpcb *tp = intotcpcb(inp);
mst = so->so_rcv.sb_tls_info->snd_tag;
if (__predict_false(mst == NULL))
return (EINVAL);
- inp = sotoinpcb(so);
- if (__predict_false(inp == NULL))
- return (EINVAL);
-
INP_RLOCK(inp);
- if (inp->inp_flags & INP_DROPPED) {
+ if (tp->t_flags & TF_DISCONNECTED) {
INP_RUNLOCK(inp);
return (ECONNRESET);
}
- tp = intotcpcb(inp);
- MPASS(tp != NULL);
-
/* Get the TCP sequence number of the next valid TLS header. */
SOCKBUF_LOCK(&so->so_rcv);
params.tls_rx.tls_hdr_tcp_sn =
@@ -2500,12 +2470,11 @@
{
struct epoch_tracker et;
struct inpcb *inp = sotoinpcb(so);
- struct tcpcb *tp;
+ struct tcpcb *tp = intotcpcb(inp);
NET_EPOCH_ENTER(et);
INP_WLOCK(inp);
- if (!(inp->inp_flags & INP_DROPPED)) {
- tp = intotcpcb(inp);
+ if (!(tp->t_flags & TF_DISCONNECTED)) {
CURVNET_SET(inp->inp_vnet);
tp = tcp_drop(tp, error);
CURVNET_RESTORE();
@@ -3372,7 +3341,8 @@
INP_WLOCK(inp);
so = inp->inp_socket;
MPASS(so != NULL);
- if (inp->inp_flags & INP_DROPPED) {
+ tp = intotcpcb(inp);
+ if (tp->t_flags & TF_DISCONNECTED) {
goto out;
}
@@ -3383,8 +3353,7 @@
if (err == 0) {
counter_u64_add(ktls_ifnet_disable_ok, 1);
/* ktls_set_tx_mode() drops inp wlock, so recheck flags */
- if ((inp->inp_flags & INP_DROPPED) == 0 &&
- (tp = intotcpcb(inp)) != NULL &&
+ if ((tp->t_flags & TF_DISCONNECTED) == 0 &&
tp->t_fb->tfb_hwtls_change != NULL)
(*tp->t_fb->tfb_hwtls_change)(tp, 0);
} else {
diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h
--- a/sys/netinet/in_pcb.h
+++ b/sys/netinet/in_pcb.h
@@ -181,7 +181,7 @@
#define INP_RECVTTL 0x00000400 /* receive incoming IP TTL */
#define INP_DONTFRAG 0x00000800 /* don't fragment packet */
#define INP_BINDANY 0x00001000 /* allow bind to any address */
-#define INP_INHASHLIST 0x00002000 /* in_pcbinshash() has been called */
+/* available 0x00002000 */
#define INP_RECVTOS 0x00004000 /* receive incoming IP TOS */
#define IN6P_IPV6_V6ONLY 0x00008000 /* restrict AF_INET6 socket for v6 */
#define IN6P_PKTINFO 0x00010000 /* receive IP6 dst and I/F */
@@ -194,7 +194,7 @@
#define IN6P_AUTOFLOWLABEL 0x00800000 /* attach flowlabel automatically */
/* INP_INLBGROUP 0x01000000 private to in_pcb.c */
#define INP_ONESBCAST 0x02000000 /* send all-ones broadcast */
-#define INP_DROPPED 0x04000000 /* protocol drop flag */
+/* INP_UNCONNECTED 0x04000000 private to in_pcb.c/in6_pcb.c */
#define INP_SOCKREF 0x08000000 /* strong socket reference */
#define INP_RESERVED_0 0x10000000 /* reserved field */
#define INP_BOUNDFIB 0x20000000 /* Bound to a specific FIB. */
@@ -213,10 +213,10 @@
"\1INP_RECVOPTS\2INP_RECVRETOPTS\3INP_RECVDSTADDR\4INP_HDRINCL" \
"\5INP_HIGHPORT\6INP_LOWPORT\7INP_ANONPORT\10INP_RECVIF" \
"\11INP_MTUDISC\12INP_FREED\13INP_RECVTTL\14INP_DONTFRAG" \
- "\15INP_BINDANY\16INP_INHASHLIST\17INP_RECVTOS\20IN6P_IPV6_V6ONLY" \
+ "\15INP_BINDANY\17INP_RECVTOS\20IN6P_IPV6_V6ONLY" \
"\21IN6P_PKTINFO\22IN6P_HOPLIMIT\23IN6P_HOPOPTS\24IN6P_DSTOPTS" \
"\25IN6P_RTHDR\26IN6P_RTHDRDSTOPTS\27IN6P_TCLASS\30IN6P_AUTOFLOWLABEL" \
- "\31INP_INLBGROUP\32INP_ONESBCAST\33INP_DROPPED\34INP_SOCKREF" \
+ "\31INP_INLBGROUP\32INP_ONESBCAST\33INP_UNCONNECTED\34INP_SOCKREF" \
"\35INP_RESERVED_0\36INP_BOUNDFIB\37IN6P_RFC2292\40IN6P_MTU"
/*
@@ -650,7 +650,6 @@
u_short *, int, struct ucred *);
int in_pcbconnect(struct inpcb *, struct sockaddr_in *, struct ucred *);
void in_pcbdisconnect(struct inpcb *);
-void in_pcbdrop(struct inpcb *);
void in_pcbfree(struct inpcb *);
int in_pcbladdr(const struct inpcb *, struct in_addr *, struct in_addr *,
struct ucred *);
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -692,6 +692,7 @@
*/
inp->inp_route.ro_flags = RT_LLE_CACHE;
refcount_init(&inp->inp_refcount, 1); /* Reference from socket. */
+ inp->inp_flags |= INP_UNCONNECTED;
INP_WLOCK(inp);
INP_HASH_WLOCK(pcbinfo);
pcbinfo->ipi_count++;
@@ -1158,14 +1159,14 @@
lport = inp->inp_lport;
MPASS(!in_nullhost(inp->inp_laddr) || inp->inp_lport != 0 ||
- !(inp->inp_flags & INP_INHASHLIST));
+ (inp->inp_flags & INP_UNCONNECTED));
inp->inp_faddr = faddr;
inp->inp_fport = sin->sin_port;
inp->inp_laddr = laddr;
inp->inp_lport = lport;
- if ((inp->inp_flags & INP_INHASHLIST) == 0) {
+ if (inp->inp_flags & INP_UNCONNECTED) {
error = in_pcbinshash(inp);
MPASS(error == 0);
} else
@@ -1426,11 +1427,15 @@
KASSERT(inp->inp_smr == SMR_SEQ_INVALID,
("%s: inp %p was already disconnected", __func__, inp));
+ if (inp->inp_flags & INP_UNCONNECTED)
+ return;
+
INP_HASH_WLOCK(inp->inp_pcbinfo);
in_pcbremhash(inp);
CK_LIST_INSERT_HEAD(&inp->inp_pcbinfo->ipi_list_unconn, inp,
inp_unconn_list);
INP_HASH_WUNLOCK(inp->inp_pcbinfo);
+ inp->inp_flags |= INP_UNCONNECTED;
if ((inp->inp_socket->so_proto->pr_flags & PR_CONNREQUIRED) == 0) {
/* See the comment in in_pcbinshash(). */
@@ -1538,11 +1543,11 @@
{
/*
- * in_pcblookup() family of functions ignore not only freed entries,
- * that may be found due to lockless access to the hash, but dropped
- * entries, too.
+ * in_pcblookup() family of functions shall ignore not onlu pcbs that
+ * had been freed that may be found due to lockless access to the hash,
+ * but also pcbs that were removed from the hash, but are still around.
*/
- return (_inp_smr_lock(inp, lock, INP_FREED | INP_DROPPED));
+ return (_inp_smr_lock(inp, lock, INP_FREED | INP_UNCONNECTED));
}
/*
@@ -1837,10 +1842,10 @@
* lock, thus in_pcbremhash() should be the first action.
*/
INP_HASH_WLOCK(pcbinfo);
- if (inp->inp_flags & INP_INHASHLIST)
- in_pcbremhash(inp);
- else
+ if (inp->inp_flags & INP_UNCONNECTED)
CK_LIST_REMOVE(inp, inp_unconn_list);
+ else
+ in_pcbremhash(inp);
inp->inp_gencnt = ++pcbinfo->ipi_gencnt;
pcbinfo->ipi_count--;
INP_HASH_WUNLOCK(pcbinfo);
@@ -1901,36 +1906,6 @@
INP_LOCK_DESTROY(inp);
}
-/*
- * in_pcbdrop() removes an inpcb from hashed lists, releasing its address and
- * port reservation, and preventing it from being returned by inpcb lookups.
- *
- * It is used by TCP to mark an inpcb as unused and avoid future packet
- * delivery or event notification when a socket remains open but TCP has
- * closed. This might occur as a result of a shutdown()-initiated TCP close
- * or a RST on the wire, and allows the port binding to be reused while still
- * maintaining the invariant that so_pcb always points to a valid inpcb until
- * in_pcbdetach().
- *
- * XXXRW: Possibly in_pcbdrop() should also prevent future notifications by
- * in_pcbpurgeif0()?
- */
-void
-in_pcbdrop(struct inpcb *inp)
-{
-
- INP_WLOCK_ASSERT(inp);
-
- inp->inp_flags |= INP_DROPPED;
- if (inp->inp_flags & INP_INHASHLIST) {
- INP_HASH_WLOCK(inp->inp_pcbinfo);
- in_pcbremhash(inp);
- CK_LIST_INSERT_HEAD(&inp->inp_pcbinfo->ipi_list_unconn, inp,
- inp_unconn_list);
- INP_HASH_WUNLOCK(inp->inp_pcbinfo);
- }
-}
-
#ifdef INET
/*
* Common routines to return the socket addresses associated with inpcbs.
@@ -2691,8 +2666,7 @@
INP_WLOCK_ASSERT(inp);
INP_HASH_WLOCK_ASSERT(pcbinfo);
- KASSERT((inp->inp_flags & INP_INHASHLIST) == 0,
- ("in_pcbinshash: INP_INHASHLIST"));
+ MPASS(inp->inp_flags & INP_UNCONNECTED);
#ifdef INET6
if (inp->inp_vflag & INP_IPV6) {
@@ -2751,7 +2725,7 @@
_in_pcbinshash_wild(pcbhash, inp);
}
CK_LIST_INSERT_HEAD(pcbporthash, inp, inp_portlist);
- inp->inp_flags |= INP_INHASHLIST;
+ inp->inp_flags &= ~INP_UNCONNECTED;
return (0);
}
@@ -2762,7 +2736,7 @@
INP_WLOCK_ASSERT(inp);
INP_HASH_WLOCK_ASSERT(inp->inp_pcbinfo);
- MPASS(inp->inp_flags & INP_INHASHLIST);
+ MPASS(!(inp->inp_flags & INP_UNCONNECTED));
if ((inp->inp_flags & INP_INLBGROUP) != 0)
in_pcbremlbgrouphash(inp);
@@ -2781,7 +2755,6 @@
CK_LIST_REMOVE(inp, inp_hash_exact);
}
CK_LIST_REMOVE(inp, inp_portlist);
- inp->inp_flags &= ~INP_INHASHLIST;
}
/*
@@ -2800,8 +2773,7 @@
INP_WLOCK_ASSERT(inp);
INP_HASH_WLOCK_ASSERT(pcbinfo);
- KASSERT(inp->inp_flags & INP_INHASHLIST,
- ("%s: !INP_INHASHLIST", __func__));
+ MPASS(!(inp->inp_flags & INP_UNCONNECTED));
KASSERT(inp->inp_smr == SMR_SEQ_INVALID,
("%s: inp was disconnected", __func__));
@@ -3040,7 +3012,13 @@
}
while ((inp = inp_next(&inpi)) != NULL)
if (inp->inp_gencnt == params->sop_id) {
- if (inp->inp_flags & INP_DROPPED) {
+ /*
+ * XXXGL
+ * 1) the inp_next() that ignores INP_UNCONNECTED needs
+ * to be generally supported.
+ * 2) Why do we ECONNRESET instead of continueing?
+ */
+ if (inp->inp_flags & INP_UNCONNECTED) {
INP_WUNLOCK(inp);
return (ECONNRESET);
}
@@ -3269,7 +3247,7 @@
* down, allocating a new send tag is not allowed. Else send
* tags may leak.
*/
- if (*st != NULL || (inp->inp_flags & INP_DROPPED) != 0)
+ if (*st != NULL || (inp->inp_flags & INP_UNCONNECTED))
return (EINVAL);
error = m_snd_tag_alloc(ifp, ¶ms, st);
diff --git a/sys/netinet/in_pcb_var.h b/sys/netinet/in_pcb_var.h
--- a/sys/netinet/in_pcb_var.h
+++ b/sys/netinet/in_pcb_var.h
@@ -41,6 +41,8 @@
* Definitions shared between netinet/in_pcb.c and netinet6/in6_pcb.c
*/
+#define INP_UNCONNECTED 0x04000000 /* Not inserted into hashes. */
+
VNET_DECLARE(uint32_t, in_pcbhashseed);
#define V_in_pcbhashseed VNET(in_pcbhashseed)
diff --git a/sys/netinet/tcp_hpts.c b/sys/netinet/tcp_hpts.c
--- a/sys/netinet/tcp_hpts.c
+++ b/sys/netinet/tcp_hpts.c
@@ -510,7 +510,7 @@
INP_WLOCK_ASSERT(inp);
HPTS_MTX_ASSERT(hpts);
MPASS(hpts->p_cpu == tp->t_hpts_cpu);
- MPASS(!(inp->inp_flags & INP_DROPPED));
+ MPASS(!(tp->t_flags & TF_DISCONNECTED));
hptsh = &hpts->p_hptss[tp->t_hpts_slot];
@@ -615,8 +615,10 @@
* tcp_hptsi() moves inpcb to detached tailq
* tcp_hpts_remove() marks as IHPTS_MOVING, slot = -1
* tcp_hpts_insert() sets slot to a meaningful value
- * tcp_hpts_remove() again (we are here!), then in_pcbdrop()
- * tcp_hptsi() finds pcb with meaningful slot and INP_DROPPED
+ * The connection is terminated with the final call to
+ tcp_hpts_remove() again (we are here!) and we fail to call
+ tcp_hpts_release() since it is IHPTS_MOVING. Set slot to -1
+ to delegate the release to the owner of the detached tailq.
*/
tp->t_hpts_slot = -1;
}
@@ -828,7 +830,7 @@
bool need_wakeup = false;
INP_WLOCK_ASSERT(tptoinpcb(tp));
- MPASS(!(tptoinpcb(tp)->inp_flags & INP_DROPPED));
+ MPASS(!(tp->t_flags & TF_DISCONNECTED));
MPASS(!(tp->t_in_hpts == IHPTS_ONQUEUE));
/*
@@ -1292,7 +1294,7 @@
}
MPASS(tp->t_in_hpts == IHPTS_ONQUEUE);
- MPASS(!(inp->inp_flags & INP_DROPPED));
+ MPASS(!(tp->t_flags & TF_DISCONNECTED));
KASSERT(runningslot == tp->t_hpts_slot,
("Hpts:%p inp:%p slot mis-aligned %u vs %u",
hpts, inp, runningslot, tp->t_hpts_slot));
diff --git a/sys/netinet/tcp_hpts_test.c b/sys/netinet/tcp_hpts_test.c
--- a/sys/netinet/tcp_hpts_test.c
+++ b/sys/netinet/tcp_hpts_test.c
@@ -175,7 +175,6 @@
/* Input PCB fields that HPTS uses */
KTEST_LOG(ctx, " inp_flags: 0x%x", inp->inp_flags);
- KTEST_LOG(ctx, " INP_DROPPED: %s", (inp->inp_flags & INP_DROPPED) ? "YES" : "NO");
KTEST_LOG(ctx, " inp_flowid: 0x%x", inp->inp_flowid);
KTEST_LOG(ctx, " inp_flowtype: %u", inp->inp_flowtype);
KTEST_LOG(ctx, " inp_numa_domain: %d", inp->inp_numa_domain);
@@ -585,7 +584,7 @@
KTEST_EQUAL(tp->t_lro_cpu, 0);
KTEST_VERIFY(tp->t_hpts_cpu < pace->rp_num_hptss);
KTEST_EQUAL(tp->t_inpcb.inp_refcount, 1);
- KTEST_VERIFY(!(tp->t_inpcb.inp_flags & INP_DROPPED));
+ KTEST_VERIFY(!(tp->t_flags & TF_DISCONNECTED));
test_hpts_free_tcpcb(tp);
tcp_hptsi_stop(pace);
diff --git a/sys/netinet/tcp_log_buf.c b/sys/netinet/tcp_log_buf.c
--- a/sys/netinet/tcp_log_buf.c
+++ b/sys/netinet/tcp_log_buf.c
@@ -517,12 +517,12 @@
}
#define RECHECK_INP_CLEAN(cleanup) do { \
- if (inp->inp_flags & INP_DROPPED) { \
+ tp = intotcpcb(inp); \
+ if (tp->t_flags & TF_DISCONNECTED) { \
rv = ECONNRESET; \
cleanup; \
goto done; \
} \
- tp = intotcpcb(inp); \
} while (0)
#define RECHECK_INP() RECHECK_INP_CLEAN(/* noop */)
@@ -2254,10 +2254,9 @@
if (error) {
/* Restore list */
+ tp = intotcpcb(inp);
INP_WLOCK(inp);
- if ((inp->inp_flags & INP_DROPPED) == 0) {
- tp = intotcpcb(inp);
-
+ if ((tp->t_flags & TF_DISCONNECTED) == 0) {
/* Merge the two lists. */
STAILQ_CONCAT(&log_tailq, &tp->t_logs);
tp->t_logs = log_tailq;
@@ -2428,14 +2427,14 @@
* may end up dropping some entries. That seems like a
* small price to pay for safety.
*/
- if (inp->inp_flags & INP_DROPPED) {
+ tp = intotcpcb(inp);
+ if (tp->t_flags & TF_DISCONNECTED) {
free(entry, M_TCPLOGDEV);
#ifdef TCPLOG_DEBUG_COUNTERS
counter_u64_add(tcp_log_que_fail2, 1);
#endif
return (ECONNRESET);
}
- tp = intotcpcb(inp);
if (tp->t_lognum == 0) {
free(entry, M_TCPLOGDEV);
return (0);
@@ -2871,14 +2870,14 @@
/* quick check to see if logging is enabled for this connection */
tp = intotcpcb(inp);
- if ((inp->inp_flags & INP_DROPPED) ||
+ if ((tp->t_flags & TF_DISCONNECTED) ||
(tp->_t_logstate == TCP_LOG_STATE_OFF)) {
return;
}
INP_WLOCK(inp);
/* double check log state now that we have the lock */
- if (inp->inp_flags & INP_DROPPED)
+ if (tp->t_flags & TF_DISCONNECTED)
goto done;
if (tcp_bblogging_on(tp)) {
struct timeval tv;
diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c
--- a/sys/netinet/tcp_output.c
+++ b/sys/netinet/tcp_output.c
@@ -220,6 +220,7 @@
NET_EPOCH_ASSERT();
INP_WLOCK_ASSERT(inp);
+ MPASS(!(tp->t_flags & TF_DISCONNECTED));
#ifdef TCP_OFFLOAD
if (tp->t_flags & TF_TOE)
diff --git a/sys/netinet/tcp_stacks/bbr.c b/sys/netinet/tcp_stacks/bbr.c
--- a/sys/netinet/tcp_stacks/bbr.c
+++ b/sys/netinet/tcp_stacks/bbr.c
@@ -14217,7 +14217,7 @@
if (error)
return (error);
INP_WLOCK(inp);
- if (inp->inp_flags & INP_DROPPED) {
+ if (tp->t_flags & TF_DISCONNECTED) {
INP_WUNLOCK(inp);
return (ECONNRESET);
}
diff --git a/sys/netinet/tcp_stacks/rack.c b/sys/netinet/tcp_stacks/rack.c
--- a/sys/netinet/tcp_stacks/rack.c
+++ b/sys/netinet/tcp_stacks/rack.c
@@ -14750,8 +14750,8 @@
*/
rack_convert_rtts(tp);
rack_log_hystart_event(rack, rack->r_ctl.roundends, 20);
- if ((tptoinpcb(tp)->inp_flags & INP_DROPPED) == 0) {
- /* We do not start any timers on DROPPED connections */
+ if ((tp->t_flags & TF_DISCONNECTED) == 0) {
+ /* We do not start any timers on disconnected connections */
if (tp->t_fb->tfb_chg_query == NULL) {
rack_start_hpts_timer(rack, tp, tcp_get_usecs(NULL), 0, 0, 0);
} else {
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -2551,10 +2551,11 @@
tcp_timer_stop(tp);
if (tp->t_fb->tfb_tcp_timer_stop_all != NULL)
tp->t_fb->tfb_tcp_timer_stop_all(tp);
- in_pcbdrop(inp);
+ in_pcbdisconnect(inp);
TCPSTAT_INC(tcps_closed);
if (tp->t_state != TCPS_CLOSED)
tcp_state_change(tp, TCPS_CLOSED);
+ tp->t_flags |= TF_DISCONNECTED;
KASSERT(inp->inp_socket != NULL, ("tcp_close: inp_socket NULL"));
tcp_free_sackholes(tp);
soisdisconnected(so);
diff --git a/sys/netinet/tcp_timewait.c b/sys/netinet/tcp_timewait.c
--- a/sys/netinet/tcp_timewait.c
+++ b/sys/netinet/tcp_timewait.c
@@ -126,10 +126,7 @@
NET_EPOCH_ASSERT();
INP_WLOCK_ASSERT(inp);
-
- /* A dropped inp should never transition to TIME_WAIT state. */
- KASSERT((inp->inp_flags & INP_DROPPED) == 0, ("tcp_twstart: "
- "(inp->inp_flags & INP_DROPPED) != 0"));
+ MPASS(!(tp->t_flags & TF_DISCONNECTED));
tcp_state_change(tp, TCPS_TIME_WAIT);
tcp_free_sackholes(tp);
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -205,9 +205,9 @@
tp = intotcpcb(inp);
- KASSERT(inp->inp_flags & INP_DROPPED ||
+ KASSERT(tp->t_flags & TF_DISCONNECTED ||
tp->t_state < TCPS_SYN_SENT,
- ("%s: inp %p not dropped or embryonic", __func__, inp));
+ ("%s: inp %p not disconnected or embryonic", __func__, inp));
tcp_discardcb(tp);
in_pcbfree(inp);
@@ -220,19 +220,16 @@
static int
tcp_usr_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
{
- int error = 0;
- struct inpcb *inp;
- struct tcpcb *tp;
+ struct inpcb *inp = sotoinpcb(so);
+ struct tcpcb *tp = intotcpcb(inp);
struct sockaddr_in *sinp;
+ int error = 0;
- inp = sotoinpcb(so);
- KASSERT(inp != NULL, ("tcp_usr_bind: inp == NULL"));
INP_WLOCK(inp);
- if (inp->inp_flags & INP_DROPPED) {
+ if (__predict_false(tp->t_flags & TF_DISCONNECTED)) {
INP_WUNLOCK(inp);
return (EINVAL);
}
- tp = intotcpcb(inp);
sinp = (struct sockaddr_in *)nam;
if (nam->sa_family != AF_INET) {
@@ -276,20 +273,17 @@
static int
tcp6_usr_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
{
- int error = 0;
- struct inpcb *inp;
- struct tcpcb *tp;
+ struct inpcb *inp = sotoinpcb(so);
+ struct tcpcb *tp = intotcpcb(inp);
struct sockaddr_in6 *sin6;
+ int error = 0;
u_char vflagsav;
- inp = sotoinpcb(so);
- KASSERT(inp != NULL, ("tcp6_usr_bind: inp == NULL"));
INP_WLOCK(inp);
- if (inp->inp_flags & INP_DROPPED) {
+ if (__predict_false(tp->t_flags & TF_DISCONNECTED)) {
INP_WUNLOCK(inp);
return (EINVAL);
}
- tp = intotcpcb(inp);
vflagsav = inp->inp_vflag;
@@ -355,19 +349,16 @@
static int
tcp_usr_listen(struct socket *so, int backlog, struct thread *td)
{
- struct inpcb *inp;
- struct tcpcb *tp;
+ struct inpcb *inp = sotoinpcb(so);
+ struct tcpcb *tp = intotcpcb(inp);
int error = 0;
bool already_listening;
- inp = sotoinpcb(so);
- KASSERT(inp != NULL, ("tcp_usr_listen: inp == NULL"));
INP_WLOCK(inp);
- if (inp->inp_flags & INP_DROPPED) {
+ if (__predict_false(tp->t_flags & TF_DISCONNECTED)) {
INP_WUNLOCK(inp);
return (EINVAL);
}
- tp = intotcpcb(inp);
SOCK_LOCK(so);
already_listening = SOLISTENING(so);
@@ -414,20 +405,17 @@
static int
tcp6_usr_listen(struct socket *so, int backlog, struct thread *td)
{
- struct inpcb *inp;
- struct tcpcb *tp;
+ struct inpcb *inp = sotoinpcb(so);
+ struct tcpcb *tp = intotcpcb(inp);
u_char vflagsav;
int error = 0;
bool already_listening;
- inp = sotoinpcb(so);
- KASSERT(inp != NULL, ("tcp6_usr_listen: inp == NULL"));
INP_WLOCK(inp);
- if (inp->inp_flags & INP_DROPPED) {
+ if (__predict_false(tp->t_flags & TF_DISCONNECTED)) {
INP_WUNLOCK(inp);
return (EINVAL);
}
- tp = intotcpcb(inp);
vflagsav = inp->inp_vflag;
@@ -488,19 +476,16 @@
tcp_usr_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
{
struct epoch_tracker et;
- int error = 0;
- struct inpcb *inp;
- struct tcpcb *tp;
+ struct inpcb *inp = sotoinpcb(so);
+ struct tcpcb *tp = intotcpcb(inp);
struct sockaddr_in *sinp;
+ int error = 0;
- inp = sotoinpcb(so);
- KASSERT(inp != NULL, ("tcp_usr_connect: inp == NULL"));
INP_WLOCK(inp);
- if (inp->inp_flags & INP_DROPPED) {
+ if (__predict_false(tp->t_flags & TF_DISCONNECTED)) {
INP_WUNLOCK(inp);
return (ECONNREFUSED);
}
- tp = intotcpcb(inp);
sinp = (struct sockaddr_in *)nam;
if (nam->sa_family != AF_INET) {
@@ -556,21 +541,18 @@
tcp6_usr_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
{
struct epoch_tracker et;
- int error = 0;
- struct inpcb *inp;
- struct tcpcb *tp;
+ struct inpcb *inp = sotoinpcb(so);
+ struct tcpcb *tp = intotcpcb(inp);
struct sockaddr_in6 *sin6;
+ int error = 0;
u_int8_t incflagsav;
u_char vflagsav;
- inp = sotoinpcb(so);
- KASSERT(inp != NULL, ("tcp6_usr_connect: inp == NULL"));
INP_WLOCK(inp);
- if (inp->inp_flags & INP_DROPPED) {
+ if (__predict_false(tp->t_flags & TF_DISCONNECTED)) {
INP_WUNLOCK(inp);
return (ECONNREFUSED);
}
- tp = intotcpcb(inp);
vflagsav = inp->inp_vflag;
incflagsav = inp->inp_inc.inc_flags;
@@ -725,18 +707,15 @@
static int
tcp_usr_accept(struct socket *so, struct sockaddr *sa)
{
- struct inpcb *inp;
- struct tcpcb *tp;
+ struct inpcb *inp = sotoinpcb(so);
+ struct tcpcb *tp = intotcpcb(inp);
int error = 0;
- inp = sotoinpcb(so);
- KASSERT(inp != NULL, ("tcp_usr_accept: inp == NULL"));
INP_WLOCK(inp);
- if (inp->inp_flags & INP_DROPPED) {
+ if (__predict_false(tp->t_flags & TF_DISCONNECTED)) {
INP_WUNLOCK(inp);
return (ECONNABORTED);
}
- tp = intotcpcb(inp);
if (so->so_state & SS_ISDISCONNECTED)
error = ECONNABORTED;
@@ -759,18 +738,15 @@
static int
tcp6_usr_accept(struct socket *so, struct sockaddr *sa)
{
- struct inpcb *inp;
- struct tcpcb *tp;
+ struct inpcb *inp = sotoinpcb(so);
+ struct tcpcb *tp = intotcpcb(inp);
int error = 0;
- inp = sotoinpcb(so);
- KASSERT(inp != NULL, ("tcp6_usr_accept: inp == NULL"));
INP_WLOCK(inp);
- if (inp->inp_flags & INP_DROPPED) {
+ if (__predict_false(tp->t_flags & TF_DISCONNECTED)) {
INP_WUNLOCK(inp);
return (ECONNABORTED);
}
- tp = intotcpcb(inp);
if (so->so_state & SS_ISDISCONNECTED) {
error = ECONNABORTED;
@@ -842,7 +818,7 @@
* return ECONNRESEST for SHUT_RD as well?
*/
INP_WLOCK(inp);
- if (inp->inp_flags & INP_DROPPED) {
+ if (tp->t_flags & TF_DISCONNECTED) {
INP_WUNLOCK(inp);
return (ECONNRESET);
}
@@ -868,18 +844,16 @@
tcp_usr_rcvd(struct socket *so, int flags)
{
struct epoch_tracker et;
- struct inpcb *inp;
- struct tcpcb *tp;
+ struct inpcb *inp = sotoinpcb(so);
+ struct tcpcb *tp = intotcpcb(inp);
int outrv = 0, error = 0;
- inp = sotoinpcb(so);
- KASSERT(inp != NULL, ("tcp_usr_rcvd: inp == NULL"));
INP_WLOCK(inp);
- if (inp->inp_flags & INP_DROPPED) {
+ if (__predict_false(tp->t_flags & TF_DISCONNECTED)) {
+ /* XXXGL: how could this happen?! */
INP_WUNLOCK(inp);
return (ECONNRESET);
}
- tp = intotcpcb(inp);
NET_EPOCH_ENTER(et);
/*
@@ -917,9 +891,8 @@
struct sockaddr *nam, struct mbuf *control, struct thread *td)
{
struct epoch_tracker et;
- int error = 0;
- struct inpcb *inp;
- struct tcpcb *tp;
+ struct inpcb *inp = sotoinpcb(so);
+ struct tcpcb *tp = intotcpcb(inp);
#ifdef INET
#ifdef INET6
struct sockaddr_in sin;
@@ -930,20 +903,18 @@
struct sockaddr_in6 *sin6;
int isipv6;
#endif
+ int error = 0;
u_int8_t incflagsav;
u_char vflagsav;
bool restoreflags;
- inp = sotoinpcb(so);
- KASSERT(inp != NULL, ("tcp_usr_send: inp == NULL"));
INP_WLOCK(inp);
- if (inp->inp_flags & INP_DROPPED) {
+ if (__predict_false(tp->t_flags & TF_DISCONNECTED)) {
if (m != NULL && (flags & PRUS_NOTREADY) == 0)
m_freem(m);
INP_WUNLOCK(inp);
return (ECONNRESET);
}
- tp = intotcpcb(inp);
vflagsav = inp->inp_vflag;
incflagsav = inp->inp_inc.inc_flags;
@@ -1121,8 +1092,7 @@
if (tp->t_fbyte_out && tp->t_fbyte_in)
tp->t_flags2 |= TF2_FBYTES_COMPLETE;
}
- if (!(inp->inp_flags & INP_DROPPED) &&
- !(flags & PRUS_NOTREADY)) {
+ if (!(flags & PRUS_NOTREADY)) {
if (flags & PRUS_MORETOCOME)
tp->t_flags |= TF_MORETOCOME;
error = tcp_output_nodrop(tp);
@@ -1232,18 +1202,16 @@
tcp_usr_ready(struct socket *so, struct mbuf *m, int count)
{
struct epoch_tracker et;
- struct inpcb *inp;
- struct tcpcb *tp;
+ struct inpcb *inp = sotoinpcb(so);
+ struct tcpcb *tp = intotcpcb(inp);
int error;
- inp = sotoinpcb(so);
INP_WLOCK(inp);
- if (inp->inp_flags & INP_DROPPED) {
+ if (__predict_false(tp->t_flags & TF_DISCONNECTED)) {
INP_WUNLOCK(inp);
mb_free_notready(m, count);
return (ECONNRESET);
}
- tp = intotcpcb(inp);
SOCK_SENDBUF_LOCK(so);
error = sbready(&so->so_snd, m, count);
@@ -1265,30 +1233,23 @@
static void
tcp_usr_abort(struct socket *so)
{
- struct inpcb *inp;
- struct tcpcb *tp;
struct epoch_tracker et;
-
- inp = sotoinpcb(so);
- KASSERT(inp != NULL, ("tcp_usr_abort: inp == NULL"));
-
- NET_EPOCH_ENTER(et);
- INP_WLOCK(inp);
- KASSERT(inp->inp_socket != NULL,
- ("tcp_usr_abort: inp_socket == NULL"));
+ struct inpcb *inp = sotoinpcb(so);
+ struct tcpcb *tp = intotcpcb(inp);
/*
* If we still have full TCP state, and we're not dropped, drop.
*/
- if (!(inp->inp_flags & INP_DROPPED)) {
- tp = intotcpcb(inp);
+ NET_EPOCH_ENTER(et);
+ INP_WLOCK(inp);
+ if (!(tp->t_flags & TF_DISCONNECTED)) {
tp = tcp_drop(tp, ECONNABORTED);
if (tp == NULL)
goto dropped;
tcp_bblog_pru(tp, PRU_ABORT, 0);
TCP_PROBE2(debug__user, tp, PRU_ABORT);
}
- if (!(inp->inp_flags & INP_DROPPED)) {
+ if (!(tp->t_flags & TF_DISCONNECTED)) {
soref(so);
inp->inp_flags |= INP_SOCKREF;
}
@@ -1303,24 +1264,17 @@
static void
tcp_usr_close(struct socket *so)
{
- struct inpcb *inp;
- struct tcpcb *tp;
struct epoch_tracker et;
-
- inp = sotoinpcb(so);
- KASSERT(inp != NULL, ("tcp_usr_close: inp == NULL"));
-
- NET_EPOCH_ENTER(et);
- INP_WLOCK(inp);
- KASSERT(inp->inp_socket != NULL,
- ("tcp_usr_close: inp_socket == NULL"));
+ struct inpcb *inp = sotoinpcb(so);
+ struct tcpcb *tp = intotcpcb(inp);
/*
* If we are still connected and we're not dropped, initiate
* a disconnect.
*/
- if (!(inp->inp_flags & INP_DROPPED)) {
- tp = intotcpcb(inp);
+ NET_EPOCH_ENTER(et);
+ INP_WLOCK(inp);
+ if (!(tp->t_flags & TF_DISCONNECTED)) {
if (tp->t_state != TCPS_TIME_WAIT) {
tp->t_flags |= TF_CLOSED;
tcp_disconnect(tp);
@@ -1328,7 +1282,7 @@
TCP_PROBE2(debug__user, tp, PRU_CLOSE);
}
}
- if (!(inp->inp_flags & INP_DROPPED)) {
+ if (!(tp->t_flags & TF_DISCONNECTED)) {
soref(so);
inp->inp_flags |= INP_SOCKREF;
}
@@ -1360,18 +1314,16 @@
static int
tcp_usr_rcvoob(struct socket *so, struct mbuf *m, int flags)
{
+ struct inpcb *inp = sotoinpcb(so);
+ struct tcpcb *tp = intotcpcb(inp);
int error = 0;
- struct inpcb *inp;
- struct tcpcb *tp;
- inp = sotoinpcb(so);
- KASSERT(inp != NULL, ("tcp_usr_rcvoob: inp == NULL"));
INP_WLOCK(inp);
- if (inp->inp_flags & INP_DROPPED) {
+ if (__predict_false(tp->t_flags & TF_DISCONNECTED)) {
+ /* XXXGL: how could this happen?! */
INP_WUNLOCK(inp);
return (ECONNRESET);
}
- tp = intotcpcb(inp);
error = tcp_pru_options_support(tp, PRUS_OOB);
if (error) {
@@ -1650,15 +1602,16 @@
* socket option arguments. When it re-acquires the lock after the copy, it
* has to revalidate that the connection is still valid for the socket
* option.
+ * XXXGL: review if this is really needed
*/
#define INP_WLOCK_RECHECK_CLEANUP(inp, cleanup) do { \
INP_WLOCK(inp); \
- if (inp->inp_flags & INP_DROPPED) { \
+ tp = intotcpcb(inp); \
+ if (tp->t_flags & TF_DISCONNECTED) { \
INP_WUNLOCK(inp); \
cleanup; \
return (ECONNRESET); \
} \
- tp = intotcpcb(inp); \
} while(0)
#define INP_WLOCK_RECHECK(inp) INP_WLOCK_RECHECK_CLEANUP((inp), /* noop */)
@@ -1671,8 +1624,8 @@
MPASS(sopt->sopt_dir == SOPT_SET);
INP_WLOCK_ASSERT(inp);
- KASSERT((inp->inp_flags & INP_DROPPED) == 0,
- ("inp_flags == %x", inp->inp_flags));
+ KASSERT((tp->t_flags & TF_DISCONNECTED) == 0,
+ ("tp_flags == %x", tp->t_flags));
KASSERT(so != NULL, ("inp_socket == NULL"));
if (sopt->sopt_level != IPPROTO_TCP) {
@@ -1839,8 +1792,8 @@
MPASS(sopt->sopt_dir == SOPT_GET);
INP_WLOCK_ASSERT(inp);
- KASSERT((inp->inp_flags & INP_DROPPED) == 0,
- ("inp_flags == %x", inp->inp_flags));
+ KASSERT((tp->t_flags & TF_DISCONNECTED) == 0,
+ ("tp_flags == %x", tp->t_flags));
KASSERT(so != NULL, ("inp_socket == NULL"));
if (sopt->sopt_level != IPPROTO_TCP) {
@@ -1883,13 +1836,11 @@
int
tcp_ctloutput(struct socket *so, struct sockopt *sopt)
{
- struct inpcb *inp;
-
- inp = sotoinpcb(so);
- KASSERT(inp != NULL, ("tcp_ctloutput: inp == NULL"));
+ struct inpcb *inp = sotoinpcb(so);
+ struct tcpcb *tp = intotcpcb(inp);
INP_WLOCK(inp);
- if (inp->inp_flags & INP_DROPPED) {
+ if (__predict_false(tp->t_flags & TF_DISCONNECTED)) {
INP_WUNLOCK(inp);
return (ECONNRESET);
}
@@ -1917,7 +1868,7 @@
{
struct cc_algo *algo;
void *ptr = NULL;
- struct tcpcb *tp;
+ struct tcpcb *tp = intotcpcb(inp);
struct cc_var cc_mem;
char buf[TCP_CA_NAME_MAX];
size_t mem_sz;
@@ -1967,7 +1918,7 @@
*/
memset(&cc_mem, 0, sizeof(cc_mem));
INP_WLOCK(inp);
- if (inp->inp_flags & INP_DROPPED) {
+ if (__predict_false(tp->t_flags & TF_DISCONNECTED)) {
INP_WUNLOCK(inp);
if (ptr)
free(ptr, M_CC_MEM);
@@ -1977,7 +1928,6 @@
CC_LIST_RUNLOCK();
return (ECONNRESET);
}
- tp = intotcpcb(inp);
if (ptr != NULL)
memset(ptr, 0, mem_sz);
cc_mem.tp = tp;
@@ -2043,8 +1993,8 @@
size_t len;
INP_WLOCK_ASSERT(inp);
- KASSERT((inp->inp_flags & INP_DROPPED) == 0,
- ("inp_flags == %x", inp->inp_flags));
+ KASSERT((tp->t_flags & TF_DISCONNECTED) == 0,
+ ("tp_flags == %x", tp->t_flags));
KASSERT(inp->inp_socket != NULL, ("inp_socket == NULL"));
switch (sopt->sopt_level) {
@@ -2673,7 +2623,7 @@
soisdisconnecting(so);
sbflush(&so->so_rcv);
tcp_usrclosed(tp);
- if (!(inp->inp_flags & INP_DROPPED))
+ if (!(tp->t_flags & TF_DISCONNECTED))
/* Ignore stack's drop request, we already at it. */
(void)tcp_output_nodrop(tp);
}
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -789,7 +789,7 @@
#define TF_TSO 0x01000000 /* TSO enabled on this connection */
#define TF_TOE 0x02000000 /* this connection is offloaded */
#define TF_CLOSED 0x04000000 /* close(2) called on socket */
-#define TF_UNUSED 0x08000000 /* was TF_SENTSYN */
+#define TF_DISCONNECTED 0x08000000 /* went through tcp_close() */
#define TF_LRD 0x10000000 /* Lost Retransmission Detection */
#define TF_CONGRECOVERY 0x20000000 /* congestion recovery mode */
#define TF_WASCRECOVERY 0x40000000 /* was in congestion recovery */
diff --git a/sys/netinet/toecore.c b/sys/netinet/toecore.c
--- a/sys/netinet/toecore.c
+++ b/sys/netinet/toecore.c
@@ -212,16 +212,15 @@
toe_listen_start(struct inpcb *inp, void *arg)
{
struct toedev *t, *tod;
- struct tcpcb *tp;
+ struct tcpcb *tp = intotcpcb(inp);
INP_WLOCK_ASSERT(inp);
KASSERT(inp->inp_pcbinfo == &V_tcbinfo,
("%s: inp is not a TCP inp", __func__));
- if (inp->inp_flags & INP_DROPPED)
+ if (tp->t_flags & TF_DISCONNECTED)
return;
- tp = intotcpcb(inp);
if (tp->t_state != TCPS_LISTEN)
return;
@@ -510,13 +509,12 @@
void
toe_connect_failed(struct toedev *tod, struct inpcb *inp, int err)
{
+ struct tcpcb *tp = intotcpcb(inp);
NET_EPOCH_ASSERT();
INP_WLOCK_ASSERT(inp);
- if (!(inp->inp_flags & INP_DROPPED)) {
- struct tcpcb *tp = intotcpcb(inp);
-
+ if (!(tp->t_flags & TF_DISCONNECTED)) {
KASSERT(tp->t_flags & TF_TOE,
("%s: tp %p not offloaded.", __func__, tp));
diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c
--- a/sys/netinet6/in6_pcb.c
+++ b/sys/netinet6/in6_pcb.c
@@ -489,12 +489,11 @@
inp->inp_flow |=
(htonl(ip6_randomflowlabel()) & IPV6_FLOWLABEL_MASK);
- if ((inp->inp_flags & INP_INHASHLIST) != 0) {
- in_pcbrehash(inp);
- } else {
+ if (inp->inp_flags & INP_UNCONNECTED) {
error = in_pcbinshash(inp);
MPASS(error == 0);
- }
+ } else
+ in_pcbrehash(inp);
return (0);
}
@@ -509,6 +508,7 @@
INP_HASH_WLOCK(inp->inp_pcbinfo);
in_pcbremhash(inp);
+ inp->inp_flags |= INP_UNCONNECTED;
CK_LIST_INSERT_HEAD(&inp->inp_pcbinfo->ipi_list_unconn, inp,
inp_unconn_list);
INP_HASH_WUNLOCK(inp->inp_pcbinfo);
diff --git a/sys/netipsec/xform_tcp.c b/sys/netipsec/xform_tcp.c
--- a/sys/netipsec/xform_tcp.c
+++ b/sys/netipsec/xform_tcp.c
@@ -76,7 +76,7 @@
static int
tcp_ipsec_pcbctl(struct inpcb *inp, struct sockopt *sopt)
{
- struct tcpcb *tp;
+ struct tcpcb *tp = intotcpcb(inp);
int error, optval;
if (sopt->sopt_name != TCP_MD5SIG) {
@@ -85,11 +85,10 @@
if (sopt->sopt_dir == SOPT_GET) {
INP_RLOCK(inp);
- if (inp->inp_flags & INP_DROPPED) {
+ if (tp->t_flags & TF_DISCONNECTED) {
INP_RUNLOCK(inp);
return (ECONNRESET);
}
- tp = intotcpcb(inp);
optval = (tp->t_flags & TF_SIGNATURE) ? 1 : 0;
INP_RUNLOCK(inp);
@@ -103,11 +102,10 @@
/* INP_WLOCK_RECHECK */
INP_WLOCK(inp);
- if (inp->inp_flags & INP_DROPPED) {
+ if (tp->t_flags & TF_DISCONNECTED) {
INP_WUNLOCK(inp);
return (ECONNRESET);
}
- tp = intotcpcb(inp);
if (optval > 0)
tp->t_flags |= TF_SIGNATURE;
else
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Jun 19, 5:58 AM (20 h, 21 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34067343
Default Alt Text
D56186.diff (56 KB)
Attached To
Mode
D56186: inpcb: retire INP_DROPPED and in_pcbdrop()
Attached
Detach File
Event Timeline
Log In to Comment