diff options
author | Ghanan Gowripalan <ghanan@google.com> | 2020-11-30 14:22:01 -0800 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2020-11-30 14:24:47 -0800 |
commit | e813008664ffb361211936dda8631754411cca4f (patch) | |
tree | f53db9f215a54f41f64a903bc6623146bc69c677 /pkg/tcpip/network/ipv6 | |
parent | 3a60bc47a082d5e9ef4903d48ef3bdb505eb8b6e (diff) |
Perform IGMP/MLD when the NIC is enabled/disabled
Test: ip_test.TestMGPWithNICLifecycle
Bug #4682, #4861
PiperOrigin-RevId: 344888091
Diffstat (limited to 'pkg/tcpip/network/ipv6')
-rw-r--r-- | pkg/tcpip/network/ipv6/ipv6.go | 34 |
1 files changed, 28 insertions, 6 deletions
diff --git a/pkg/tcpip/network/ipv6/ipv6.go b/pkg/tcpip/network/ipv6/ipv6.go index ac67d4ac5..4d49afcbb 100644 --- a/pkg/tcpip/network/ipv6/ipv6.go +++ b/pkg/tcpip/network/ipv6/ipv6.go @@ -228,6 +228,15 @@ func (e *endpoint) Enable() *tcpip.Error { return nil } + // Groups may have been joined when the endpoint was disabled, or the + // endpoint may have left groups from the perspective of MLD when the + // endpoint was disabled. Either way, we need to let routers know to + // send us multicast traffic. + joinedGroups := e.mu.addressableEndpointState.JoinedGroups() + for _, group := range joinedGroups { + e.mld.joinGroup(group) + } + // Join the IPv6 All-Nodes Multicast group if the stack is configured to // use IPv6. This is required to ensure that this node properly receives // and responds to the various NDP messages that are destined to the @@ -338,6 +347,13 @@ func (e *endpoint) disableLocked() { if _, err := e.leaveGroupLocked(header.IPv6AllNodesMulticastAddress); err != nil && err != tcpip.ErrBadLocalAddress { panic(fmt.Sprintf("unexpected error when leaving group = %s: %s", header.IPv6AllNodesMulticastAddress, err)) } + + // Leave groups from the perspective of MLD so that routers know that + // we are no longer interested in the group. + joinedGroups := e.mu.addressableEndpointState.JoinedGroups() + for _, group := range joinedGroups { + e.mld.leaveGroup(group) + } } // stopDADForPermanentAddressesLocked stops DAD for all permaneent addresses. @@ -1409,6 +1425,15 @@ func (e *endpoint) joinGroupLocked(addr tcpip.Address) (bool, *tcpip.Error) { return joined, err } + // Only join the group from the perspective of IGMP when the endpoint is + // enabled. + // + // If we are not enabled right now, we will join the group from the + // perspective of MLD when the endpoint is enabled. + if !e.Enabled() { + return true, nil + } + // joinGroup only returns an error if we try to join a group twice, but we // checked above to make sure that the group was newly joined. if err := e.mld.joinGroup(addr); err != nil { @@ -1430,15 +1455,12 @@ func (e *endpoint) LeaveGroup(addr tcpip.Address) (bool, *tcpip.Error) { // Precondition: e.mu must be locked. func (e *endpoint) leaveGroupLocked(addr tcpip.Address) (bool, *tcpip.Error) { left, err := e.mu.addressableEndpointState.LeaveGroup(addr) - if err != nil { + if err != nil || !left { return left, err } - if left { - e.mld.leaveGroup(addr) - } - - return left, nil + e.mld.leaveGroup(addr) + return true, nil } // IsInGroup implements stack.GroupAddressableEndpoint. |