mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Return current IGMP/MLD version
Updates #8346 PiperOrigin-RevId: 508218820
This commit is contained in:
committed by
gVisor bot
parent
c15ea6da04
commit
a5ac059e27
@@ -292,38 +292,45 @@ type GenericMulticastProtocolState struct {
|
||||
stateChangedReportV2TimerSet bool
|
||||
}
|
||||
|
||||
// GetV1ModeLocked returns the V1 configuration.
|
||||
//
|
||||
// Precondition: g.protocolMU must be read locked.
|
||||
func (g *GenericMulticastProtocolState) GetV1ModeLocked() bool {
|
||||
switch g.mode {
|
||||
case protocolModeV2, protocolModeV1Compatibility:
|
||||
return false
|
||||
case protocolModeV1:
|
||||
return true
|
||||
default:
|
||||
panic(fmt.Sprintf("unrecognized mode = %d", g.mode))
|
||||
}
|
||||
}
|
||||
|
||||
func (g *GenericMulticastProtocolState) stopModeTimer() {
|
||||
if g.modeTimer != nil {
|
||||
g.modeTimer.Stop()
|
||||
}
|
||||
}
|
||||
|
||||
// SetV1ModeLocked sets the V1 configuration.
|
||||
//
|
||||
// Returns the previous configuration.
|
||||
//
|
||||
// Precondition: g.protocolMU must be locked.
|
||||
func (g *GenericMulticastProtocolState) SetV1ModeLocked(v bool) bool {
|
||||
if g.GetV1ModeLocked() == v {
|
||||
return v
|
||||
}
|
||||
|
||||
if v {
|
||||
switch g.mode {
|
||||
case protocolModeV2:
|
||||
g.cancelV2ReportTimers()
|
||||
case protocolModeV1Compatibility:
|
||||
g.modeTimer.Stop()
|
||||
case protocolModeV1:
|
||||
// Already in V1 mode; nothing to do.
|
||||
return true
|
||||
default:
|
||||
panic(fmt.Sprintf("unrecognized mode = %d", g.mode))
|
||||
}
|
||||
g.stopModeTimer()
|
||||
g.cancelV2ReportTimers()
|
||||
g.mode = protocolModeV1
|
||||
return false
|
||||
}
|
||||
|
||||
switch g.mode {
|
||||
case protocolModeV2, protocolModeV1Compatibility:
|
||||
// Not in V1 mode; nothing to do.
|
||||
return false
|
||||
case protocolModeV1:
|
||||
g.mode = protocolModeV2
|
||||
return true
|
||||
default:
|
||||
panic(fmt.Sprintf("unrecognized mode = %d", g.mode))
|
||||
}
|
||||
g.mode = protocolModeV2
|
||||
return true
|
||||
}
|
||||
|
||||
func (g *GenericMulticastProtocolState) cancelV2ReportTimers() {
|
||||
@@ -375,9 +382,7 @@ func (g *GenericMulticastProtocolState) MakeAllNonMemberLocked() {
|
||||
return
|
||||
}
|
||||
|
||||
if g.modeTimer != nil {
|
||||
g.modeTimer.Stop()
|
||||
}
|
||||
g.stopModeTimer()
|
||||
g.cancelV2ReportTimers()
|
||||
|
||||
var v2ReportBuilder MulticastGroupProtocolV2ReportBuilder
|
||||
|
||||
@@ -88,6 +88,12 @@ func (m *mockMulticastGroupProtocol) setV1Mode(v bool) bool {
|
||||
return m.mu.genericMulticastGroup.SetV1ModeLocked(v)
|
||||
}
|
||||
|
||||
func (m *mockMulticastGroupProtocol) getV1Mode() bool {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
return m.mu.genericMulticastGroup.GetV1ModeLocked()
|
||||
}
|
||||
|
||||
func (m *mockMulticastGroupProtocol) joinGroup(addr tcpip.Address) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
@@ -1506,7 +1512,7 @@ func TestQueuedPackets(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetV1Mode(t *testing.T) {
|
||||
func TestGetSetV1Mode(t *testing.T) {
|
||||
clock := faketime.NewManualClock()
|
||||
mgp := mockMulticastGroupProtocol{t: t}
|
||||
mgp.init(ip.GenericMulticastProtocolOptions{
|
||||
@@ -1515,6 +1521,10 @@ func TestSetV1Mode(t *testing.T) {
|
||||
MaxUnsolicitedReportDelay: maxUnsolicitedReportDelay,
|
||||
}, false /* v1Compatibility */)
|
||||
|
||||
if mgp.getV1Mode() {
|
||||
t.Error("got mgp.getV1Mode() = true, want = false")
|
||||
}
|
||||
|
||||
mgp.joinGroup(addr1)
|
||||
if diff := mgp.check(checkFields{sentV2Reports: []mockReportV2{{records: []mockReportV2Record{
|
||||
{
|
||||
@@ -1528,6 +1538,9 @@ func TestSetV1Mode(t *testing.T) {
|
||||
if mgp.setV1Mode(true) {
|
||||
t.Error("got mgp.setV1Mode(true) = true, want = false")
|
||||
}
|
||||
if !mgp.getV1Mode() {
|
||||
t.Error("got mgp.getV1Mode() = false, want = true")
|
||||
}
|
||||
mgp.joinGroup(addr2)
|
||||
if diff := mgp.check(checkFields{sendReportGroupAddresses: []tcpip.Address{addr2}}); diff != "" {
|
||||
t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
|
||||
@@ -1536,6 +1549,9 @@ func TestSetV1Mode(t *testing.T) {
|
||||
if !mgp.setV1Mode(false) {
|
||||
t.Error("got mgp.setV1Mode(false) = false, want = true")
|
||||
}
|
||||
if mgp.getV1Mode() {
|
||||
t.Error("got mgp.getV1Mode() = true, want = false")
|
||||
}
|
||||
mgp.joinGroup(addr3)
|
||||
if diff := mgp.check(checkFields{sentV2Reports: []mockReportV2{{records: []mockReportV2Record{
|
||||
{
|
||||
|
||||
@@ -80,10 +80,13 @@ const (
|
||||
|
||||
// IGMPEndpoint is a network endpoint that supports IGMP.
|
||||
type IGMPEndpoint interface {
|
||||
// Sets the IGMP version.
|
||||
// SetIGMPVersion sets the IGMP version.
|
||||
//
|
||||
// Returns the previous IGMP version.
|
||||
SetIGMPVersion(IGMPVersion) IGMPVersion
|
||||
|
||||
// GetIGMPVersion returns the IGMP version.
|
||||
GetIGMPVersion() IGMPVersion
|
||||
}
|
||||
|
||||
// IGMPOptions holds options for IGMP.
|
||||
@@ -622,15 +625,26 @@ func (igmp *igmpState) setVersion(v IGMPVersion) IGMPVersion {
|
||||
panic(fmt.Sprintf("unrecognized version = %d", v))
|
||||
}
|
||||
|
||||
switch prev {
|
||||
return toIGMPVersion(prev, prevGenericModeV1)
|
||||
}
|
||||
|
||||
func toIGMPVersion(mode protocolMode, genericV1 bool) IGMPVersion {
|
||||
switch mode {
|
||||
case protocolModeV2OrV3, protocolModeV1Compatibility:
|
||||
if prevGenericModeV1 {
|
||||
if genericV1 {
|
||||
return IGMPVersion2
|
||||
}
|
||||
return IGMPVersion3
|
||||
case protocolModeV1:
|
||||
return IGMPVersion1
|
||||
default:
|
||||
panic(fmt.Sprintf("unrecognized mode = %d", igmp.mode))
|
||||
panic(fmt.Sprintf("unrecognized mode = %d", mode))
|
||||
}
|
||||
}
|
||||
|
||||
// getVersion returns the IGMP version.
|
||||
//
|
||||
// +checklocksread:igmp.ep.mu
|
||||
func (igmp *igmpState) getVersion() IGMPVersion {
|
||||
return toIGMPVersion(igmp.mode, igmp.genericMulticastProtocol.GetV1ModeLocked())
|
||||
}
|
||||
|
||||
@@ -509,7 +509,7 @@ func TestIGMPPacketValidation(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetIGMPVersion(t *testing.T) {
|
||||
func TestGetSetIGMPVersion(t *testing.T) {
|
||||
const nicID = 1
|
||||
|
||||
c := newIGMPTestContext(t, true /* igmpEnabled */)
|
||||
@@ -525,6 +525,9 @@ func TestSetIGMPVersion(t *testing.T) {
|
||||
if !ok {
|
||||
t.Fatalf("got (%T).(%T) = (_, false), want = (_ true)", ep, igmpEP)
|
||||
}
|
||||
if got := igmpEP.GetIGMPVersion(); got != ipv4.IGMPVersion3 {
|
||||
t.Errorf("got igmpEP.GetIGMPVersion() = %d, want = %d", got, ipv4.IGMPVersion3)
|
||||
}
|
||||
|
||||
protocolAddr := tcpip.ProtocolAddress{
|
||||
Protocol: ipv4.ProtocolNumber,
|
||||
@@ -547,6 +550,9 @@ func TestSetIGMPVersion(t *testing.T) {
|
||||
if got := igmpEP.SetIGMPVersion(ipv4.IGMPVersion2); got != ipv4.IGMPVersion3 {
|
||||
t.Errorf("got igmpEP.SetIGMPVersion(%d) = %d, want = %d", ipv4.IGMPVersion2, got, ipv4.IGMPVersion3)
|
||||
}
|
||||
if got := igmpEP.GetIGMPVersion(); got != ipv4.IGMPVersion2 {
|
||||
t.Errorf("got igmpEP.GetIGMPVersion() = %d, want = %d", got, ipv4.IGMPVersion2)
|
||||
}
|
||||
if err := s.JoinGroup(ipv4.ProtocolNumber, nicID, multicastAddr2); err != nil {
|
||||
t.Fatalf("JoinGroup(ipv4, nic, %s) = %s", multicastAddr2, err)
|
||||
}
|
||||
@@ -560,6 +566,9 @@ func TestSetIGMPVersion(t *testing.T) {
|
||||
if got := igmpEP.SetIGMPVersion(ipv4.IGMPVersion1); got != ipv4.IGMPVersion2 {
|
||||
t.Errorf("got igmpEP.SetIGMPVersion(%d) = %d, want = %d", ipv4.IGMPVersion1, got, ipv4.IGMPVersion2)
|
||||
}
|
||||
if got := igmpEP.GetIGMPVersion(); got != ipv4.IGMPVersion1 {
|
||||
t.Errorf("got igmpEP.GetIGMPVersion() = %d, want = %d", got, ipv4.IGMPVersion1)
|
||||
}
|
||||
if err := s.JoinGroup(ipv4.ProtocolNumber, nicID, multicastAddr3); err != nil {
|
||||
t.Fatalf("JoinGroup(ipv4, nic, %s) = %s", multicastAddr3, err)
|
||||
}
|
||||
@@ -573,6 +582,9 @@ func TestSetIGMPVersion(t *testing.T) {
|
||||
if got := igmpEP.SetIGMPVersion(ipv4.IGMPVersion3); got != ipv4.IGMPVersion1 {
|
||||
t.Errorf("got igmpEP.SetIGMPVersion(%d) = %d, want = %d", ipv4.IGMPVersion3, got, ipv4.IGMPVersion1)
|
||||
}
|
||||
if got := igmpEP.GetIGMPVersion(); got != ipv4.IGMPVersion3 {
|
||||
t.Errorf("got igmpEP.GetIGMPVersion() = %d, want = %d", got, ipv4.IGMPVersion3)
|
||||
}
|
||||
if err := s.JoinGroup(ipv4.ProtocolNumber, nicID, multicastAddr4); err != nil {
|
||||
t.Fatalf("JoinGroup(ipv4, nic, %s) = %s", multicastAddr4, err)
|
||||
}
|
||||
|
||||
@@ -117,12 +117,25 @@ func (e *endpoint) SetIGMPVersion(v IGMPVersion) IGMPVersion {
|
||||
return e.setIGMPVersionLocked(v)
|
||||
}
|
||||
|
||||
// GetIGMPVersion implements IGMPEndpoint.
|
||||
func (e *endpoint) GetIGMPVersion() IGMPVersion {
|
||||
e.mu.RLock()
|
||||
defer e.mu.RUnlock()
|
||||
return e.getIGMPVersionLocked()
|
||||
}
|
||||
|
||||
// +checklocks:e.mu
|
||||
// +checklocksalias:e.igmp.ep.mu=e.mu
|
||||
func (e *endpoint) setIGMPVersionLocked(v IGMPVersion) IGMPVersion {
|
||||
return e.igmp.setVersion(v)
|
||||
}
|
||||
|
||||
// +checklocksread:e.mu
|
||||
// +checklocksalias:e.igmp.ep.mu=e.mu
|
||||
func (e *endpoint) getIGMPVersionLocked() IGMPVersion {
|
||||
return e.igmp.getVersion()
|
||||
}
|
||||
|
||||
// HandleLinkResolutionFailure implements stack.LinkResolvableNetworkEndpoint.
|
||||
func (e *endpoint) HandleLinkResolutionFailure(pkt stack.PacketBufferPtr) {
|
||||
// If we are operating as a router, return an ICMP error to the original
|
||||
|
||||
@@ -364,6 +364,13 @@ func (e *endpoint) SetMLDVersion(v MLDVersion) MLDVersion {
|
||||
return e.mu.mld.setVersion(v)
|
||||
}
|
||||
|
||||
// GetMLDVersion implements MLDEndpoint.
|
||||
func (e *endpoint) GetMLDVersion() MLDVersion {
|
||||
e.mu.RLock()
|
||||
defer e.mu.RUnlock()
|
||||
return e.mu.mld.getVersion()
|
||||
}
|
||||
|
||||
// SetNDPConfigurations implements NDPEndpoint.
|
||||
func (e *endpoint) SetNDPConfigurations(c NDPConfigurations) {
|
||||
c.validate()
|
||||
|
||||
@@ -47,10 +47,13 @@ const (
|
||||
|
||||
// MLDEndpoint is a network endpoint that supports MLD.
|
||||
type MLDEndpoint interface {
|
||||
// Sets the MLD version.
|
||||
// SetMLDVersions sets the MLD version.
|
||||
//
|
||||
// Returns the previous MLD version.
|
||||
SetMLDVersion(MLDVersion) MLDVersion
|
||||
|
||||
// GetMLDVersion returns the MLD version.
|
||||
GetMLDVersion() MLDVersion
|
||||
}
|
||||
|
||||
// MLDOptions holds options for MLD.
|
||||
@@ -334,12 +337,23 @@ func (mld *mldState) setVersion(v MLDVersion) MLDVersion {
|
||||
panic(fmt.Sprintf("unrecognized version = %d", v))
|
||||
}
|
||||
|
||||
if prev {
|
||||
return toMLDVersion(prev)
|
||||
}
|
||||
|
||||
func toMLDVersion(v1Generic bool) MLDVersion {
|
||||
if v1Generic {
|
||||
return MLDVersion1
|
||||
}
|
||||
return MLDVersion2
|
||||
}
|
||||
|
||||
// getVersion returns the MLD version.
|
||||
//
|
||||
// Precondition: mld.ep.mu must be read locked.
|
||||
func (mld *mldState) getVersion() MLDVersion {
|
||||
return toMLDVersion(mld.genericMulticastProtocol.GetV1ModeLocked())
|
||||
}
|
||||
|
||||
// writePacket assembles and sends an MLD packet.
|
||||
//
|
||||
// Precondition: mld.ep.mu must be read locked.
|
||||
|
||||
@@ -759,7 +759,7 @@ func TestMLDSkipProtocol(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetMLDVersion(t *testing.T) {
|
||||
func TestGetSetMLDVersion(t *testing.T) {
|
||||
const nicID = 1
|
||||
|
||||
c := newMLDTestContext()
|
||||
@@ -781,6 +781,9 @@ func TestSetMLDVersion(t *testing.T) {
|
||||
if !ok {
|
||||
t.Fatalf("got (%T).(%T) = (_, false), want = (_ true)", ep, mldEP)
|
||||
}
|
||||
if got := mldEP.GetMLDVersion(); got != ipv6.MLDVersion2 {
|
||||
t.Errorf("got mldEP.GetMLDVersion() = %d, want = %d", got, ipv6.MLDVersion2)
|
||||
}
|
||||
|
||||
protocolAddr := tcpip.ProtocolAddress{
|
||||
Protocol: ipv6.ProtocolNumber,
|
||||
@@ -799,6 +802,9 @@ func TestSetMLDVersion(t *testing.T) {
|
||||
if got := mldEP.SetMLDVersion(ipv6.MLDVersion1); got != ipv6.MLDVersion2 {
|
||||
t.Errorf("got mldEP.SetMLDVersion(%d) = %d, want = %d", ipv6.MLDVersion1, got, ipv6.MLDVersion2)
|
||||
}
|
||||
if got := mldEP.GetMLDVersion(); got != ipv6.MLDVersion1 {
|
||||
t.Errorf("got mldEP.GetMLDVersion() = %d, want = %d", got, ipv6.MLDVersion1)
|
||||
}
|
||||
if err := s.JoinGroup(ipv6.ProtocolNumber, nicID, globalMulticastAddr); err != nil {
|
||||
t.Fatalf("s.JoinGroup(%d, %d, %s): %s", ipv6.ProtocolNumber, nicID, globalMulticastAddr, err)
|
||||
}
|
||||
@@ -812,6 +818,9 @@ func TestSetMLDVersion(t *testing.T) {
|
||||
if got := mldEP.SetMLDVersion(ipv6.MLDVersion2); got != ipv6.MLDVersion1 {
|
||||
t.Errorf("got mldEP.SetMLDVersion(%d) = %d, want = %d", ipv6.MLDVersion2, got, ipv6.MLDVersion1)
|
||||
}
|
||||
if got := mldEP.GetMLDVersion(); got != ipv6.MLDVersion2 {
|
||||
t.Errorf("got mldEP.GetMLDVersion() = %d, want = %d", got, ipv6.MLDVersion2)
|
||||
}
|
||||
if err := s.LeaveGroup(ipv6.ProtocolNumber, nicID, globalMulticastAddr); err != nil {
|
||||
t.Fatalf("s.LeaveGroup(%d, %d, %s): %s", ipv6.ProtocolNumber, nicID, globalMulticastAddr, err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user