mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Limit the number of discovered SLAAC prefixes
...to prevent address explosion. Fuchsia bug: https://fxbug.dev/110896 PiperOrigin-RevId: 479613489
This commit is contained in:
committed by
gVisor bot
parent
1f101ba738
commit
76d800d410
@@ -97,6 +97,11 @@ const (
|
||||
// prefixes.
|
||||
MaxDiscoveredOnLinkPrefixes = 10
|
||||
|
||||
// MaxDiscoveredSLAACPrefixes is the maximum number of discovered
|
||||
// SLAAC prefixes. The stack will stop discovering new SLAAC
|
||||
// prefixes after discovering MaxDiscoveredSLAACPrefixes SLAAC prefixes.
|
||||
MaxDiscoveredSLAACPrefixes = 10
|
||||
|
||||
// validPrefixLenForAutoGen is the expected prefix length that an
|
||||
// address can be generated for. Must be 64 bits as the interface
|
||||
// identifier (IID) is 64 bits and an IPv6 address is 128 bits, so
|
||||
@@ -1039,6 +1044,11 @@ func (ndp *ndpState) handleAutonomousPrefixInformation(pi header.NDPPrefixInform
|
||||
return
|
||||
}
|
||||
|
||||
// Limit the number of discovered SLAAC prefixes.
|
||||
if len(ndp.slaacPrefixes) == MaxDiscoveredSLAACPrefixes {
|
||||
return
|
||||
}
|
||||
|
||||
ndp.doSLAAC(prefix, pl, vl)
|
||||
}
|
||||
|
||||
|
||||
@@ -2098,6 +2098,87 @@ func expectAutoGenAddrNewEvent(ndpDisp *ndpDispatcher, addr tcpip.AddressWithPre
|
||||
}
|
||||
}
|
||||
|
||||
func TestMaxSlaacPrefixes(t *testing.T) {
|
||||
const (
|
||||
nicID = 1
|
||||
// Each SLAAC prefix gets a stable and temporary address.
|
||||
slaacAddrsPerPrefix = 2
|
||||
// Send an extra prefix than what we will discover to make sure we do not
|
||||
// discover the extra prefix.
|
||||
slaacPrefixesInRA = ipv6.MaxDiscoveredSLAACPrefixes + 1
|
||||
)
|
||||
|
||||
ndpDisp := ndpDispatcher{
|
||||
autoGenAddrNewC: make(chan ndpAutoGenAddrNewEvent, slaacPrefixesInRA*slaacAddrsPerPrefix),
|
||||
}
|
||||
e := channel.New(0, 1280, linkAddr1)
|
||||
s := stack.New(stack.Options{
|
||||
NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
|
||||
NDPConfigs: ipv6.NDPConfigurations{
|
||||
HandleRAs: ipv6.HandlingRAsEnabledWhenForwardingDisabled,
|
||||
AutoGenGlobalAddresses: true,
|
||||
AutoGenTempGlobalAddresses: true,
|
||||
},
|
||||
NDPDisp: &ndpDisp,
|
||||
})},
|
||||
})
|
||||
|
||||
if err := s.CreateNIC(nicID, e); err != nil {
|
||||
t.Fatalf("CreateNIC(%d) = %s", nicID, err)
|
||||
}
|
||||
|
||||
optSer := make(header.NDPOptionsSerializer, 0, slaacPrefixesInRA)
|
||||
prefixes := [slaacPrefixesInRA]tcpip.Subnet{}
|
||||
for i := 0; i < slaacPrefixesInRA; i++ {
|
||||
prefixAddr := [16]byte{1, 2, 3, 4, 5, 6, 7, byte(i), 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
prefix := tcpip.AddressWithPrefix{
|
||||
Address: tcpip.Address(prefixAddr[:]),
|
||||
PrefixLen: 64,
|
||||
}
|
||||
prefixes[i] = prefix.Subnet()
|
||||
// Serialize a perfix information option.
|
||||
buf := [30]byte{}
|
||||
buf[0] = uint8(prefix.PrefixLen)
|
||||
// Set the autonomous configuration flag.
|
||||
buf[1] = 64
|
||||
// Set the preferred and valid lifetimes to the maxiumum possible value.
|
||||
binary.BigEndian.PutUint32(buf[2:], math.MaxUint32)
|
||||
binary.BigEndian.PutUint32(buf[6:], math.MaxUint32)
|
||||
if n := copy(buf[14:], prefix.Address); n != len(prefix.Address) {
|
||||
t.Fatalf("got copy(...) = %d, want = %d", n, len(prefix.Address))
|
||||
}
|
||||
optSer = append(optSer, header.NDPPrefixInformation(buf[:]))
|
||||
}
|
||||
|
||||
e.InjectInbound(header.IPv6ProtocolNumber, raBufWithOpts(llAddr1, 0, optSer))
|
||||
for i := 0; i < slaacPrefixesInRA; i++ {
|
||||
for j := 0; j < slaacAddrsPerPrefix; j++ {
|
||||
if i < ipv6.MaxDiscoveredSLAACPrefixes {
|
||||
select {
|
||||
case e := <-ndpDisp.autoGenAddrNewC:
|
||||
if e.nicID != nicID {
|
||||
t.Errorf("got e.nicID = %d, want = %d", e.nicID, nicID)
|
||||
}
|
||||
if !prefixes[i].Contains(e.addr.Address) {
|
||||
t.Errorf("got prefixes[%d].Contains(%s) = false, want = true", i, e.addr)
|
||||
}
|
||||
if e.addrDisp != nil {
|
||||
t.Error("auto-gen new addr event unexpectedly contains address dispatcher")
|
||||
}
|
||||
default:
|
||||
t.Fatalf("expected auto-gen new addr event; i=%d, j=%d", i, j)
|
||||
}
|
||||
} else {
|
||||
select {
|
||||
case <-ndpDisp.autoGenAddrNewC:
|
||||
t.Fatal("should not have discovered a new auto-gen addr after we already discovered the max number of prefixes")
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestAutoGenAddr tests that an address is properly generated and invalidated
|
||||
// when configured to do so.
|
||||
func TestAutoGenAddr(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user