summaryrefslogtreecommitdiffstats
path: root/sys/netinet
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/in_pcb.c12
-rw-r--r--sys/netinet/in_pcb.h1
2 files changed, 12 insertions, 1 deletions
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index dd1460f..6073c49 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -1105,8 +1105,17 @@ in_pcbrele_rlocked(struct inpcb *inp)
INP_RLOCK_ASSERT(inp);
- if (refcount_release(&inp->inp_refcount) == 0)
+ if (refcount_release(&inp->inp_refcount) == 0) {
+ /*
+ * If the inpcb has been freed, let the caller know, even if
+ * this isn't the last reference.
+ */
+ if (inp->inp_flags2 & INP_FREED) {
+ INP_RUNLOCK(inp);
+ return (1);
+ }
return (0);
+ }
KASSERT(inp->inp_socket == NULL, ("%s: inp_socket != NULL", __func__));
@@ -1186,6 +1195,7 @@ in_pcbfree(struct inpcb *inp)
inp_freemoptions(inp->inp_moptions);
#endif
inp->inp_vflag = 0;
+ inp->inp_flags2 |= INP_FREED;
crfree(inp->inp_cred);
#ifdef MAC
mac_inpcb_destroy(inp);
diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h
index 4945b0f..2df90b0 100644
--- a/sys/netinet/in_pcb.h
+++ b/sys/netinet/in_pcb.h
@@ -542,6 +542,7 @@ void inp_4tuple_get(struct inpcb *inp, uint32_t *laddr, uint16_t *lp,
#define INP_RT_VALID 0x00000002 /* cached rtentry is valid */
#define INP_PCBGROUPWILD 0x00000004 /* in pcbgroup wildcard list */
#define INP_REUSEPORT 0x00000008 /* SO_REUSEPORT option is set */
+#define INP_FREED 0x00000010 /* inp itself is not valid */
/*
* Flags passed to in_pcblookup*() functions.
OpenPOWER on IntegriCloud