From 818274a6e981bb62199c5fae68f46b73c8cb1796 Mon Sep 17 00:00:00 2001 From: Ievgen Bondarenko Date: Tue, 19 May 2026 17:06:16 -0700 Subject: [PATCH] tcpip/ipv6: use isEnabled() in disableLocked() to match ipv4 sibling The IPv4 (*endpoint).disableLocked at pkg/tcpip/network/ipv4/ipv4.go:363 early-returns on !e.isEnabled(). The IPv6 sibling at pkg/tcpip/network/ipv6/ipv6.go:675 early-returns on !e.Enabled(), and e.Enabled() folds in e.nic.Enabled(). When the NIC has been disabled independently but the endpoint's local enabled flag is still set, the IPv6 path skips ndp.stopSolicitingRouters, ndp.cleanupState, MLD softLeaveAll, DAD stop, the all-nodes multicast leave, and the final setEnabled(false). After early-return, e.isEnabled() still reports true. A subsequent endpoint.Close calls disableLocked again, hits the same early-return, then runs addressableEndpointState.Cleanup while NDP state and any still-armed SLAAC, RS, or DAD timer remain alive against the wiped address state. The 2020 commit 53a95ad0df introduced e.Enabled() for packet-sending sites that need to honor both nic and endpoint flags. The disable path should not gate on nic state; it should run the local teardown regardless and let the per-protocol state machine reach a clean stop. IPv4 already gets this right. Mirror the IPv4 form. Signed-off-by: Ievgen Bondarenko --- pkg/tcpip/network/ipv6/ipv6.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/tcpip/network/ipv6/ipv6.go b/pkg/tcpip/network/ipv6/ipv6.go index b4a38a5669..68fed377e8 100644 --- a/pkg/tcpip/network/ipv6/ipv6.go +++ b/pkg/tcpip/network/ipv6/ipv6.go @@ -672,7 +672,7 @@ func (e *endpoint) Disable() { } func (e *endpoint) disableLocked() { - if !e.Enabled() { + if !e.isEnabled() { return }