Always accept discovered configurations from NDP

Before this change, the NDPDispatcher was allowed to "cancel" the
discovery of default routers/prefixes and auto-generate addresses.
No use case exists for this today so we drop this for now. If a
use case comes up in the future, we should instead invalidate the
discovered configuration through the stack instead of during
discovery.

PiperOrigin-RevId: 379327009
This commit is contained in:
Ghanan Gowripalan
2021-06-14 12:17:53 -07:00
committed by gVisor bot
parent 397a59fc95
commit b720bcb6f6
4 changed files with 29 additions and 162 deletions
+9 -25
View File
@@ -215,12 +215,11 @@ type NDPDispatcher interface {
OnDuplicateAddressDetectionResult(tcpip.NICID, tcpip.Address, stack.DADResult)
// OnDefaultRouterDiscovered is called when a new default router is
// discovered. Implementations must return true if the newly discovered
// router should be remembered.
// discovered.
//
// This function is not permitted to block indefinitely. This function
// is also not permitted to call into the stack.
OnDefaultRouterDiscovered(tcpip.NICID, tcpip.Address) bool
OnDefaultRouterDiscovered(tcpip.NICID, tcpip.Address)
// OnDefaultRouterInvalidated is called when a discovered default router that
// was remembered is invalidated.
@@ -230,12 +229,10 @@ type NDPDispatcher interface {
OnDefaultRouterInvalidated(tcpip.NICID, tcpip.Address)
// OnOnLinkPrefixDiscovered is called when a new on-link prefix is discovered.
// Implementations must return true if the newly discovered on-link prefix
// should be remembered.
//
// This function is not permitted to block indefinitely. This function
// is also not permitted to call into the stack.
OnOnLinkPrefixDiscovered(tcpip.NICID, tcpip.Subnet) bool
OnOnLinkPrefixDiscovered(tcpip.NICID, tcpip.Subnet)
// OnOnLinkPrefixInvalidated is called when a discovered on-link prefix that
// was remembered is invalidated.
@@ -245,13 +242,11 @@ type NDPDispatcher interface {
OnOnLinkPrefixInvalidated(tcpip.NICID, tcpip.Subnet)
// OnAutoGenAddress is called when a new prefix with its autonomous address-
// configuration flag set is received and SLAAC was performed. Implementations
// may prevent the stack from assigning the address to the NIC by returning
// false.
// configuration flag set is received and SLAAC was performed.
//
// This function is not permitted to block indefinitely. It must not
// call functions on the stack itself.
OnAutoGenAddress(tcpip.NICID, tcpip.AddressWithPrefix) bool
OnAutoGenAddress(tcpip.NICID, tcpip.AddressWithPrefix)
// OnAutoGenAddressDeprecated is called when an auto-generated address (SLAAC)
// is deprecated, but is still considered valid. Note, if an address is
@@ -848,11 +843,7 @@ func (ndp *ndpState) rememberDefaultRouter(ip tcpip.Address, rl time.Duration) {
}
// Inform the integrator when we discovered a default router.
if !ndpDisp.OnDefaultRouterDiscovered(ndp.ep.nic.ID(), ip) {
// Informed by the integrator to not remember the router, do
// nothing further.
return
}
ndpDisp.OnDefaultRouterDiscovered(ndp.ep.nic.ID(), ip)
state := defaultRouterState{
invalidationJob: ndp.ep.protocol.stack.NewJob(&ndp.ep.mu, func() {
@@ -878,11 +869,7 @@ func (ndp *ndpState) rememberOnLinkPrefix(prefix tcpip.Subnet, l time.Duration)
}
// Inform the integrator when we discovered an on-link prefix.
if !ndpDisp.OnOnLinkPrefixDiscovered(ndp.ep.nic.ID(), prefix) {
// Informed by the integrator to not remember the prefix, do
// nothing further.
return
}
ndpDisp.OnOnLinkPrefixDiscovered(ndp.ep.nic.ID(), prefix)
state := onLinkPrefixState{
invalidationJob: ndp.ep.protocol.stack.NewJob(&ndp.ep.mu, func() {
@@ -1096,16 +1083,13 @@ func (ndp *ndpState) addAndAcquireSLAACAddr(addr tcpip.AddressWithPrefix, config
return nil
}
if !ndpDisp.OnAutoGenAddress(ndp.ep.nic.ID(), addr) {
// Informed by the integrator not to add the address.
return nil
}
addressEndpoint, err := ndp.ep.addAndAcquirePermanentAddressLocked(addr, stack.FirstPrimaryEndpoint, configType, deprecated)
if err != nil {
panic(fmt.Sprintf("ndp: error when adding SLAAC address %+v: %s", addr, err))
}
ndpDisp.OnAutoGenAddress(ndp.ep.nic.ID(), addr)
return addressEndpoint
}
+3 -6
View File
@@ -42,24 +42,21 @@ type testNDPDispatcher struct {
func (*testNDPDispatcher) OnDuplicateAddressDetectionResult(tcpip.NICID, tcpip.Address, stack.DADResult) {
}
func (t *testNDPDispatcher) OnDefaultRouterDiscovered(_ tcpip.NICID, addr tcpip.Address) bool {
func (t *testNDPDispatcher) OnDefaultRouterDiscovered(_ tcpip.NICID, addr tcpip.Address) {
t.addr = addr
return true
}
func (t *testNDPDispatcher) OnDefaultRouterInvalidated(_ tcpip.NICID, addr tcpip.Address) {
t.addr = addr
}
func (*testNDPDispatcher) OnOnLinkPrefixDiscovered(tcpip.NICID, tcpip.Subnet) bool {
return false
func (*testNDPDispatcher) OnOnLinkPrefixDiscovered(tcpip.NICID, tcpip.Subnet) {
}
func (*testNDPDispatcher) OnOnLinkPrefixInvalidated(tcpip.NICID, tcpip.Subnet) {
}
func (*testNDPDispatcher) OnAutoGenAddress(tcpip.NICID, tcpip.AddressWithPrefix) bool {
return false
func (*testNDPDispatcher) OnAutoGenAddress(tcpip.NICID, tcpip.AddressWithPrefix) {
}
func (*testNDPDispatcher) OnAutoGenAddressDeprecated(tcpip.NICID, tcpip.AddressWithPrefix) {
+14 -125
View File
@@ -168,9 +168,7 @@ var _ ipv6.NDPDispatcher = (*ndpDispatcher)(nil)
type ndpDispatcher struct {
dadC chan ndpDADEvent
routerC chan ndpRouterEvent
rememberRouter bool
prefixC chan ndpPrefixEvent
rememberPrefix bool
autoGenAddrC chan ndpAutoGenAddrEvent
rdnssC chan ndpRDNSSEvent
dnsslC chan ndpDNSSLEvent
@@ -190,7 +188,7 @@ func (n *ndpDispatcher) OnDuplicateAddressDetectionResult(nicID tcpip.NICID, add
}
// Implements ipv6.NDPDispatcher.OnDefaultRouterDiscovered.
func (n *ndpDispatcher) OnDefaultRouterDiscovered(nicID tcpip.NICID, addr tcpip.Address) bool {
func (n *ndpDispatcher) OnDefaultRouterDiscovered(nicID tcpip.NICID, addr tcpip.Address) {
if c := n.routerC; c != nil {
c <- ndpRouterEvent{
nicID,
@@ -198,8 +196,6 @@ func (n *ndpDispatcher) OnDefaultRouterDiscovered(nicID tcpip.NICID, addr tcpip.
true,
}
}
return n.rememberRouter
}
// Implements ipv6.NDPDispatcher.OnDefaultRouterInvalidated.
@@ -214,7 +210,7 @@ func (n *ndpDispatcher) OnDefaultRouterInvalidated(nicID tcpip.NICID, addr tcpip
}
// Implements ipv6.NDPDispatcher.OnOnLinkPrefixDiscovered.
func (n *ndpDispatcher) OnOnLinkPrefixDiscovered(nicID tcpip.NICID, prefix tcpip.Subnet) bool {
func (n *ndpDispatcher) OnOnLinkPrefixDiscovered(nicID tcpip.NICID, prefix tcpip.Subnet) {
if c := n.prefixC; c != nil {
c <- ndpPrefixEvent{
nicID,
@@ -222,8 +218,6 @@ func (n *ndpDispatcher) OnOnLinkPrefixDiscovered(nicID tcpip.NICID, prefix tcpip
true,
}
}
return n.rememberPrefix
}
// Implements ipv6.NDPDispatcher.OnOnLinkPrefixInvalidated.
@@ -237,7 +231,7 @@ func (n *ndpDispatcher) OnOnLinkPrefixInvalidated(nicID tcpip.NICID, prefix tcpi
}
}
func (n *ndpDispatcher) OnAutoGenAddress(nicID tcpip.NICID, addr tcpip.AddressWithPrefix) bool {
func (n *ndpDispatcher) OnAutoGenAddress(nicID tcpip.NICID, addr tcpip.AddressWithPrefix) {
if c := n.autoGenAddrC; c != nil {
c <- ndpAutoGenAddrEvent{
nicID,
@@ -245,7 +239,6 @@ func (n *ndpDispatcher) OnAutoGenAddress(nicID tcpip.NICID, addr tcpip.AddressWi
newAddr,
}
}
return true
}
func (n *ndpDispatcher) OnAutoGenAddressDeprecated(nicID tcpip.NICID, addr tcpip.AddressWithPrefix) {
@@ -1340,57 +1333,10 @@ func testWithRAs(t *testing.T, f func(*testing.T, ipv6.HandleRAsConfiguration, b
}
}
// TestRouterDiscoveryDispatcherNoRemember tests that the stack does not
// remember a discovered router when the dispatcher asks it not to.
func TestRouterDiscoveryDispatcherNoRemember(t *testing.T) {
ndpDisp := ndpDispatcher{
routerC: make(chan ndpRouterEvent, 1),
}
e := channel.New(0, 1280, linkAddr1)
clock := faketime.NewManualClock()
s := stack.New(stack.Options{
NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
NDPConfigs: ipv6.NDPConfigurations{
HandleRAs: ipv6.HandlingRAsEnabledWhenForwardingDisabled,
DiscoverDefaultRouters: true,
},
NDPDisp: &ndpDisp,
})},
Clock: clock,
})
if err := s.CreateNIC(1, e); err != nil {
t.Fatalf("CreateNIC(1) = %s", err)
}
// Receive an RA for a router we should not remember.
const lifetimeSeconds = 1
e.InjectInbound(header.IPv6ProtocolNumber, raBuf(llAddr2, lifetimeSeconds))
select {
case e := <-ndpDisp.routerC:
if diff := checkRouterEvent(e, llAddr2, true); diff != "" {
t.Errorf("router event mismatch (-want +got):\n%s", diff)
}
default:
t.Fatal("expected router discovery event")
}
// Wait for the invalidation time plus some buffer to make sure we do
// not actually receive any invalidation events as we should not have
// remembered the router in the first place.
clock.Advance(lifetimeSeconds * time.Second)
select {
case <-ndpDisp.routerC:
t.Fatal("should not have received any router events")
default:
}
}
func TestRouterDiscovery(t *testing.T) {
testWithRAs(t, func(t *testing.T, handleRAs ipv6.HandleRAsConfiguration, forwarding bool) {
ndpDisp := ndpDispatcher{
routerC: make(chan ndpRouterEvent, 1),
rememberRouter: true,
routerC: make(chan ndpRouterEvent, 1),
}
e := channel.New(0, 1280, linkAddr1)
clock := faketime.NewManualClock()
@@ -1499,8 +1445,7 @@ func TestRouterDiscovery(t *testing.T) {
// ipv6.MaxDiscoveredDefaultRouters discovered routers are remembered.
func TestRouterDiscoveryMaxRouters(t *testing.T) {
ndpDisp := ndpDispatcher{
routerC: make(chan ndpRouterEvent, 1),
rememberRouter: true,
routerC: make(chan ndpRouterEvent, 1),
}
e := channel.New(0, 1280, linkAddr1)
s := stack.New(stack.Options{
@@ -1551,54 +1496,6 @@ func checkPrefixEvent(e ndpPrefixEvent, prefix tcpip.Subnet, discovered bool) st
return cmp.Diff(ndpPrefixEvent{nicID: 1, prefix: prefix, discovered: discovered}, e, cmp.AllowUnexported(e))
}
// TestPrefixDiscoveryDispatcherNoRemember tests that the stack does not
// remember a discovered on-link prefix when the dispatcher asks it not to.
func TestPrefixDiscoveryDispatcherNoRemember(t *testing.T) {
prefix, subnet, _ := prefixSubnetAddr(0, "")
ndpDisp := ndpDispatcher{
prefixC: make(chan ndpPrefixEvent, 1),
}
e := channel.New(0, 1280, linkAddr1)
clock := faketime.NewManualClock()
s := stack.New(stack.Options{
NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
NDPConfigs: ipv6.NDPConfigurations{
HandleRAs: ipv6.HandlingRAsEnabledWhenForwardingDisabled,
DiscoverOnLinkPrefixes: true,
},
NDPDisp: &ndpDisp,
})},
Clock: clock,
})
if err := s.CreateNIC(1, e); err != nil {
t.Fatalf("CreateNIC(1) = %s", err)
}
// Receive an RA with prefix that we should not remember.
const lifetimeSeconds = 1
e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, false, lifetimeSeconds, 0))
select {
case e := <-ndpDisp.prefixC:
if diff := checkPrefixEvent(e, subnet, true); diff != "" {
t.Errorf("prefix event mismatch (-want +got):\n%s", diff)
}
default:
t.Fatal("expected prefix discovery event")
}
// Wait for the invalidation time plus some buffer to make sure we do
// not actually receive any invalidation events as we should not have
// remembered the prefix in the first place.
clock.Advance(lifetimeSeconds * time.Second)
select {
case <-ndpDisp.prefixC:
t.Fatal("should not have received any prefix events")
default:
}
}
func TestPrefixDiscovery(t *testing.T) {
prefix1, subnet1, _ := prefixSubnetAddr(0, "")
prefix2, subnet2, _ := prefixSubnetAddr(1, "")
@@ -1606,8 +1503,7 @@ func TestPrefixDiscovery(t *testing.T) {
testWithRAs(t, func(t *testing.T, handleRAs ipv6.HandleRAsConfiguration, forwarding bool) {
ndpDisp := ndpDispatcher{
prefixC: make(chan ndpPrefixEvent, 1),
rememberPrefix: true,
prefixC: make(chan ndpPrefixEvent, 1),
}
e := channel.New(0, 1280, linkAddr1)
clock := faketime.NewManualClock()
@@ -1715,8 +1611,7 @@ func TestPrefixDiscoveryWithInfiniteLifetime(t *testing.T) {
subnet := prefix.Subnet()
ndpDisp := ndpDispatcher{
prefixC: make(chan ndpPrefixEvent, 1),
rememberPrefix: true,
prefixC: make(chan ndpPrefixEvent, 1),
}
e := channel.New(0, 1280, linkAddr1)
clock := faketime.NewManualClock()
@@ -1806,8 +1701,7 @@ func TestPrefixDiscoveryWithInfiniteLifetime(t *testing.T) {
// ipv6.MaxDiscoveredOnLinkPrefixes discovered on-link prefixes are remembered.
func TestPrefixDiscoveryMaxOnLinkPrefixes(t *testing.T) {
ndpDisp := ndpDispatcher{
prefixC: make(chan ndpPrefixEvent, ipv6.MaxDiscoveredOnLinkPrefixes+3),
rememberPrefix: true,
prefixC: make(chan ndpPrefixEvent, ipv6.MaxDiscoveredOnLinkPrefixes+3),
}
e := channel.New(0, 1280, linkAddr1)
s := stack.New(stack.Options{
@@ -4718,11 +4612,9 @@ func TestNoCleanupNDPStateWhenForwardingEnabled(t *testing.T) {
)
ndpDisp := ndpDispatcher{
routerC: make(chan ndpRouterEvent, 1),
rememberRouter: true,
prefixC: make(chan ndpPrefixEvent, 1),
rememberPrefix: true,
autoGenAddrC: make(chan ndpAutoGenAddrEvent, 1),
routerC: make(chan ndpRouterEvent, 1),
prefixC: make(chan ndpPrefixEvent, 1),
autoGenAddrC: make(chan ndpAutoGenAddrEvent, 1),
}
s := stack.New(stack.Options{
NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
@@ -4884,11 +4776,9 @@ func TestCleanupNDPState(t *testing.T) {
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
ndpDisp := ndpDispatcher{
routerC: make(chan ndpRouterEvent, maxRouterAndPrefixEvents),
rememberRouter: true,
prefixC: make(chan ndpPrefixEvent, maxRouterAndPrefixEvents),
rememberPrefix: true,
autoGenAddrC: make(chan ndpAutoGenAddrEvent, test.maxAutoGenAddrEvents),
routerC: make(chan ndpRouterEvent, maxRouterAndPrefixEvents),
prefixC: make(chan ndpPrefixEvent, maxRouterAndPrefixEvents),
autoGenAddrC: make(chan ndpAutoGenAddrEvent, test.maxAutoGenAddrEvents),
}
clock := faketime.NewManualClock()
s := stack.New(stack.Options{
@@ -5163,7 +5053,6 @@ func TestDHCPv6ConfigurationFromNDPDA(t *testing.T) {
ndpDisp := ndpDispatcher{
dhcpv6ConfigurationC: make(chan ndpDHCPv6Event, 1),
rememberRouter: true,
}
e := channel.New(0, 1280, linkAddr1)
s := stack.New(stack.Options{
+3 -6
View File
@@ -44,20 +44,17 @@ type ndpDispatcher struct{}
func (*ndpDispatcher) OnDuplicateAddressDetectionResult(tcpip.NICID, tcpip.Address, stack.DADResult) {
}
func (*ndpDispatcher) OnDefaultRouterDiscovered(tcpip.NICID, tcpip.Address) bool {
return false
func (*ndpDispatcher) OnDefaultRouterDiscovered(tcpip.NICID, tcpip.Address) {
}
func (*ndpDispatcher) OnDefaultRouterInvalidated(tcpip.NICID, tcpip.Address) {}
func (*ndpDispatcher) OnOnLinkPrefixDiscovered(tcpip.NICID, tcpip.Subnet) bool {
return false
func (*ndpDispatcher) OnOnLinkPrefixDiscovered(tcpip.NICID, tcpip.Subnet) {
}
func (*ndpDispatcher) OnOnLinkPrefixInvalidated(tcpip.NICID, tcpip.Subnet) {}
func (*ndpDispatcher) OnAutoGenAddress(tcpip.NICID, tcpip.AddressWithPrefix) bool {
return true
func (*ndpDispatcher) OnAutoGenAddress(tcpip.NICID, tcpip.AddressWithPrefix) {
}
func (*ndpDispatcher) OnAutoGenAddressDeprecated(tcpip.NICID, tcpip.AddressWithPrefix) {}