Merge release-20210322.0-53-gd7fd00bad (automated)

This commit is contained in:
gVisor bot 2021-04-06 17:20:52 +00:00
commit 5f79ea8aa0
4 changed files with 80 additions and 58 deletions

View File

@ -142,11 +142,6 @@ const (
// ipv6MulticastAddressScopeMask is the mask for the scope (scop) field,
// within the byte holding the field, as per RFC 4291 section 2.7.
ipv6MulticastAddressScopeMask = 0xF
// ipv6LinkLocalMulticastScope is the value of the scope (scop) field within
// a multicast IPv6 address that indicates the address has link-local scope,
// as per RFC 4291 section 2.7.
ipv6LinkLocalMulticastScope = 2
)
// IPv6EmptySubnet is the empty IPv6 subnet. It may also be known as the
@ -399,7 +394,7 @@ func IsV6LoopbackAddress(addr tcpip.Address) bool {
// IsV6LinkLocalMulticastAddress determines if the provided address is an IPv6
// link-local multicast address.
func IsV6LinkLocalMulticastAddress(addr tcpip.Address) bool {
return IsV6MulticastAddress(addr) && addr[ipv6MulticastAddressScopeByteIdx]&ipv6MulticastAddressScopeMask == ipv6LinkLocalMulticastScope
return IsV6MulticastAddress(addr) && V6MulticastScope(addr) == IPv6LinkLocalMulticastScope
}
// AppendOpaqueInterfaceIdentifier appends a 64 bit opaque interface identifier
@ -520,3 +515,45 @@ func GenerateTempIPv6SLAACAddr(tempIIDHistory []byte, stableAddr tcpip.Address)
PrefixLen: IIDOffsetInIPv6Address * 8,
}
}
// IPv6MulticastScope is the scope of a multicast IPv6 address.
type IPv6MulticastScope uint8
// The various values for IPv6 multicast scopes, as per RFC 7346 section 2:
//
// +------+--------------------------+-------------------------+
// | scop | NAME | REFERENCE |
// +------+--------------------------+-------------------------+
// | 0 | Reserved | [RFC4291], RFC 7346 |
// | 1 | Interface-Local scope | [RFC4291], RFC 7346 |
// | 2 | Link-Local scope | [RFC4291], RFC 7346 |
// | 3 | Realm-Local scope | [RFC4291], RFC 7346 |
// | 4 | Admin-Local scope | [RFC4291], RFC 7346 |
// | 5 | Site-Local scope | [RFC4291], RFC 7346 |
// | 6 | Unassigned | |
// | 7 | Unassigned | |
// | 8 | Organization-Local scope | [RFC4291], RFC 7346 |
// | 9 | Unassigned | |
// | A | Unassigned | |
// | B | Unassigned | |
// | C | Unassigned | |
// | D | Unassigned | |
// | E | Global scope | [RFC4291], RFC 7346 |
// | F | Reserved | [RFC4291], RFC 7346 |
// +------+--------------------------+-------------------------+
const (
IPv6Reserved0MulticastScope = IPv6MulticastScope(0x0)
IPv6InterfaceLocalMulticastScope = IPv6MulticastScope(0x1)
IPv6LinkLocalMulticastScope = IPv6MulticastScope(0x2)
IPv6RealmLocalMulticastScope = IPv6MulticastScope(0x3)
IPv6AdminLocalMulticastScope = IPv6MulticastScope(0x4)
IPv6SiteLocalMulticastScope = IPv6MulticastScope(0x5)
IPv6OrganizationLocalMulticastScope = IPv6MulticastScope(0x8)
IPv6GlobalMulticastScope = IPv6MulticastScope(0xE)
IPv6ReservedFMulticastScope = IPv6MulticastScope(0xF)
)
// V6MulticastScope returns the scope of a multicast address.
func V6MulticastScope(addr tcpip.Address) IPv6MulticastScope {
return IPv6MulticastScope(addr[ipv6MulticastAddressScopeByteIdx] & ipv6MulticastAddressScopeMask)
}

View File

