Rename DefaultRouter event to OffLinkRoute event

This change prepares for a later change which supports the NDP
Route Information option to discover more-specific routes, as
per RFC 4191.

Updates #6172.

PiperOrigin-RevId: 379361330
This commit is contained in:
Ghanan Gowripalan
2021-06-14 15:29:42 -07:00
committed by gVisor bot
parent b9db1c0313
commit d4af8da361
4 changed files with 98 additions and 97 deletions
+6 -8
View File
@@ -214,19 +214,17 @@ type NDPDispatcher interface {
// is also not permitted to call into the stack.
OnDuplicateAddressDetectionResult(tcpip.NICID, tcpip.Address, stack.DADResult)
// OnDefaultRouterDiscovered is called when a new default router is
// discovered.
// OnOffLinkRouteUpdated is called when an off-link route is updated.
//
// This function is not permitted to block indefinitely. This function
// is also not permitted to call into the stack.
OnDefaultRouterDiscovered(tcpip.NICID, tcpip.Address)
OnOffLinkRouteUpdated(tcpip.NICID, tcpip.Subnet, tcpip.Address)
// OnDefaultRouterInvalidated is called when a discovered default router that
// was remembered is invalidated.
// OnOffLinkRouteInvalidated is called when an off-link route is invalidated.
//
// This function is not permitted to block indefinitely. This function
// is also not permitted to call into the stack.
OnDefaultRouterInvalidated(tcpip.NICID, tcpip.Address)
OnOffLinkRouteInvalidated(tcpip.NICID, tcpip.Subnet, tcpip.Address)
// OnOnLinkPrefixDiscovered is called when a new on-link prefix is discovered.
//
@@ -826,7 +824,7 @@ func (ndp *ndpState) invalidateDefaultRouter(ip tcpip.Address) {
// Let the integrator know a discovered default router is invalidated.
if ndpDisp := ndp.ep.protocol.options.NDPDisp; ndpDisp != nil {
ndpDisp.OnDefaultRouterInvalidated(ndp.ep.nic.ID(), ip)
ndpDisp.OnOffLinkRouteInvalidated(ndp.ep.nic.ID(), header.IPv6EmptySubnet, ip)
}
}
@@ -843,7 +841,7 @@ func (ndp *ndpState) rememberDefaultRouter(ip tcpip.Address, rl time.Duration) {
}
// Inform the integrator when we discovered a default router.
ndpDisp.OnDefaultRouterDiscovered(ndp.ep.nic.ID(), ip)
ndpDisp.OnOffLinkRouteUpdated(ndp.ep.nic.ID(), header.IPv6EmptySubnet, ip)
state := defaultRouterState{
invalidationJob: ndp.ep.protocol.stack.NewJob(&ndp.ep.mu, func() {
+2 -2
View File
@@ -42,11 +42,11 @@ type testNDPDispatcher struct {
func (*testNDPDispatcher) OnDuplicateAddressDetectionResult(tcpip.NICID, tcpip.Address, stack.DADResult) {
}
func (t *testNDPDispatcher) OnDefaultRouterDiscovered(_ tcpip.NICID, addr tcpip.Address) {
func (t *testNDPDispatcher) OnOffLinkRouteUpdated(_ tcpip.NICID, _ tcpip.Subnet, addr tcpip.Address) {
t.addr = addr
}
func (t *testNDPDispatcher) OnDefaultRouterInvalidated(_ tcpip.NICID, addr tcpip.Address) {
func (t *testNDPDispatcher) OnOffLinkRouteInvalidated(_ tcpip.NICID, _ tcpip.Subnet, addr tcpip.Address) {
t.addr = addr
}
+88 -85
View File
@@ -112,11 +112,12 @@ type ndpDADEvent struct {
res stack.DADResult
}
type ndpRouterEvent struct {
nicID tcpip.NICID
addr tcpip.Address
// true if router was discovered, false if invalidated.
discovered bool
type ndpOffLinkRouteEvent struct {
nicID tcpip.NICID
subnet tcpip.Subnet
router tcpip.Address
// true if route was updated, false if invalidated.
updated bool
}
type ndpPrefixEvent struct {
@@ -167,7 +168,7 @@ var _ ipv6.NDPDispatcher = (*ndpDispatcher)(nil)
// related events happen for test purposes.
type ndpDispatcher struct {
dadC chan ndpDADEvent
routerC chan ndpRouterEvent
offLinkRouteC chan ndpOffLinkRouteEvent
prefixC chan ndpPrefixEvent
autoGenAddrC chan ndpAutoGenAddrEvent
rdnssC chan ndpRDNSSEvent
@@ -187,23 +188,25 @@ func (n *ndpDispatcher) OnDuplicateAddressDetectionResult(nicID tcpip.NICID, add
}
}
// Implements ipv6.NDPDispatcher.OnDefaultRouterDiscovered.
func (n *ndpDispatcher) OnDefaultRouterDiscovered(nicID tcpip.NICID, addr tcpip.Address) {
if c := n.routerC; c != nil {
c <- ndpRouterEvent{
// Implements ipv6.NDPDispatcher.OnOffLinkRouteUpdated.
func (n *ndpDispatcher) OnOffLinkRouteUpdated(nicID tcpip.NICID, subnet tcpip.Subnet, router tcpip.Address) {
if c := n.offLinkRouteC; c != nil {
c <- ndpOffLinkRouteEvent{
nicID,
addr,
subnet,
router,
true,
}
}
}
// Implements ipv6.NDPDispatcher.OnDefaultRouterInvalidated.
func (n *ndpDispatcher) OnDefaultRouterInvalidated(nicID tcpip.NICID, addr tcpip.Address) {
if c := n.routerC; c != nil {
c <- ndpRouterEvent{
// Implements ipv6.NDPDispatcher.OnOffLinkRouteInvalidated.
func (n *ndpDispatcher) OnOffLinkRouteInvalidated(nicID tcpip.NICID, subnet tcpip.Subnet, router tcpip.Address) {
if c := n.offLinkRouteC; c != nil {
c <- ndpOffLinkRouteEvent{
nicID,
addr,
subnet,
router,
false,
}
}
@@ -1198,9 +1201,9 @@ func TestDynamicConfigurationsDisabled(t *testing.T) {
t.Run(fmt.Sprintf("HandleRAs(%s), Forwarding(%t), Enabled(%t)", handle, forwarding, enable), func(t *testing.T) {
ndpDisp := ndpDispatcher{
routerC: make(chan ndpRouterEvent, 1),
prefixC: make(chan ndpPrefixEvent, 1),
autoGenAddrC: make(chan ndpAutoGenAddrEvent, 1),
offLinkRouteC: make(chan ndpOffLinkRouteEvent, 1),
prefixC: make(chan ndpPrefixEvent, 1),
autoGenAddrC: make(chan ndpAutoGenAddrEvent, 1),
}
ndpConfigs := test.config(enable)
ndpConfigs.HandleRAs = handle
@@ -1270,8 +1273,8 @@ func TestDynamicConfigurationsDisabled(t *testing.T) {
t.Errorf("got v6Stats.UnhandledRouterAdvertisements.Value() = %d, want = %d", got, want)
}
select {
case e := <-ndpDisp.routerC:
t.Errorf("unexpectedly discovered a router when configured not to: %#v", e)
case e := <-ndpDisp.offLinkRouteC:
t.Errorf("unexpectedly updated an off-link route when configured not to: %#v", e)
default:
}
select {
@@ -1298,9 +1301,9 @@ func boolToUint64(v bool) uint64 {
}
// Check e to make sure that the event is for addr on nic with ID 1, and the
// discovered flag set to discovered.
func checkRouterEvent(e ndpRouterEvent, addr tcpip.Address, discovered bool) string {
return cmp.Diff(ndpRouterEvent{nicID: 1, addr: addr, discovered: discovered}, e, cmp.AllowUnexported(e))
// update flag set to updated.
func checkOffLinkRouteEvent(e ndpOffLinkRouteEvent, router tcpip.Address, updated bool) string {
return cmp.Diff(ndpOffLinkRouteEvent{nicID: 1, subnet: header.IPv6EmptySubnet, router: router, updated: updated}, e, cmp.AllowUnexported(e))
}
func testWithRAs(t *testing.T, f func(*testing.T, ipv6.HandleRAsConfiguration, bool)) {
@@ -1336,7 +1339,7 @@ func testWithRAs(t *testing.T, f func(*testing.T, ipv6.HandleRAsConfiguration, b
func TestRouterDiscovery(t *testing.T) {
testWithRAs(t, func(t *testing.T, handleRAs ipv6.HandleRAsConfiguration, forwarding bool) {
ndpDisp := ndpDispatcher{
routerC: make(chan ndpRouterEvent, 1),
offLinkRouteC: make(chan ndpOffLinkRouteEvent, 1),
}
e := channel.New(0, 1280, linkAddr1)
clock := faketime.NewManualClock()
@@ -1351,27 +1354,27 @@ func TestRouterDiscovery(t *testing.T) {
Clock: clock,
})
expectRouterEvent := func(addr tcpip.Address, discovered bool) {
expectOffLinkRouteEvent := func(addr tcpip.Address, updated bool) {
t.Helper()
select {
case e := <-ndpDisp.routerC:
if diff := checkRouterEvent(e, addr, discovered); diff != "" {
t.Errorf("router event mismatch (-want +got):\n%s", diff)
case e := <-ndpDisp.offLinkRouteC:
if diff := checkOffLinkRouteEvent(e, addr, updated); diff != "" {
t.Errorf("off-link route event mismatch (-want +got):\n%s", diff)
}
default:
t.Fatal("expected router discovery event")
}
}
expectAsyncRouterInvalidationEvent := func(addr tcpip.Address, timeout time.Duration) {
expectAsyncOffLinkRouteInvalidationEvent := func(addr tcpip.Address, timeout time.Duration) {
t.Helper()
clock.Advance(timeout)
select {
case e := <-ndpDisp.routerC:
if diff := checkRouterEvent(e, addr, false); diff != "" {
t.Errorf("router event mismatch (-want +got):\n%s", diff)
case e := <-ndpDisp.offLinkRouteC:
if diff := checkOffLinkRouteEvent(e, addr, false); diff != "" {
t.Errorf("off-link route event mismatch (-want +got):\n%s", diff)
}
default:
t.Fatal("timed out waiting for router discovery event")
@@ -1390,26 +1393,26 @@ func TestRouterDiscovery(t *testing.T) {
// remembered.
e.InjectInbound(header.IPv6ProtocolNumber, raBuf(llAddr2, 0))
select {
case <-ndpDisp.routerC:
t.Fatal("unexpectedly discovered a router with 0 lifetime")
case <-ndpDisp.offLinkRouteC:
t.Fatal("unexpectedly updated an off-link route with 0 lifetime")
default:
}
// Rx an RA from lladdr2 with a huge lifetime.
e.InjectInbound(header.IPv6ProtocolNumber, raBuf(llAddr2, 1000))
expectRouterEvent(llAddr2, true)
expectOffLinkRouteEvent(llAddr2, true)
// Rx an RA from another router (lladdr3) with non-zero lifetime.
const l3LifetimeSeconds = 6
e.InjectInbound(header.IPv6ProtocolNumber, raBuf(llAddr3, l3LifetimeSeconds))
expectRouterEvent(llAddr3, true)
expectOffLinkRouteEvent(llAddr3, true)
// Rx an RA from lladdr2 with lesser lifetime.
const l2LifetimeSeconds = 2
e.InjectInbound(header.IPv6ProtocolNumber, raBuf(llAddr2, l2LifetimeSeconds))
select {
case <-ndpDisp.routerC:
t.Fatal("Should not receive a router event when updating lifetimes for known routers")
case <-ndpDisp.offLinkRouteC:
t.Fatal("should not receive a off-link route event when updating lifetimes for known routers")
default:
}
@@ -1420,15 +1423,15 @@ func TestRouterDiscovery(t *testing.T) {
// Wait for the normal lifetime plus an extra bit for the
// router to get invalidated. If we don't get an invalidation
// event after this time, then something is wrong.
expectAsyncRouterInvalidationEvent(llAddr2, l2LifetimeSeconds*time.Second)
expectAsyncOffLinkRouteInvalidationEvent(llAddr2, l2LifetimeSeconds*time.Second)
// Rx an RA from lladdr2 with huge lifetime.
e.InjectInbound(header.IPv6ProtocolNumber, raBuf(llAddr2, 1000))
expectRouterEvent(llAddr2, true)
expectOffLinkRouteEvent(llAddr2, true)
// Rx an RA from lladdr2 with zero lifetime. It should be invalidated.
e.InjectInbound(header.IPv6ProtocolNumber, raBuf(llAddr2, 0))
expectRouterEvent(llAddr2, false)
expectOffLinkRouteEvent(llAddr2, false)
// Wait for lladdr3's router invalidation job to execute. The lifetime
// of the router should have been updated to the most recent (smaller)
@@ -1437,7 +1440,7 @@ func TestRouterDiscovery(t *testing.T) {
// Wait for the normal lifetime plus an extra bit for the
// router to get invalidated. If we don't get an invalidation
// event after this time, then something is wrong.
expectAsyncRouterInvalidationEvent(llAddr3, l3LifetimeSeconds*time.Second)
expectAsyncOffLinkRouteInvalidationEvent(llAddr3, l3LifetimeSeconds*time.Second)
})
}
@@ -1445,7 +1448,7 @@ func TestRouterDiscovery(t *testing.T) {
// ipv6.MaxDiscoveredDefaultRouters discovered routers are remembered.
func TestRouterDiscoveryMaxRouters(t *testing.T) {
ndpDisp := ndpDispatcher{
routerC: make(chan ndpRouterEvent, 1),
offLinkRouteC: make(chan ndpOffLinkRouteEvent, 1),
}
e := channel.New(0, 1280, linkAddr1)
s := stack.New(stack.Options{
@@ -1472,9 +1475,9 @@ func TestRouterDiscoveryMaxRouters(t *testing.T) {
if i <= ipv6.MaxDiscoveredDefaultRouters {
select {
case e := <-ndpDisp.routerC:
if diff := checkRouterEvent(e, llAddr, true); diff != "" {
t.Errorf("router event mismatch (-want +got):\n%s", diff)
case e := <-ndpDisp.offLinkRouteC:
if diff := checkOffLinkRouteEvent(e, llAddr, true); diff != "" {
t.Errorf("off-link route event mismatch (-want +got):\n%s", diff)
}
default:
t.Fatal("expected router discovery event")
@@ -1482,7 +1485,7 @@ func TestRouterDiscoveryMaxRouters(t *testing.T) {
} else {
select {
case <-ndpDisp.routerC:
case <-ndpDisp.offLinkRouteC:
t.Fatal("should not have discovered a new router after we already discovered the max number of routers")
default:
}
@@ -4612,9 +4615,9 @@ func TestNoCleanupNDPStateWhenForwardingEnabled(t *testing.T) {
)
ndpDisp := ndpDispatcher{
routerC: make(chan ndpRouterEvent, 1),
prefixC: make(chan ndpPrefixEvent, 1),
autoGenAddrC: make(chan ndpAutoGenAddrEvent, 1),
offLinkRouteC: make(chan ndpOffLinkRouteEvent, 1),
prefixC: make(chan ndpPrefixEvent, 1),
autoGenAddrC: make(chan ndpAutoGenAddrEvent, 1),
}
s := stack.New(stack.Options{
NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
@@ -4657,17 +4660,17 @@ func TestNoCleanupNDPStateWhenForwardingEnabled(t *testing.T) {
),
)
select {
case e := <-ndpDisp.routerC:
if diff := checkRouterEvent(e, llAddr3, true /* discovered */); diff != "" {
t.Errorf("router event mismatch (-want +got):\n%s", diff)
case e := <-ndpDisp.offLinkRouteC:
if diff := checkOffLinkRouteEvent(e, llAddr3, true /* discovered */); diff != "" {
t.Errorf("off-link route event mismatch (-want +got):\n%s", diff)
}
default:
t.Errorf("expected router event for %s on NIC(%d)", llAddr3, nicID)
t.Errorf("expected off-link route event for %s on NIC(%d)", llAddr3, nicID)
}
select {
case e := <-ndpDisp.prefixC:
if diff := checkPrefixEvent(e, subnet, true /* discovered */); diff != "" {
t.Errorf("router event mismatch (-want +got):\n%s", diff)
t.Errorf("off-link route event mismatch (-want +got):\n%s", diff)
}
default:
t.Errorf("expected prefix event for %s on NIC(%d)", prefix, nicID)
@@ -4689,8 +4692,8 @@ func TestNoCleanupNDPStateWhenForwardingEnabled(t *testing.T) {
t.Fatalf("SetForwardingDefaultAndAllNICs(%d, %t): %s", ipv6.ProtocolNumber, forwarding, err)
}
select {
case e := <-ndpDisp.routerC:
t.Errorf("unexpected router event = %#v", e)
case e := <-ndpDisp.offLinkRouteC:
t.Errorf("unexpected off-link route event = %#v", e)
default:
}
select {
@@ -4776,9 +4779,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),
prefixC: make(chan ndpPrefixEvent, maxRouterAndPrefixEvents),
autoGenAddrC: make(chan ndpAutoGenAddrEvent, test.maxAutoGenAddrEvents),
offLinkRouteC: make(chan ndpOffLinkRouteEvent, maxRouterAndPrefixEvents),
prefixC: make(chan ndpPrefixEvent, maxRouterAndPrefixEvents),
autoGenAddrC: make(chan ndpAutoGenAddrEvent, test.maxAutoGenAddrEvents),
}
clock := faketime.NewManualClock()
s := stack.New(stack.Options{
@@ -4795,14 +4798,14 @@ func TestCleanupNDPState(t *testing.T) {
Clock: clock,
})
expectRouterEvent := func() (bool, ndpRouterEvent) {
expectOffLinkRouteEvent := func() (bool, ndpOffLinkRouteEvent) {
select {
case e := <-ndpDisp.routerC:
case e := <-ndpDisp.offLinkRouteC:
return true, e
default:
}
return false, ndpRouterEvent{}
return false, ndpOffLinkRouteEvent{}
}
expectPrefixEvent := func() (bool, ndpPrefixEvent) {
@@ -4847,8 +4850,8 @@ func TestCleanupNDPState(t *testing.T) {
// multiple addresses.
e1.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr3, lifetimeSeconds, prefix1, true, true, lifetimeSeconds, lifetimeSeconds))
if ok, _ := expectRouterEvent(); !ok {
t.Errorf("expected router event for %s on NIC(%d)", llAddr3, nicID1)
if ok, _ := expectOffLinkRouteEvent(); !ok {
t.Errorf("expected off-link route event for %s on NIC(%d)", llAddr3, nicID1)
}
if ok, _ := expectPrefixEvent(); !ok {
t.Errorf("expected prefix event for %s on NIC(%d)", prefix1, nicID1)
@@ -4858,8 +4861,8 @@ func TestCleanupNDPState(t *testing.T) {
}
e1.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr4, lifetimeSeconds, prefix2, true, true, lifetimeSeconds, lifetimeSeconds))
if ok, _ := expectRouterEvent(); !ok {
t.Errorf("expected router event for %s on NIC(%d)", llAddr4, nicID1)
if ok, _ := expectOffLinkRouteEvent(); !ok {
t.Errorf("expected off-link route event for %s on NIC(%d)", llAddr4, nicID1)
}
if ok, _ := expectPrefixEvent(); !ok {
t.Errorf("expected prefix event for %s on NIC(%d)", prefix2, nicID1)
@@ -4869,8 +4872,8 @@ func TestCleanupNDPState(t *testing.T) {
}
e2.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr3, lifetimeSeconds, prefix1, true, true, lifetimeSeconds, lifetimeSeconds))
if ok, _ := expectRouterEvent(); !ok {
t.Errorf("expected router event for %s on NIC(%d)", llAddr3, nicID2)
if ok, _ := expectOffLinkRouteEvent(); !ok {
t.Errorf("expected off-link route event for %s on NIC(%d)", llAddr3, nicID2)
}
if ok, _ := expectPrefixEvent(); !ok {
t.Errorf("expected prefix event for %s on NIC(%d)", prefix1, nicID2)
@@ -4880,8 +4883,8 @@ func TestCleanupNDPState(t *testing.T) {
}
e2.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr4, lifetimeSeconds, prefix2, true, true, lifetimeSeconds, lifetimeSeconds))
if ok, _ := expectRouterEvent(); !ok {
t.Errorf("expected router event for %s on NIC(%d)", llAddr4, nicID2)
if ok, _ := expectOffLinkRouteEvent(); !ok {
t.Errorf("expected off-link route event for %s on NIC(%d)", llAddr4, nicID2)
}
if ok, _ := expectPrefixEvent(); !ok {
t.Errorf("expected prefix event for %s on NIC(%d)", prefix2, nicID2)
@@ -4922,14 +4925,14 @@ func TestCleanupNDPState(t *testing.T) {
test.cleanupFn(t, s)
// Collect invalidation events after having NDP state cleaned up.
gotRouterEvents := make(map[ndpRouterEvent]int)
gotOffLinkRouteEvents := make(map[ndpOffLinkRouteEvent]int)
for i := 0; i < maxRouterAndPrefixEvents; i++ {
ok, e := expectRouterEvent()
ok, e := expectOffLinkRouteEvent()
if !ok {
t.Errorf("expected %d router events after becoming a router; got = %d", maxRouterAndPrefixEvents, i)
t.Errorf("expected %d off-link route events after becoming a router; got = %d", maxRouterAndPrefixEvents, i)
break
}
gotRouterEvents[e]++
gotOffLinkRouteEvents[e]++
}
gotPrefixEvents := make(map[ndpPrefixEvent]int)
for i := 0; i < maxRouterAndPrefixEvents; i++ {
@@ -4956,14 +4959,14 @@ func TestCleanupNDPState(t *testing.T) {
t.FailNow()
}
expectedRouterEvents := map[ndpRouterEvent]int{
{nicID: nicID1, addr: llAddr3, discovered: false}: 1,
{nicID: nicID1, addr: llAddr4, discovered: false}: 1,
{nicID: nicID2, addr: llAddr3, discovered: false}: 1,
{nicID: nicID2, addr: llAddr4, discovered: false}: 1,
expectedOffLinkRouteEvents := map[ndpOffLinkRouteEvent]int{
{nicID: nicID1, subnet: header.IPv6EmptySubnet, router: llAddr3, updated: false}: 1,
{nicID: nicID1, subnet: header.IPv6EmptySubnet, router: llAddr4, updated: false}: 1,
{nicID: nicID2, subnet: header.IPv6EmptySubnet, router: llAddr3, updated: false}: 1,
{nicID: nicID2, subnet: header.IPv6EmptySubnet, router: llAddr4, updated: false}: 1,
}
if diff := cmp.Diff(expectedRouterEvents, gotRouterEvents); diff != "" {
t.Errorf("router events mismatch (-want +got):\n%s", diff)
if diff := cmp.Diff(expectedOffLinkRouteEvents, gotOffLinkRouteEvents); diff != "" {
t.Errorf("off-link route events mismatch (-want +got):\n%s", diff)
}
expectedPrefixEvents := map[ndpPrefixEvent]int{
{nicID: nicID1, prefix: subnet1, discovered: false}: 1,
@@ -5027,8 +5030,8 @@ func TestCleanupNDPState(t *testing.T) {
// cancelled when the NDP state was cleaned up).
clock.Advance(lifetimeSeconds * time.Second)
select {
case <-ndpDisp.routerC:
t.Error("unexpected router event")
case <-ndpDisp.offLinkRouteC:
t.Error("unexpected off-link route event")
default:
}
select {
+2 -2
View File
@@ -44,10 +44,10 @@ type ndpDispatcher struct{}
func (*ndpDispatcher) OnDuplicateAddressDetectionResult(tcpip.NICID, tcpip.Address, stack.DADResult) {
}
func (*ndpDispatcher) OnDefaultRouterDiscovered(tcpip.NICID, tcpip.Address) {
func (*ndpDispatcher) OnOffLinkRouteUpdated(tcpip.NICID, tcpip.Subnet, tcpip.Address) {
}
func (*ndpDispatcher) OnDefaultRouterInvalidated(tcpip.NICID, tcpip.Address) {}
func (*ndpDispatcher) OnOffLinkRouteInvalidated(tcpip.NICID, tcpip.Subnet, tcpip.Address) {}
func (*ndpDispatcher) OnOnLinkPrefixDiscovered(tcpip.NICID, tcpip.Subnet) {
}