git: ce283e115b02 - main - netinet6: remove INP_DROPPED checks from setsockopt(2)

From: Gleb Smirnoff <glebius_at_FreeBSD.org>
Date: Sun, 12 Apr 2026 18:35:34 UTC
The branch main has been updated by glebius:

URL: https://cgit.FreeBSD.org/src/commit/?id=ce283e115b023514a8886c1c1f1c68df7cd5e9a9

commit ce283e115b023514a8886c1c1f1c68df7cd5e9a9
Author:     Gleb Smirnoff <glebius@FreeBSD.org>
AuthorDate: 2026-04-12 18:32:15 +0000
Commit:     Gleb Smirnoff <glebius@FreeBSD.org>
CommitDate: 2026-04-12 18:32:15 +0000

    netinet6: remove INP_DROPPED checks from setsockopt(2)
    
    The INP_DROPPED is going to become an internal flag for inpcb.  As of now
    it means a TCP pcb that is in TCPS_CLOSED.  There is nothing wrong with
    calling setsockopt(2) on such socket, although has no practical use.
    
    This deletes a piece of code from 56713d16a06c5 / D16201.  There is no
    description of the panic fixed, but I will speculate that the panic was
    about in6p->in6p_outputopts being NULL as the inpcb already went through
    in_pcbfree_deferred().  This also can be related to compressed TIME-WAIT,
    that is also gone now.
    
    With current locking this shouldn't be possible.  An inpcb goes through
    in_pcbfree() only with pr_detach method, which is called from sofree(),
    and the latter is called on losing the very last socket reference.  So, at
    the point when in_pcbfree() is called, the socket has lost its file
    descriptor reference and there can not be any running setsockopt() on it.
    
    Leave the call to ip6_pcbopt() still embraced with INP_WLOCK(), since we
    are modifying inpcb contents.
    
    NB: the IPv6 setsockopt(2) definitely has room for improvement.  Several
    memory allocations should be moved out of lock and made M_WAITOK.
    Covering large piece of setsockopt(2) code with epoch(9) just because
    ip6_setpktopts() calls ifnet_byindex() isn't correct either.
    
    Reviewed by:            markj
    Differential Revision:  https://reviews.freebsd.org/D56169
---
 sys/netinet6/ip6_output.c | 17 -----------------
 1 file changed, 17 deletions(-)

diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c
index 29374a39e336..359bfdd336e9 100644
--- a/sys/netinet6/ip6_output.c
+++ b/sys/netinet6/ip6_output.c
@@ -1698,10 +1698,6 @@ do {									\
 						break;
 					}
 					INP_WLOCK(inp);
-					if (inp->inp_flags & INP_DROPPED) {
-						INP_WUNLOCK(inp);
-						return (ECONNRESET);
-					}
 					optp = &inp->in6p_outputopts;
 					error = ip6_pcbopt(IPV6_HOPLIMIT,
 					    (u_char *)&optval, sizeof(optval),
@@ -1827,10 +1823,6 @@ do {									\
 				{
 					struct ip6_pktopts **optp;
 					INP_WLOCK(inp);
-					if (inp->inp_flags & INP_DROPPED) {
-						INP_WUNLOCK(inp);
-						return (ECONNRESET);
-					}
 					optp = &inp->in6p_outputopts;
 					error = ip6_pcbopt(optname,
 					    (u_char *)&optval, sizeof(optval),
@@ -1919,10 +1911,6 @@ do {									\
 				optlen = sopt->sopt_valsize;
 				optbuf = optbuf_storage;
 				INP_WLOCK(inp);
-				if (inp->inp_flags & INP_DROPPED) {
-					INP_WUNLOCK(inp);
-					return (ECONNRESET);
-				}
 				optp = &inp->in6p_outputopts;
 				error = ip6_pcbopt(optname, optbuf, optlen,
 				    optp, (td != NULL) ? td->td_ucred : NULL,
@@ -2410,11 +2398,6 @@ ip6_pcbopt(int optname, u_char *buf, int len, struct ip6_pktopts **pktopt,
 		optdata = malloc(sopt->sopt_valsize, M_TEMP, M_WAITOK);	\
 		malloc_optdata = true;					\
 		INP_RLOCK(inp);						\
-		if (inp->inp_flags & INP_DROPPED) {			\
-			INP_RUNLOCK(inp);				\
-			free(optdata, M_TEMP);				\
-			return (ECONNRESET);				\
-		}							\
 		pktopt = inp->in6p_outputopts;				\
 		if (pktopt && pktopt->field) {				\
 			optdatalen = min(lenexpr, sopt->sopt_valsize);	\