@ -156,14 +156,6 @@ type GenericMulticastProtocolOptions struct {
//
// Unsolicited reports are transmitted when a group is newly joined.
MaxUnsolicitedReportDelay time.Duration
// AllNodesAddress is a multicast address that all nodes on a network should
// be a member of.
//
// This address will not have the generic multicast protocol performed on it;
// it will be left in the non member/listener state, and packets will never
// be sent for it.
AllNodesAddress tcpip.Address
}
// MulticastGroupProtocol is a multicast group protocol whose core state machine
@ -188,6 +180,10 @@ type MulticastGroupProtocol interface {
// SendLeave sends a multicast leave for the specified group address.
SendLeave(groupAddress tcpip.Address) tcpip.Error
// ShouldPerformProtocol returns true iff the protocol should be performed for
// the specified group.
ShouldPerformProtocol(tcpip.Address) bool
}
// GenericMulticastProtocolState is the per interface generic multicast protocol
@ -455,20 +451,7 @@ func (g *GenericMulticastProtocolState) initializeNewMemberLocked(groupAddress t
info.lastToSendReport = false
if groupAddress == g.opts.AllNodesAddress {
// As per RFC 2236 section 6 page 10 (for IGMPv2),
//
// The all-systems group (address 224.0.0.1) is handled as a special
// case. The host starts in Idle Member state for that group on every
// interface, never transitions to another state, and never sends a
// report for that group.
//
// As per RFC 2710 section 5 page 10 (for MLDv1),
//
// The link-scope all-nodes address (FF02::1) is handled as a special
// case. The node starts in Idle Listener state for that address on
// every interface, never transitions to another state, and never sends
// a Report or Done for that address.
if !g.opts.Protocol.ShouldPerformProtocol(groupAddress) {
info.state = idleMember
return
}
@ -537,20 +520,7 @@ func (g *GenericMulticastProtocolState) maybeSendLeave(groupAddress tcpip.Addres
return
}
if groupAddress == g.opts.AllNodesAddress {
// As per RFC 2236 section 6 page 10 (for IGMPv2),
//
// The all-systems group (address 224.0.0.1) is handled as a special
// case. The host starts in Idle Member state for that group on every
// interface, never transitions to another state, and never sends a
// report for that group.
//
// As per RFC 2710 section 5 page 10 (for MLDv1),
//
// The link-scope all-nodes address (FF02::1) is handled as a special
// case. The node starts in Idle Listener state for that address on
// every interface, never transitions to another state, and never sends
// a Report or Done for that address.
if !g.opts.Protocol.ShouldPerformProtocol(groupAddress) {
return
}
@ -627,20 +597,7 @@ func (g *GenericMulticastProtocolState) setDelayTimerForAddressRLocked(groupAddr
return
}
if groupAddress == g.opts.AllNodesAddress {
// As per RFC 2236 section 6 page 10 (for IGMPv2),
//
// The all-systems group (address 224.0.0.1) is handled as a special
// case. The host starts in Idle Member state for that group on every
// interface, never transitions to another state, and never sends a
// report for that group.
//
// As per RFC 2710 section 5 page 10 (for MLDv1),
//
// The link-scope all-nodes address (FF02::1) is handled as a special
// case. The node starts in Idle Listener state for that address on
// every interface, never transitions to another state, and never sends
// a Report or Done for that address.
if !g.opts.Protocol.ShouldPerformProtocol(groupAddress) {
return
}

View File

@ -126,6 +126,17 @@ func (igmp *igmpState) SendLeave(groupAddress tcpip.Address) tcpip.Error {
return err
}
// ShouldPerformProtocol implements ip.MulticastGroupProtocol.
func (igmp *igmpState) ShouldPerformProtocol(groupAddress tcpip.Address) bool {
// As per RFC 2236 section 6 page 10,
//
// The all-systems group (address 224.0.0.1) is handled as a special
// case. The host starts in Idle Member state for that group on every
// interface, never transitions to another state, and never sends a
// report for that group.
return groupAddress != header.IPv4AllSystems
}
// init sets up an igmpState struct, and is required to be called before using
// a new igmpState.
//
@ -137,7 +148,6 @@ func (igmp *igmpState) init(ep *endpoint) {
Clock: ep.protocol.stack.Clock(),
Protocol: igmp,
MaxUnsolicitedReportDelay: UnsolicitedReportIntervalMax,
AllNodesAddress: header.IPv4AllSystems,
})
igmp.igmpV1Present = igmpV1PresentDefault
igmp.igmpV1Job = ep.protocol.stack.NewJob(&ep.mu, func() {

View File

@ -80,6 +80,25 @@ func (mld *mldState) SendLeave(groupAddress tcpip.Address) tcpip.Error {
return err
}
// ShouldPerformProtocol implements ip.MulticastGroupProtocol.
func (mld *mldState) ShouldPerformProtocol(groupAddress tcpip.Address) bool {
// As per RFC 2710 section 5 page 10,
//
// The link-scope all-nodes address (FF02::1) is handled as a special
// case. The node starts in Idle Listener state for that address on
// every interface, never transitions to another state, and never sends
// a Report or Done for that address.
//
// MLD messages are never sent for multicast addresses whose scope is 0
// (reserved) or 1 (node-local).
if groupAddress == header.IPv6AllNodesMulticastAddress {
return false
}
scope := header.V6MulticastScope(groupAddress)
return scope != header.IPv6Reserved0MulticastScope && scope != header.IPv6InterfaceLocalMulticastScope
}
// init sets up an mldState struct, and is required to be called before using
// a new mldState.
//
@ -91,7 +110,6 @@ func (mld *mldState) init(ep *endpoint) {
Clock: ep.protocol.stack.Clock(),
Protocol: mld,
MaxUnsolicitedReportDelay: UnsolicitedReportIntervalMax,
AllNodesAddress: header.IPv6AllNodesMulticastAddress,
})
}