diff options
author | Ghanan Gowripalan <ghanan@google.com> | 2021-02-24 12:30:20 -0800 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2021-02-24 12:32:20 -0800 |
commit | fcd4ff4fca31e3c594b30aff6b008e7af4c7c1a5 (patch) | |
tree | 8de6b5c714b5955d31431a1625e0762f94440415 /pkg/tcpip/network/ipv6/ipv6.go | |
parent | ba4dfa7172a00f8b104a75a4655fe3de1e4a94c9 (diff) |
Cleanup temp SLAAC address jobs on DAD conflicts
Previously, when DAD would detect a conflict for a temporary address,
the address would be removed but its timers would not be stopped,
resulting in a panic when the removed address's invalidation timer
fired.
While I'm here, remove the check for unicast-ness on removed address
endpoints since multicast addresses are no longer stored in the same
structure as unicast addresses as of 27ee4fe76ad586ac8751951a842b3681f93.
Test: stack_test.TestMixedSLAACAddrConflictRegen
PiperOrigin-RevId: 359344849
Diffstat (limited to 'pkg/tcpip/network/ipv6/ipv6.go')
-rw-r--r-- | pkg/tcpip/network/ipv6/ipv6.go | 34 |
1 files changed, 18 insertions, 16 deletions
diff --git a/pkg/tcpip/network/ipv6/ipv6.go b/pkg/tcpip/network/ipv6/ipv6.go index c5c3ef882..b16a2d322 100644 --- a/pkg/tcpip/network/ipv6/ipv6.go +++ b/pkg/tcpip/network/ipv6/ipv6.go @@ -1441,28 +1441,30 @@ func (e *endpoint) RemovePermanentAddress(addr tcpip.Address) tcpip.Error { // Precondition: e.mu must be write locked. func (e *endpoint) removePermanentEndpointLocked(addressEndpoint stack.AddressEndpoint, allowSLAACInvalidation, dadFailure bool) tcpip.Error { addr := addressEndpoint.AddressWithPrefix() - unicast := header.IsV6UnicastAddress(addr.Address) - if unicast { - e.mu.ndp.stopDuplicateAddressDetection(addr.Address, dadFailure) - - // If we are removing an address generated via SLAAC, cleanup - // its SLAAC resources and notify the integrator. - switch addressEndpoint.ConfigType() { - case stack.AddressConfigSlaac: - e.mu.ndp.cleanupSLAACAddrResourcesAndNotify(addr, allowSLAACInvalidation) - case stack.AddressConfigSlaacTemp: - e.mu.ndp.cleanupTempSLAACAddrResourcesAndNotify(addr, allowSLAACInvalidation) - } + // If we are removing an address generated via SLAAC, cleanup + // its SLAAC resources and notify the integrator. + switch addressEndpoint.ConfigType() { + case stack.AddressConfigSlaac: + e.mu.ndp.cleanupSLAACAddrResourcesAndNotify(addr, allowSLAACInvalidation) + case stack.AddressConfigSlaacTemp: + e.mu.ndp.cleanupTempSLAACAddrResourcesAndNotify(addr) } + return e.removePermanentEndpointInnerLocked(addressEndpoint, dadFailure) +} + +// removePermanentEndpointInnerLocked is like removePermanentEndpointLocked +// except it does not cleanup SLAAC address state. +// +// Precondition: e.mu must be write locked. +func (e *endpoint) removePermanentEndpointInnerLocked(addressEndpoint stack.AddressEndpoint, dadFailure bool) tcpip.Error { + addr := addressEndpoint.AddressWithPrefix() + e.mu.ndp.stopDuplicateAddressDetection(addr.Address, dadFailure) + if err := e.mu.addressableEndpointState.RemovePermanentEndpoint(addressEndpoint); err != nil { return err } - if !unicast { - return nil - } - snmc := header.SolicitedNodeAddr(addr.Address) err := e.leaveGroupLocked(snmc) // The endpoint may have already left the multicast group. |