gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/pkg/tcpip/stack/ndp_test.go (about)

     1  // Copyright 2019 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package stack_test
    16  
    17  import (
    18  	"encoding/binary"
    19  	"fmt"
    20  	"math"
    21  	"math/rand"
    22  	"testing"
    23  	"time"
    24  
    25  	"github.com/google/go-cmp/cmp"
    26  	"gvisor.dev/gvisor/pkg/buffer"
    27  	cryptorand "gvisor.dev/gvisor/pkg/rand"
    28  	"gvisor.dev/gvisor/pkg/tcpip"
    29  	"gvisor.dev/gvisor/pkg/tcpip/checker"
    30  	"gvisor.dev/gvisor/pkg/tcpip/faketime"
    31  	"gvisor.dev/gvisor/pkg/tcpip/header"
    32  	"gvisor.dev/gvisor/pkg/tcpip/link/channel"
    33  	"gvisor.dev/gvisor/pkg/tcpip/link/loopback"
    34  	"gvisor.dev/gvisor/pkg/tcpip/network/ipv6"
    35  	"gvisor.dev/gvisor/pkg/tcpip/prependable"
    36  	"gvisor.dev/gvisor/pkg/tcpip/stack"
    37  	"gvisor.dev/gvisor/pkg/tcpip/testutil"
    38  	"gvisor.dev/gvisor/pkg/tcpip/transport/icmp"
    39  	"gvisor.dev/gvisor/pkg/tcpip/transport/udp"
    40  	"gvisor.dev/gvisor/pkg/waiter"
    41  )
    42  
    43  var (
    44  	addr1 = testutil.MustParse6("a00::1")
    45  	addr2 = testutil.MustParse6("a00::2")
    46  	addr3 = testutil.MustParse6("a00::3")
    47  )
    48  
    49  const (
    50  	linkAddr1 = tcpip.LinkAddress("\x02\x02\x03\x04\x05\x06")
    51  	linkAddr2 = tcpip.LinkAddress("\x02\x02\x03\x04\x05\x07")
    52  	linkAddr3 = tcpip.LinkAddress("\x02\x02\x03\x04\x05\x08")
    53  	linkAddr4 = tcpip.LinkAddress("\x02\x02\x03\x04\x05\x09")
    54  
    55  	defaultPrefixLen  = 128
    56  	infiniteVLSeconds = math.MaxUint32
    57  )
    58  
    59  var (
    60  	llAddr1 = header.LinkLocalAddr(linkAddr1)
    61  	llAddr2 = header.LinkLocalAddr(linkAddr2)
    62  	llAddr3 = header.LinkLocalAddr(linkAddr3)
    63  	llAddr4 = header.LinkLocalAddr(linkAddr4)
    64  	dstAddr = tcpip.FullAddress{
    65  		Addr: tcpip.AddrFromSlice([]byte("\x0a\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01")),
    66  		Port: 25,
    67  	}
    68  )
    69  
    70  func addrForSubnet(subnet tcpip.Subnet, linkAddr tcpip.LinkAddress) tcpip.AddressWithPrefix {
    71  	if !header.IsValidUnicastEthernetAddress(linkAddr) {
    72  		return tcpip.AddressWithPrefix{}
    73  	}
    74  
    75  	subnetID := subnet.ID()
    76  	addrBytes := subnetID.AsSlice()
    77  	header.EthernetAdddressToModifiedEUI64IntoBuf(linkAddr, addrBytes[header.IIDOffsetInIPv6Address:])
    78  	return tcpip.AddressWithPrefix{
    79  		Address:   tcpip.AddrFromSlice(addrBytes),
    80  		PrefixLen: 64,
    81  	}
    82  }
    83  
    84  // prefixSubnetAddr returns a prefix (Address + Length), the prefix's equivalent
    85  // tcpip.Subnet, and an address where the lower half of the address is composed
    86  // of the EUI-64 of linkAddr if it is a valid unicast ethernet address.
    87  func prefixSubnetAddr(offset uint8, linkAddr tcpip.LinkAddress) (tcpip.AddressWithPrefix, tcpip.Subnet, tcpip.AddressWithPrefix) {
    88  	prefixBytes := []byte{1, 2, 3, 4, 5, 6, 7, 8 + offset, 0, 0, 0, 0, 0, 0, 0, 0}
    89  	prefix := tcpip.AddressWithPrefix{
    90  		Address:   tcpip.AddrFrom16Slice(prefixBytes),
    91  		PrefixLen: 64,
    92  	}
    93  
    94  	subnet := prefix.Subnet()
    95  
    96  	return prefix, subnet, addrForSubnet(subnet, linkAddr)
    97  }
    98  
    99  // ndpDADEvent is a set of parameters that was passed to
   100  // ndpDispatcher.OnDuplicateAddressDetectionResult.
   101  type ndpDADEvent struct {
   102  	nicID tcpip.NICID
   103  	addr  tcpip.Address
   104  	res   stack.DADResult
   105  }
   106  
   107  type ndpOffLinkRouteEvent struct {
   108  	nicID  tcpip.NICID
   109  	subnet tcpip.Subnet
   110  	router tcpip.Address
   111  	prf    header.NDPRoutePreference
   112  	// true if route was updated, false if invalidated.
   113  	updated bool
   114  }
   115  
   116  type ndpPrefixEvent struct {
   117  	nicID  tcpip.NICID
   118  	prefix tcpip.Subnet
   119  	// true if prefix was discovered, false if invalidated.
   120  	discovered bool
   121  }
   122  
   123  type ndpAutoGenAddrNewEvent struct {
   124  	nicID    tcpip.NICID
   125  	addr     tcpip.AddressWithPrefix
   126  	addrDisp *addressDispatcher
   127  }
   128  
   129  type ndpAutoGenAddrEventType int
   130  
   131  const (
   132  	deprecatedAddr ndpAutoGenAddrEventType = iota
   133  	invalidatedAddr
   134  )
   135  
   136  type ndpAutoGenAddrEvent struct {
   137  	nicID     tcpip.NICID
   138  	addr      tcpip.AddressWithPrefix
   139  	eventType ndpAutoGenAddrEventType
   140  }
   141  
   142  func (e ndpAutoGenAddrEvent) String() string {
   143  	return fmt.Sprintf("%T{nicID=%d addr=%s eventType=%d}", e, e.nicID, e.addr, e.eventType)
   144  }
   145  
   146  type ndpRDNSS struct {
   147  	addrs    []tcpip.Address
   148  	lifetime time.Duration
   149  }
   150  
   151  type ndpRDNSSEvent struct {
   152  	nicID tcpip.NICID
   153  	rdnss ndpRDNSS
   154  }
   155  
   156  type ndpDNSSLEvent struct {
   157  	nicID       tcpip.NICID
   158  	domainNames []string
   159  	lifetime    time.Duration
   160  }
   161  
   162  type ndpDHCPv6Event struct {
   163  	nicID         tcpip.NICID
   164  	configuration ipv6.DHCPv6ConfigurationFromNDPRA
   165  }
   166  
   167  var _ ipv6.NDPDispatcher = (*ndpDispatcher)(nil)
   168  
   169  // ndpDispatcher implements NDPDispatcher so tests can know when various NDP
   170  // related events happen for test purposes.
   171  type ndpDispatcher struct {
   172  	dadC            chan ndpDADEvent
   173  	offLinkRouteC   chan ndpOffLinkRouteEvent
   174  	prefixC         chan ndpPrefixEvent
   175  	autoGenAddrC    chan ndpAutoGenAddrEvent
   176  	autoGenAddrNewC chan ndpAutoGenAddrNewEvent
   177  	// autoGenInstallDisp controls whether address dispatchers are installed for
   178  	// new auto-generated addresses.
   179  	autoGenInstallDisp   bool
   180  	rdnssC               chan ndpRDNSSEvent
   181  	dnsslC               chan ndpDNSSLEvent
   182  	routeTable           []tcpip.Route
   183  	dhcpv6ConfigurationC chan ndpDHCPv6Event
   184  }
   185  
   186  // Implements ipv6.NDPDispatcher.OnDuplicateAddressDetectionResult.
   187  func (n *ndpDispatcher) OnDuplicateAddressDetectionResult(nicID tcpip.NICID, addr tcpip.Address, res stack.DADResult) {
   188  	if n.dadC != nil {
   189  		n.dadC <- ndpDADEvent{
   190  			nicID,
   191  			addr,
   192  			res,
   193  		}
   194  	}
   195  }
   196  
   197  // Implements ipv6.NDPDispatcher.OnOffLinkRouteUpdated.
   198  func (n *ndpDispatcher) OnOffLinkRouteUpdated(nicID tcpip.NICID, subnet tcpip.Subnet, router tcpip.Address, prf header.NDPRoutePreference) {
   199  	if c := n.offLinkRouteC; c != nil {
   200  		c <- ndpOffLinkRouteEvent{
   201  			nicID,
   202  			subnet,
   203  			router,
   204  			prf,
   205  			true,
   206  		}
   207  	}
   208  }
   209  
   210  // Implements ipv6.NDPDispatcher.OnOffLinkRouteInvalidated.
   211  func (n *ndpDispatcher) OnOffLinkRouteInvalidated(nicID tcpip.NICID, subnet tcpip.Subnet, router tcpip.Address) {
   212  	if c := n.offLinkRouteC; c != nil {
   213  		var prf header.NDPRoutePreference
   214  		c <- ndpOffLinkRouteEvent{
   215  			nicID,
   216  			subnet,
   217  			router,
   218  			prf,
   219  			false,
   220  		}
   221  	}
   222  }
   223  
   224  // Implements ipv6.NDPDispatcher.OnOnLinkPrefixDiscovered.
   225  func (n *ndpDispatcher) OnOnLinkPrefixDiscovered(nicID tcpip.NICID, prefix tcpip.Subnet) {
   226  	if c := n.prefixC; c != nil {
   227  		c <- ndpPrefixEvent{
   228  			nicID,
   229  			prefix,
   230  			true,
   231  		}
   232  	}
   233  }
   234  
   235  // Implements ipv6.NDPDispatcher.OnOnLinkPrefixInvalidated.
   236  func (n *ndpDispatcher) OnOnLinkPrefixInvalidated(nicID tcpip.NICID, prefix tcpip.Subnet) {
   237  	if c := n.prefixC; c != nil {
   238  		c <- ndpPrefixEvent{
   239  			nicID,
   240  			prefix,
   241  			false,
   242  		}
   243  	}
   244  }
   245  
   246  func (n *ndpDispatcher) OnAutoGenAddress(nicID tcpip.NICID, addr tcpip.AddressWithPrefix) stack.AddressDispatcher {
   247  	if c := n.autoGenAddrNewC; c != nil {
   248  		e := ndpAutoGenAddrNewEvent{
   249  			nicID,
   250  			addr,
   251  			nil,
   252  		}
   253  		if n.autoGenInstallDisp {
   254  			e.addrDisp = &addressDispatcher{
   255  				changedCh: make(chan addressChangedEvent, 1),
   256  				removedCh: make(chan stack.AddressRemovalReason, 1),
   257  				nicid:     nicID,
   258  				addr:      addr,
   259  			}
   260  		}
   261  		c <- e
   262  		if n.autoGenInstallDisp {
   263  			return e.addrDisp
   264  		}
   265  	}
   266  	return nil
   267  }
   268  
   269  func (n *ndpDispatcher) OnAutoGenAddressDeprecated(nicID tcpip.NICID, addr tcpip.AddressWithPrefix) {
   270  	if c := n.autoGenAddrC; c != nil {
   271  		c <- ndpAutoGenAddrEvent{
   272  			nicID,
   273  			addr,
   274  			deprecatedAddr,
   275  		}
   276  	}
   277  }
   278  
   279  func (n *ndpDispatcher) OnAutoGenAddressInvalidated(nicID tcpip.NICID, addr tcpip.AddressWithPrefix) {
   280  	if c := n.autoGenAddrC; c != nil {
   281  		c <- ndpAutoGenAddrEvent{
   282  			nicID,
   283  			addr,
   284  			invalidatedAddr,
   285  		}
   286  	}
   287  }
   288  
   289  // Implements ipv6.NDPDispatcher.OnRecursiveDNSServerOption.
   290  func (n *ndpDispatcher) OnRecursiveDNSServerOption(nicID tcpip.NICID, addrs []tcpip.Address, lifetime time.Duration) {
   291  	if c := n.rdnssC; c != nil {
   292  		c <- ndpRDNSSEvent{
   293  			nicID,
   294  			ndpRDNSS{
   295  				addrs,
   296  				lifetime,
   297  			},
   298  		}
   299  	}
   300  }
   301  
   302  // Implements ipv6.NDPDispatcher.OnDNSSearchListOption.
   303  func (n *ndpDispatcher) OnDNSSearchListOption(nicID tcpip.NICID, domainNames []string, lifetime time.Duration) {
   304  	if n.dnsslC != nil {
   305  		n.dnsslC <- ndpDNSSLEvent{
   306  			nicID,
   307  			domainNames,
   308  			lifetime,
   309  		}
   310  	}
   311  }
   312  
   313  // Implements ipv6.NDPDispatcher.OnDHCPv6Configuration.
   314  func (n *ndpDispatcher) OnDHCPv6Configuration(nicID tcpip.NICID, configuration ipv6.DHCPv6ConfigurationFromNDPRA) {
   315  	if c := n.dhcpv6ConfigurationC; c != nil {
   316  		c <- ndpDHCPv6Event{
   317  			nicID,
   318  			configuration,
   319  		}
   320  	}
   321  }
   322  
   323  // channelLinkWithHeaderLength is a channel.Endpoint with a configurable
   324  // header length.
   325  type channelLinkWithHeaderLength struct {
   326  	*channel.Endpoint
   327  	headerLength uint16
   328  }
   329  
   330  func (l *channelLinkWithHeaderLength) MaxHeaderLength() uint16 {
   331  	return l.headerLength
   332  }
   333  
   334  // Check e to make sure that the event is for addr on nic with ID 1, and the
   335  // resolved flag set to resolved with the specified err.
   336  func checkDADEvent(e ndpDADEvent, nicID tcpip.NICID, addr tcpip.Address, res stack.DADResult) string {
   337  	return cmp.Diff(ndpDADEvent{nicID: nicID, addr: addr, res: res}, e, cmp.AllowUnexported(e))
   338  }
   339  
   340  // addressLifetimes returns address lifetimes computed by adding pl and vl
   341  // from the reference time.
   342  //
   343  // If pl is 0, the returned lifetimes will be deprecated and have a zero value
   344  // for the PreferredUntil field.
   345  //
   346  // If vl is infinite, the returned lifetimes will contain a maximal ValidUntil
   347  // value.
   348  func addressLifetimes(received tcpip.MonotonicTime, pl, vl uint32) stack.AddressLifetimes {
   349  	var preferredUntil, validUntil tcpip.MonotonicTime
   350  	if pl > 0 {
   351  		preferredUntil = received.Add(time.Duration(pl) * time.Second)
   352  	}
   353  	if vl == math.MaxUint32 {
   354  		validUntil = tcpip.MonotonicTimeInfinite()
   355  	} else {
   356  		validUntil = received.Add(time.Duration(vl) * time.Second)
   357  	}
   358  	return stack.AddressLifetimes{
   359  		Deprecated:     pl == 0,
   360  		PreferredUntil: preferredUntil,
   361  		ValidUntil:     validUntil,
   362  	}
   363  }
   364  
   365  // TestDADDisabled tests that an address successfully resolves immediately
   366  // when DAD is not enabled (the default for an empty stack.Options).
   367  func TestDADDisabled(t *testing.T) {
   368  	const nicID = 1
   369  	ndpDisp := ndpDispatcher{
   370  		dadC: make(chan ndpDADEvent, 1),
   371  	}
   372  	e := channel.New(0, 1280, linkAddr1)
   373  	s := stack.New(stack.Options{
   374  		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
   375  			NDPDisp: &ndpDisp,
   376  		})},
   377  	})
   378  	if err := s.CreateNIC(nicID, e); err != nil {
   379  		t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
   380  	}
   381  
   382  	addrWithPrefix := tcpip.AddressWithPrefix{
   383  		Address:   addr1,
   384  		PrefixLen: defaultPrefixLen,
   385  	}
   386  	protocolAddr := tcpip.ProtocolAddress{
   387  		Protocol:          header.IPv6ProtocolNumber,
   388  		AddressWithPrefix: addrWithPrefix,
   389  	}
   390  	addrDisp := &addressDispatcher{
   391  		changedCh: make(chan addressChangedEvent, 1),
   392  		nicid:     nicID,
   393  		addr:      addrWithPrefix,
   394  	}
   395  	properties := stack.AddressProperties{
   396  		Disp: addrDisp,
   397  	}
   398  	if err := s.AddProtocolAddress(nicID, protocolAddr, properties); err != nil {
   399  		t.Fatalf("AddProtocolAddress(%d, %+v, %#v) = %s", nicID, protocolAddr, properties, err)
   400  	}
   401  
   402  	// Should get the address immediately since we should not have performed
   403  	// DAD on it.
   404  	select {
   405  	case e := <-ndpDisp.dadC:
   406  		if diff := checkDADEvent(e, nicID, addr1, &stack.DADSucceeded{}); diff != "" {
   407  			t.Errorf("DAD event mismatch (-want +got):\n%s", diff)
   408  		}
   409  	default:
   410  		t.Fatal("expected DAD event")
   411  	}
   412  	if err := addrDisp.expectChanged(stack.AddressLifetimes{}, stack.AddressAssigned); err != nil {
   413  		t.Error(err)
   414  	}
   415  	if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, addrWithPrefix); err != nil {
   416  		t.Fatal(err)
   417  	}
   418  
   419  	// We should not have sent any NDP NS messages.
   420  	if got := s.Stats().ICMP.V6.PacketsSent.NeighborSolicit.Value(); got != 0 {
   421  		t.Fatalf("got NeighborSolicit = %d, want = 0", got)
   422  	}
   423  }
   424  
   425  func TestDADResolveLoopback(t *testing.T) {
   426  	const nicID = 1
   427  	ndpDisp := ndpDispatcher{
   428  		dadC: make(chan ndpDADEvent, 1),
   429  	}
   430  
   431  	dadConfigs := stack.DADConfigurations{
   432  		RetransmitTimer:        time.Second,
   433  		DupAddrDetectTransmits: 1,
   434  	}
   435  	clock := faketime.NewManualClock()
   436  	s := stack.New(stack.Options{
   437  		Clock: clock,
   438  		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
   439  			NDPDisp:    &ndpDisp,
   440  			DADConfigs: dadConfigs,
   441  		})},
   442  	})
   443  	if err := s.CreateNIC(nicID, loopback.New()); err != nil {
   444  		t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
   445  	}
   446  
   447  	addrWithPrefix := tcpip.AddressWithPrefix{
   448  		Address:   addr1,
   449  		PrefixLen: defaultPrefixLen,
   450  	}
   451  	addrDisp := &addressDispatcher{
   452  		nicid:     nicID,
   453  		addr:      addrWithPrefix,
   454  		changedCh: make(chan addressChangedEvent, 1),
   455  	}
   456  	properties := stack.AddressProperties{
   457  		Disp: addrDisp,
   458  	}
   459  	protocolAddr := tcpip.ProtocolAddress{
   460  		Protocol:          header.IPv6ProtocolNumber,
   461  		AddressWithPrefix: addrWithPrefix,
   462  	}
   463  	if err := s.AddProtocolAddress(nicID, protocolAddr, properties); err != nil {
   464  		t.Fatalf("AddProtocolAddress(%d, %+v, %#v) = %s", nicID, protocolAddr, properties, err)
   465  	}
   466  
   467  	// Address should not be considered bound to the NIC yet (DAD ongoing).
   468  	if err := addrDisp.expectChanged(stack.AddressLifetimes{}, stack.AddressTentative); err != nil {
   469  		t.Error(err)
   470  	}
   471  	if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil {
   472  		t.Fatal(err)
   473  	}
   474  
   475  	// DAD should not resolve after the normal resolution time since our DAD
   476  	// message was looped back - we should extend our DAD process.
   477  	dadResolutionTime := time.Duration(dadConfigs.DupAddrDetectTransmits) * dadConfigs.RetransmitTimer
   478  	clock.Advance(dadResolutionTime)
   479  	if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil {
   480  		t.Error(err)
   481  	}
   482  
   483  	// Make sure the address does not resolve before the extended resolution time
   484  	// has passed.
   485  	const delta = time.Nanosecond
   486  	// DAD will send extra NS probes if an NS message is looped back.
   487  	const extraTransmits = 3
   488  	clock.Advance(dadResolutionTime*extraTransmits - delta)
   489  	if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil {
   490  		t.Error(err)
   491  	}
   492  
   493  	// DAD should now resolve.
   494  	clock.Advance(delta)
   495  	if diff := checkDADEvent(<-ndpDisp.dadC, nicID, addr1, &stack.DADSucceeded{}); diff != "" {
   496  		t.Errorf("DAD event mismatch (-want +got):\n%s", diff)
   497  	}
   498  	if err := addrDisp.expectStateChanged(stack.AddressAssigned); err != nil {
   499  		t.Error(err)
   500  	}
   501  }
   502  
   503  // TestDADResolve tests that an address successfully resolves after performing
   504  // DAD for various values of DupAddrDetectTransmits and RetransmitTimer.
   505  // Included in the subtests is a test to make sure that an invalid
   506  // RetransmitTimer (<1ms) values get fixed to the default RetransmitTimer of 1s.
   507  // This tests also validates the NDP NS packet that is transmitted.
   508  func TestDADResolve(t *testing.T) {
   509  	const nicID = 1
   510  
   511  	tests := []struct {
   512  		name                    string
   513  		linkHeaderLen           uint16
   514  		dupAddrDetectTransmits  uint8
   515  		retransTimer            time.Duration
   516  		expectedRetransmitTimer time.Duration
   517  	}{
   518  		{
   519  			name:                    "1:1s:1s",
   520  			dupAddrDetectTransmits:  1,
   521  			retransTimer:            time.Second,
   522  			expectedRetransmitTimer: time.Second,
   523  		},
   524  		{
   525  			name:                    "2:1s:1s",
   526  			linkHeaderLen:           1,
   527  			dupAddrDetectTransmits:  2,
   528  			retransTimer:            time.Second,
   529  			expectedRetransmitTimer: time.Second,
   530  		},
   531  		{
   532  			name:                    "1:2s:2s",
   533  			linkHeaderLen:           2,
   534  			dupAddrDetectTransmits:  1,
   535  			retransTimer:            2 * time.Second,
   536  			expectedRetransmitTimer: 2 * time.Second,
   537  		},
   538  		// 0s is an invalid RetransmitTimer timer and will be fixed to
   539  		// the default RetransmitTimer value of 1s.
   540  		{
   541  			name:                    "1:0s:1s",
   542  			linkHeaderLen:           3,
   543  			dupAddrDetectTransmits:  1,
   544  			retransTimer:            0,
   545  			expectedRetransmitTimer: time.Second,
   546  		},
   547  	}
   548  
   549  	for _, test := range tests {
   550  		t.Run(test.name, func(t *testing.T) {
   551  			ndpDisp := ndpDispatcher{
   552  				dadC: make(chan ndpDADEvent, 1),
   553  			}
   554  			e := channelLinkWithHeaderLength{
   555  				Endpoint:     channel.New(int(test.dupAddrDetectTransmits), 1280, linkAddr1),
   556  				headerLength: test.linkHeaderLen,
   557  			}
   558  			e.Endpoint.LinkEPCapabilities |= stack.CapabilityResolutionRequired
   559  
   560  			clock := faketime.NewManualClock()
   561  			s := stack.New(stack.Options{
   562  				Clock:      clock,
   563  				RandSource: rand.NewSource(time.Now().UnixNano()),
   564  				NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
   565  					NDPDisp: &ndpDisp,
   566  					DADConfigs: stack.DADConfigurations{
   567  						RetransmitTimer:        test.retransTimer,
   568  						DupAddrDetectTransmits: test.dupAddrDetectTransmits,
   569  					},
   570  				})},
   571  			})
   572  			if err := s.CreateNIC(nicID, &e); err != nil {
   573  				t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
   574  			}
   575  
   576  			// We add a default route so the call to FindRoute below will succeed
   577  			// once we have an assigned address.
   578  			s.SetRouteTable([]tcpip.Route{{
   579  				Destination: header.IPv6EmptySubnet,
   580  				Gateway:     addr3,
   581  				NIC:         nicID,
   582  			}})
   583  
   584  			addrWithPrefix := tcpip.AddressWithPrefix{
   585  				Address:   addr1,
   586  				PrefixLen: defaultPrefixLen,
   587  			}
   588  			addrDisp := &addressDispatcher{
   589  				nicid:     nicID,
   590  				addr:      addrWithPrefix,
   591  				changedCh: make(chan addressChangedEvent, 1),
   592  			}
   593  			protocolAddr := tcpip.ProtocolAddress{
   594  				Protocol:          header.IPv6ProtocolNumber,
   595  				AddressWithPrefix: addrWithPrefix,
   596  			}
   597  			if err := s.AddProtocolAddress(nicID, protocolAddr, stack.AddressProperties{Disp: addrDisp}); err != nil {
   598  				t.Fatalf("AddProtocolAddress(%d, %+v, {}) = %s", nicID, protocolAddr, err)
   599  			}
   600  			if err := addrDisp.expectChanged(stack.AddressLifetimes{}, stack.AddressTentative); err != nil {
   601  				t.Error(err)
   602  			}
   603  
   604  			// Make sure the address does not resolve before the resolution time has
   605  			// passed.
   606  			const delta = time.Nanosecond
   607  			clock.Advance(test.expectedRetransmitTimer*time.Duration(test.dupAddrDetectTransmits) - delta)
   608  			if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil {
   609  				t.Error(err)
   610  			}
   611  			// Should not get a route even if we specify the local address as the
   612  			// tentative address.
   613  			{
   614  				r, err := s.FindRoute(nicID, tcpip.Address{}, addr2, header.IPv6ProtocolNumber, false)
   615  				if _, ok := err.(*tcpip.ErrHostUnreachable); !ok {
   616  					t.Errorf("got FindRoute(%d, '', %s, %d, false) = (%+v, %v), want = (_, %s)", nicID, addr2, header.IPv6ProtocolNumber, r, err, &tcpip.ErrHostUnreachable{})
   617  				}
   618  				if r != nil {
   619  					r.Release()
   620  				}
   621  			}
   622  			{
   623  				r, err := s.FindRoute(nicID, addr1, addr2, header.IPv6ProtocolNumber, false)
   624  				if _, ok := err.(*tcpip.ErrHostUnreachable); !ok {
   625  					t.Errorf("got FindRoute(%d, %s, %s, %d, false) = (%+v, %v), want = (_, %s)", nicID, addr1, addr2, header.IPv6ProtocolNumber, r, err, &tcpip.ErrHostUnreachable{})
   626  				}
   627  				if r != nil {
   628  					r.Release()
   629  				}
   630  			}
   631  
   632  			if t.Failed() {
   633  				t.FailNow()
   634  			}
   635  
   636  			// Wait for DAD to resolve.
   637  			clock.Advance(delta)
   638  			select {
   639  			case e := <-ndpDisp.dadC:
   640  				if diff := checkDADEvent(e, nicID, addr1, &stack.DADSucceeded{}); diff != "" {
   641  					t.Errorf("DAD event mismatch (-want +got):\n%s", diff)
   642  				}
   643  			default:
   644  				t.Fatalf("expected DAD event for %s on NIC(%d)", addr1, nicID)
   645  			}
   646  			if err := addrDisp.expectStateChanged(stack.AddressAssigned); err != nil {
   647  				t.Error(err)
   648  			}
   649  			if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, addrWithPrefix); err != nil {
   650  				t.Error(err)
   651  			}
   652  			// Should get a route using the address now that it is resolved.
   653  			{
   654  				r, err := s.FindRoute(nicID, tcpip.Address{}, addr2, header.IPv6ProtocolNumber, false)
   655  				if err != nil {
   656  					t.Errorf("got FindRoute(%d, '', %s, %d, false): %s", nicID, addr2, header.IPv6ProtocolNumber, err)
   657  				} else if r.LocalAddress() != addr1 {
   658  					t.Errorf("got r.LocalAddress() = %s, want = %s", r.LocalAddress(), addr1)
   659  				}
   660  				r.Release()
   661  			}
   662  			{
   663  				r, err := s.FindRoute(nicID, addr1, addr2, header.IPv6ProtocolNumber, false)
   664  				if err != nil {
   665  					t.Errorf("got FindRoute(%d, %s, %s, %d, false): %s", nicID, addr1, addr2, header.IPv6ProtocolNumber, err)
   666  				} else if r.LocalAddress() != addr1 {
   667  					t.Errorf("got r.LocalAddress() = %s, want = %s", r.LocalAddress(), addr1)
   668  				}
   669  				if r != nil {
   670  					r.Release()
   671  				}
   672  			}
   673  
   674  			if t.Failed() {
   675  				t.FailNow()
   676  			}
   677  
   678  			// Should not have sent any more NS messages.
   679  			if got := s.Stats().ICMP.V6.PacketsSent.NeighborSolicit.Value(); got != uint64(test.dupAddrDetectTransmits) {
   680  				t.Fatalf("got NeighborSolicit = %d, want = %d", got, test.dupAddrDetectTransmits)
   681  			}
   682  
   683  			// Validate the sent Neighbor Solicitation messages.
   684  			for i := uint8(0); i < test.dupAddrDetectTransmits; i++ {
   685  				p := e.Read()
   686  				if p == nil {
   687  					t.Fatal("packet didn't arrive")
   688  				}
   689  
   690  				// Make sure its an IPv6 packet.
   691  				if p.NetworkProtocolNumber != header.IPv6ProtocolNumber {
   692  					t.Fatalf("got Proto = %d, want = %d", p.NetworkProtocolNumber, header.IPv6ProtocolNumber)
   693  				}
   694  
   695  				// Make sure the right remote link address is used.
   696  				snmc := header.SolicitedNodeAddr(addr1)
   697  				if want := header.EthernetAddressFromMulticastIPv6Address(snmc); p.EgressRoute.RemoteLinkAddress != want {
   698  					t.Errorf("got remote link address = %s, want = %s", p.EgressRoute.RemoteLinkAddress, want)
   699  				}
   700  
   701  				// Check NDP NS packet.
   702  				//
   703  				// As per RFC 4861 section 4.3, a possible option is the Source Link
   704  				// Layer option, but this option MUST NOT be included when the source
   705  				// address of the packet is the unspecified address.
   706  				payload := stack.PayloadSince(p.NetworkHeader())
   707  				defer payload.Release()
   708  				checker.IPv6(t, payload,
   709  					checker.SrcAddr(header.IPv6Any),
   710  					checker.DstAddr(snmc),
   711  					checker.TTL(header.NDPHopLimit),
   712  					checker.NDPNS(
   713  						checker.NDPNSTargetAddress(addr1),
   714  					))
   715  
   716  				if l, want := p.AvailableHeaderBytes(), int(test.linkHeaderLen); l != want {
   717  					t.Errorf("got p.AvailableHeaderBytes() = %d; want = %d", l, want)
   718  				}
   719  				p.DecRef()
   720  			}
   721  		})
   722  	}
   723  }
   724  
   725  func rxNDPSolicit(e *channel.Endpoint, tgt tcpip.Address) {
   726  	hdr := prependable.New(header.IPv6MinimumSize + header.ICMPv6NeighborSolicitMinimumSize)
   727  	pkt := header.ICMPv6(hdr.Prepend(header.ICMPv6NeighborSolicitMinimumSize))
   728  	pkt.SetType(header.ICMPv6NeighborSolicit)
   729  	ns := header.NDPNeighborSolicit(pkt.MessageBody())
   730  	ns.SetTargetAddress(tgt)
   731  	snmc := header.SolicitedNodeAddr(tgt)
   732  	pkt.SetChecksum(header.ICMPv6Checksum(header.ICMPv6ChecksumParams{
   733  		Header: pkt,
   734  		Src:    header.IPv6Any,
   735  		Dst:    snmc,
   736  	}))
   737  	payloadLength := hdr.UsedLength()
   738  	ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize))
   739  	ip.Encode(&header.IPv6Fields{
   740  		PayloadLength:     uint16(payloadLength),
   741  		TransportProtocol: icmp.ProtocolNumber6,
   742  		HopLimit:          255,
   743  		SrcAddr:           header.IPv6Any,
   744  		DstAddr:           snmc,
   745  	})
   746  	e.InjectInbound(header.IPv6ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{Payload: buffer.MakeWithData(hdr.View())}))
   747  }
   748  
   749  // TestDADFail tests to make sure that the DAD process fails if another node is
   750  // detected to be performing DAD on the same address (receive an NS message from
   751  // a node doing DAD for the same address), or if another node is detected to own
   752  // the address already (receive an NA message for the tentative address).
   753  func TestDADFail(t *testing.T) {
   754  	const nicID = 1
   755  
   756  	tests := []struct {
   757  		name                      string
   758  		rxPkt                     func(e *channel.Endpoint, tgt tcpip.Address)
   759  		getStat                   func(s tcpip.ICMPv6ReceivedPacketStats) *tcpip.StatCounter
   760  		expectedHolderLinkAddress tcpip.LinkAddress
   761  	}{
   762  		{
   763  			name:  "RxSolicit",
   764  			rxPkt: rxNDPSolicit,
   765  			getStat: func(s tcpip.ICMPv6ReceivedPacketStats) *tcpip.StatCounter {
   766  				return s.NeighborSolicit
   767  			},
   768  			expectedHolderLinkAddress: "",
   769  		},
   770  		{
   771  			name: "RxAdvert",
   772  			rxPkt: func(e *channel.Endpoint, tgt tcpip.Address) {
   773  				naSize := header.ICMPv6NeighborAdvertMinimumSize + header.NDPLinkLayerAddressSize
   774  				hdr := prependable.New(header.IPv6MinimumSize + naSize)
   775  				pkt := header.ICMPv6(hdr.Prepend(naSize))
   776  				pkt.SetType(header.ICMPv6NeighborAdvert)
   777  				na := header.NDPNeighborAdvert(pkt.MessageBody())
   778  				na.SetSolicitedFlag(true)
   779  				na.SetOverrideFlag(true)
   780  				na.SetTargetAddress(tgt)
   781  				na.Options().Serialize(header.NDPOptionsSerializer{
   782  					header.NDPTargetLinkLayerAddressOption(linkAddr1),
   783  				})
   784  				pkt.SetChecksum(header.ICMPv6Checksum(header.ICMPv6ChecksumParams{
   785  					Header: pkt,
   786  					Src:    tgt,
   787  					Dst:    header.IPv6AllNodesMulticastAddress,
   788  				}))
   789  				payloadLength := hdr.UsedLength()
   790  				ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize))
   791  				ip.Encode(&header.IPv6Fields{
   792  					PayloadLength:     uint16(payloadLength),
   793  					TransportProtocol: icmp.ProtocolNumber6,
   794  					HopLimit:          255,
   795  					SrcAddr:           tgt,
   796  					DstAddr:           header.IPv6AllNodesMulticastAddress,
   797  				})
   798  				e.InjectInbound(header.IPv6ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{Payload: buffer.MakeWithData(hdr.View())}))
   799  			},
   800  			getStat: func(s tcpip.ICMPv6ReceivedPacketStats) *tcpip.StatCounter {
   801  				return s.NeighborAdvert
   802  			},
   803  			expectedHolderLinkAddress: linkAddr1,
   804  		},
   805  	}
   806  
   807  	for _, test := range tests {
   808  		t.Run(test.name, func(t *testing.T) {
   809  			ndpDisp := ndpDispatcher{
   810  				dadC: make(chan ndpDADEvent, 1),
   811  			}
   812  			dadConfigs := stack.DefaultDADConfigurations()
   813  			dadConfigs.RetransmitTimer = time.Second * 2
   814  
   815  			e := channel.New(0, 1280, linkAddr1)
   816  			clock := faketime.NewManualClock()
   817  			s := stack.New(stack.Options{
   818  				NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
   819  					NDPDisp:    &ndpDisp,
   820  					DADConfigs: dadConfigs,
   821  				})},
   822  				Clock: clock,
   823  			})
   824  			if err := s.CreateNIC(nicID, e); err != nil {
   825  				t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
   826  			}
   827  
   828  			addrDisp := &addressDispatcher{
   829  				changedCh: make(chan addressChangedEvent, 1),
   830  				removedCh: make(chan stack.AddressRemovalReason, 1),
   831  				nicid:     nicID,
   832  				addr:      addr1.WithPrefix(),
   833  			}
   834  			properties := stack.AddressProperties{
   835  				Disp: addrDisp,
   836  			}
   837  			protocolAddr := tcpip.ProtocolAddress{
   838  				Protocol:          header.IPv6ProtocolNumber,
   839  				AddressWithPrefix: addr1.WithPrefix(),
   840  			}
   841  			if err := s.AddProtocolAddress(nicID, protocolAddr, properties); err != nil {
   842  				t.Fatalf("AddProtocolAddress(%d, %+v, %#v): %s", nicID, protocolAddr, properties, err)
   843  			}
   844  			if err := addrDisp.expectChanged(stack.AddressLifetimes{}, stack.AddressTentative); err != nil {
   845  				t.Fatal(err)
   846  			}
   847  
   848  			// Address should not be considered bound to the NIC yet
   849  			// (DAD ongoing).
   850  			if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil {
   851  				t.Fatal(err)
   852  			}
   853  
   854  			// Receive a packet to simulate an address conflict.
   855  			test.rxPkt(e, addr1)
   856  
   857  			stat := test.getStat(s.Stats().ICMP.V6.PacketsReceived)
   858  			if got := stat.Value(); got != 1 {
   859  				t.Fatalf("got stat = %d, want = 1", got)
   860  			}
   861  
   862  			// Wait for DAD to fail and make sure the address did
   863  			// not get resolved.
   864  			clock.Advance(time.Duration(dadConfigs.DupAddrDetectTransmits) * dadConfigs.RetransmitTimer)
   865  			select {
   866  			case e := <-ndpDisp.dadC:
   867  				if diff := checkDADEvent(e, nicID, addr1, &stack.DADDupAddrDetected{HolderLinkAddress: test.expectedHolderLinkAddress}); diff != "" {
   868  					t.Errorf("DAD event mismatch (-want +got):\n%s", diff)
   869  				}
   870  			default:
   871  				// If we don't get a failure event after the
   872  				// expected resolution time + extra 1s buffer,
   873  				// something is wrong.
   874  				t.Fatal("timed out waiting for DAD failure")
   875  			}
   876  			if err := addrDisp.expectRemoved(stack.AddressRemovalDADFailed); err != nil {
   877  				t.Fatal(err)
   878  			}
   879  			if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil {
   880  				t.Fatal(err)
   881  			}
   882  
   883  			// Attempting to add the address again should not fail if the address's
   884  			// state was cleaned up when DAD failed.
   885  			if err := s.AddProtocolAddress(nicID, protocolAddr, stack.AddressProperties{}); err != nil {
   886  				t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", nicID, protocolAddr, err)
   887  			}
   888  		})
   889  	}
   890  }
   891  
   892  func TestDADStop(t *testing.T) {
   893  	const nicID = 1
   894  
   895  	tests := []struct {
   896  		name               string
   897  		stopFn             func(t *testing.T, s *stack.Stack)
   898  		verifyFn           func(t *testing.T, ad *addressDispatcher)
   899  		skipFinalAddrCheck bool
   900  	}{
   901  		// Tests to make sure that DAD stops when an address is removed.
   902  		{
   903  			name: "Remove address",
   904  			stopFn: func(t *testing.T, s *stack.Stack) {
   905  				if err := s.RemoveAddress(nicID, addr1); err != nil {
   906  					t.Fatalf("RemoveAddress(%d, %s): %s", nicID, addr1, err)
   907  				}
   908  			},
   909  			verifyFn: func(t *testing.T, ad *addressDispatcher) {
   910  				if err := ad.expectRemoved(stack.AddressRemovalManualAction); err != nil {
   911  					t.Error(err)
   912  				}
   913  			},
   914  		},
   915  
   916  		// Tests to make sure that DAD stops when the NIC is disabled.
   917  		{
   918  			name: "Disable NIC",
   919  			stopFn: func(t *testing.T, s *stack.Stack) {
   920  				if err := s.DisableNIC(nicID); err != nil {
   921  					t.Fatalf("DisableNIC(%d): %s", nicID, err)
   922  				}
   923  			},
   924  			verifyFn: func(t *testing.T, ad *addressDispatcher) {
   925  				if err := ad.expectStateChanged(stack.AddressDisabled); err != nil {
   926  					t.Error(err)
   927  				}
   928  			},
   929  		},
   930  
   931  		// Tests to make sure that DAD stops when the NIC is removed.
   932  		{
   933  			name: "Remove NIC",
   934  			stopFn: func(t *testing.T, s *stack.Stack) {
   935  				if err := s.RemoveNIC(nicID); err != nil {
   936  					t.Fatalf("RemoveNIC(%d): %s", nicID, err)
   937  				}
   938  			},
   939  			verifyFn: func(t *testing.T, ad *addressDispatcher) {
   940  				if err := ad.expectRemoved(stack.AddressRemovalInterfaceRemoved); err != nil {
   941  					t.Error(err)
   942  				}
   943  			},
   944  			// The NIC is removed so we can't check its addresses after calling
   945  			// stopFn.
   946  			skipFinalAddrCheck: true,
   947  		},
   948  	}
   949  
   950  	for _, test := range tests {
   951  		t.Run(test.name, func(t *testing.T) {
   952  			ndpDisp := ndpDispatcher{
   953  				dadC: make(chan ndpDADEvent, 1),
   954  			}
   955  
   956  			dadConfigs := stack.DADConfigurations{
   957  				RetransmitTimer:        time.Second,
   958  				DupAddrDetectTransmits: 2,
   959  			}
   960  
   961  			e := channel.New(0, 1280, linkAddr1)
   962  			clock := faketime.NewManualClock()
   963  			s := stack.New(stack.Options{
   964  				NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
   965  					NDPDisp:    &ndpDisp,
   966  					DADConfigs: dadConfigs,
   967  				})},
   968  				Clock: clock,
   969  			})
   970  			if err := s.CreateNIC(nicID, e); err != nil {
   971  				t.Fatalf("CreateNIC(%d, _): %s", nicID, err)
   972  			}
   973  
   974  			addrDisp := &addressDispatcher{
   975  				nicid:     nicID,
   976  				addr:      addr1.WithPrefix(),
   977  				changedCh: make(chan addressChangedEvent, 1),
   978  				removedCh: make(chan stack.AddressRemovalReason, 1),
   979  			}
   980  			properties := stack.AddressProperties{
   981  				Disp: addrDisp,
   982  			}
   983  			protocolAddr := tcpip.ProtocolAddress{
   984  				Protocol:          header.IPv6ProtocolNumber,
   985  				AddressWithPrefix: addr1.WithPrefix(),
   986  			}
   987  			if err := s.AddProtocolAddress(nicID, protocolAddr, properties); err != nil {
   988  				t.Fatalf("AddProtocolAddress(%d, %+v, %#v): %s", nicID, protocolAddr, properties, err)
   989  			}
   990  			if err := addrDisp.expectChanged(stack.AddressLifetimes{}, stack.AddressTentative); err != nil {
   991  				t.Fatal(err)
   992  			}
   993  
   994  			// Address should not be considered bound to the NIC yet (DAD ongoing).
   995  			if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil {
   996  				t.Fatal(err)
   997  			}
   998  
   999  			test.stopFn(t, s)
  1000  
  1001  			// Wait for DAD to fail (since the address was removed during DAD).
  1002  			clock.Advance(time.Duration(dadConfigs.DupAddrDetectTransmits) * dadConfigs.RetransmitTimer)
  1003  			select {
  1004  			case e := <-ndpDisp.dadC:
  1005  				if diff := checkDADEvent(e, nicID, addr1, &stack.DADAborted{}); diff != "" {
  1006  					t.Errorf("DAD event mismatch (-want +got):\n%s", diff)
  1007  				}
  1008  			default:
  1009  				// If we don't get a failure event after the expected resolution
  1010  				// time + extra 1s buffer, something is wrong.
  1011  				t.Fatal("timed out waiting for DAD failure")
  1012  			}
  1013  			test.verifyFn(t, addrDisp)
  1014  
  1015  			if !test.skipFinalAddrCheck {
  1016  				if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil {
  1017  					t.Fatal(err)
  1018  				}
  1019  			}
  1020  
  1021  			// Should not have sent more than 1 NS message.
  1022  			if got := s.Stats().ICMP.V6.PacketsSent.NeighborSolicit.Value(); got > 1 {
  1023  				t.Errorf("got NeighborSolicit = %d, want <= 1", got)
  1024  			}
  1025  		})
  1026  	}
  1027  }
  1028  
  1029  // TestSetNDPConfigurations tests that we can update and use per-interface NDP
  1030  // configurations without affecting the default NDP configurations or other
  1031  // interfaces' configurations.
  1032  func TestSetNDPConfigurations(t *testing.T) {
  1033  	const nicID1 = 1
  1034  	const nicID2 = 2
  1035  	const nicID3 = 3
  1036  
  1037  	tests := []struct {
  1038  		name                    string
  1039  		dupAddrDetectTransmits  uint8
  1040  		retransmitTimer         time.Duration
  1041  		expectedRetransmitTimer time.Duration
  1042  	}{
  1043  		{
  1044  			"OK",
  1045  			1,
  1046  			time.Second,
  1047  			time.Second,
  1048  		},
  1049  		{
  1050  			"Invalid Retransmit Timer",
  1051  			1,
  1052  			0,
  1053  			time.Second,
  1054  		},
  1055  	}
  1056  
  1057  	for _, test := range tests {
  1058  		t.Run(test.name, func(t *testing.T) {
  1059  			ndpDisp := ndpDispatcher{
  1060  				dadC: make(chan ndpDADEvent, 1),
  1061  			}
  1062  			e := channel.New(0, 1280, linkAddr1)
  1063  			clock := faketime.NewManualClock()
  1064  			s := stack.New(stack.Options{
  1065  				NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
  1066  					NDPDisp: &ndpDisp,
  1067  				})},
  1068  				Clock: clock,
  1069  			})
  1070  
  1071  			expectDADSucceeded := func(nicID tcpip.NICID, addr tcpip.Address) {
  1072  				select {
  1073  				case e := <-ndpDisp.dadC:
  1074  					if diff := checkDADEvent(e, nicID, addr, &stack.DADSucceeded{}); diff != "" {
  1075  						t.Errorf("DAD event mismatch (-want +got):\n%s", diff)
  1076  					}
  1077  				default:
  1078  					t.Fatalf("expected DAD event for %s", addr)
  1079  				}
  1080  			}
  1081  
  1082  			// This NIC(1)'s NDP configurations will be updated to
  1083  			// be different from the default.
  1084  			if err := s.CreateNIC(nicID1, e); err != nil {
  1085  				t.Fatalf("CreateNIC(%d, _) = %s", nicID1, err)
  1086  			}
  1087  
  1088  			// Created before updating NIC(1)'s NDP configurations
  1089  			// but updating NIC(1)'s NDP configurations should not
  1090  			// affect other existing NICs.
  1091  			if err := s.CreateNIC(nicID2, e); err != nil {
  1092  				t.Fatalf("CreateNIC(%d, _) = %s", nicID2, err)
  1093  			}
  1094  
  1095  			// Update the configurations on NIC(1) to use DAD.
  1096  			if ipv6Ep, err := s.GetNetworkEndpoint(nicID1, header.IPv6ProtocolNumber); err != nil {
  1097  				t.Fatalf("s.GetNetworkEndpoint(%d, %d): %s", nicID1, header.IPv6ProtocolNumber, err)
  1098  			} else {
  1099  				dad := ipv6Ep.(stack.DuplicateAddressDetector)
  1100  				dad.SetDADConfigurations(stack.DADConfigurations{
  1101  					DupAddrDetectTransmits: test.dupAddrDetectTransmits,
  1102  					RetransmitTimer:        test.retransmitTimer,
  1103  				})
  1104  			}
  1105  
  1106  			// Created after updating NIC(1)'s NDP configurations
  1107  			// but the stack's default NDP configurations should not
  1108  			// have been updated.
  1109  			if err := s.CreateNIC(nicID3, e); err != nil {
  1110  				t.Fatalf("CreateNIC(%d, _) = %s", nicID3, err)
  1111  			}
  1112  
  1113  			// Add addresses for each NIC.
  1114  			addrWithPrefix1 := tcpip.AddressWithPrefix{Address: addr1, PrefixLen: defaultPrefixLen}
  1115  			protocolAddr1 := tcpip.ProtocolAddress{
  1116  				Protocol:          header.IPv6ProtocolNumber,
  1117  				AddressWithPrefix: addrWithPrefix1,
  1118  			}
  1119  			addr1Disp := addressDispatcher{
  1120  				nicid:     nicID1,
  1121  				addr:      addrWithPrefix1,
  1122  				changedCh: make(chan addressChangedEvent, 1),
  1123  				removedCh: make(chan stack.AddressRemovalReason, 1),
  1124  			}
  1125  			properties1 := stack.AddressProperties{
  1126  				Disp: &addr1Disp,
  1127  			}
  1128  			if err := s.AddProtocolAddress(nicID1, protocolAddr1, properties1); err != nil {
  1129  				t.Fatalf("AddProtocolAddress(%d, %+v, %#v) = %s", nicID1, protocolAddr1, properties1, err)
  1130  			}
  1131  			if err := addr1Disp.expectChanged(stack.AddressLifetimes{}, stack.AddressTentative); err != nil {
  1132  				t.Error(err)
  1133  			}
  1134  			addrWithPrefix2 := tcpip.AddressWithPrefix{Address: addr2, PrefixLen: defaultPrefixLen}
  1135  			protocolAddr2 := tcpip.ProtocolAddress{
  1136  				Protocol:          header.IPv6ProtocolNumber,
  1137  				AddressWithPrefix: addrWithPrefix2,
  1138  			}
  1139  			addr2Disp := addressDispatcher{
  1140  				nicid:     nicID2,
  1141  				addr:      addrWithPrefix2,
  1142  				changedCh: make(chan addressChangedEvent, 1),
  1143  				removedCh: make(chan stack.AddressRemovalReason, 1),
  1144  			}
  1145  			properties2 := stack.AddressProperties{
  1146  				Disp: &addr2Disp,
  1147  			}
  1148  			if err := s.AddProtocolAddress(nicID2, protocolAddr2, properties2); err != nil {
  1149  				t.Fatalf("AddProtocolAddress(%d, %+v, %#v) = %s", nicID2, protocolAddr2, properties2, err)
  1150  			}
  1151  			expectDADSucceeded(nicID2, addr2)
  1152  			if err := addr2Disp.expectChanged(stack.AddressLifetimes{}, stack.AddressAssigned); err != nil {
  1153  				t.Error(err)
  1154  			}
  1155  			addrWithPrefix3 := tcpip.AddressWithPrefix{Address: addr3, PrefixLen: defaultPrefixLen}
  1156  			protocolAddr3 := tcpip.ProtocolAddress{
  1157  				Protocol:          header.IPv6ProtocolNumber,
  1158  				AddressWithPrefix: addrWithPrefix3,
  1159  			}
  1160  			addr3Disp := addressDispatcher{
  1161  				nicid:     nicID3,
  1162  				addr:      addrWithPrefix3,
  1163  				changedCh: make(chan addressChangedEvent, 1),
  1164  				removedCh: make(chan stack.AddressRemovalReason, 1),
  1165  			}
  1166  			properties3 := stack.AddressProperties{
  1167  				Disp: &addr3Disp,
  1168  			}
  1169  			if err := s.AddProtocolAddress(nicID3, protocolAddr3, properties3); err != nil {
  1170  				t.Fatalf("AddProtocolAddress(%d, %+v, %#v) = %s", nicID3, protocolAddr3, properties3, err)
  1171  			}
  1172  			expectDADSucceeded(nicID3, addr3)
  1173  			if err := addr3Disp.expectChanged(stack.AddressLifetimes{}, stack.AddressAssigned); err != nil {
  1174  				t.Error(err)
  1175  			}
  1176  
  1177  			// Address should not be considered bound to NIC(1) yet
  1178  			// (DAD ongoing).
  1179  			if err := checkGetMainNICAddress(s, nicID1, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil {
  1180  				t.Fatal(err)
  1181  			}
  1182  
  1183  			// Should get the address on NIC(2) and NIC(3)
  1184  			// immediately since we should not have performed DAD on
  1185  			// it as the stack was configured to not do DAD by
  1186  			// default and we only updated the NDP configurations on
  1187  			// NIC(1).
  1188  			if err := checkGetMainNICAddress(s, nicID2, header.IPv6ProtocolNumber, addrWithPrefix2); err != nil {
  1189  				t.Fatal(err)
  1190  			}
  1191  			if err := checkGetMainNICAddress(s, nicID3, header.IPv6ProtocolNumber, addrWithPrefix3); err != nil {
  1192  				t.Fatal(err)
  1193  			}
  1194  
  1195  			// Sleep until right before resolution to make sure the address didn't
  1196  			// resolve on NIC(1) yet.
  1197  			const delta = 1
  1198  			clock.Advance(time.Duration(test.dupAddrDetectTransmits)*test.expectedRetransmitTimer - delta)
  1199  			if err := checkGetMainNICAddress(s, nicID1, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil {
  1200  				t.Fatal(err)
  1201  			}
  1202  
  1203  			// Wait for DAD to resolve.
  1204  			clock.Advance(delta)
  1205  			expectDADSucceeded(nicID1, addr1)
  1206  			if err := addr1Disp.expectStateChanged(stack.AddressAssigned); err != nil {
  1207  				t.Error(err)
  1208  			}
  1209  			if err := checkGetMainNICAddress(s, nicID1, header.IPv6ProtocolNumber, addrWithPrefix1); err != nil {
  1210  				t.Fatal(err)
  1211  			}
  1212  		})
  1213  	}
  1214  }
  1215  
  1216  // raBuf returns a valid NDP Router Advertisement with options, router
  1217  // preference and DHCPv6 configurations specified.
  1218  func raBuf(ip tcpip.Address, rl uint16, managedAddress, otherConfigurations bool, prf header.NDPRoutePreference, optSer header.NDPOptionsSerializer) *stack.PacketBuffer {
  1219  	const flagsByte = 1
  1220  	const routerLifetimeOffset = 2
  1221  
  1222  	icmpSize := header.ICMPv6HeaderSize + header.NDPRAMinimumSize + optSer.Length()
  1223  	hdr := prependable.New(header.IPv6MinimumSize + icmpSize)
  1224  	pkt := header.ICMPv6(hdr.Prepend(icmpSize))
  1225  	pkt.SetType(header.ICMPv6RouterAdvert)
  1226  	pkt.SetCode(0)
  1227  	raPayload := pkt.MessageBody()
  1228  	ra := header.NDPRouterAdvert(raPayload)
  1229  	// Populate the Router Lifetime.
  1230  	binary.BigEndian.PutUint16(raPayload[routerLifetimeOffset:], rl)
  1231  	// Populate the Managed Address flag field.
  1232  	if managedAddress {
  1233  		// The Managed Addresses flag field is the 7th bit of the flags byte.
  1234  		raPayload[flagsByte] |= 1 << 7
  1235  	}
  1236  	// Populate the Other Configurations flag field.
  1237  	if otherConfigurations {
  1238  		// The Other Configurations flag field is the 6th bit of the flags byte.
  1239  		raPayload[flagsByte] |= 1 << 6
  1240  	}
  1241  	// The Prf field is held in the flags byte.
  1242  	raPayload[flagsByte] |= byte(prf) << 3
  1243  	opts := ra.Options()
  1244  	opts.Serialize(optSer)
  1245  	pkt.SetChecksum(header.ICMPv6Checksum(header.ICMPv6ChecksumParams{
  1246  		Header: pkt,
  1247  		Src:    ip,
  1248  		Dst:    header.IPv6AllNodesMulticastAddress,
  1249  	}))
  1250  	payloadLength := hdr.UsedLength()
  1251  	iph := header.IPv6(hdr.Prepend(header.IPv6MinimumSize))
  1252  	iph.Encode(&header.IPv6Fields{
  1253  		PayloadLength:     uint16(payloadLength),
  1254  		TransportProtocol: icmp.ProtocolNumber6,
  1255  		HopLimit:          header.NDPHopLimit,
  1256  		SrcAddr:           ip,
  1257  		DstAddr:           header.IPv6AllNodesMulticastAddress,
  1258  	})
  1259  
  1260  	return stack.NewPacketBuffer(stack.PacketBufferOptions{
  1261  		Payload: buffer.MakeWithData(hdr.View()),
  1262  	})
  1263  }
  1264  
  1265  // raBufWithOpts returns a valid NDP Router Advertisement with options.
  1266  //
  1267  // Note, raBufWithOpts does not populate any of the RA fields other than the
  1268  // Router Lifetime.
  1269  func raBufWithOpts(ip tcpip.Address, rl uint16, optSer header.NDPOptionsSerializer) *stack.PacketBuffer {
  1270  	return raBuf(ip, rl, false /* managedAddress */, false /* otherConfigurations */, 0 /* prf */, optSer)
  1271  }
  1272  
  1273  // raBufWithDHCPv6 returns a valid NDP Router Advertisement with DHCPv6 related
  1274  // fields set.
  1275  //
  1276  // Note, raBufWithDHCPv6 does not populate any of the RA fields other than the
  1277  // DHCPv6 related ones.
  1278  func raBufWithDHCPv6(ip tcpip.Address, managedAddresses, otherConfigurations bool) *stack.PacketBuffer {
  1279  	return raBuf(ip, 0, managedAddresses, otherConfigurations, 0 /* prf */, header.NDPOptionsSerializer{})
  1280  }
  1281  
  1282  // raBuf returns a valid NDP Router Advertisement.
  1283  //
  1284  // Note, raBuf does not populate any of the RA fields other than the
  1285  // Router Lifetime.
  1286  func raBufSimple(ip tcpip.Address, rl uint16) *stack.PacketBuffer {
  1287  	return raBufWithOpts(ip, rl, header.NDPOptionsSerializer{})
  1288  }
  1289  
  1290  // raBufWithPrf returns a valid NDP Router Advertisement with a preference.
  1291  //
  1292  // Note, raBufWithPrf does not populate any of the RA fields other than the
  1293  // Router Lifetime and Default Router Preference fields.
  1294  func raBufWithPrf(ip tcpip.Address, rl uint16, prf header.NDPRoutePreference) *stack.PacketBuffer {
  1295  	return raBuf(ip, rl, false /* managedAddress */, false /* otherConfigurations */, prf, header.NDPOptionsSerializer{})
  1296  }
  1297  
  1298  // raBufWithPI returns a valid NDP Router Advertisement with a single Prefix
  1299  // Information option.
  1300  //
  1301  // Note, raBufWithPI does not populate any of the RA fields other than the
  1302  // Router Lifetime.
  1303  func raBufWithPI(ip tcpip.Address, rl uint16, prefix tcpip.AddressWithPrefix, onLink, auto bool, vl, pl uint32) *stack.PacketBuffer {
  1304  	flags := uint8(0)
  1305  	if onLink {
  1306  		// The OnLink flag is the 7th bit in the flags byte.
  1307  		flags |= 1 << 7
  1308  	}
  1309  	if auto {
  1310  		// The Address Auto-Configuration flag is the 6th bit in the
  1311  		// flags byte.
  1312  		flags |= 1 << 6
  1313  	}
  1314  
  1315  	// A valid header.NDPPrefixInformation must be 30 bytes.
  1316  	buf := [30]byte{}
  1317  	// The first byte in a header.NDPPrefixInformation is the Prefix Length
  1318  	// field.
  1319  	buf[0] = uint8(prefix.PrefixLen)
  1320  	// The 2nd byte within a header.NDPPrefixInformation is the Flags field.
  1321  	buf[1] = flags
  1322  	// The Valid Lifetime field starts after the 2nd byte within a
  1323  	// header.NDPPrefixInformation.
  1324  	binary.BigEndian.PutUint32(buf[2:], vl)
  1325  	// The Preferred Lifetime field starts after the 6th byte within a
  1326  	// header.NDPPrefixInformation.
  1327  	binary.BigEndian.PutUint32(buf[6:], pl)
  1328  	// The Prefix Address field starts after the 14th byte within a
  1329  	// header.NDPPrefixInformation.
  1330  	copy(buf[14:], prefix.Address.AsSlice())
  1331  	return raBufWithOpts(ip, rl, header.NDPOptionsSerializer{
  1332  		header.NDPPrefixInformation(buf[:]),
  1333  	})
  1334  }
  1335  
  1336  // raBufWithRIO returns a valid NDP Router Advertisement with a single Route
  1337  // Information option.
  1338  //
  1339  // All fields in the RA will be zero except the RIO option.
  1340  func raBufWithRIO(t *testing.T, ip tcpip.Address, prefix tcpip.AddressWithPrefix, lifetimeSeconds uint32, prf header.NDPRoutePreference) *stack.PacketBuffer {
  1341  	// buf will hold the route information option after the Type and Length
  1342  	// fields.
  1343  	//
  1344  	//  2.3.  Route Information Option
  1345  	//
  1346  	//      0                   1                   2                   3
  1347  	//       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  1348  	//      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  1349  	//      |     Type      |    Length     | Prefix Length |Resvd|Prf|Resvd|
  1350  	//      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  1351  	//      |                        Route Lifetime                         |
  1352  	//      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  1353  	//      |                   Prefix (Variable Length)                    |
  1354  	//      .                                                               .
  1355  	//      .                                                               .
  1356  	//      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  1357  	var buf [22]byte
  1358  	buf[0] = uint8(prefix.PrefixLen)
  1359  	buf[1] = byte(prf) << 3
  1360  	binary.BigEndian.PutUint32(buf[2:], lifetimeSeconds)
  1361  	if n := copy(buf[6:], prefix.Address.AsSlice()); n != prefix.Address.Len() {
  1362  		t.Fatalf("got copy(...) = %d, want = %d", n, prefix.Address.Len())
  1363  	}
  1364  	return raBufWithOpts(ip, 0 /* router lifetime */, header.NDPOptionsSerializer{
  1365  		header.NDPRouteInformation(buf[:]),
  1366  	})
  1367  }
  1368  
  1369  func TestDynamicConfigurationsDisabled(t *testing.T) {
  1370  	const (
  1371  		nicID              = 1
  1372  		maxRtrSolicitDelay = time.Second
  1373  	)
  1374  
  1375  	prefix := tcpip.AddressWithPrefix{
  1376  		Address:   testutil.MustParse6("102:304:506:708::"),
  1377  		PrefixLen: 64,
  1378  	}
  1379  
  1380  	tests := []struct {
  1381  		name   string
  1382  		config func(bool) ipv6.NDPConfigurations
  1383  		ra     *stack.PacketBuffer
  1384  	}{
  1385  		{
  1386  			name: "No Router Discovery",
  1387  			config: func(enable bool) ipv6.NDPConfigurations {
  1388  				return ipv6.NDPConfigurations{DiscoverDefaultRouters: enable}
  1389  			},
  1390  			ra: raBufSimple(llAddr2, 1000),
  1391  		},
  1392  		{
  1393  			name: "No Prefix Discovery",
  1394  			config: func(enable bool) ipv6.NDPConfigurations {
  1395  				return ipv6.NDPConfigurations{DiscoverOnLinkPrefixes: enable}
  1396  			},
  1397  			ra: raBufWithPI(llAddr2, 0, prefix, true, false, 10, 0),
  1398  		},
  1399  		{
  1400  			name: "No Autogenerate Addresses",
  1401  			config: func(enable bool) ipv6.NDPConfigurations {
  1402  				return ipv6.NDPConfigurations{AutoGenGlobalAddresses: enable}
  1403  			},
  1404  			ra: raBufWithPI(llAddr2, 0, prefix, false, true, 10, 0),
  1405  		},
  1406  	}
  1407  
  1408  	for _, test := range tests {
  1409  		t.Run(test.name, func(t *testing.T) {
  1410  			// Being configured to discover routers/prefixes or auto-generate
  1411  			// addresses means RAs must be handled, and router/prefix discovery or
  1412  			// SLAAC must be enabled.
  1413  			//
  1414  			// This tests all possible combinations of the configurations where
  1415  			// router/prefix discovery or SLAAC are disabled.
  1416  			for i := 0; i < 7; i++ {
  1417  				handle := ipv6.HandlingRAsDisabled
  1418  				if i&1 != 0 {
  1419  					handle = ipv6.HandlingRAsEnabledWhenForwardingDisabled
  1420  				}
  1421  				enable := i&2 != 0
  1422  				forwarding := i&4 == 0
  1423  
  1424  				t.Run(fmt.Sprintf("HandleRAs(%s), Forwarding(%t), Enabled(%t)", handle, forwarding, enable), func(t *testing.T) {
  1425  					ndpDisp := ndpDispatcher{
  1426  						offLinkRouteC: make(chan ndpOffLinkRouteEvent, 1),
  1427  						prefixC:       make(chan ndpPrefixEvent, 1),
  1428  						autoGenAddrC:  make(chan ndpAutoGenAddrEvent, 1),
  1429  					}
  1430  					ndpConfigs := test.config(enable)
  1431  					ndpConfigs.HandleRAs = handle
  1432  					ndpConfigs.MaxRtrSolicitations = 1
  1433  					ndpConfigs.RtrSolicitationInterval = maxRtrSolicitDelay
  1434  					ndpConfigs.MaxRtrSolicitationDelay = maxRtrSolicitDelay
  1435  					clock := faketime.NewManualClock()
  1436  					s := stack.New(stack.Options{
  1437  						Clock: clock,
  1438  						NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
  1439  							NDPConfigs: ndpConfigs,
  1440  							NDPDisp:    &ndpDisp,
  1441  						})},
  1442  					})
  1443  					if err := s.SetForwardingDefaultAndAllNICs(ipv6.ProtocolNumber, forwarding); err != nil {
  1444  						t.Fatalf("SetForwardingDefaultAndAllNICs(%d, %t): %s", ipv6.ProtocolNumber, forwarding, err)
  1445  					}
  1446  
  1447  					e := channel.New(1, 1280, linkAddr1)
  1448  					if err := s.CreateNIC(nicID, e); err != nil {
  1449  						t.Fatalf("CreateNIC(%d, _): %s", nicID, err)
  1450  					}
  1451  
  1452  					handleRAsDisabled := handle == ipv6.HandlingRAsDisabled || forwarding
  1453  					ep, err := s.GetNetworkEndpoint(nicID, ipv6.ProtocolNumber)
  1454  					if err != nil {
  1455  						t.Fatalf("s.GetNetworkEndpoint(%d, %d): %s", nicID, ipv6.ProtocolNumber, err)
  1456  					}
  1457  					stats := ep.Stats()
  1458  					v6Stats, ok := stats.(*ipv6.Stats)
  1459  					if !ok {
  1460  						t.Fatalf("got v6Stats = %T, expected = %T", stats, v6Stats)
  1461  					}
  1462  
  1463  					// Make sure that when handling RAs are enabled, we solicit routers.
  1464  					clock.Advance(maxRtrSolicitDelay)
  1465  					if got, want := v6Stats.ICMP.PacketsSent.RouterSolicit.Value(), boolToUint64(!handleRAsDisabled); got != want {
  1466  						t.Errorf("got v6Stats.ICMP.PacketsSent.RouterSolicit.Value() = %d, want = %d", got, want)
  1467  					}
  1468  					if handleRAsDisabled {
  1469  						if p := e.Read(); p != nil {
  1470  							t.Errorf("unexpectedly got a packet = %#v", p)
  1471  						}
  1472  					} else if p := e.Read(); p == nil {
  1473  						t.Error("expected router solicitation packet")
  1474  					} else if p.NetworkProtocolNumber != header.IPv6ProtocolNumber {
  1475  						t.Errorf("got Proto = %d, want = %d", p.NetworkProtocolNumber, header.IPv6ProtocolNumber)
  1476  						p.DecRef()
  1477  					} else {
  1478  						if want := header.EthernetAddressFromMulticastIPv6Address(header.IPv6AllRoutersLinkLocalMulticastAddress); p.EgressRoute.RemoteLinkAddress != want {
  1479  							t.Errorf("got remote link address = %s, want = %s", p.EgressRoute.RemoteLinkAddress, want)
  1480  						}
  1481  
  1482  						checker.IPv6(t, stack.PayloadSince(p.NetworkHeader()),
  1483  							checker.SrcAddr(header.IPv6Any),
  1484  							checker.DstAddr(header.IPv6AllRoutersLinkLocalMulticastAddress),
  1485  							checker.TTL(header.NDPHopLimit),
  1486  							checker.NDPRS(checker.NDPRSOptions(nil)),
  1487  						)
  1488  						p.DecRef()
  1489  					}
  1490  
  1491  					// Make sure we do not discover any routers or prefixes, or perform
  1492  					// SLAAC on reception of an RA.
  1493  					e.InjectInbound(header.IPv6ProtocolNumber, test.ra.Clone())
  1494  					// Make sure that the unhandled RA stat is only incremented when
  1495  					// handling RAs is disabled.
  1496  					if got, want := v6Stats.UnhandledRouterAdvertisements.Value(), boolToUint64(handleRAsDisabled); got != want {
  1497  						t.Errorf("got v6Stats.UnhandledRouterAdvertisements.Value() = %d, want = %d", got, want)
  1498  					}
  1499  					select {
  1500  					case e := <-ndpDisp.offLinkRouteC:
  1501  						t.Errorf("unexpectedly updated an off-link route when configured not to: %#v", e)
  1502  					default:
  1503  					}
  1504  					select {
  1505  					case e := <-ndpDisp.prefixC:
  1506  						t.Errorf("unexpectedly discovered a prefix when configured not to: %#v", e)
  1507  					default:
  1508  					}
  1509  					select {
  1510  					case e := <-ndpDisp.autoGenAddrC:
  1511  						t.Errorf("unexpectedly auto-generated an address when configured not to: %#v", e)
  1512  					default:
  1513  					}
  1514  				})
  1515  			}
  1516  		})
  1517  	}
  1518  }
  1519  
  1520  func boolToUint64(v bool) uint64 {
  1521  	if v {
  1522  		return 1
  1523  	}
  1524  	return 0
  1525  }
  1526  
  1527  func checkOffLinkRouteEvent(e ndpOffLinkRouteEvent, nicID tcpip.NICID, subnet tcpip.Subnet, router tcpip.Address, prf header.NDPRoutePreference, updated bool) string {
  1528  	return cmp.Diff(ndpOffLinkRouteEvent{nicID: nicID, subnet: subnet, router: router, prf: prf, updated: updated}, e, cmp.AllowUnexported(e))
  1529  }
  1530  
  1531  func testWithRAs(t *testing.T, f func(*testing.T, ipv6.HandleRAsConfiguration, bool)) {
  1532  	tests := [...]struct {
  1533  		name       string
  1534  		handleRAs  ipv6.HandleRAsConfiguration
  1535  		forwarding bool
  1536  	}{
  1537  		{
  1538  			name:       "Handle RAs when forwarding disabled",
  1539  			handleRAs:  ipv6.HandlingRAsEnabledWhenForwardingDisabled,
  1540  			forwarding: false,
  1541  		},
  1542  		{
  1543  			name:       "Always Handle RAs with forwarding disabled",
  1544  			handleRAs:  ipv6.HandlingRAsAlwaysEnabled,
  1545  			forwarding: false,
  1546  		},
  1547  		{
  1548  			name:       "Always Handle RAs with forwarding enabled",
  1549  			handleRAs:  ipv6.HandlingRAsAlwaysEnabled,
  1550  			forwarding: true,
  1551  		},
  1552  	}
  1553  
  1554  	for _, test := range tests {
  1555  		t.Run(test.name, func(t *testing.T) {
  1556  			f(t, test.handleRAs, test.forwarding)
  1557  		})
  1558  	}
  1559  }
  1560  
  1561  func TestOffLinkRouteDiscovery(t *testing.T) {
  1562  	const nicID = 1
  1563  
  1564  	moreSpecificPrefix := tcpip.AddressWithPrefix{Address: testutil.MustParse6("a00::"), PrefixLen: 16}
  1565  	tests := []struct {
  1566  		name string
  1567  
  1568  		discoverDefaultRouters     bool
  1569  		discoverMoreSpecificRoutes bool
  1570  
  1571  		dest tcpip.Subnet
  1572  		ra   func(*testing.T, tcpip.Address, uint16, header.NDPRoutePreference) *stack.PacketBuffer
  1573  	}{
  1574  		{
  1575  			name:                       "Default router discovery",
  1576  			discoverDefaultRouters:     true,
  1577  			discoverMoreSpecificRoutes: false,
  1578  			dest:                       header.IPv6EmptySubnet,
  1579  			ra: func(_ *testing.T, router tcpip.Address, lifetimeSeconds uint16, prf header.NDPRoutePreference) *stack.PacketBuffer {
  1580  				return raBufWithPrf(router, lifetimeSeconds, prf)
  1581  			},
  1582  		},
  1583  		{
  1584  			name:                       "More-specific route discovery",
  1585  			discoverDefaultRouters:     false,
  1586  			discoverMoreSpecificRoutes: true,
  1587  			dest:                       moreSpecificPrefix.Subnet(),
  1588  			ra: func(t *testing.T, router tcpip.Address, lifetimeSeconds uint16, prf header.NDPRoutePreference) *stack.PacketBuffer {
  1589  				return raBufWithRIO(t, router, moreSpecificPrefix, uint32(lifetimeSeconds), prf)
  1590  			},
  1591  		},
  1592  	}
  1593  
  1594  	for _, test := range tests {
  1595  		t.Run(test.name, func(t *testing.T) {
  1596  			testWithRAs(t, func(t *testing.T, handleRAs ipv6.HandleRAsConfiguration, forwarding bool) {
  1597  				ndpDisp := ndpDispatcher{
  1598  					offLinkRouteC: make(chan ndpOffLinkRouteEvent, 1),
  1599  				}
  1600  				e := channel.New(0, 1280, linkAddr1)
  1601  				clock := faketime.NewManualClock()
  1602  				s := stack.New(stack.Options{
  1603  					NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
  1604  						NDPConfigs: ipv6.NDPConfigurations{
  1605  							HandleRAs:                  handleRAs,
  1606  							DiscoverDefaultRouters:     test.discoverDefaultRouters,
  1607  							DiscoverMoreSpecificRoutes: test.discoverMoreSpecificRoutes,
  1608  						},
  1609  						NDPDisp: &ndpDisp,
  1610  					})},
  1611  					Clock: clock,
  1612  				})
  1613  
  1614  				expectOffLinkRouteEvent := func(addr tcpip.Address, prf header.NDPRoutePreference, updated bool) {
  1615  					t.Helper()
  1616  
  1617  					select {
  1618  					case e := <-ndpDisp.offLinkRouteC:
  1619  						if diff := checkOffLinkRouteEvent(e, nicID, test.dest, addr, prf, updated); diff != "" {
  1620  							t.Errorf("off-link route event mismatch (-want +got):\n%s", diff)
  1621  						}
  1622  					default:
  1623  						t.Fatal("expected router discovery event")
  1624  					}
  1625  				}
  1626  
  1627  				expectAsyncOffLinkRouteInvalidationEvent := func(addr tcpip.Address, timeout time.Duration) {
  1628  					t.Helper()
  1629  
  1630  					clock.Advance(timeout)
  1631  					select {
  1632  					case e := <-ndpDisp.offLinkRouteC:
  1633  						var prf header.NDPRoutePreference
  1634  						if diff := checkOffLinkRouteEvent(e, nicID, test.dest, addr, prf, false); diff != "" {
  1635  							t.Errorf("off-link route event mismatch (-want +got):\n%s", diff)
  1636  						}
  1637  					default:
  1638  						t.Fatal("timed out waiting for router discovery event")
  1639  					}
  1640  				}
  1641  
  1642  				if err := s.SetForwardingDefaultAndAllNICs(ipv6.ProtocolNumber, forwarding); err != nil {
  1643  					t.Fatalf("SetForwardingDefaultAndAllNICs(%d, %t): %s", ipv6.ProtocolNumber, forwarding, err)
  1644  				}
  1645  
  1646  				if err := s.CreateNIC(nicID, e); err != nil {
  1647  					t.Fatalf("CreateNIC(%d, _): %s", nicID, err)
  1648  				}
  1649  
  1650  				// Rx an RA from lladdr2 with zero lifetime. It should not be
  1651  				// remembered.
  1652  				e.InjectInbound(header.IPv6ProtocolNumber, test.ra(t, llAddr2, 0, header.MediumRoutePreference))
  1653  				select {
  1654  				case <-ndpDisp.offLinkRouteC:
  1655  					t.Fatal("unexpectedly updated an off-link route with 0 lifetime")
  1656  				default:
  1657  				}
  1658  
  1659  				// Discover an off-link route through llAddr2.
  1660  				e.InjectInbound(header.IPv6ProtocolNumber, test.ra(t, llAddr2, 1000, header.ReservedRoutePreference))
  1661  				if test.discoverMoreSpecificRoutes {
  1662  					// The reserved value is considered invalid with more-specific route
  1663  					// discovery so we inject the same packet but with the default
  1664  					// (medium) preference value.
  1665  					select {
  1666  					case <-ndpDisp.offLinkRouteC:
  1667  						t.Fatal("unexpectedly updated an off-link route with a reserved preference value")
  1668  					default:
  1669  					}
  1670  					e.InjectInbound(header.IPv6ProtocolNumber, test.ra(t, llAddr2, 1000, header.MediumRoutePreference))
  1671  				}
  1672  				expectOffLinkRouteEvent(llAddr2, header.MediumRoutePreference, true)
  1673  
  1674  				// Rx an RA from another router (lladdr3) with non-zero lifetime and
  1675  				// non-default preference value.
  1676  				const l3LifetimeSeconds = 6
  1677  				e.InjectInbound(header.IPv6ProtocolNumber, test.ra(t, llAddr3, l3LifetimeSeconds, header.HighRoutePreference))
  1678  				expectOffLinkRouteEvent(llAddr3, header.HighRoutePreference, true)
  1679  
  1680  				// Rx an RA from lladdr2 with lesser lifetime and default (medium)
  1681  				// preference value.
  1682  				const l2LifetimeSeconds = 2
  1683  				e.InjectInbound(header.IPv6ProtocolNumber, test.ra(t, llAddr2, l2LifetimeSeconds, header.MediumRoutePreference))
  1684  				select {
  1685  				case <-ndpDisp.offLinkRouteC:
  1686  					t.Fatal("should not receive a off-link route event when updating lifetimes for known routers")
  1687  				default:
  1688  				}
  1689  
  1690  				// Rx an RA from lladdr2 with a different preference.
  1691  				e.InjectInbound(header.IPv6ProtocolNumber, test.ra(t, llAddr2, l2LifetimeSeconds, header.LowRoutePreference))
  1692  				expectOffLinkRouteEvent(llAddr2, header.LowRoutePreference, true)
  1693  
  1694  				// Wait for lladdr2's router invalidation job to execute. The lifetime
  1695  				// of the router should have been updated to the most recent (smaller)
  1696  				// lifetime.
  1697  				//
  1698  				// Wait for the normal lifetime plus an extra bit for the
  1699  				// router to get invalidated. If we don't get an invalidation
  1700  				// event after this time, then something is wrong.
  1701  				expectAsyncOffLinkRouteInvalidationEvent(llAddr2, l2LifetimeSeconds*time.Second)
  1702  
  1703  				// Rx an RA from lladdr2 with huge lifetime.
  1704  				e.InjectInbound(header.IPv6ProtocolNumber, test.ra(t, llAddr2, 1000, header.MediumRoutePreference))
  1705  				expectOffLinkRouteEvent(llAddr2, header.MediumRoutePreference, true)
  1706  
  1707  				// Rx an RA from lladdr2 with zero lifetime. It should be invalidated.
  1708  				e.InjectInbound(header.IPv6ProtocolNumber, test.ra(t, llAddr2, 0, header.MediumRoutePreference))
  1709  				expectOffLinkRouteEvent(llAddr2, header.MediumRoutePreference, false)
  1710  
  1711  				// Wait for lladdr3's router invalidation job to execute. The lifetime
  1712  				// of the router should have been updated to the most recent (smaller)
  1713  				// lifetime.
  1714  				//
  1715  				// Wait for the normal lifetime plus an extra bit for the
  1716  				// router to get invalidated. If we don't get an invalidation
  1717  				// event after this time, then something is wrong.
  1718  				expectAsyncOffLinkRouteInvalidationEvent(llAddr3, l3LifetimeSeconds*time.Second)
  1719  			})
  1720  		})
  1721  	}
  1722  }
  1723  
  1724  // TestRouterDiscoveryMaxRouters tests that only
  1725  // ipv6.MaxDiscoveredOffLinkRoutes discovered routers are remembered.
  1726  func TestRouterDiscoveryMaxRouters(t *testing.T) {
  1727  	const nicID = 1
  1728  
  1729  	ndpDisp := ndpDispatcher{
  1730  		offLinkRouteC: make(chan ndpOffLinkRouteEvent, 1),
  1731  	}
  1732  	e := channel.New(0, 1280, linkAddr1)
  1733  	s := stack.New(stack.Options{
  1734  		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
  1735  			NDPConfigs: ipv6.NDPConfigurations{
  1736  				HandleRAs:              ipv6.HandlingRAsEnabledWhenForwardingDisabled,
  1737  				DiscoverDefaultRouters: true,
  1738  			},
  1739  			NDPDisp: &ndpDisp,
  1740  		})},
  1741  	})
  1742  
  1743  	if err := s.CreateNIC(nicID, e); err != nil {
  1744  		t.Fatalf("CreateNIC(%d, _): %s", nicID, err)
  1745  	}
  1746  
  1747  	// Receive an RA from 2 more than the max number of discovered routers.
  1748  	for i := 1; i <= ipv6.MaxDiscoveredOffLinkRoutes+2; i++ {
  1749  		linkAddr := []byte{2, 2, 3, 4, 5, 0}
  1750  		linkAddr[5] = byte(i)
  1751  		llAddr := header.LinkLocalAddr(tcpip.LinkAddress(linkAddr))
  1752  
  1753  		e.InjectInbound(header.IPv6ProtocolNumber, raBufSimple(llAddr, 5))
  1754  
  1755  		if i <= ipv6.MaxDiscoveredOffLinkRoutes {
  1756  			select {
  1757  			case e := <-ndpDisp.offLinkRouteC:
  1758  				if diff := checkOffLinkRouteEvent(e, nicID, header.IPv6EmptySubnet, llAddr, header.MediumRoutePreference, true); diff != "" {
  1759  					t.Errorf("off-link route event mismatch (-want +got):\n%s", diff)
  1760  				}
  1761  			default:
  1762  				t.Fatal("expected router discovery event")
  1763  			}
  1764  
  1765  		} else {
  1766  			select {
  1767  			case <-ndpDisp.offLinkRouteC:
  1768  				t.Fatal("should not have discovered a new router after we already discovered the max number of routers")
  1769  			default:
  1770  			}
  1771  		}
  1772  	}
  1773  }
  1774  
  1775  // Check e to make sure that the event is for prefix on nic with ID 1, and the
  1776  // discovered flag set to discovered.
  1777  func checkPrefixEvent(e ndpPrefixEvent, prefix tcpip.Subnet, discovered bool) string {
  1778  	return cmp.Diff(ndpPrefixEvent{nicID: 1, prefix: prefix, discovered: discovered}, e, cmp.AllowUnexported(e))
  1779  }
  1780  
  1781  func TestPrefixDiscovery(t *testing.T) {
  1782  	prefix1, subnet1, _ := prefixSubnetAddr(0, "")
  1783  	prefix2, subnet2, _ := prefixSubnetAddr(1, "")
  1784  	prefix3, subnet3, _ := prefixSubnetAddr(2, "")
  1785  
  1786  	testWithRAs(t, func(t *testing.T, handleRAs ipv6.HandleRAsConfiguration, forwarding bool) {
  1787  		ndpDisp := ndpDispatcher{
  1788  			prefixC: make(chan ndpPrefixEvent, 1),
  1789  		}
  1790  		e := channel.New(0, 1280, linkAddr1)
  1791  		clock := faketime.NewManualClock()
  1792  		s := stack.New(stack.Options{
  1793  			NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
  1794  				NDPConfigs: ipv6.NDPConfigurations{
  1795  					HandleRAs:              handleRAs,
  1796  					DiscoverOnLinkPrefixes: true,
  1797  				},
  1798  				NDPDisp: &ndpDisp,
  1799  			})},
  1800  			Clock: clock,
  1801  		})
  1802  
  1803  		if err := s.CreateNIC(1, e); err != nil {
  1804  			t.Fatalf("CreateNIC(1) = %s", err)
  1805  		}
  1806  
  1807  		expectPrefixEvent := func(prefix tcpip.Subnet, discovered bool) {
  1808  			t.Helper()
  1809  
  1810  			select {
  1811  			case e := <-ndpDisp.prefixC:
  1812  				if diff := checkPrefixEvent(e, prefix, discovered); diff != "" {
  1813  					t.Errorf("prefix event mismatch (-want +got):\n%s", diff)
  1814  				}
  1815  			default:
  1816  				t.Fatal("expected prefix discovery event")
  1817  			}
  1818  		}
  1819  
  1820  		if err := s.SetForwardingDefaultAndAllNICs(ipv6.ProtocolNumber, forwarding); err != nil {
  1821  			t.Fatalf("SetForwardingDefaultAndAllNICs(%d, %t): %s", ipv6.ProtocolNumber, forwarding, err)
  1822  		}
  1823  
  1824  		// Receive an RA with prefix1 in an NDP Prefix Information option (PI)
  1825  		// with zero valid lifetime.
  1826  		e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, false, 0, 0))
  1827  		select {
  1828  		case <-ndpDisp.prefixC:
  1829  			t.Fatal("unexpectedly discovered a prefix with 0 lifetime")
  1830  		default:
  1831  		}
  1832  
  1833  		// Receive an RA with prefix1 in an NDP Prefix Information option (PI)
  1834  		// with non-zero lifetime.
  1835  		e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, false, 100, 0))
  1836  		expectPrefixEvent(subnet1, true)
  1837  
  1838  		// Receive an RA with prefix2 in a PI.
  1839  		e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix2, true, false, 100, 0))
  1840  		expectPrefixEvent(subnet2, true)
  1841  
  1842  		// Receive an RA with prefix3 in a PI.
  1843  		e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix3, true, false, 100, 0))
  1844  		expectPrefixEvent(subnet3, true)
  1845  
  1846  		// Receive an RA with prefix1 in a PI with lifetime = 0.
  1847  		e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, false, 0, 0))
  1848  		expectPrefixEvent(subnet1, false)
  1849  
  1850  		// Receive an RA with prefix2 in a PI with lesser lifetime.
  1851  		lifetime := uint32(2)
  1852  		e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix2, true, false, lifetime, 0))
  1853  		select {
  1854  		case <-ndpDisp.prefixC:
  1855  			t.Fatal("unexpectedly received prefix event when updating lifetime")
  1856  		default:
  1857  		}
  1858  
  1859  		// Wait for prefix2's most recent invalidation job plus some buffer to
  1860  		// expire.
  1861  		clock.Advance(time.Duration(lifetime) * time.Second)
  1862  		select {
  1863  		case e := <-ndpDisp.prefixC:
  1864  			if diff := checkPrefixEvent(e, subnet2, false); diff != "" {
  1865  				t.Errorf("prefix event mismatch (-want +got):\n%s", diff)
  1866  			}
  1867  		default:
  1868  			t.Fatal("timed out waiting for prefix discovery event")
  1869  		}
  1870  
  1871  		// Receive RA to invalidate prefix3.
  1872  		e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix3, true, false, 0, 0))
  1873  		expectPrefixEvent(subnet3, false)
  1874  	})
  1875  }
  1876  
  1877  func TestPrefixDiscoveryWithInfiniteLifetime(t *testing.T) {
  1878  	prefix := tcpip.AddressWithPrefix{
  1879  		Address:   testutil.MustParse6("102:304:506:708::"),
  1880  		PrefixLen: 64,
  1881  	}
  1882  	subnet := prefix.Subnet()
  1883  
  1884  	ndpDisp := ndpDispatcher{
  1885  		prefixC: make(chan ndpPrefixEvent, 1),
  1886  	}
  1887  	e := channel.New(0, 1280, linkAddr1)
  1888  	clock := faketime.NewManualClock()
  1889  	s := stack.New(stack.Options{
  1890  		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
  1891  			NDPConfigs: ipv6.NDPConfigurations{
  1892  				HandleRAs:              ipv6.HandlingRAsEnabledWhenForwardingDisabled,
  1893  				DiscoverOnLinkPrefixes: true,
  1894  			},
  1895  			NDPDisp: &ndpDisp,
  1896  		})},
  1897  		Clock: clock,
  1898  	})
  1899  
  1900  	if err := s.CreateNIC(1, e); err != nil {
  1901  		t.Fatalf("CreateNIC(1) = %s", err)
  1902  	}
  1903  
  1904  	expectPrefixEvent := func(prefix tcpip.Subnet, discovered bool) {
  1905  		t.Helper()
  1906  
  1907  		select {
  1908  		case e := <-ndpDisp.prefixC:
  1909  			if diff := checkPrefixEvent(e, prefix, discovered); diff != "" {
  1910  				t.Errorf("prefix event mismatch (-want +got):\n%s", diff)
  1911  			}
  1912  		default:
  1913  			t.Fatal("expected prefix discovery event")
  1914  		}
  1915  	}
  1916  
  1917  	// Receive an RA with prefix in an NDP Prefix Information option (PI)
  1918  	// with infinite valid lifetime which should not get invalidated.
  1919  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, false, infiniteLifetimeSeconds, 0))
  1920  	expectPrefixEvent(subnet, true)
  1921  	clock.Advance(header.NDPInfiniteLifetime)
  1922  	select {
  1923  	case <-ndpDisp.prefixC:
  1924  		t.Fatal("unexpectedly invalidated a prefix with infinite lifetime")
  1925  	default:
  1926  	}
  1927  
  1928  	// Receive an RA with finite lifetime.
  1929  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, false, infiniteLifetimeSeconds-1, 0))
  1930  	clock.Advance(header.NDPInfiniteLifetime - time.Second)
  1931  	select {
  1932  	case e := <-ndpDisp.prefixC:
  1933  		if diff := checkPrefixEvent(e, subnet, false); diff != "" {
  1934  			t.Errorf("prefix event mismatch (-want +got):\n%s", diff)
  1935  		}
  1936  	default:
  1937  		t.Fatal("timed out waiting for prefix discovery event")
  1938  	}
  1939  
  1940  	// Receive an RA with finite lifetime.
  1941  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, false, infiniteLifetimeSeconds-1, 0))
  1942  	expectPrefixEvent(subnet, true)
  1943  
  1944  	// Receive an RA with prefix with an infinite lifetime.
  1945  	// The prefix should not be invalidated.
  1946  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, false, infiniteLifetimeSeconds, 0))
  1947  	clock.Advance(header.NDPInfiniteLifetime)
  1948  	select {
  1949  	case <-ndpDisp.prefixC:
  1950  		t.Fatal("unexpectedly invalidated a prefix with infinite lifetime")
  1951  	default:
  1952  	}
  1953  
  1954  	// Receive an RA with 0 lifetime.
  1955  	// The prefix should get invalidated.
  1956  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, false, 0, 0))
  1957  	expectPrefixEvent(subnet, false)
  1958  }
  1959  
  1960  // TestPrefixDiscoveryMaxRouters tests that only
  1961  // ipv6.MaxDiscoveredOnLinkPrefixes discovered on-link prefixes are remembered.
  1962  func TestPrefixDiscoveryMaxOnLinkPrefixes(t *testing.T) {
  1963  	ndpDisp := ndpDispatcher{
  1964  		prefixC: make(chan ndpPrefixEvent, ipv6.MaxDiscoveredOnLinkPrefixes+3),
  1965  	}
  1966  	e := channel.New(0, 1280, linkAddr1)
  1967  	s := stack.New(stack.Options{
  1968  		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
  1969  			NDPConfigs: ipv6.NDPConfigurations{
  1970  				HandleRAs:              ipv6.HandlingRAsEnabledWhenForwardingDisabled,
  1971  				DiscoverDefaultRouters: false,
  1972  				DiscoverOnLinkPrefixes: true,
  1973  			},
  1974  			NDPDisp: &ndpDisp,
  1975  		})},
  1976  	})
  1977  
  1978  	if err := s.CreateNIC(1, e); err != nil {
  1979  		t.Fatalf("CreateNIC(1) = %s", err)
  1980  	}
  1981  
  1982  	optSer := make(header.NDPOptionsSerializer, ipv6.MaxDiscoveredOnLinkPrefixes+2)
  1983  	prefixes := [ipv6.MaxDiscoveredOnLinkPrefixes + 2]tcpip.Subnet{}
  1984  
  1985  	// Receive an RA with 2 more than the max number of discovered on-link
  1986  	// prefixes.
  1987  	for i := 0; i < ipv6.MaxDiscoveredOnLinkPrefixes+2; i++ {
  1988  		prefixAddr := [16]byte{1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0}
  1989  		prefixAddr[7] = byte(i)
  1990  		prefix := tcpip.AddressWithPrefix{
  1991  			Address:   tcpip.AddrFromSlice(prefixAddr[:]),
  1992  			PrefixLen: 64,
  1993  		}
  1994  		prefixes[i] = prefix.Subnet()
  1995  		buf := [30]byte{}
  1996  		buf[0] = uint8(prefix.PrefixLen)
  1997  		buf[1] = 128
  1998  		binary.BigEndian.PutUint32(buf[2:], 10)
  1999  		copy(buf[14:], prefix.Address.AsSlice())
  2000  
  2001  		optSer[i] = header.NDPPrefixInformation(buf[:])
  2002  	}
  2003  
  2004  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithOpts(llAddr1, 0, optSer))
  2005  	for i := 0; i < ipv6.MaxDiscoveredOnLinkPrefixes+2; i++ {
  2006  		if i < ipv6.MaxDiscoveredOnLinkPrefixes {
  2007  			select {
  2008  			case e := <-ndpDisp.prefixC:
  2009  				if diff := checkPrefixEvent(e, prefixes[i], true); diff != "" {
  2010  					t.Errorf("prefix event mismatch (-want +got):\n%s", diff)
  2011  				}
  2012  			default:
  2013  				t.Fatal("expected prefix discovery event")
  2014  			}
  2015  		} else {
  2016  			select {
  2017  			case <-ndpDisp.prefixC:
  2018  				t.Fatal("should not have discovered a new prefix after we already discovered the max number of prefixes")
  2019  			default:
  2020  			}
  2021  		}
  2022  	}
  2023  }
  2024  
  2025  // Checks to see if list contains an IPv6 address, item.
  2026  func containsV6Addr(list []tcpip.ProtocolAddress, item tcpip.AddressWithPrefix) bool {
  2027  	protocolAddress := tcpip.ProtocolAddress{
  2028  		Protocol:          header.IPv6ProtocolNumber,
  2029  		AddressWithPrefix: item,
  2030  	}
  2031  
  2032  	return containsAddr(list, protocolAddress)
  2033  }
  2034  
  2035  // Check e to make sure that the event is for addr on nic with ID 1, and the
  2036  // event type is set to eventType.
  2037  func checkAutoGenAddrEvent(e ndpAutoGenAddrEvent, addr tcpip.AddressWithPrefix, eventType ndpAutoGenAddrEventType) string {
  2038  	return cmp.Diff(
  2039  		ndpAutoGenAddrEvent{nicID: 1, addr: addr, eventType: eventType},
  2040  		e,
  2041  		cmp.AllowUnexported(e),
  2042  	)
  2043  }
  2044  
  2045  const minVLSeconds = uint32(ipv6.MinPrefixInformationValidLifetimeForUpdate / time.Second)
  2046  const infiniteLifetimeSeconds = uint32(header.NDPInfiniteLifetime / time.Second)
  2047  
  2048  func expectAutoGenAddrEvent(t *testing.T, ndpDisp *ndpDispatcher, addr tcpip.AddressWithPrefix, eventType ndpAutoGenAddrEventType) {
  2049  	t.Helper()
  2050  
  2051  	select {
  2052  	case e := <-ndpDisp.autoGenAddrC:
  2053  		if diff := checkAutoGenAddrEvent(e, addr, eventType); diff != "" {
  2054  			t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
  2055  		}
  2056  	default:
  2057  		t.Fatal("expected addr auto gen event")
  2058  	}
  2059  }
  2060  
  2061  // expectAutoGenAddrNewEvent expects that a new auto-gen addr event is
  2062  // immediately available with addr.
  2063  //
  2064  // The return *addressDispatcher is non-nil iff ndpDisp.autoGenInstallDisp is
  2065  // true.
  2066  func expectAutoGenAddrNewEvent(ndpDisp *ndpDispatcher, addr tcpip.AddressWithPrefix) (*addressDispatcher, error) {
  2067  	select {
  2068  	case e := <-ndpDisp.autoGenAddrNewC:
  2069  		if diff := cmp.Diff(
  2070  			ndpAutoGenAddrNewEvent{nicID: 1, addr: addr},
  2071  			e,
  2072  			cmp.AllowUnexported(e),
  2073  			cmp.FilterValues(func(*addressDispatcher, *addressDispatcher) bool { return true }, cmp.Ignore()),
  2074  		); diff != "" {
  2075  			return nil, fmt.Errorf("new auto-gen addr event mismatch (-want +got):\n%s", diff)
  2076  		}
  2077  		if ndpDisp.autoGenInstallDisp != (e.addrDisp != nil) {
  2078  			return nil, fmt.Errorf("install-disp=%t but addr-disp=%#v", ndpDisp.autoGenInstallDisp, e.addrDisp)
  2079  		}
  2080  		return e.addrDisp, nil
  2081  	default:
  2082  		return nil, fmt.Errorf("expected new auto-gen addr event")
  2083  	}
  2084  }
  2085  
  2086  func TestMaxSlaacPrefixes(t *testing.T) {
  2087  	const (
  2088  		nicID = 1
  2089  		// Each SLAAC prefix gets a stable and temporary address.
  2090  		slaacAddrsPerPrefix = 2
  2091  		// Send an extra prefix than what we will discover to make sure we do not
  2092  		// discover the extra prefix.
  2093  		slaacPrefixesInRA = ipv6.MaxDiscoveredSLAACPrefixes + 1
  2094  	)
  2095  
  2096  	ndpDisp := ndpDispatcher{
  2097  		autoGenAddrNewC: make(chan ndpAutoGenAddrNewEvent, slaacPrefixesInRA*slaacAddrsPerPrefix),
  2098  	}
  2099  	e := channel.New(0, 1280, linkAddr1)
  2100  	s := stack.New(stack.Options{
  2101  		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
  2102  			NDPConfigs: ipv6.NDPConfigurations{
  2103  				HandleRAs:                  ipv6.HandlingRAsEnabledWhenForwardingDisabled,
  2104  				AutoGenGlobalAddresses:     true,
  2105  				AutoGenTempGlobalAddresses: true,
  2106  			},
  2107  			NDPDisp: &ndpDisp,
  2108  		})},
  2109  	})
  2110  
  2111  	if err := s.CreateNIC(nicID, e); err != nil {
  2112  		t.Fatalf("CreateNIC(%d) = %s", nicID, err)
  2113  	}
  2114  
  2115  	optSer := make(header.NDPOptionsSerializer, 0, slaacPrefixesInRA)
  2116  	prefixes := [slaacPrefixesInRA]tcpip.Subnet{}
  2117  	for i := 0; i < slaacPrefixesInRA; i++ {
  2118  		prefixAddr := [16]byte{1, 2, 3, 4, 5, 6, 7, byte(i), 0, 0, 0, 0, 0, 0, 0, 0}
  2119  		prefix := tcpip.AddressWithPrefix{
  2120  			Address:   tcpip.AddrFromSlice(prefixAddr[:]),
  2121  			PrefixLen: 64,
  2122  		}
  2123  		prefixes[i] = prefix.Subnet()
  2124  		// Serialize a prefix information option.
  2125  		buf := [30]byte{}
  2126  		buf[0] = uint8(prefix.PrefixLen)
  2127  		// Set the autonomous configuration flag.
  2128  		buf[1] = 64
  2129  		// Set the preferred and valid lifetimes to the maximum possible value.
  2130  		binary.BigEndian.PutUint32(buf[2:], math.MaxUint32)
  2131  		binary.BigEndian.PutUint32(buf[6:], math.MaxUint32)
  2132  		if n := copy(buf[14:], prefix.Address.AsSlice()); n != prefix.Address.Len() {
  2133  			t.Fatalf("got copy(...) = %d, want = %d", n, prefix.Address.Len())
  2134  		}
  2135  		optSer = append(optSer, header.NDPPrefixInformation(buf[:]))
  2136  	}
  2137  
  2138  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithOpts(llAddr1, 0, optSer))
  2139  	for i := 0; i < slaacPrefixesInRA; i++ {
  2140  		for j := 0; j < slaacAddrsPerPrefix; j++ {
  2141  			if i < ipv6.MaxDiscoveredSLAACPrefixes {
  2142  				select {
  2143  				case e := <-ndpDisp.autoGenAddrNewC:
  2144  					if e.nicID != nicID {
  2145  						t.Errorf("got e.nicID = %d, want = %d", e.nicID, nicID)
  2146  					}
  2147  					if !prefixes[i].Contains(e.addr.Address) {
  2148  						t.Errorf("got prefixes[%d].Contains(%s) = false, want = true", i, e.addr)
  2149  					}
  2150  					if e.addrDisp != nil {
  2151  						t.Error("auto-gen new addr event unexpectedly contains address dispatcher")
  2152  					}
  2153  				default:
  2154  					t.Fatalf("expected auto-gen new addr event; i=%d, j=%d", i, j)
  2155  				}
  2156  			} else {
  2157  				select {
  2158  				case <-ndpDisp.autoGenAddrNewC:
  2159  					t.Fatal("should not have discovered a new auto-gen addr after we already discovered the max number of prefixes")
  2160  				default:
  2161  				}
  2162  			}
  2163  		}
  2164  	}
  2165  }
  2166  
  2167  // TestAutoGenAddr tests that an address is properly generated and invalidated
  2168  // when configured to do so.
  2169  func TestAutoGenAddr(t *testing.T) {
  2170  	prefix1, _, addr1 := prefixSubnetAddr(0, linkAddr1)
  2171  	prefix2, _, addr2 := prefixSubnetAddr(1, linkAddr1)
  2172  
  2173  	testWithRAs(t, func(t *testing.T, handleRAs ipv6.HandleRAsConfiguration, forwarding bool) {
  2174  		const autoGenAddrCount = 1
  2175  		ndpDisp := ndpDispatcher{
  2176  			autoGenAddrNewC:    make(chan ndpAutoGenAddrNewEvent, autoGenAddrCount),
  2177  			autoGenAddrC:       make(chan ndpAutoGenAddrEvent, autoGenAddrCount),
  2178  			autoGenInstallDisp: true,
  2179  		}
  2180  		e := channel.New(0, 1280, linkAddr1)
  2181  		clock := faketime.NewManualClock()
  2182  		s := stack.New(stack.Options{
  2183  			NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
  2184  				NDPConfigs: ipv6.NDPConfigurations{
  2185  					HandleRAs:              handleRAs,
  2186  					AutoGenGlobalAddresses: true,
  2187  				},
  2188  				NDPDisp: &ndpDisp,
  2189  			})},
  2190  			Clock: clock,
  2191  		})
  2192  
  2193  		if err := s.SetForwardingDefaultAndAllNICs(ipv6.ProtocolNumber, forwarding); err != nil {
  2194  			t.Fatalf("SetForwardingDefaultAndAllNICs(%d, %t): %s", ipv6.ProtocolNumber, forwarding, err)
  2195  		}
  2196  
  2197  		if err := s.CreateNIC(1, e); err != nil {
  2198  			t.Fatalf("CreateNIC(1) = %s", err)
  2199  		}
  2200  
  2201  		// Receive an RA with prefix1 in an NDP Prefix Information option (PI)
  2202  		// with zero valid lifetime.
  2203  		e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, 0, 0))
  2204  		select {
  2205  		case <-ndpDisp.autoGenAddrC:
  2206  			t.Fatal("unexpectedly auto-generated an address with 0 lifetime")
  2207  		default:
  2208  		}
  2209  
  2210  		// Receive an RA with prefix1 in an NDP Prefix Information option (PI)
  2211  		// with non-zero lifetime.
  2212  		var preferredLifetime1 uint32
  2213  		validLifetime1 := uint32(100)
  2214  		received := clock.NowMonotonic()
  2215  		e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, validLifetime1, preferredLifetime1))
  2216  		addr1Disp, err := expectAutoGenAddrNewEvent(&ndpDisp, addr1)
  2217  		if err != nil {
  2218  			t.Fatalf("error expecting prefix1 stable address generated event: %s", err)
  2219  		}
  2220  		if err := addr1Disp.expectChanged(addressLifetimes(received, preferredLifetime1, validLifetime1), stack.AddressAssigned); err != nil {
  2221  			t.Error(err)
  2222  		}
  2223  		if !containsV6Addr(s.NICInfo()[1].ProtocolAddresses, addr1) {
  2224  			t.Fatalf("Should have %s in the list of addresses", addr1)
  2225  		}
  2226  
  2227  		// Receive an RA with prefix2 in an NDP Prefix Information option (PI)
  2228  		// with preferred lifetime > valid lifetime
  2229  		e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, 5, 6))
  2230  		select {
  2231  		case <-ndpDisp.autoGenAddrC:
  2232  			t.Fatal("unexpectedly auto-generated an address with preferred lifetime > valid lifetime")
  2233  		default:
  2234  		}
  2235  
  2236  		// Receive an RA with prefix2 in a PI with a valid lifetime that exceeds
  2237  		// the minimum.
  2238  		validLifetime2 := uint32(minVLSeconds + 1)
  2239  		preferredLifetime2 := uint32(minVLSeconds + 1)
  2240  		received = clock.NowMonotonic()
  2241  		e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix2, true, true, validLifetime2, preferredLifetime2))
  2242  		addr2Disp, err := expectAutoGenAddrNewEvent(&ndpDisp, addr2)
  2243  		if err != nil {
  2244  			t.Fatalf("error expecting prefix2 stable address generated event: %s", err)
  2245  		}
  2246  		if err := addr2Disp.expectChanged(addressLifetimes(received, preferredLifetime2, validLifetime2), stack.AddressAssigned); err != nil {
  2247  			t.Error(err)
  2248  		}
  2249  		if !containsV6Addr(s.NICInfo()[1].ProtocolAddresses, addr1) {
  2250  			t.Fatalf("Should have %s in the list of addresses", addr1)
  2251  		}
  2252  		if !containsV6Addr(s.NICInfo()[1].ProtocolAddresses, addr2) {
  2253  			t.Fatalf("Should have %s in the list of addresses", addr2)
  2254  		}
  2255  
  2256  		// Refresh valid lifetime for addr of prefix1.
  2257  		e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, validLifetime1, 0))
  2258  		select {
  2259  		case <-ndpDisp.autoGenAddrC:
  2260  			t.Fatal("unexpectedly auto-generated an address when we already have an address for a prefix")
  2261  		default:
  2262  		}
  2263  
  2264  		// Wait for addr of prefix1 to be invalidated.
  2265  		clock.Advance(ipv6.MinPrefixInformationValidLifetimeForUpdate)
  2266  		expectAutoGenAddrEvent(t, &ndpDisp, addr1, invalidatedAddr)
  2267  		if err := addr1Disp.expectRemoved(stack.AddressRemovalInvalidated); err != nil {
  2268  			t.Fatal(err)
  2269  		}
  2270  		if containsV6Addr(s.NICInfo()[1].ProtocolAddresses, addr1) {
  2271  			t.Fatalf("Should not have %s in the list of addresses", addr1)
  2272  		}
  2273  		if !containsV6Addr(s.NICInfo()[1].ProtocolAddresses, addr2) {
  2274  			t.Fatalf("Should have %s in the list of addresses", addr2)
  2275  		}
  2276  	})
  2277  }
  2278  
  2279  func addressCheck(addrs []tcpip.ProtocolAddress, containList, notContainList []tcpip.AddressWithPrefix) string {
  2280  	ret := ""
  2281  	for _, c := range containList {
  2282  		if !containsV6Addr(addrs, c) {
  2283  			ret += fmt.Sprintf("should have %s in the list of addresses\n", c)
  2284  		}
  2285  	}
  2286  	for _, c := range notContainList {
  2287  		if containsV6Addr(addrs, c) {
  2288  			ret += fmt.Sprintf("should not have %s in the list of addresses\n", c)
  2289  		}
  2290  	}
  2291  	return ret
  2292  }
  2293  
  2294  // TestAutoGenTempAddr tests that temporary SLAAC addresses are generated when
  2295  // configured to do so as part of IPv6 Privacy Extensions.
  2296  func TestAutoGenTempAddr(t *testing.T) {
  2297  	const nicID = 1
  2298  
  2299  	prefix1, _, addr1 := prefixSubnetAddr(0, linkAddr1)
  2300  	prefix2, _, addr2 := prefixSubnetAddr(1, linkAddr1)
  2301  
  2302  	tests := []struct {
  2303  		name             string
  2304  		dupAddrTransmits uint8
  2305  		retransmitTimer  time.Duration
  2306  	}{
  2307  		{
  2308  			name: "DAD disabled",
  2309  		},
  2310  		{
  2311  			name:             "DAD enabled",
  2312  			dupAddrTransmits: 1,
  2313  			retransmitTimer:  time.Second,
  2314  		},
  2315  	}
  2316  
  2317  	for i, test := range tests {
  2318  		t.Run(test.name, func(t *testing.T) {
  2319  			seed := []byte{uint8(i)}
  2320  			var tempIIDHistory [header.IIDSize]byte
  2321  			header.InitialTempIID(tempIIDHistory[:], seed, nicID)
  2322  			newTempAddr := func(stableAddr tcpip.Address) tcpip.AddressWithPrefix {
  2323  				return header.GenerateTempIPv6SLAACAddr(tempIIDHistory[:], stableAddr)
  2324  			}
  2325  
  2326  			const autoGenAddrCount = 2
  2327  			ndpDisp := ndpDispatcher{
  2328  				dadC:               make(chan ndpDADEvent, 2),
  2329  				autoGenAddrNewC:    make(chan ndpAutoGenAddrNewEvent, autoGenAddrCount),
  2330  				autoGenAddrC:       make(chan ndpAutoGenAddrEvent, autoGenAddrCount),
  2331  				autoGenInstallDisp: true,
  2332  			}
  2333  			e := channel.New(0, 1280, linkAddr1)
  2334  			clock := faketime.NewManualClock()
  2335  			s := stack.New(stack.Options{
  2336  				NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
  2337  					DADConfigs: stack.DADConfigurations{
  2338  						DupAddrDetectTransmits: test.dupAddrTransmits,
  2339  						RetransmitTimer:        test.retransmitTimer,
  2340  					},
  2341  					NDPConfigs: ipv6.NDPConfigurations{
  2342  						HandleRAs:                    ipv6.HandlingRAsEnabledWhenForwardingDisabled,
  2343  						AutoGenGlobalAddresses:       true,
  2344  						AutoGenTempGlobalAddresses:   true,
  2345  						MaxTempAddrValidLifetime:     3 * ipv6.MinPrefixInformationValidLifetimeForUpdate,
  2346  						MaxTempAddrPreferredLifetime: 3 * ipv6.MinPrefixInformationValidLifetimeForUpdate,
  2347  					},
  2348  					NDPDisp:     &ndpDisp,
  2349  					TempIIDSeed: seed,
  2350  				})},
  2351  				Clock: clock,
  2352  			})
  2353  
  2354  			if err := s.CreateNIC(nicID, e); err != nil {
  2355  				t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
  2356  			}
  2357  
  2358  			expectDADEventAsync := func(addr tcpip.Address) {
  2359  				t.Helper()
  2360  
  2361  				clock.Advance(time.Duration(test.dupAddrTransmits) * test.retransmitTimer)
  2362  				select {
  2363  				case e := <-ndpDisp.dadC:
  2364  					if diff := checkDADEvent(e, nicID, addr, &stack.DADSucceeded{}); diff != "" {
  2365  						t.Errorf("DAD event mismatch (-want +got):\n%s", diff)
  2366  					}
  2367  				default:
  2368  					t.Fatal("timed out waiting for DAD event")
  2369  				}
  2370  			}
  2371  
  2372  			expectAddrDispatcherTentative := func(addrDisp *addressDispatcher, wantLifetimes stack.AddressLifetimes) {
  2373  				t.Helper()
  2374  
  2375  				if test.dupAddrTransmits != 0 {
  2376  					if err := addrDisp.expectChanged(wantLifetimes, stack.AddressTentative); err != nil {
  2377  						t.Error(err)
  2378  					}
  2379  				}
  2380  			}
  2381  
  2382  			// Receive an RA with prefix1 in an NDP Prefix Information option (PI)
  2383  			// with zero valid lifetime.
  2384  			e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, 0, 0))
  2385  			select {
  2386  			case e := <-ndpDisp.autoGenAddrC:
  2387  				t.Fatalf("unexpectedly auto-generated an address with 0 lifetime; event = %+v", e)
  2388  			default:
  2389  			}
  2390  
  2391  			// Receive an RA with prefix1 in an NDP Prefix Information option (PI)
  2392  			// with non-zero valid lifetime.
  2393  			prefix1VL := uint32(100)
  2394  			var prefix1PL uint32
  2395  			received := clock.NowMonotonic()
  2396  			e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, prefix1VL, prefix1PL))
  2397  			addr1Disp, err := expectAutoGenAddrNewEvent(&ndpDisp, addr1)
  2398  			if err != nil {
  2399  				t.Fatalf("error expecting prefix1 stable address generated event: %s", err)
  2400  			}
  2401  			expectAddrDispatcherTentative(addr1Disp, addressLifetimes(received, prefix1PL, prefix1VL))
  2402  			expectDADEventAsync(addr1.Address)
  2403  			if err := addr1Disp.expectChanged(addressLifetimes(received, prefix1PL, prefix1VL), stack.AddressAssigned); err != nil {
  2404  				t.Error(err)
  2405  			}
  2406  			select {
  2407  			case e := <-ndpDisp.autoGenAddrC:
  2408  				t.Fatalf("unexpectedly got an auto gen addr event = %+v", e)
  2409  			default:
  2410  			}
  2411  			if mismatch := addressCheck(s.NICInfo()[nicID].ProtocolAddresses, []tcpip.AddressWithPrefix{addr1}, nil); mismatch != "" {
  2412  				t.Fatal(mismatch)
  2413  			}
  2414  
  2415  			// Receive an RA with prefix1 in an NDP Prefix Information option (PI)
  2416  			// with non-zero valid & preferred lifetimes.
  2417  			tempAddr1 := newTempAddr(addr1.Address)
  2418  			prefix1PL = uint32(100)
  2419  			received = clock.NowMonotonic()
  2420  			e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, prefix1VL, prefix1PL))
  2421  			if err := addr1Disp.expectLifetimesChanged(addressLifetimes(received, prefix1PL, prefix1VL)); err != nil {
  2422  				t.Error(err)
  2423  			}
  2424  			tempAddr1Disp, err := expectAutoGenAddrNewEvent(&ndpDisp, tempAddr1)
  2425  			if err != nil {
  2426  				t.Fatalf("error expecting prefix1 temp address generated event: %s", err)
  2427  			}
  2428  			expectAddrDispatcherTentative(tempAddr1Disp, addressLifetimes(received, prefix1PL, prefix1VL))
  2429  			expectDADEventAsync(tempAddr1.Address)
  2430  			if err := tempAddr1Disp.expectChanged(addressLifetimes(received, prefix1PL, prefix1VL), stack.AddressAssigned); err != nil {
  2431  				t.Error(err)
  2432  			}
  2433  			if mismatch := addressCheck(s.NICInfo()[1].ProtocolAddresses, []tcpip.AddressWithPrefix{addr1, tempAddr1}, nil); mismatch != "" {
  2434  				t.Fatal(mismatch)
  2435  			}
  2436  
  2437  			// Receive an RA with prefix2 in an NDP Prefix Information option (PI)
  2438  			// with preferred lifetime > valid lifetime
  2439  			e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, 5, 6))
  2440  			select {
  2441  			case e := <-ndpDisp.autoGenAddrC:
  2442  				t.Fatalf("unexpectedly auto-generated an address with preferred lifetime > valid lifetime; event = %+v", e)
  2443  			default:
  2444  			}
  2445  			if mismatch := addressCheck(s.NICInfo()[nicID].ProtocolAddresses, []tcpip.AddressWithPrefix{addr1, tempAddr1}, nil); mismatch != "" {
  2446  				t.Fatal(mismatch)
  2447  			}
  2448  
  2449  			// Receive an RA with prefix2 in a PI with a valid lifetime that exceeds
  2450  			// the minimum and won't be reached in this test.
  2451  			tempAddr2 := newTempAddr(addr2.Address)
  2452  			lifetime2 := 2 * minVLSeconds
  2453  			received2 := clock.NowMonotonic()
  2454  			e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix2, true, true, lifetime2, lifetime2))
  2455  			addr2Disp, err := expectAutoGenAddrNewEvent(&ndpDisp, addr2)
  2456  			if err != nil {
  2457  				t.Fatalf("error expecting prefix2 stable address generated event: %s", err)
  2458  			}
  2459  			expectAddrDispatcherTentative(addr2Disp, addressLifetimes(received2, lifetime2, lifetime2))
  2460  			expectDADEventAsync(addr2.Address)
  2461  			if err := addr2Disp.expectChanged(addressLifetimes(received2, lifetime2, lifetime2), stack.AddressAssigned); err != nil {
  2462  				t.Error(err)
  2463  			}
  2464  
  2465  			clock.RunImmediatelyScheduledJobs()
  2466  			tempAddr2Disp, err := expectAutoGenAddrNewEvent(&ndpDisp, tempAddr2)
  2467  			if err != nil {
  2468  				t.Fatalf("error expecting prefix2 temp address generated event: %s", err)
  2469  			}
  2470  			expectAddrDispatcherTentative(tempAddr2Disp, addressLifetimes(received2, lifetime2, lifetime2))
  2471  			expectDADEventAsync(tempAddr2.Address)
  2472  			if err := tempAddr2Disp.expectChanged(addressLifetimes(received2, lifetime2, lifetime2), stack.AddressAssigned); err != nil {
  2473  				t.Error(err)
  2474  			}
  2475  			if mismatch := addressCheck(s.NICInfo()[nicID].ProtocolAddresses, []tcpip.AddressWithPrefix{addr1, tempAddr1, addr2, tempAddr2}, nil); mismatch != "" {
  2476  				t.Fatal(mismatch)
  2477  			}
  2478  
  2479  			// Deprecate prefix1.
  2480  			{
  2481  				prefix1VL := uint32(100)
  2482  				received = clock.NowMonotonic()
  2483  				e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, prefix1VL, 0))
  2484  				expectAutoGenAddrEvent(t, &ndpDisp, addr1, deprecatedAddr)
  2485  				if err := addr1Disp.expectLifetimesChanged(addressLifetimes(received, 0, prefix1VL)); err != nil {
  2486  					t.Error(err)
  2487  				}
  2488  				expectAutoGenAddrEvent(t, &ndpDisp, tempAddr1, deprecatedAddr)
  2489  				if err := tempAddr1Disp.expectLifetimesChanged(addressLifetimes(received, 0, prefix1VL)); err != nil {
  2490  					t.Error(err)
  2491  				}
  2492  				if mismatch := addressCheck(s.NICInfo()[nicID].ProtocolAddresses, []tcpip.AddressWithPrefix{addr1, tempAddr1, addr2, tempAddr2}, nil); mismatch != "" {
  2493  					t.Fatal(mismatch)
  2494  				}
  2495  			}
  2496  
  2497  			// Refresh lifetimes for prefix1.
  2498  			{
  2499  				prefix1VL := uint32(100)
  2500  				prefix1PL := uint32(100)
  2501  				received := clock.NowMonotonic()
  2502  				e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, prefix1VL, prefix1PL))
  2503  				if mismatch := addressCheck(s.NICInfo()[nicID].ProtocolAddresses, []tcpip.AddressWithPrefix{addr1, tempAddr1, addr2, tempAddr2}, nil); mismatch != "" {
  2504  					t.Fatal(mismatch)
  2505  				}
  2506  				if err := addr1Disp.expectLifetimesChanged(addressLifetimes(received, prefix1PL, prefix1VL)); err != nil {
  2507  					t.Error(err)
  2508  				}
  2509  				if err := tempAddr1Disp.expectLifetimesChanged(addressLifetimes(received, prefix1PL, prefix1VL)); err != nil {
  2510  					t.Error(err)
  2511  				}
  2512  			}
  2513  
  2514  			// Reduce valid lifetime and deprecate addresses of prefix1.
  2515  			received = clock.NowMonotonic()
  2516  			e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, minVLSeconds, 0))
  2517  			expectAutoGenAddrEvent(t, &ndpDisp, addr1, deprecatedAddr)
  2518  			expectAutoGenAddrEvent(t, &ndpDisp, tempAddr1, deprecatedAddr)
  2519  			if err := addr1Disp.expectLifetimesChanged(addressLifetimes(received, 0, minVLSeconds)); err != nil {
  2520  				t.Error(err)
  2521  			}
  2522  			if err := tempAddr1Disp.expectLifetimesChanged(addressLifetimes(received, 0, minVLSeconds)); err != nil {
  2523  				t.Error(err)
  2524  			}
  2525  			if mismatch := addressCheck(s.NICInfo()[nicID].ProtocolAddresses, []tcpip.AddressWithPrefix{addr1, tempAddr1, addr2, tempAddr2}, nil); mismatch != "" {
  2526  				t.Fatal(mismatch)
  2527  			}
  2528  
  2529  			// Wait for addrs of prefix1 to be invalidated. They should be
  2530  			// invalidated at the same time.
  2531  			clock.Advance(ipv6.MinPrefixInformationValidLifetimeForUpdate)
  2532  			select {
  2533  			case e := <-ndpDisp.autoGenAddrC:
  2534  				var nextAddr tcpip.AddressWithPrefix
  2535  				if e.addr == addr1 {
  2536  					if diff := checkAutoGenAddrEvent(e, addr1, invalidatedAddr); diff != "" {
  2537  						t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
  2538  					}
  2539  					nextAddr = tempAddr1
  2540  				} else {
  2541  					if diff := checkAutoGenAddrEvent(e, tempAddr1, invalidatedAddr); diff != "" {
  2542  						t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
  2543  					}
  2544  					nextAddr = addr1
  2545  				}
  2546  
  2547  				expectAutoGenAddrEvent(t, &ndpDisp, nextAddr, invalidatedAddr)
  2548  			default:
  2549  				t.Fatal("timed out waiting for addr auto gen event")
  2550  			}
  2551  			if err := addr1Disp.expectRemoved(stack.AddressRemovalInvalidated); err != nil {
  2552  				t.Error(err)
  2553  			}
  2554  			if err := tempAddr1Disp.expectRemoved(stack.AddressRemovalInvalidated); err != nil {
  2555  				t.Error(err)
  2556  			}
  2557  			if mismatch := addressCheck(s.NICInfo()[nicID].ProtocolAddresses, []tcpip.AddressWithPrefix{addr2, tempAddr2}, []tcpip.AddressWithPrefix{addr1, tempAddr1}); mismatch != "" {
  2558  				t.Fatal(mismatch)
  2559  			}
  2560  
  2561  			// Receive an RA with prefix2 in a PI w/ 0 lifetimes.
  2562  			e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix2, true, true, 0, 0))
  2563  			expectAutoGenAddrEvent(t, &ndpDisp, addr2, deprecatedAddr)
  2564  			expectAutoGenAddrEvent(t, &ndpDisp, tempAddr2, deprecatedAddr)
  2565  			select {
  2566  			case e := <-ndpDisp.autoGenAddrC:
  2567  				t.Errorf("got unexpected auto gen addr event = %+v", e)
  2568  			default:
  2569  			}
  2570  			// Addresses should be deprecated, but their valid-until should be untouched
  2571  			// as their remaining valid lifetime is too low.
  2572  			if err := addr2Disp.expectDeprecated(); err != nil {
  2573  				t.Error(err)
  2574  			}
  2575  			if err := tempAddr2Disp.expectDeprecated(); err != nil {
  2576  				t.Error(err)
  2577  			}
  2578  			if mismatch := addressCheck(s.NICInfo()[nicID].ProtocolAddresses, []tcpip.AddressWithPrefix{addr2, tempAddr2}, []tcpip.AddressWithPrefix{addr1, tempAddr1}); mismatch != "" {
  2579  				t.Fatal(mismatch)
  2580  			}
  2581  		})
  2582  	}
  2583  }
  2584  
  2585  // TestNoAutoGenTempAddrForLinkLocal test that temporary SLAAC addresses are not
  2586  // generated for auto generated link-local addresses.
  2587  func TestNoAutoGenTempAddrForLinkLocal(t *testing.T) {
  2588  	const nicID = 1
  2589  
  2590  	tests := []struct {
  2591  		name             string
  2592  		dupAddrTransmits uint8
  2593  		retransmitTimer  time.Duration
  2594  	}{
  2595  		{
  2596  			name: "DAD disabled",
  2597  		},
  2598  		{
  2599  			name:             "DAD enabled",
  2600  			dupAddrTransmits: 1,
  2601  			retransmitTimer:  time.Second,
  2602  		},
  2603  	}
  2604  
  2605  	for _, test := range tests {
  2606  		t.Run(test.name, func(t *testing.T) {
  2607  			const autoGenAddrCount = 1
  2608  			ndpDisp := ndpDispatcher{
  2609  				dadC:               make(chan ndpDADEvent, 1),
  2610  				autoGenAddrNewC:    make(chan ndpAutoGenAddrNewEvent, autoGenAddrCount),
  2611  				autoGenAddrC:       make(chan ndpAutoGenAddrEvent, autoGenAddrCount),
  2612  				autoGenInstallDisp: true,
  2613  			}
  2614  			e := channel.New(0, 1280, linkAddr1)
  2615  			clock := faketime.NewManualClock()
  2616  			s := stack.New(stack.Options{
  2617  				NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
  2618  					NDPConfigs: ipv6.NDPConfigurations{
  2619  						AutoGenTempGlobalAddresses: true,
  2620  					},
  2621  					DADConfigs: stack.DADConfigurations{
  2622  						DupAddrDetectTransmits: test.dupAddrTransmits,
  2623  						RetransmitTimer:        test.retransmitTimer,
  2624  					},
  2625  					NDPDisp:          &ndpDisp,
  2626  					AutoGenLinkLocal: true,
  2627  				})},
  2628  				Clock: clock,
  2629  			})
  2630  
  2631  			if err := s.CreateNIC(nicID, e); err != nil {
  2632  				t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
  2633  			}
  2634  
  2635  			// The stable link-local address should auto-generate and resolve DAD.
  2636  			addrDisp, err := expectAutoGenAddrNewEvent(&ndpDisp, tcpip.AddressWithPrefix{Address: llAddr1, PrefixLen: header.IIDOffsetInIPv6Address * 8})
  2637  			if err != nil {
  2638  				t.Fatalf("error expecting stable auto-gen address generated event: %s", err)
  2639  			}
  2640  			if test.dupAddrTransmits > 0 {
  2641  				if err := addrDisp.expectChanged(infiniteLifetimes(), stack.AddressTentative); err != nil {
  2642  					t.Error(err)
  2643  				}
  2644  			}
  2645  			clock.Advance(time.Duration(test.dupAddrTransmits) * test.retransmitTimer)
  2646  			select {
  2647  			case e := <-ndpDisp.dadC:
  2648  				if diff := checkDADEvent(e, nicID, llAddr1, &stack.DADSucceeded{}); diff != "" {
  2649  					t.Errorf("DAD event mismatch (-want +got):\n%s", diff)
  2650  				}
  2651  			default:
  2652  				t.Fatal("timed out waiting for DAD event")
  2653  			}
  2654  			if err := addrDisp.expectChanged(infiniteLifetimes(), stack.AddressAssigned); err != nil {
  2655  				t.Error(err)
  2656  			}
  2657  
  2658  			// No new addresses should be generated.
  2659  			select {
  2660  			case e := <-ndpDisp.autoGenAddrC:
  2661  				t.Errorf("got unexpected auto gen addr event = %+v", e)
  2662  			default:
  2663  			}
  2664  		})
  2665  	}
  2666  }
  2667  
  2668  // TestNoAutoGenTempAddrWithoutStableAddr tests that a temporary SLAAC address
  2669  // will not be generated until after DAD completes, even if a new Router
  2670  // Advertisement is received to refresh lifetimes.
  2671  func TestNoAutoGenTempAddrWithoutStableAddr(t *testing.T) {
  2672  	const (
  2673  		nicID           = 1
  2674  		dadTransmits    = 1
  2675  		retransmitTimer = 2 * time.Second
  2676  	)
  2677  
  2678  	prefix, _, addr := prefixSubnetAddr(0, linkAddr1)
  2679  	var tempIIDHistory [header.IIDSize]byte
  2680  	header.InitialTempIID(tempIIDHistory[:], nil, nicID)
  2681  	tempAddr := header.GenerateTempIPv6SLAACAddr(tempIIDHistory[:], addr.Address)
  2682  
  2683  	const autoGenAddrCount = 1
  2684  	ndpDisp := ndpDispatcher{
  2685  		dadC:               make(chan ndpDADEvent, 1),
  2686  		autoGenAddrNewC:    make(chan ndpAutoGenAddrNewEvent, autoGenAddrCount),
  2687  		autoGenAddrC:       make(chan ndpAutoGenAddrEvent, autoGenAddrCount),
  2688  		autoGenInstallDisp: true,
  2689  	}
  2690  	e := channel.New(0, 1280, linkAddr1)
  2691  	clock := faketime.NewManualClock()
  2692  	s := stack.New(stack.Options{
  2693  		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
  2694  			DADConfigs: stack.DADConfigurations{
  2695  				DupAddrDetectTransmits: dadTransmits,
  2696  				RetransmitTimer:        retransmitTimer,
  2697  			},
  2698  			NDPConfigs: ipv6.NDPConfigurations{
  2699  				HandleRAs:                  ipv6.HandlingRAsEnabledWhenForwardingDisabled,
  2700  				AutoGenGlobalAddresses:     true,
  2701  				AutoGenTempGlobalAddresses: true,
  2702  			},
  2703  			NDPDisp: &ndpDisp,
  2704  		})},
  2705  		Clock: clock,
  2706  	})
  2707  
  2708  	if err := s.CreateNIC(nicID, e); err != nil {
  2709  		t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
  2710  	}
  2711  
  2712  	// Receive an RA to trigger SLAAC for prefix.
  2713  	received, pl, vl := clock.NowMonotonic(), uint32(100), uint32(100)
  2714  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, vl, pl))
  2715  	addrDisp, err := expectAutoGenAddrNewEvent(&ndpDisp, addr)
  2716  	if err != nil {
  2717  		t.Fatalf("error expecting stable auto-gen address generated event: %s", err)
  2718  	}
  2719  	if err := addrDisp.expectChanged(addressLifetimes(received, pl, vl), stack.AddressTentative); err != nil {
  2720  		t.Error(err)
  2721  	}
  2722  
  2723  	// DAD on the stable address for prefix has not yet completed. Receiving a new
  2724  	// RA that would refresh lifetimes should not generate a temporary SLAAC
  2725  	// address for the prefix.
  2726  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, vl, pl))
  2727  	select {
  2728  	case e := <-ndpDisp.autoGenAddrC:
  2729  		t.Fatalf("unexpected auto gen addr event = %+v", e)
  2730  	default:
  2731  	}
  2732  
  2733  	// Wait for DAD to complete for the stable address then expect the temporary
  2734  	// address to be generated.
  2735  	clock.Advance(dadTransmits * retransmitTimer)
  2736  	select {
  2737  	case e := <-ndpDisp.dadC:
  2738  		if diff := checkDADEvent(e, nicID, addr.Address, &stack.DADSucceeded{}); diff != "" {
  2739  			t.Errorf("DAD event mismatch (-want +got):\n%s", diff)
  2740  		}
  2741  	default:
  2742  		t.Fatal("timed out waiting for DAD event")
  2743  	}
  2744  	if err := addrDisp.expectStateChanged(stack.AddressAssigned); err != nil {
  2745  		t.Error(err)
  2746  	}
  2747  	tempAddrDisp, err := expectAutoGenAddrNewEvent(&ndpDisp, tempAddr)
  2748  	if err != nil {
  2749  		t.Fatalf("error expecting temp auto-gen address generated event: %s", err)
  2750  	}
  2751  	tempAddrDisp.disable()
  2752  }
  2753  
  2754  type tempAddrState struct {
  2755  	addrWithPrefix tcpip.AddressWithPrefix
  2756  	generated      tcpip.MonotonicTime
  2757  	disp           *addressDispatcher
  2758  }
  2759  
  2760  // TestAutoGenTempAddrRegen tests that temporary SLAAC addresses are
  2761  // regenerated.
  2762  func TestAutoGenTempAddrRegen(t *testing.T) {
  2763  	const (
  2764  		nicID    = 1
  2765  		regenAdv = 2 * time.Second
  2766  
  2767  		numTempAddrs             = 3
  2768  		maxTempAddrValidLifetime = numTempAddrs * ipv6.MinPrefixInformationValidLifetimeForUpdate
  2769  	)
  2770  
  2771  	prefix, _, addr := prefixSubnetAddr(0, linkAddr1)
  2772  	var tempIIDHistory [header.IIDSize]byte
  2773  	header.InitialTempIID(tempIIDHistory[:], nil, nicID)
  2774  	var tempAddrs [numTempAddrs]tempAddrState
  2775  	for i := 0; i < len(tempAddrs); i++ {
  2776  		tempAddrs[i] = tempAddrState{
  2777  			addrWithPrefix: header.GenerateTempIPv6SLAACAddr(tempIIDHistory[:], addr.Address),
  2778  		}
  2779  	}
  2780  
  2781  	const autoGenAddrCount = 2
  2782  	ndpDisp := ndpDispatcher{
  2783  		autoGenAddrNewC:    make(chan ndpAutoGenAddrNewEvent, autoGenAddrCount),
  2784  		autoGenAddrC:       make(chan ndpAutoGenAddrEvent, autoGenAddrCount),
  2785  		autoGenInstallDisp: true,
  2786  	}
  2787  	e := channel.New(0, 1280, linkAddr1)
  2788  	ndpConfigs := ipv6.NDPConfigurations{
  2789  		HandleRAs:                    ipv6.HandlingRAsEnabledWhenForwardingDisabled,
  2790  		AutoGenGlobalAddresses:       true,
  2791  		AutoGenTempGlobalAddresses:   true,
  2792  		RegenAdvanceDuration:         regenAdv,
  2793  		MaxTempAddrValidLifetime:     maxTempAddrValidLifetime,
  2794  		MaxTempAddrPreferredLifetime: ipv6.MinPrefixInformationValidLifetimeForUpdate,
  2795  	}
  2796  	clock := faketime.NewManualClock()
  2797  	randSource := savingRandSource{
  2798  		s: rand.NewSource(time.Now().UnixNano()),
  2799  	}
  2800  	s := stack.New(stack.Options{
  2801  		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
  2802  			NDPConfigs: ndpConfigs,
  2803  			NDPDisp:    &ndpDisp,
  2804  		})},
  2805  		Clock:      clock,
  2806  		RandSource: &randSource,
  2807  	})
  2808  
  2809  	if err := s.CreateNIC(nicID, e); err != nil {
  2810  		t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
  2811  	}
  2812  
  2813  	expectAutoGenAddrEventAsync := func(addr tcpip.AddressWithPrefix, eventType ndpAutoGenAddrEventType, timeout time.Duration) {
  2814  		t.Helper()
  2815  
  2816  		clock.Advance(timeout)
  2817  		expectAutoGenAddrEvent(t, &ndpDisp, addr, eventType)
  2818  	}
  2819  
  2820  	tempDesyncFactor := time.Duration(randSource.lastInt63) % ipv6.MaxDesyncFactor
  2821  	effectiveMaxTempAddrPL := ipv6.MinPrefixInformationValidLifetimeForUpdate - tempDesyncFactor
  2822  	// The time since the last regeneration before a new temporary address is
  2823  	// generated.
  2824  	tempAddrRegenerationTime := effectiveMaxTempAddrPL - regenAdv
  2825  
  2826  	// Receive an RA with prefix1 in an NDP Prefix Information option (PI)
  2827  	// with non-zero valid & preferred lifetimes.
  2828  	received := clock.NowMonotonic()
  2829  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, minVLSeconds, minVLSeconds))
  2830  	addrDisp, err := expectAutoGenAddrNewEvent(&ndpDisp, addr)
  2831  	if err != nil {
  2832  		t.Fatalf("error expecting stable auto-gen address generated event: %s", err)
  2833  	}
  2834  	// Disable receiving events on the stable address since it's not of interest
  2835  	// to this particular test.
  2836  	addrDisp.disable()
  2837  	tempAddrs[0].disp, err = expectAutoGenAddrNewEvent(&ndpDisp, tempAddrs[0].addrWithPrefix)
  2838  	if err != nil {
  2839  		t.Fatalf("error expecting temp auto-gen address generated event: %s", err)
  2840  	}
  2841  	tempAddrs[0].generated = clock.NowMonotonic()
  2842  	// Since the max temporary address preferred lifetime is equal to the valid
  2843  	// lifetime of the prefix, the temporary address generated is preferred
  2844  	// until the max minus the desync factor.
  2845  	if err := tempAddrs[0].disp.expectChanged(stack.AddressLifetimes{
  2846  		ValidUntil:     received.Add(time.Duration(minVLSeconds) * time.Second),
  2847  		PreferredUntil: received.Add(effectiveMaxTempAddrPL),
  2848  	}, stack.AddressAssigned); err != nil {
  2849  		t.Error(err)
  2850  	}
  2851  	if mismatch := addressCheck(s.NICInfo()[nicID].ProtocolAddresses, []tcpip.AddressWithPrefix{addr, tempAddrs[0].addrWithPrefix}, nil); mismatch != "" {
  2852  		t.Fatal(mismatch)
  2853  	}
  2854  
  2855  	// Wait for regeneration
  2856  	clock.Advance(tempAddrRegenerationTime)
  2857  	tempAddrs[1].disp, err = expectAutoGenAddrNewEvent(&ndpDisp, tempAddrs[1].addrWithPrefix)
  2858  	if err != nil {
  2859  		t.Fatalf("error expecting new temp regenerated address event: %s", err)
  2860  	}
  2861  	tempAddrs[1].generated = clock.NowMonotonic()
  2862  	// New temp address generated with lifetimes of the prefix.
  2863  	if err := tempAddrs[1].disp.expectChanged(addressLifetimes(received, minVLSeconds, minVLSeconds), stack.AddressAssigned); err != nil {
  2864  		t.Error(err)
  2865  	}
  2866  	received = clock.NowMonotonic()
  2867  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, minVLSeconds, minVLSeconds))
  2868  	// The first temporary address only has valid lifetime refreshed.
  2869  	if err := tempAddrs[0].disp.expectValidUntilChanged(received.Add(time.Duration(minVLSeconds) * time.Second)); err != nil {
  2870  		t.Error(err)
  2871  	}
  2872  	if err := tempAddrs[1].disp.expectChanged(stack.AddressLifetimes{
  2873  		ValidUntil:     received.Add(time.Duration(minVLSeconds) * time.Second),
  2874  		PreferredUntil: received.Add(effectiveMaxTempAddrPL),
  2875  	}, stack.AddressAssigned); err != nil {
  2876  		t.Error(err)
  2877  	}
  2878  	if mismatch := addressCheck(s.NICInfo()[nicID].ProtocolAddresses, []tcpip.AddressWithPrefix{addr, tempAddrs[0].addrWithPrefix, tempAddrs[1].addrWithPrefix}, nil); mismatch != "" {
  2879  		t.Fatal(mismatch)
  2880  	}
  2881  	expectAutoGenAddrEventAsync(tempAddrs[0].addrWithPrefix, deprecatedAddr, regenAdv)
  2882  	if err := tempAddrs[0].disp.expectDeprecated(); err != nil {
  2883  		t.Error(err)
  2884  	}
  2885  
  2886  	// Wait for regeneration
  2887  	clock.Advance(tempAddrRegenerationTime - regenAdv)
  2888  	tempAddrs[2].disp, err = expectAutoGenAddrNewEvent(&ndpDisp, tempAddrs[2].addrWithPrefix)
  2889  	if err != nil {
  2890  		t.Fatalf("error expecting new temp twice-regenerated address event: %s", err)
  2891  	}
  2892  	tempAddrs[2].generated = clock.NowMonotonic()
  2893  	if err := tempAddrs[2].disp.expectChanged(addressLifetimes(received, minVLSeconds, minVLSeconds), stack.AddressAssigned); err != nil {
  2894  		t.Error(err)
  2895  	}
  2896  	expectAutoGenAddrEventAsync(tempAddrs[1].addrWithPrefix, deprecatedAddr, regenAdv)
  2897  	if err := tempAddrs[1].disp.expectDeprecated(); err != nil {
  2898  		t.Error(err)
  2899  	}
  2900  
  2901  	// Stop generating temporary addresses
  2902  	ndpConfigs.AutoGenTempGlobalAddresses = false
  2903  	if ipv6Ep, err := s.GetNetworkEndpoint(nicID, header.IPv6ProtocolNumber); err != nil {
  2904  		t.Fatalf("s.GetNetworkEndpoint(%d, %d): %s", nicID, header.IPv6ProtocolNumber, err)
  2905  	} else {
  2906  		ndpEP := ipv6Ep.(ipv6.NDPEndpoint)
  2907  		ndpEP.SetNDPConfigurations(ndpConfigs)
  2908  	}
  2909  
  2910  	// Refresh lifetimes and wait for the last temporary address to be deprecated.
  2911  	received = clock.NowMonotonic()
  2912  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, minVLSeconds, minVLSeconds))
  2913  	for i, tempAddrState := range tempAddrs {
  2914  		if i == 2 {
  2915  			if err := tempAddrState.disp.expectLifetimesChanged(stack.AddressLifetimes{
  2916  				ValidUntil: received.Add(time.Duration(minVLSeconds) * time.Second),
  2917  				// The effective max preferred lifetime since address generation is used
  2918  				// since it is less than the refreshed prefix preferred lifetime.
  2919  				PreferredUntil: tempAddrState.generated.Add(effectiveMaxTempAddrPL),
  2920  			}); err != nil {
  2921  				t.Error(err)
  2922  			}
  2923  		} else {
  2924  			if err := tempAddrState.disp.expectValidUntilChanged(received.Add(time.Duration(minVLSeconds) * time.Second)); err != nil {
  2925  				t.Errorf("addr %d error: %s", i, err)
  2926  			}
  2927  		}
  2928  	}
  2929  	expectAutoGenAddrEventAsync(tempAddrs[2].addrWithPrefix, deprecatedAddr, effectiveMaxTempAddrPL-regenAdv)
  2930  	if err := tempAddrs[2].disp.expectDeprecated(); err != nil {
  2931  		t.Error(err)
  2932  	}
  2933  
  2934  	// Refresh lifetimes such that the prefix is valid and preferred forever.
  2935  	//
  2936  	// This should not affect the lifetimes of temporary addresses because they
  2937  	// are capped by the maximum valid and preferred lifetimes for temporary
  2938  	// addresses.
  2939  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, infiniteLifetimeSeconds, infiniteLifetimeSeconds))
  2940  	for i, tempAddrState := range tempAddrs {
  2941  		if err := tempAddrState.disp.expectValidUntilChanged(tempAddrState.generated.Add(maxTempAddrValidLifetime)); err != nil {
  2942  			t.Errorf("addr %d error: %s", i, err)
  2943  		}
  2944  	}
  2945  
  2946  	// Wait for all the temporary addresses to get invalidated.
  2947  	invalidateAfter := maxTempAddrValidLifetime - clock.NowMonotonic().Sub(tcpip.MonotonicTime{})
  2948  	var tempAddrWithPrefix [numTempAddrs]tcpip.AddressWithPrefix
  2949  	for i, tempAddrState := range tempAddrs {
  2950  		tempAddrWithPrefix[i] = tempAddrState.addrWithPrefix
  2951  		expectAutoGenAddrEventAsync(tempAddrState.addrWithPrefix, invalidatedAddr, invalidateAfter)
  2952  		invalidateAfter = tempAddrRegenerationTime
  2953  		if err := tempAddrState.disp.expectRemoved(stack.AddressRemovalInvalidated); err != nil {
  2954  			t.Errorf("addr %d error: %s", i, err)
  2955  		}
  2956  	}
  2957  	if mismatch := addressCheck(s.NICInfo()[nicID].ProtocolAddresses, []tcpip.AddressWithPrefix{addr}, tempAddrWithPrefix[:]); mismatch != "" {
  2958  		t.Fatal(mismatch)
  2959  	}
  2960  }
  2961  
  2962  // TestAutoGenTempAddrRegenJobUpdates tests that a temporary address's
  2963  // regeneration job gets updated when refreshing the address's lifetimes.
  2964  func TestAutoGenTempAddrRegenJobUpdates(t *testing.T) {
  2965  	const (
  2966  		nicID    = 1
  2967  		regenAdv = 2 * time.Second
  2968  
  2969  		numTempAddrs                        = 3
  2970  		maxTempAddrPreferredLifetime        = ipv6.MinPrefixInformationValidLifetimeForUpdate
  2971  		maxTempAddrPreferredLifetimeSeconds = uint32(maxTempAddrPreferredLifetime / time.Second)
  2972  	)
  2973  
  2974  	prefix, _, addr := prefixSubnetAddr(0, linkAddr1)
  2975  	var tempIIDHistory [header.IIDSize]byte
  2976  	header.InitialTempIID(tempIIDHistory[:], nil, nicID)
  2977  	var tempAddrs [numTempAddrs]tempAddrState
  2978  	for i := 0; i < len(tempAddrs); i++ {
  2979  		tempAddrs[i] = tempAddrState{
  2980  			addrWithPrefix: header.GenerateTempIPv6SLAACAddr(tempIIDHistory[:], addr.Address),
  2981  		}
  2982  	}
  2983  
  2984  	const autoGenAddrCount = 2
  2985  	ndpDisp := ndpDispatcher{
  2986  		autoGenAddrNewC:    make(chan ndpAutoGenAddrNewEvent, autoGenAddrCount),
  2987  		autoGenAddrC:       make(chan ndpAutoGenAddrEvent, autoGenAddrCount),
  2988  		autoGenInstallDisp: true,
  2989  	}
  2990  	e := channel.New(0, 1280, linkAddr1)
  2991  	ndpConfigs := ipv6.NDPConfigurations{
  2992  		HandleRAs:                    ipv6.HandlingRAsEnabledWhenForwardingDisabled,
  2993  		AutoGenGlobalAddresses:       true,
  2994  		AutoGenTempGlobalAddresses:   true,
  2995  		RegenAdvanceDuration:         regenAdv,
  2996  		MaxTempAddrPreferredLifetime: maxTempAddrPreferredLifetime,
  2997  		MaxTempAddrValidLifetime:     maxTempAddrPreferredLifetime * 2,
  2998  	}
  2999  	clock := faketime.NewManualClock()
  3000  	initialTime := clock.NowMonotonic()
  3001  	randSource := savingRandSource{
  3002  		s: rand.NewSource(time.Now().UnixNano()),
  3003  	}
  3004  	s := stack.New(stack.Options{
  3005  		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
  3006  			NDPConfigs: ndpConfigs,
  3007  			NDPDisp:    &ndpDisp,
  3008  		})},
  3009  		Clock:      clock,
  3010  		RandSource: &randSource,
  3011  	})
  3012  
  3013  	if err := s.CreateNIC(nicID, e); err != nil {
  3014  		t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
  3015  	}
  3016  
  3017  	tempDesyncFactor := time.Duration(randSource.lastInt63) % ipv6.MaxDesyncFactor
  3018  	effectiveMaxTempAddrPL := maxTempAddrPreferredLifetime - tempDesyncFactor
  3019  
  3020  	expectAutoGenAddrEventAsync := func(addr tcpip.AddressWithPrefix, eventType ndpAutoGenAddrEventType, timeout time.Duration) {
  3021  		t.Helper()
  3022  
  3023  		clock.Advance(timeout)
  3024  		expectAutoGenAddrEvent(t, &ndpDisp, addr, eventType)
  3025  	}
  3026  
  3027  	// Receive an RA with prefix1 in an NDP Prefix Information option (PI)
  3028  	// with non-zero valid & preferred lifetimes.
  3029  	received := clock.NowMonotonic()
  3030  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, maxTempAddrPreferredLifetimeSeconds, maxTempAddrPreferredLifetimeSeconds))
  3031  	addrDisp, err := expectAutoGenAddrNewEvent(&ndpDisp, addr)
  3032  	if err != nil {
  3033  		t.Fatalf("error expecting stable auto-gen address generated event: %s", err)
  3034  	}
  3035  	// Ignore events about the stable address, since that's not relevant to this test.
  3036  	addrDisp.disable()
  3037  	tempAddrs[0].disp, err = expectAutoGenAddrNewEvent(&ndpDisp, tempAddrs[0].addrWithPrefix)
  3038  	if err != nil {
  3039  		t.Fatalf("error expecting temp auto-gen address generated event: %s", err)
  3040  	}
  3041  	tempAddrs[0].generated = clock.NowMonotonic()
  3042  	if err := tempAddrs[0].disp.expectChanged(stack.AddressLifetimes{
  3043  		ValidUntil:     received.Add(maxTempAddrPreferredLifetime),
  3044  		PreferredUntil: received.Add(effectiveMaxTempAddrPL),
  3045  	}, stack.AddressAssigned); err != nil {
  3046  		t.Error(err)
  3047  	}
  3048  	if mismatch := addressCheck(s.NICInfo()[nicID].ProtocolAddresses, []tcpip.AddressWithPrefix{addr, tempAddrs[0].addrWithPrefix}, nil); mismatch != "" {
  3049  		t.Fatal(mismatch)
  3050  	}
  3051  
  3052  	// Deprecate the prefix.
  3053  	//
  3054  	// A new temporary address should be generated after the regeneration
  3055  	// time has passed since the prefix is deprecated.
  3056  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, maxTempAddrPreferredLifetimeSeconds, 0))
  3057  	expectAutoGenAddrEvent(t, &ndpDisp, addr, deprecatedAddr)
  3058  	expectAutoGenAddrEvent(t, &ndpDisp, tempAddrs[0].addrWithPrefix, deprecatedAddr)
  3059  	if err := tempAddrs[0].disp.expectDeprecated(); err != nil {
  3060  		t.Error(err)
  3061  	}
  3062  	select {
  3063  	case e := <-ndpDisp.autoGenAddrC:
  3064  		t.Fatalf("unexpected auto gen addr event = %#v", e)
  3065  	default:
  3066  	}
  3067  
  3068  	// The time since the last regeneration before a new temporary address is
  3069  	// generated.
  3070  	tempAddrRegenenerationTime := effectiveMaxTempAddrPL - regenAdv
  3071  
  3072  	// Advance the clock by the regeneration time but don't expect a new temporary
  3073  	// address as the prefix is deprecated.
  3074  	clock.Advance(tempAddrRegenenerationTime)
  3075  	select {
  3076  	case e := <-ndpDisp.autoGenAddrC:
  3077  		t.Fatalf("unexpected auto gen addr event = %#v", e)
  3078  	default:
  3079  	}
  3080  
  3081  	// Prefer the prefix again.
  3082  	//
  3083  	// A new temporary address should immediately be generated since the
  3084  	// regeneration time has already passed since the last address was generated
  3085  	// - this regeneration does not depend on a job.
  3086  	received = clock.NowMonotonic()
  3087  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, maxTempAddrPreferredLifetimeSeconds, maxTempAddrPreferredLifetimeSeconds))
  3088  	if err := tempAddrs[0].disp.expectLifetimesChanged(
  3089  		stack.AddressLifetimes{
  3090  			ValidUntil:     received.Add(maxTempAddrPreferredLifetime),
  3091  			PreferredUntil: tempAddrs[0].generated.Add(effectiveMaxTempAddrPL),
  3092  		}); err != nil {
  3093  		t.Error(err)
  3094  	}
  3095  	tempAddrs[1].disp, err = expectAutoGenAddrNewEvent(&ndpDisp, tempAddrs[1].addrWithPrefix)
  3096  	if err != nil {
  3097  		t.Fatalf("error expecting temp auto-gen address regenerated event: %s", err)
  3098  	}
  3099  	tempAddrs[1].generated = clock.NowMonotonic()
  3100  	if err := tempAddrs[1].disp.expectChanged(stack.AddressLifetimes{
  3101  		ValidUntil:     received.Add(maxTempAddrPreferredLifetime),
  3102  		PreferredUntil: received.Add(effectiveMaxTempAddrPL),
  3103  	}, stack.AddressAssigned); err != nil {
  3104  		t.Error(err)
  3105  	}
  3106  	// Wait for the first temporary address to be deprecated.
  3107  	expectAutoGenAddrEventAsync(tempAddrs[0].addrWithPrefix, deprecatedAddr, regenAdv)
  3108  	if err := tempAddrs[0].disp.expectDeprecated(); err != nil {
  3109  		t.Error(err)
  3110  	}
  3111  	select {
  3112  	case e := <-ndpDisp.autoGenAddrC:
  3113  		t.Fatalf("unexpected auto gen addr event = %s", e)
  3114  	default:
  3115  	}
  3116  
  3117  	// Increase the maximum lifetimes for temporary addresses to large values
  3118  	// then refresh the lifetimes of the prefix.
  3119  	//
  3120  	// A new address should not be generated after the regeneration time that was
  3121  	// expected for the previous check. This is because the preferred lifetime for
  3122  	// the temporary addresses has increased, so it will take more time to
  3123  	// regenerate a new temporary address. Note, new addresses are only
  3124  	// regenerated after the preferred lifetime - the regenerate advance duration
  3125  	// has passed.
  3126  	const largeLifetimeSeconds = minVLSeconds * 2
  3127  	const largeLifetime = time.Duration(largeLifetimeSeconds) * time.Second
  3128  	ndpConfigs.MaxTempAddrValidLifetime = 2 * largeLifetime
  3129  	ndpConfigs.MaxTempAddrPreferredLifetime = largeLifetime
  3130  	ipv6Ep, tcpipErr := s.GetNetworkEndpoint(nicID, header.IPv6ProtocolNumber)
  3131  	if tcpipErr != nil {
  3132  		t.Fatalf("s.GetNetworkEndpoint(%d, %d): %s", nicID, header.IPv6ProtocolNumber, tcpipErr)
  3133  	}
  3134  	ndpEP := ipv6Ep.(ipv6.NDPEndpoint)
  3135  	ndpEP.SetNDPConfigurations(ndpConfigs)
  3136  	received = clock.NowMonotonic()
  3137  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, largeLifetimeSeconds, largeLifetimeSeconds))
  3138  	for i := 0; i <= 1; i++ {
  3139  		if err := tempAddrs[i].disp.expectLifetimesChanged(stack.AddressLifetimes{
  3140  			ValidUntil:     received.Add(largeLifetime),
  3141  			PreferredUntil: tempAddrs[i].generated.Add(largeLifetime - tempDesyncFactor),
  3142  		}); err != nil {
  3143  			t.Errorf("addr %d dispatcher error: %s", i, err)
  3144  		}
  3145  	}
  3146  	timeSinceInitialTime := clock.NowMonotonic().Sub(initialTime)
  3147  	clock.Advance(largeLifetime - timeSinceInitialTime)
  3148  	expectAutoGenAddrEvent(t, &ndpDisp, tempAddrs[0].addrWithPrefix, deprecatedAddr)
  3149  	if err := tempAddrs[0].disp.expectDeprecated(); err != nil {
  3150  		t.Error(err)
  3151  	}
  3152  	// to offset the advancement of time to test the first temporary address's
  3153  	// deprecation after the second was generated
  3154  	advLess := regenAdv
  3155  	clock.Advance(timeSinceInitialTime - advLess - (tempDesyncFactor + regenAdv))
  3156  	tempAddrs[2].disp, err = expectAutoGenAddrNewEvent(&ndpDisp, tempAddrs[2].addrWithPrefix)
  3157  	if err != nil {
  3158  		t.Fatalf("error expecting temp auto-gen address twice-regenerated event: %s", err)
  3159  	}
  3160  	tempAddrs[2].generated = clock.NowMonotonic()
  3161  	if err := tempAddrs[2].disp.expectChanged(addressLifetimes(received, largeLifetimeSeconds, largeLifetimeSeconds), stack.AddressAssigned); err != nil {
  3162  		t.Error(err)
  3163  	}
  3164  	expectAutoGenAddrEventAsync(tempAddrs[1].addrWithPrefix, deprecatedAddr, regenAdv)
  3165  	if err := tempAddrs[1].disp.expectDeprecated(); err != nil {
  3166  		t.Error(err)
  3167  	}
  3168  	select {
  3169  	case e := <-ndpDisp.autoGenAddrC:
  3170  		t.Fatalf("unexpected auto gen addr event = %+v", e)
  3171  	default:
  3172  	}
  3173  }
  3174  
  3175  // TestMixedSLAACAddrConflictRegen tests SLAAC address regeneration in response
  3176  // to a mix of DAD conflicts and NIC-local conflicts.
  3177  func TestMixedSLAACAddrConflictRegen(t *testing.T) {
  3178  	const (
  3179  		nicID           = 1
  3180  		nicName         = "nic"
  3181  		lifetimeSeconds = 9999
  3182  		// From stack.maxSLAACAddrLocalRegenAttempts
  3183  		maxSLAACAddrLocalRegenAttempts = 10
  3184  		// We use 2 more addresses than the maximum local regeneration attempts
  3185  		// because we want to also trigger regeneration in response to a DAD
  3186  		// conflicts for this test.
  3187  		maxAddrs         = maxSLAACAddrLocalRegenAttempts + 2
  3188  		dupAddrTransmits = 1
  3189  		retransmitTimer  = time.Second
  3190  	)
  3191  
  3192  	var tempIIDHistoryWithModifiedEUI64 [header.IIDSize]byte
  3193  	header.InitialTempIID(tempIIDHistoryWithModifiedEUI64[:], nil, nicID)
  3194  
  3195  	var tempIIDHistoryWithOpaqueIID [header.IIDSize]byte
  3196  	header.InitialTempIID(tempIIDHistoryWithOpaqueIID[:], nil, nicID)
  3197  
  3198  	prefix, subnet, stableAddrWithModifiedEUI64 := prefixSubnetAddr(0, linkAddr1)
  3199  	var stableAddrsWithOpaqueIID [maxAddrs]tcpip.AddressWithPrefix
  3200  	var tempAddrsWithOpaqueIID [maxAddrs]tcpip.AddressWithPrefix
  3201  	var tempAddrsWithModifiedEUI64 [maxAddrs]tcpip.AddressWithPrefix
  3202  	subnetID := subnet.ID()
  3203  	addrBytes := subnetID.AsSlice()
  3204  	for i := 0; i < maxAddrs; i++ {
  3205  		stableAddrsWithOpaqueIID[i] = tcpip.AddressWithPrefix{
  3206  			Address:   tcpip.AddrFromSlice(header.AppendOpaqueInterfaceIdentifier(addrBytes[:header.IIDOffsetInIPv6Address], subnet, nicName, uint8(i), nil)),
  3207  			PrefixLen: header.IIDOffsetInIPv6Address * 8,
  3208  		}
  3209  		// When generating temporary addresses, the resolved stable address for the
  3210  		// SLAAC prefix will be the first address stable address generated for the
  3211  		// prefix as we will not simulate address conflicts for the stable addresses
  3212  		// in tests involving temporary addresses. Address conflicts for stable
  3213  		// addresses will be done in their own tests.
  3214  		tempAddrsWithOpaqueIID[i] = header.GenerateTempIPv6SLAACAddr(tempIIDHistoryWithOpaqueIID[:], stableAddrsWithOpaqueIID[0].Address)
  3215  		tempAddrsWithModifiedEUI64[i] = header.GenerateTempIPv6SLAACAddr(tempIIDHistoryWithModifiedEUI64[:], stableAddrWithModifiedEUI64.Address)
  3216  	}
  3217  
  3218  	tests := []struct {
  3219  		name          string
  3220  		addrs         []tcpip.AddressWithPrefix
  3221  		tempAddrs     bool
  3222  		initialExpect tcpip.AddressWithPrefix
  3223  		maxAddrs      int
  3224  		nicNameFromID func(tcpip.NICID, string) string
  3225  	}{
  3226  		{
  3227  			name:     "Stable addresses with opaque IIDs",
  3228  			addrs:    stableAddrsWithOpaqueIID[:],
  3229  			maxAddrs: 1,
  3230  			nicNameFromID: func(tcpip.NICID, string) string {
  3231  				return nicName
  3232  			},
  3233  		},
  3234  		{
  3235  			name:          "Temporary addresses with opaque IIDs",
  3236  			addrs:         tempAddrsWithOpaqueIID[:],
  3237  			tempAddrs:     true,
  3238  			initialExpect: stableAddrsWithOpaqueIID[0],
  3239  			maxAddrs:      1 /* initial (stable) address */ + maxSLAACAddrLocalRegenAttempts,
  3240  			nicNameFromID: func(tcpip.NICID, string) string {
  3241  				return nicName
  3242  			},
  3243  		},
  3244  		{
  3245  			name:          "Temporary addresses with modified EUI64",
  3246  			addrs:         tempAddrsWithModifiedEUI64[:],
  3247  			tempAddrs:     true,
  3248  			maxAddrs:      1 /* initial (stable) address */ + maxSLAACAddrLocalRegenAttempts,
  3249  			initialExpect: stableAddrWithModifiedEUI64,
  3250  		},
  3251  	}
  3252  
  3253  	for _, test := range tests {
  3254  		t.Run(test.name, func(t *testing.T) {
  3255  			ndpDisp := ndpDispatcher{
  3256  				autoGenAddrNewC: make(chan ndpAutoGenAddrNewEvent, test.maxAddrs),
  3257  				// We may receive a deprecated and invalidated event for each SLAAC
  3258  				// address that is assigned.
  3259  				autoGenAddrC: make(chan ndpAutoGenAddrEvent, test.maxAddrs*2),
  3260  			}
  3261  			e := channel.New(0, 1280, linkAddr1)
  3262  			clock := faketime.NewManualClock()
  3263  			s := stack.New(stack.Options{
  3264  				Clock: clock,
  3265  				NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
  3266  					NDPConfigs: ipv6.NDPConfigurations{
  3267  						HandleRAs:                     ipv6.HandlingRAsEnabledWhenForwardingDisabled,
  3268  						AutoGenGlobalAddresses:        true,
  3269  						AutoGenTempGlobalAddresses:    test.tempAddrs,
  3270  						AutoGenAddressConflictRetries: 1,
  3271  					},
  3272  					NDPDisp: &ndpDisp,
  3273  					OpaqueIIDOpts: ipv6.OpaqueInterfaceIdentifierOptions{
  3274  						NICNameFromID: test.nicNameFromID,
  3275  					},
  3276  				})},
  3277  				TransportProtocols: []stack.TransportProtocolFactory{udp.NewProtocol},
  3278  			})
  3279  
  3280  			s.SetRouteTable([]tcpip.Route{{
  3281  				Destination: header.IPv6EmptySubnet,
  3282  				Gateway:     llAddr2,
  3283  				NIC:         nicID,
  3284  			}})
  3285  
  3286  			if err := s.CreateNIC(nicID, e); err != nil {
  3287  				t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
  3288  			}
  3289  
  3290  			manuallyAssignedAddresses := make(map[tcpip.Address]struct{})
  3291  			for j := 0; j < len(test.addrs)-1; j++ {
  3292  				// The NIC will not attempt to generate an address in response to a
  3293  				// NIC-local conflict after some maximum number of attempts. We skip
  3294  				// creating a conflict for the address that would be generated as part
  3295  				// of the last attempt so we can simulate a DAD conflict for this
  3296  				// address and restart the NIC-local generation process.
  3297  				if j == maxSLAACAddrLocalRegenAttempts-1 {
  3298  					continue
  3299  				}
  3300  
  3301  				protocolAddr := tcpip.ProtocolAddress{
  3302  					Protocol:          ipv6.ProtocolNumber,
  3303  					AddressWithPrefix: test.addrs[j].Address.WithPrefix(),
  3304  				}
  3305  				if err := s.AddProtocolAddress(nicID, protocolAddr, stack.AddressProperties{}); err != nil {
  3306  					t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", nicID, protocolAddr, err)
  3307  				}
  3308  
  3309  				manuallyAssignedAddresses[test.addrs[j].Address] = struct{}{}
  3310  			}
  3311  
  3312  			expectAutoGenAddrNewEventAsync := func(addr tcpip.AddressWithPrefix) {
  3313  				t.Helper()
  3314  
  3315  				e := <-ndpDisp.autoGenAddrNewC
  3316  				if diff := cmp.Diff(
  3317  					ndpAutoGenAddrNewEvent{nicID: 1, addr: addr},
  3318  					e,
  3319  					cmp.AllowUnexported(e),
  3320  					cmp.FilterValues(func(*addressDispatcher, *addressDispatcher) bool { return true }, cmp.Ignore()),
  3321  				); diff != "" {
  3322  					t.Errorf("auto-gen new addr event mismatch (-want +got):\n%s", diff)
  3323  				}
  3324  				if e.addrDisp != nil {
  3325  					t.Error("auto-gen new addr event unexpectedly contains address dispatcher")
  3326  				}
  3327  			}
  3328  
  3329  			expectDADEventAsync := func(addr tcpip.Address) {
  3330  				t.Helper()
  3331  
  3332  				clock.Advance(dupAddrTransmits * retransmitTimer)
  3333  				if diff := checkDADEvent(<-ndpDisp.dadC, nicID, addr, &stack.DADSucceeded{}); diff != "" {
  3334  					t.Errorf("DAD event mismatch (-want +got):\n%s", diff)
  3335  				}
  3336  			}
  3337  
  3338  			// Enable DAD.
  3339  			ndpDisp.dadC = make(chan ndpDADEvent, 2)
  3340  			if ipv6Ep, err := s.GetNetworkEndpoint(nicID, header.IPv6ProtocolNumber); err != nil {
  3341  				t.Fatalf("s.GetNetworkEndpoint(%d, %d): %s", nicID, header.IPv6ProtocolNumber, err)
  3342  			} else {
  3343  				ndpEP := ipv6Ep.(stack.DuplicateAddressDetector)
  3344  				ndpEP.SetDADConfigurations(stack.DADConfigurations{
  3345  					DupAddrDetectTransmits: dupAddrTransmits,
  3346  					RetransmitTimer:        retransmitTimer,
  3347  				})
  3348  			}
  3349  
  3350  			// Do SLAAC for prefix.
  3351  			e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, lifetimeSeconds, lifetimeSeconds))
  3352  			if test.initialExpect != (tcpip.AddressWithPrefix{}) {
  3353  				if _, err := expectAutoGenAddrNewEvent(&ndpDisp, test.initialExpect); err != nil {
  3354  					t.Fatalf("error expecting auto-gen address generated event: %s", err)
  3355  				}
  3356  				expectDADEventAsync(test.initialExpect.Address)
  3357  			}
  3358  
  3359  			// The last local generation attempt should succeed, but we introduce a
  3360  			// DAD failure to restart the local generation process.
  3361  			addr := test.addrs[maxSLAACAddrLocalRegenAttempts-1]
  3362  			expectAutoGenAddrNewEventAsync(addr)
  3363  			rxNDPSolicit(e, addr.Address)
  3364  			select {
  3365  			case e := <-ndpDisp.dadC:
  3366  				if diff := checkDADEvent(e, nicID, addr.Address, &stack.DADDupAddrDetected{}); diff != "" {
  3367  					t.Errorf("DAD event mismatch (-want +got):\n%s", diff)
  3368  				}
  3369  			default:
  3370  				t.Fatal("expected DAD event")
  3371  			}
  3372  			expectAutoGenAddrEvent(t, &ndpDisp, addr, invalidatedAddr)
  3373  
  3374  			// The last address generated should resolve DAD.
  3375  			addr = test.addrs[len(test.addrs)-1]
  3376  			expectAutoGenAddrNewEventAsync(addr)
  3377  			expectDADEventAsync(addr.Address)
  3378  
  3379  			select {
  3380  			case e := <-ndpDisp.autoGenAddrC:
  3381  				t.Fatalf("unexpected auto gen addr event = %+v", e)
  3382  			default:
  3383  			}
  3384  
  3385  			// Wait for all the SLAAC addresses to be invalidated.
  3386  			clock.Advance(lifetimeSeconds * time.Second)
  3387  			gotAddresses := make(map[tcpip.Address]struct{})
  3388  			for _, a := range s.NICInfo()[nicID].ProtocolAddresses {
  3389  				gotAddresses[a.AddressWithPrefix.Address] = struct{}{}
  3390  			}
  3391  			if diff := cmp.Diff(manuallyAssignedAddresses, gotAddresses); diff != "" {
  3392  				t.Fatalf("assigned addresses mismatch (-want +got):\n%s", diff)
  3393  			}
  3394  		})
  3395  	}
  3396  }
  3397  
  3398  // stackAndNdpDispatcherWithDefaultRoute returns an ndpDispatcher,
  3399  // channel.Endpoint and stack.Stack.
  3400  //
  3401  // stack.Stack will have a default route through the router (llAddr3) installed
  3402  // and a static link-address (linkAddr3) added to the link address cache for the
  3403  // router.
  3404  func stackAndNdpDispatcherWithDefaultRoute(t *testing.T, nicID tcpip.NICID) (*ndpDispatcher, *channel.Endpoint, *stack.Stack, *faketime.ManualClock) {
  3405  	t.Helper()
  3406  	const autoGenAddrCount = 1
  3407  	ndpDisp := &ndpDispatcher{
  3408  		autoGenAddrNewC: make(chan ndpAutoGenAddrNewEvent, autoGenAddrCount),
  3409  		autoGenAddrC:    make(chan ndpAutoGenAddrEvent, autoGenAddrCount),
  3410  	}
  3411  	e := channel.New(0, 1280, linkAddr1)
  3412  	e.LinkEPCapabilities |= stack.CapabilityResolutionRequired
  3413  	clock := faketime.NewManualClock()
  3414  	s := stack.New(stack.Options{
  3415  		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
  3416  			NDPConfigs: ipv6.NDPConfigurations{
  3417  				HandleRAs:              ipv6.HandlingRAsEnabledWhenForwardingDisabled,
  3418  				AutoGenGlobalAddresses: true,
  3419  			},
  3420  			NDPDisp: ndpDisp,
  3421  		})},
  3422  		TransportProtocols: []stack.TransportProtocolFactory{udp.NewProtocol},
  3423  		Clock:              clock,
  3424  	})
  3425  	if err := s.CreateNIC(nicID, e); err != nil {
  3426  		t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
  3427  	}
  3428  	s.SetRouteTable([]tcpip.Route{{
  3429  		Destination: header.IPv6EmptySubnet,
  3430  		Gateway:     llAddr3,
  3431  		NIC:         nicID,
  3432  	}})
  3433  
  3434  	if err := s.AddStaticNeighbor(nicID, ipv6.ProtocolNumber, llAddr3, linkAddr3); err != nil {
  3435  		t.Fatalf("s.AddStaticNeighbor(%d, %d, %s, %s): %s", nicID, ipv6.ProtocolNumber, llAddr3, linkAddr3, err)
  3436  	}
  3437  	return ndpDisp, e, s, clock
  3438  }
  3439  
  3440  // addrForNewConnectionTo returns the local address used when creating a new
  3441  // connection to addr.
  3442  func addrForNewConnectionTo(t *testing.T, s *stack.Stack, addr tcpip.FullAddress) tcpip.Address {
  3443  	t.Helper()
  3444  
  3445  	wq := waiter.Queue{}
  3446  	we, ch := waiter.NewChannelEntry(waiter.ReadableEvents)
  3447  	wq.EventRegister(&we)
  3448  	defer wq.EventUnregister(&we)
  3449  	defer close(ch)
  3450  	ep, err := s.NewEndpoint(header.UDPProtocolNumber, header.IPv6ProtocolNumber, &wq)
  3451  	if err != nil {
  3452  		t.Fatalf("s.NewEndpoint(%d, %d, _): %s", header.UDPProtocolNumber, header.IPv6ProtocolNumber, err)
  3453  	}
  3454  	defer ep.Close()
  3455  	ep.SocketOptions().SetV6Only(true)
  3456  	if err := ep.Connect(addr); err != nil {
  3457  		t.Fatalf("ep.Connect(%+v): %s", addr, err)
  3458  	}
  3459  	got, err := ep.GetLocalAddress()
  3460  	if err != nil {
  3461  		t.Fatalf("ep.GetLocalAddress(): %s", err)
  3462  	}
  3463  	return got.Addr
  3464  }
  3465  
  3466  // addrForNewConnection returns the local address used when creating a new
  3467  // connection.
  3468  func addrForNewConnection(t *testing.T, s *stack.Stack) tcpip.Address {
  3469  	t.Helper()
  3470  
  3471  	return addrForNewConnectionTo(t, s, dstAddr)
  3472  }
  3473  
  3474  // addrForNewConnectionWithAddr returns the local address used when creating a
  3475  // new connection with a specific local address.
  3476  func addrForNewConnectionWithAddr(t *testing.T, s *stack.Stack, addr tcpip.FullAddress) tcpip.Address {
  3477  	t.Helper()
  3478  
  3479  	wq := waiter.Queue{}
  3480  	we, ch := waiter.NewChannelEntry(waiter.ReadableEvents)
  3481  	wq.EventRegister(&we)
  3482  	defer wq.EventUnregister(&we)
  3483  	defer close(ch)
  3484  	ep, err := s.NewEndpoint(header.UDPProtocolNumber, header.IPv6ProtocolNumber, &wq)
  3485  	if err != nil {
  3486  		t.Fatalf("s.NewEndpoint(%d, %d, _): %s", header.UDPProtocolNumber, header.IPv6ProtocolNumber, err)
  3487  	}
  3488  	defer ep.Close()
  3489  	ep.SocketOptions().SetV6Only(true)
  3490  	if err := ep.Bind(addr); err != nil {
  3491  		t.Fatalf("ep.Bind(%+v): %s", addr, err)
  3492  	}
  3493  	if err := ep.Connect(dstAddr); err != nil {
  3494  		t.Fatalf("ep.Connect(%+v): %s", dstAddr, err)
  3495  	}
  3496  	got, err := ep.GetLocalAddress()
  3497  	if err != nil {
  3498  		t.Fatalf("ep.GetLocalAddress(): %s", err)
  3499  	}
  3500  	return got.Addr
  3501  }
  3502  
  3503  // TestAutoGenAddrDeprecateFromPI tests deprecating a SLAAC address when
  3504  // receiving a PI with 0 preferred lifetime.
  3505  func TestAutoGenAddrDeprecateFromPI(t *testing.T) {
  3506  	const nicID = 1
  3507  
  3508  	prefix1, _, addr1 := prefixSubnetAddr(0, linkAddr1)
  3509  	prefix2, _, addr2 := prefixSubnetAddr(1, linkAddr1)
  3510  
  3511  	ndpDisp, e, s, _ := stackAndNdpDispatcherWithDefaultRoute(t, nicID)
  3512  
  3513  	expectPrimaryAddr := func(addr tcpip.AddressWithPrefix) {
  3514  		t.Helper()
  3515  
  3516  		if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, addr); err != nil {
  3517  			t.Fatal(err)
  3518  		}
  3519  
  3520  		if got := addrForNewConnection(t, s); got != addr.Address {
  3521  			t.Errorf("got addrForNewConnection = %s, want = %s", got, addr.Address)
  3522  		}
  3523  	}
  3524  
  3525  	// Receive PI for prefix1.
  3526  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, 100, 100))
  3527  	if _, err := expectAutoGenAddrNewEvent(ndpDisp, addr1); err != nil {
  3528  		t.Fatalf("error expecting prefix1 stable auto-gen address generated event: %s", err)
  3529  	}
  3530  	if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr1) {
  3531  		t.Fatalf("should have %s in the list of addresses", addr1)
  3532  	}
  3533  	expectPrimaryAddr(addr1)
  3534  
  3535  	// Deprecate addr for prefix1 immediately.
  3536  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, 100, 0))
  3537  	expectAutoGenAddrEvent(t, ndpDisp, addr1, deprecatedAddr)
  3538  	if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr1) {
  3539  		t.Fatalf("should have %s in the list of addresses", addr1)
  3540  	}
  3541  	// addr should still be the primary endpoint as there are no other addresses.
  3542  	expectPrimaryAddr(addr1)
  3543  
  3544  	// Refresh lifetimes of addr generated from prefix1.
  3545  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, 100, 100))
  3546  	select {
  3547  	case <-ndpDisp.autoGenAddrC:
  3548  		t.Fatal("unexpectedly got an auto-generated event")
  3549  	default:
  3550  	}
  3551  	expectPrimaryAddr(addr1)
  3552  
  3553  	// Receive PI for prefix2.
  3554  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix2, true, true, 100, 100))
  3555  	if _, err := expectAutoGenAddrNewEvent(ndpDisp, addr2); err != nil {
  3556  		t.Fatalf("error expecting prefix2 stable auto-gen address generated event: %s", err)
  3557  	}
  3558  	if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr2) {
  3559  		t.Fatalf("should have %s in the list of addresses", addr2)
  3560  	}
  3561  	expectPrimaryAddr(addr2)
  3562  
  3563  	// Deprecate addr for prefix2 immediately.
  3564  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix2, true, true, 100, 0))
  3565  	expectAutoGenAddrEvent(t, ndpDisp, addr2, deprecatedAddr)
  3566  	if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr2) {
  3567  		t.Fatalf("should have %s in the list of addresses", addr2)
  3568  	}
  3569  	// addr1 should be the primary endpoint now since addr2 is deprecated but
  3570  	// addr1 is not.
  3571  	expectPrimaryAddr(addr1)
  3572  	// addr2 is deprecated but if explicitly requested, it should be used.
  3573  	fullAddr2 := tcpip.FullAddress{Addr: addr2.Address, NIC: nicID}
  3574  	if got := addrForNewConnectionWithAddr(t, s, fullAddr2); got != addr2.Address {
  3575  		t.Errorf("got addrForNewConnectionWithAddr(_, _, %+v) = %s, want = %s", fullAddr2, got, addr2.Address)
  3576  	}
  3577  
  3578  	// Another PI w/ 0 preferred lifetime should not result in a deprecation
  3579  	// event.
  3580  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix2, true, true, 100, 0))
  3581  	select {
  3582  	case <-ndpDisp.autoGenAddrC:
  3583  		t.Fatal("unexpectedly got an auto-generated event")
  3584  	default:
  3585  	}
  3586  	expectPrimaryAddr(addr1)
  3587  	if got := addrForNewConnectionWithAddr(t, s, fullAddr2); got != addr2.Address {
  3588  		t.Errorf("got addrForNewConnectionWithAddr(_, _, %+v) = %s, want = %s", fullAddr2, got, addr2.Address)
  3589  	}
  3590  
  3591  	// Refresh lifetimes of addr generated from prefix2.
  3592  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix2, true, true, 100, 100))
  3593  	select {
  3594  	case <-ndpDisp.autoGenAddrC:
  3595  		t.Fatal("unexpectedly got an auto-generated event")
  3596  	default:
  3597  	}
  3598  	expectPrimaryAddr(addr2)
  3599  }
  3600  
  3601  // TestAutoGenAddrJobDeprecation tests that an address is properly deprecated
  3602  // when its preferred lifetime expires.
  3603  func TestAutoGenAddrJobDeprecation(t *testing.T) {
  3604  	const nicID = 1
  3605  
  3606  	prefix1, _, addr1 := prefixSubnetAddr(0, linkAddr1)
  3607  	prefix2, _, addr2 := prefixSubnetAddr(1, linkAddr1)
  3608  
  3609  	ndpDisp, e, s, clock := stackAndNdpDispatcherWithDefaultRoute(t, nicID)
  3610  
  3611  	expectAutoGenAddrEventAfter := func(addr tcpip.AddressWithPrefix, eventType ndpAutoGenAddrEventType, timeout time.Duration) {
  3612  		t.Helper()
  3613  
  3614  		clock.Advance(timeout)
  3615  		expectAutoGenAddrEvent(t, ndpDisp, addr, eventType)
  3616  	}
  3617  
  3618  	expectPrimaryAddr := func(addr tcpip.AddressWithPrefix) {
  3619  		t.Helper()
  3620  
  3621  		if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, addr); err != nil {
  3622  			t.Fatal(err)
  3623  		}
  3624  
  3625  		if got := addrForNewConnection(t, s); got != addr.Address {
  3626  			t.Errorf("got addrForNewConnection = %s, want = %s", got, addr.Address)
  3627  		}
  3628  	}
  3629  
  3630  	// Receive PI for prefix2.
  3631  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix2, true, true, infiniteLifetimeSeconds, infiniteLifetimeSeconds))
  3632  	if _, err := expectAutoGenAddrNewEvent(ndpDisp, addr2); err != nil {
  3633  		t.Fatalf("error expecting prefix2 stable auto-gen address generated event: %s", err)
  3634  	}
  3635  	if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr2) {
  3636  		t.Fatalf("should have %s in the list of addresses", addr2)
  3637  	}
  3638  	expectPrimaryAddr(addr2)
  3639  
  3640  	// Receive a PI for prefix1.
  3641  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, 100, 90))
  3642  	if _, err := expectAutoGenAddrNewEvent(ndpDisp, addr1); err != nil {
  3643  		t.Fatalf("error expecting prefix1 stable auto-gen address generated event: %s", err)
  3644  	}
  3645  	if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr1) {
  3646  		t.Fatalf("should have %s in the list of addresses", addr1)
  3647  	}
  3648  	if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr2) {
  3649  		t.Fatalf("should have %s in the list of addresses", addr2)
  3650  	}
  3651  	expectPrimaryAddr(addr1)
  3652  
  3653  	// Refresh lifetime for addr of prefix1.
  3654  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, minVLSeconds, minVLSeconds-1))
  3655  	select {
  3656  	case <-ndpDisp.autoGenAddrC:
  3657  		t.Fatal("unexpectedly got an auto-generated event")
  3658  	default:
  3659  	}
  3660  	expectPrimaryAddr(addr1)
  3661  
  3662  	// Wait for addr of prefix1 to be deprecated.
  3663  	expectAutoGenAddrEventAfter(addr1, deprecatedAddr, ipv6.MinPrefixInformationValidLifetimeForUpdate-time.Second)
  3664  	if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr1) {
  3665  		t.Fatalf("should not have %s in the list of addresses", addr1)
  3666  	}
  3667  	if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr2) {
  3668  		t.Fatalf("should have %s in the list of addresses", addr2)
  3669  	}
  3670  	// addr2 should be the primary endpoint now since addr1 is deprecated but
  3671  	// addr2 is not.
  3672  	expectPrimaryAddr(addr2)
  3673  
  3674  	// addr1 is deprecated but if explicitly requested, it should be used.
  3675  	fullAddr1 := tcpip.FullAddress{Addr: addr1.Address, NIC: nicID}
  3676  	if got := addrForNewConnectionWithAddr(t, s, fullAddr1); got != addr1.Address {
  3677  		t.Errorf("got addrForNewConnectionWithAddr(_, _, %+v) = %s, want = %s", fullAddr1, got, addr1.Address)
  3678  	}
  3679  
  3680  	// Refresh valid lifetime for addr of prefix1, w/ 0 preferred lifetime to make
  3681  	// sure we do not get a deprecation event again.
  3682  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, minVLSeconds, 0))
  3683  	select {
  3684  	case <-ndpDisp.autoGenAddrC:
  3685  		t.Fatal("unexpectedly got an auto-generated event")
  3686  	default:
  3687  	}
  3688  	expectPrimaryAddr(addr2)
  3689  	if got := addrForNewConnectionWithAddr(t, s, fullAddr1); got != addr1.Address {
  3690  		t.Errorf("got addrForNewConnectionWithAddr(_, _, %+v) = %s, want = %s", fullAddr1, got, addr1.Address)
  3691  	}
  3692  
  3693  	// Refresh lifetimes for addr of prefix1.
  3694  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, minVLSeconds, minVLSeconds-1))
  3695  	select {
  3696  	case <-ndpDisp.autoGenAddrC:
  3697  		t.Fatal("unexpectedly got an auto-generated event")
  3698  	default:
  3699  	}
  3700  	// addr1 is the primary endpoint again since it is non-deprecated now.
  3701  	expectPrimaryAddr(addr1)
  3702  
  3703  	// Wait for addr of prefix1 to be deprecated.
  3704  	expectAutoGenAddrEventAfter(addr1, deprecatedAddr, ipv6.MinPrefixInformationValidLifetimeForUpdate-time.Second)
  3705  	if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr1) {
  3706  		t.Fatalf("should not have %s in the list of addresses", addr1)
  3707  	}
  3708  	if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr2) {
  3709  		t.Fatalf("should have %s in the list of addresses", addr2)
  3710  	}
  3711  	// addr2 should be the primary endpoint now since it is not deprecated.
  3712  	expectPrimaryAddr(addr2)
  3713  	if got := addrForNewConnectionWithAddr(t, s, fullAddr1); got != addr1.Address {
  3714  		t.Errorf("got addrForNewConnectionWithAddr(_, _, %+v) = %s, want = %s", fullAddr1, got, addr1.Address)
  3715  	}
  3716  
  3717  	// Wait for addr of prefix1 to be invalidated.
  3718  	expectAutoGenAddrEventAfter(addr1, invalidatedAddr, time.Second)
  3719  	if containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr1) {
  3720  		t.Fatalf("should not have %s in the list of addresses", addr1)
  3721  	}
  3722  	if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr2) {
  3723  		t.Fatalf("should have %s in the list of addresses", addr2)
  3724  	}
  3725  	expectPrimaryAddr(addr2)
  3726  
  3727  	// Refresh both lifetimes for addr of prefix2 to the same value.
  3728  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix2, true, true, minVLSeconds, minVLSeconds))
  3729  	select {
  3730  	case <-ndpDisp.autoGenAddrC:
  3731  		t.Fatal("unexpectedly got an auto-generated event")
  3732  	default:
  3733  	}
  3734  
  3735  	// Wait for a deprecation then invalidation events, or just an invalidation
  3736  	// event. We need to cover both cases but cannot deterministically hit both
  3737  	// cases because the deprecation and invalidation handlers could be handled in
  3738  	// either deprecation then invalidation, or invalidation then deprecation
  3739  	// (which should be cancelled by the invalidation handler).
  3740  	//
  3741  	// Since we're about to cause both events to fire, we need the dispatcher
  3742  	// channel to be able to hold both.
  3743  	if got, want := len(ndpDisp.autoGenAddrC), 0; got != want {
  3744  		t.Fatalf("got len(ndpDisp.autoGenAddrC) = %d, want %d", got, want)
  3745  	}
  3746  	if got, want := cap(ndpDisp.autoGenAddrC), 1; got != want {
  3747  		t.Fatalf("got cap(ndpDisp.autoGenAddrC) = %d, want %d", got, want)
  3748  	}
  3749  	ndpDisp.autoGenAddrC = make(chan ndpAutoGenAddrEvent, 2)
  3750  	clock.Advance(ipv6.MinPrefixInformationValidLifetimeForUpdate)
  3751  	select {
  3752  	case e := <-ndpDisp.autoGenAddrC:
  3753  		if diff := checkAutoGenAddrEvent(e, addr2, deprecatedAddr); diff == "" {
  3754  			// If we get a deprecation event first, we should get an invalidation
  3755  			// event almost immediately after.
  3756  			select {
  3757  			case e := <-ndpDisp.autoGenAddrC:
  3758  				if diff := checkAutoGenAddrEvent(e, addr2, invalidatedAddr); diff != "" {
  3759  					t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
  3760  				}
  3761  			default:
  3762  				t.Fatal("timed out waiting for addr auto gen event")
  3763  			}
  3764  		} else if diff := checkAutoGenAddrEvent(e, addr2, invalidatedAddr); diff == "" {
  3765  			// If we get an invalidation event first, we should not get a deprecation
  3766  			// event after.
  3767  			select {
  3768  			case <-ndpDisp.autoGenAddrC:
  3769  				t.Fatal("unexpectedly got an auto-generated event")
  3770  			default:
  3771  			}
  3772  		} else {
  3773  			t.Fatalf("got unexpected auto-generated event")
  3774  		}
  3775  	default:
  3776  		t.Fatal("timed out waiting for addr auto gen event")
  3777  	}
  3778  	if containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr1) {
  3779  		t.Fatalf("should not have %s in the list of addresses", addr1)
  3780  	}
  3781  	if containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr2) {
  3782  		t.Fatalf("should not have %s in the list of addresses", addr2)
  3783  	}
  3784  	// Should not have any primary endpoints.
  3785  	if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil {
  3786  		t.Fatal(err)
  3787  	}
  3788  	wq := waiter.Queue{}
  3789  	we, ch := waiter.NewChannelEntry(waiter.ReadableEvents)
  3790  	wq.EventRegister(&we)
  3791  	defer wq.EventUnregister(&we)
  3792  	defer close(ch)
  3793  	ep, err := s.NewEndpoint(header.UDPProtocolNumber, header.IPv6ProtocolNumber, &wq)
  3794  	if err != nil {
  3795  		t.Fatalf("s.NewEndpoint(%d, %d, _): %s", header.UDPProtocolNumber, header.IPv6ProtocolNumber, err)
  3796  	}
  3797  	defer ep.Close()
  3798  	ep.SocketOptions().SetV6Only(true)
  3799  
  3800  	{
  3801  		err := ep.Connect(dstAddr)
  3802  		if _, ok := err.(*tcpip.ErrHostUnreachable); !ok {
  3803  			t.Errorf("got ep.Connect(%+v) = %s, want = %s", dstAddr, err, &tcpip.ErrHostUnreachable{})
  3804  		}
  3805  	}
  3806  }
  3807  
  3808  // Tests transitioning a SLAAC address's valid lifetime between finite and
  3809  // infinite values.
  3810  func TestAutoGenAddrFiniteToInfiniteToFiniteVL(t *testing.T) {
  3811  	const infiniteVLSeconds = math.MaxUint32
  3812  
  3813  	prefix, _, addr := prefixSubnetAddr(0, linkAddr1)
  3814  
  3815  	const autoGenAddrCount = 1
  3816  	ndpDisp := ndpDispatcher{
  3817  		autoGenAddrNewC:    make(chan ndpAutoGenAddrNewEvent, autoGenAddrCount),
  3818  		autoGenAddrC:       make(chan ndpAutoGenAddrEvent, autoGenAddrCount),
  3819  		autoGenInstallDisp: true,
  3820  	}
  3821  	e := channel.New(0, 1280, linkAddr1)
  3822  	clock := faketime.NewManualClock()
  3823  	s := stack.New(stack.Options{
  3824  		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
  3825  			NDPConfigs: ipv6.NDPConfigurations{
  3826  				HandleRAs:              ipv6.HandlingRAsEnabledWhenForwardingDisabled,
  3827  				AutoGenGlobalAddresses: true,
  3828  			},
  3829  			NDPDisp: &ndpDisp,
  3830  		})},
  3831  		Clock: clock,
  3832  	})
  3833  
  3834  	if err := s.CreateNIC(1, e); err != nil {
  3835  		t.Fatalf("CreateNIC(1) = %s", err)
  3836  	}
  3837  
  3838  	// Receive an RA with finite prefix.
  3839  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, minVLSeconds, 0))
  3840  	addrDisp, err := expectAutoGenAddrNewEvent(&ndpDisp, addr)
  3841  	if err != nil {
  3842  		t.Fatalf("error expecting stable auto-gen address generated event: %s", err)
  3843  	}
  3844  	if err := addrDisp.expectChanged(addressLifetimes(clock.NowMonotonic(), 0, minVLSeconds), stack.AddressAssigned); err != nil {
  3845  		t.Error(err)
  3846  	}
  3847  
  3848  	// Receive an new RA with prefix with infinite VL.
  3849  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, infiniteVLSeconds, 0))
  3850  	if err := addrDisp.expectLifetimesChanged(addressLifetimes(clock.NowMonotonic(), 0, infiniteVLSeconds)); err != nil {
  3851  		t.Error(err)
  3852  	}
  3853  
  3854  	// Receive a new RA with prefix with finite VL.
  3855  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, minVLSeconds, 0))
  3856  	if err := addrDisp.expectLifetimesChanged(addressLifetimes(clock.NowMonotonic(), 0, minVLSeconds)); err != nil {
  3857  		t.Error(err)
  3858  	}
  3859  
  3860  	clock.Advance(ipv6.MinPrefixInformationValidLifetimeForUpdate)
  3861  	expectAutoGenAddrEvent(t, &ndpDisp, addr, invalidatedAddr)
  3862  	if err := addrDisp.expectRemoved(stack.AddressRemovalInvalidated); err != nil {
  3863  		t.Error(err)
  3864  	}
  3865  }
  3866  
  3867  // TestAutoGenAddrValidLifetimeUpdates tests that the valid lifetime of an
  3868  // auto-generated address only gets updated when required to, as specified in
  3869  // RFC 4862 section 5.5.3.e.
  3870  func TestAutoGenAddrValidLifetimeUpdates(t *testing.T) {
  3871  	prefix, _, addr := prefixSubnetAddr(0, linkAddr1)
  3872  
  3873  	tests := []struct {
  3874  		name string
  3875  		ovl  uint32
  3876  		nvl  uint32
  3877  		evl  uint32
  3878  	}{
  3879  		// Should update the VL to the minimum VL for updating if the
  3880  		// new VL is less than minVLSeconds but was originally greater than
  3881  		// it.
  3882  		{
  3883  			"LargeVLToVLLessThanMinVLForUpdate",
  3884  			9999,
  3885  			1,
  3886  			minVLSeconds,
  3887  		},
  3888  		{
  3889  			"LargeVLTo0",
  3890  			9999,
  3891  			0,
  3892  			minVLSeconds,
  3893  		},
  3894  		{
  3895  			"InfiniteVLToVLLessThanMinVLForUpdate",
  3896  			infiniteVLSeconds,
  3897  			1,
  3898  			minVLSeconds,
  3899  		},
  3900  		{
  3901  			"InfiniteVLTo0",
  3902  			infiniteVLSeconds,
  3903  			0,
  3904  			minVLSeconds,
  3905  		},
  3906  
  3907  		// Should not update VL if original VL was less than minVLSeconds
  3908  		// and the new VL is also less than minVLSeconds.
  3909  		{
  3910  			"ShouldNotUpdateWhenBothOldAndNewAreLessThanMinVLForUpdate",
  3911  			minVLSeconds - 1,
  3912  			minVLSeconds - 3,
  3913  			minVLSeconds - 1,
  3914  		},
  3915  
  3916  		// Should take the new VL if the new VL is greater than the
  3917  		// remaining time or is greater than minVLSeconds.
  3918  		{
  3919  			"MorethanMinVLToLesserButStillMoreThanMinVLForUpdate",
  3920  			minVLSeconds + 5,
  3921  			minVLSeconds + 3,
  3922  			minVLSeconds + 3,
  3923  		},
  3924  		{
  3925  			"SmallVLToGreaterVLButStillLessThanMinVLForUpdate",
  3926  			minVLSeconds - 3,
  3927  			minVLSeconds - 1,
  3928  			minVLSeconds - 1,
  3929  		},
  3930  		{
  3931  			"SmallVLToGreaterVLThatIsMoreThaMinVLForUpdate",
  3932  			minVLSeconds - 3,
  3933  			minVLSeconds + 1,
  3934  			minVLSeconds + 1,
  3935  		},
  3936  	}
  3937  
  3938  	for _, test := range tests {
  3939  		t.Run(test.name, func(t *testing.T) {
  3940  			const autoGenAddrCount = 10
  3941  			ndpDisp := ndpDispatcher{
  3942  				autoGenInstallDisp: true,
  3943  				autoGenAddrNewC:    make(chan ndpAutoGenAddrNewEvent, autoGenAddrCount),
  3944  				autoGenAddrC:       make(chan ndpAutoGenAddrEvent, autoGenAddrCount),
  3945  			}
  3946  			e := channel.New(10, 1280, linkAddr1)
  3947  			clock := faketime.NewManualClock()
  3948  			s := stack.New(stack.Options{
  3949  				NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
  3950  					NDPConfigs: ipv6.NDPConfigurations{
  3951  						HandleRAs:              ipv6.HandlingRAsEnabledWhenForwardingDisabled,
  3952  						AutoGenGlobalAddresses: true,
  3953  					},
  3954  					NDPDisp: &ndpDisp,
  3955  				})},
  3956  				Clock: clock,
  3957  			})
  3958  
  3959  			if err := s.CreateNIC(1, e); err != nil {
  3960  				t.Fatalf("CreateNIC(1) = %s", err)
  3961  			}
  3962  
  3963  			// Receive an RA with prefix with initial VL,
  3964  			// test.ovl.
  3965  			e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, test.ovl, 0))
  3966  			addrDisp, err := expectAutoGenAddrNewEvent(&ndpDisp, addr)
  3967  			if err != nil {
  3968  				t.Fatalf("error expecting stable auto-gen address generated event: %s", err)
  3969  			}
  3970  			if err := addrDisp.expectChanged(addressLifetimes(clock.NowMonotonic(), 0, test.ovl), stack.AddressAssigned); err != nil {
  3971  				t.Error(err)
  3972  			}
  3973  
  3974  			// Receive an new RA with prefix with new VL,
  3975  			// test.nvl.
  3976  			e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, test.nvl, 0))
  3977  			if test.evl != test.ovl {
  3978  				if err := addrDisp.expectValidUntilChanged(clock.NowMonotonic().Add(time.Duration(test.evl) * time.Second)); err != nil {
  3979  					t.Error(err)
  3980  				}
  3981  			}
  3982  
  3983  			//
  3984  			// Validate that the VL for the address got set
  3985  			// to test.evl.
  3986  			//
  3987  
  3988  			// The address should not be invalidated until the effective valid
  3989  			// lifetime has passed.
  3990  			const delta = 1
  3991  			clock.Advance(time.Duration(test.evl)*time.Second - delta)
  3992  			select {
  3993  			case <-ndpDisp.autoGenAddrC:
  3994  				t.Fatal("unexpectedly received an auto gen addr event")
  3995  			default:
  3996  			}
  3997  			if err := addrDisp.expectNoEvent(); err != nil {
  3998  				t.Error(err)
  3999  			}
  4000  
  4001  			// Wait for the invalidation event.
  4002  			clock.Advance(delta)
  4003  			select {
  4004  			case e := <-ndpDisp.autoGenAddrC:
  4005  				if diff := checkAutoGenAddrEvent(e, addr, invalidatedAddr); diff != "" {
  4006  					t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
  4007  				}
  4008  			default:
  4009  				t.Fatal("timeout waiting for addr auto gen event")
  4010  			}
  4011  			if err := addrDisp.expectRemoved(stack.AddressRemovalInvalidated); err != nil {
  4012  				t.Error(err)
  4013  			}
  4014  		})
  4015  	}
  4016  }
  4017  
  4018  // TestAutoGenAddrRemoval tests that when auto-generated addresses are removed
  4019  // by the user, its resources will be cleaned up and an invalidation event will
  4020  // be sent to the integrator.
  4021  func TestAutoGenAddrRemoval(t *testing.T) {
  4022  	prefix, _, addr := prefixSubnetAddr(0, linkAddr1)
  4023  
  4024  	const autoGenAddrCount = 1
  4025  	ndpDisp := ndpDispatcher{
  4026  		autoGenAddrNewC:    make(chan ndpAutoGenAddrNewEvent, autoGenAddrCount),
  4027  		autoGenAddrC:       make(chan ndpAutoGenAddrEvent, autoGenAddrCount),
  4028  		autoGenInstallDisp: true,
  4029  	}
  4030  	e := channel.New(0, 1280, linkAddr1)
  4031  	clock := faketime.NewManualClock()
  4032  	s := stack.New(stack.Options{
  4033  		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
  4034  			NDPConfigs: ipv6.NDPConfigurations{
  4035  				HandleRAs:              ipv6.HandlingRAsEnabledWhenForwardingDisabled,
  4036  				AutoGenGlobalAddresses: true,
  4037  			},
  4038  			NDPDisp: &ndpDisp,
  4039  		})},
  4040  		Clock: clock,
  4041  	})
  4042  
  4043  	if err := s.CreateNIC(1, e); err != nil {
  4044  		t.Fatalf("CreateNIC(1) = %s", err)
  4045  	}
  4046  
  4047  	// Receive a PI to auto-generate an address.
  4048  	const lifetimeSeconds = 1
  4049  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, lifetimeSeconds, 0))
  4050  	addrDisp, err := expectAutoGenAddrNewEvent(&ndpDisp, addr)
  4051  	if err != nil {
  4052  		t.Fatalf("error expecting stable auto-gen address generated event: %s", err)
  4053  	}
  4054  	if err := addrDisp.expectChanged(addressLifetimes(clock.NowMonotonic(), 0, lifetimeSeconds), stack.AddressAssigned); err != nil {
  4055  		t.Error(err)
  4056  	}
  4057  
  4058  	// Removing the address should result in an invalidation event
  4059  	// immediately.
  4060  	if err := s.RemoveAddress(1, addr.Address); err != nil {
  4061  		t.Fatalf("RemoveAddress(_, %s) = %s", addr.Address, err)
  4062  	}
  4063  	expectAutoGenAddrEvent(t, &ndpDisp, addr, invalidatedAddr)
  4064  	if err := addrDisp.expectRemoved(stack.AddressRemovalManualAction); err != nil {
  4065  		t.Error(err)
  4066  	}
  4067  
  4068  	// Wait for the original valid lifetime to make sure the original job got
  4069  	// cancelled/cleaned up.
  4070  	clock.Advance(lifetimeSeconds * time.Second)
  4071  	select {
  4072  	case <-ndpDisp.autoGenAddrC:
  4073  		t.Fatal("unexpectedly received an auto gen addr event")
  4074  	default:
  4075  	}
  4076  	if err := addrDisp.expectNoEvent(); err != nil {
  4077  		t.Error(err)
  4078  	}
  4079  }
  4080  
  4081  // TestAutoGenAddrAfterRemoval tests adding a SLAAC address that was previously
  4082  // assigned to the NIC but is in the permanentExpired state.
  4083  func TestAutoGenAddrAfterRemoval(t *testing.T) {
  4084  	const nicID = 1
  4085  
  4086  	prefix1, _, addr1 := prefixSubnetAddr(0, linkAddr1)
  4087  	prefix2, _, addr2 := prefixSubnetAddr(1, linkAddr1)
  4088  	ndpDisp, e, s, clock := stackAndNdpDispatcherWithDefaultRoute(t, nicID)
  4089  	ndpDisp.autoGenInstallDisp = true
  4090  
  4091  	expectPrimaryAddr := func(addr tcpip.AddressWithPrefix) {
  4092  		t.Helper()
  4093  
  4094  		if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, addr); err != nil {
  4095  			t.Fatal(err)
  4096  		}
  4097  
  4098  		if got := addrForNewConnection(t, s); got != addr.Address {
  4099  			t.Errorf("got addrForNewConnection = %s, want = %s", got, addr.Address)
  4100  		}
  4101  	}
  4102  
  4103  	// Receive a PI to auto-generate addr1 with a large valid and preferred
  4104  	// lifetime.
  4105  	const largeLifetimeSeconds = 999
  4106  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr3, 0, prefix1, true, true, largeLifetimeSeconds, largeLifetimeSeconds))
  4107  	if addrDisp, err := expectAutoGenAddrNewEvent(ndpDisp, addr1); err != nil {
  4108  		t.Fatalf("error expecting prefix1 stable auto-gen address generated event: %s", err)
  4109  	} else {
  4110  		addrDisp.disable()
  4111  	}
  4112  	expectPrimaryAddr(addr1)
  4113  
  4114  	// Add addr2 as a static address.
  4115  	protoAddr2 := tcpip.ProtocolAddress{
  4116  		Protocol:          header.IPv6ProtocolNumber,
  4117  		AddressWithPrefix: addr2,
  4118  	}
  4119  	properties := stack.AddressProperties{PEB: stack.FirstPrimaryEndpoint}
  4120  	if err := s.AddProtocolAddress(nicID, protoAddr2, properties); err != nil {
  4121  		t.Fatalf("AddProtocolAddress(%d, %+v, %+v) = %s", nicID, protoAddr2, properties, err)
  4122  	}
  4123  	// addr2 should be more preferred now since it is at the front of the primary
  4124  	// list.
  4125  	expectPrimaryAddr(addr2)
  4126  
  4127  	// Get a route using addr2 to increment its reference count then remove it
  4128  	// to leave it in the permanentExpired state.
  4129  	if r, err := s.FindRoute(nicID, addr2.Address, addr3, header.IPv6ProtocolNumber, false); err != nil {
  4130  		t.Fatalf("FindRoute(%d, %s, %s, %d, false): %s", nicID, addr2.Address, addr3, header.IPv6ProtocolNumber, err)
  4131  	} else {
  4132  		defer r.Release()
  4133  	}
  4134  	if err := s.RemoveAddress(nicID, addr2.Address); err != nil {
  4135  		t.Fatalf("s.RemoveAddress(%d, %s): %s", nicID, addr2.Address, err)
  4136  	}
  4137  	// addr1 should be preferred again since addr2 is in the expired state.
  4138  	expectPrimaryAddr(addr1)
  4139  
  4140  	// Receive a PI to auto-generate addr2 as valid and preferred.
  4141  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr3, 0, prefix2, true, true, largeLifetimeSeconds, largeLifetimeSeconds))
  4142  	addr2Disp, err := expectAutoGenAddrNewEvent(ndpDisp, addr2)
  4143  	if err != nil {
  4144  		t.Fatalf("error expecting prefix2 stable auto-gen address generated event: %s", err)
  4145  	}
  4146  	if err := addr2Disp.expectChanged(addressLifetimes(clock.NowMonotonic(), largeLifetimeSeconds, largeLifetimeSeconds), stack.AddressAssigned); err != nil {
  4147  		t.Error(err)
  4148  	}
  4149  	// addr2 should be more preferred now that it is closer to the front of the
  4150  	// primary list and not deprecated.
  4151  	expectPrimaryAddr(addr2)
  4152  
  4153  	// Removing the address should result in an invalidation event immediately.
  4154  	// It should still be in the permanentExpired state because r is still held.
  4155  	//
  4156  	// We remove addr2 here to make sure addr2 was marked as a SLAAC address
  4157  	// (it was previously marked as a static address).
  4158  	if err := s.RemoveAddress(1, addr2.Address); err != nil {
  4159  		t.Fatalf("RemoveAddress(_, %s) = %s", addr2.Address, err)
  4160  	}
  4161  	expectAutoGenAddrEvent(t, ndpDisp, addr2, invalidatedAddr)
  4162  	if err := addr2Disp.expectRemoved(stack.AddressRemovalManualAction); err != nil {
  4163  		t.Error(err)
  4164  	}
  4165  	// addr1 should be more preferred since addr2 is in the expired state.
  4166  	expectPrimaryAddr(addr1)
  4167  
  4168  	// Receive a PI to auto-generate addr2 as valid and deprecated.
  4169  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr3, 0, prefix2, true, true, largeLifetimeSeconds, 0))
  4170  	addr2Disp, err = expectAutoGenAddrNewEvent(ndpDisp, addr2)
  4171  	if err != nil {
  4172  		t.Fatalf("error expecting prefix2 stable auto-gen address generated event after removing address and new PI: %s", err)
  4173  	}
  4174  	if err := addr2Disp.expectChanged(addressLifetimes(clock.NowMonotonic(), 0, largeLifetimeSeconds), stack.AddressAssigned); err != nil {
  4175  		t.Error(err)
  4176  	}
  4177  	// addr1 should still be more preferred since addr2 is deprecated, even though
  4178  	// it is closer to the front of the primary list.
  4179  	expectPrimaryAddr(addr1)
  4180  
  4181  	// Receive a PI to refresh addr2's preferred lifetime.
  4182  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr3, 0, prefix2, true, true, largeLifetimeSeconds, largeLifetimeSeconds))
  4183  	select {
  4184  	case <-ndpDisp.autoGenAddrC:
  4185  		t.Fatal("unexpectedly got an auto gen addr event")
  4186  	default:
  4187  	}
  4188  	if err := addr2Disp.expectChanged(addressLifetimes(clock.NowMonotonic(), largeLifetimeSeconds, largeLifetimeSeconds), stack.AddressAssigned); err != nil {
  4189  		t.Error(err)
  4190  	}
  4191  	// addr2 should be more preferred now that it is not deprecated.
  4192  	expectPrimaryAddr(addr2)
  4193  
  4194  	if err := s.RemoveAddress(1, addr2.Address); err != nil {
  4195  		t.Fatalf("RemoveAddress(_, %s) = %s", addr2.Address, err)
  4196  	}
  4197  	expectAutoGenAddrEvent(t, ndpDisp, addr2, invalidatedAddr)
  4198  	if err := addr2Disp.expectRemoved(stack.AddressRemovalManualAction); err != nil {
  4199  		t.Error(err)
  4200  	}
  4201  	expectPrimaryAddr(addr1)
  4202  }
  4203  
  4204  // TestAutoGenAddrStaticConflict tests that if SLAAC generates an address that
  4205  // is already assigned to the NIC, the static address remains.
  4206  func TestAutoGenAddrStaticConflict(t *testing.T) {
  4207  	prefix, _, addr := prefixSubnetAddr(0, linkAddr1)
  4208  
  4209  	const autoGenAddrCount = 1
  4210  	ndpDisp := ndpDispatcher{
  4211  		autoGenAddrNewC: make(chan ndpAutoGenAddrNewEvent, autoGenAddrCount),
  4212  		autoGenAddrC:    make(chan ndpAutoGenAddrEvent, autoGenAddrCount),
  4213  	}
  4214  	e := channel.New(0, 1280, linkAddr1)
  4215  	clock := faketime.NewManualClock()
  4216  	s := stack.New(stack.Options{
  4217  		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
  4218  			NDPConfigs: ipv6.NDPConfigurations{
  4219  				HandleRAs:              ipv6.HandlingRAsEnabledWhenForwardingDisabled,
  4220  				AutoGenGlobalAddresses: true,
  4221  			},
  4222  			NDPDisp: &ndpDisp,
  4223  		})},
  4224  		Clock: clock,
  4225  	})
  4226  
  4227  	if err := s.CreateNIC(1, e); err != nil {
  4228  		t.Fatalf("CreateNIC(1) = %s", err)
  4229  	}
  4230  
  4231  	// Add the address as a static address before SLAAC tries to add it.
  4232  	protocolAddr := tcpip.ProtocolAddress{Protocol: header.IPv6ProtocolNumber, AddressWithPrefix: addr}
  4233  	if err := s.AddProtocolAddress(1, protocolAddr, stack.AddressProperties{}); err != nil {
  4234  		t.Fatalf("AddProtocolAddress(1, %+v, {}) = %s", protocolAddr, err)
  4235  	}
  4236  	if !containsV6Addr(s.NICInfo()[1].ProtocolAddresses, addr) {
  4237  		t.Fatalf("Should have %s in the list of addresses", addr1)
  4238  	}
  4239  
  4240  	// Receive a PI where the generated address will be the same as the one
  4241  	// that we already have assigned statically.
  4242  	const lifetimeSeconds = 1
  4243  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, lifetimeSeconds, 0))
  4244  	select {
  4245  	case <-ndpDisp.autoGenAddrC:
  4246  		t.Fatal("unexpectedly received an auto gen addr event for an address we already have statically")
  4247  	default:
  4248  	}
  4249  	if !containsV6Addr(s.NICInfo()[1].ProtocolAddresses, addr) {
  4250  		t.Fatalf("Should have %s in the list of addresses", addr1)
  4251  	}
  4252  
  4253  	// Should not get an invalidation event after the PI's invalidation
  4254  	// time.
  4255  	clock.Advance(lifetimeSeconds * time.Second)
  4256  	select {
  4257  	case <-ndpDisp.autoGenAddrC:
  4258  		t.Fatal("unexpectedly received an auto gen addr event")
  4259  	default:
  4260  	}
  4261  	if !containsV6Addr(s.NICInfo()[1].ProtocolAddresses, addr) {
  4262  		t.Fatalf("Should have %s in the list of addresses", addr1)
  4263  	}
  4264  }
  4265  
  4266  func makeSecretKey(t *testing.T) []byte {
  4267  	secretKey := make([]byte, header.OpaqueIIDSecretKeyMinBytes)
  4268  	n, err := cryptorand.Read(secretKey)
  4269  	if err != nil {
  4270  		t.Fatalf("cryptorand.Read(_): %s", err)
  4271  	}
  4272  	if l := len(secretKey); n != l {
  4273  		t.Fatalf("got cryptorand.Read(_) = (%d, nil), want = (%d, nil)", n, l)
  4274  	}
  4275  	return secretKey
  4276  }
  4277  
  4278  // TestAutoGenAddrWithOpaqueIID tests that SLAAC generated addresses will use
  4279  // opaque interface identifiers when configured to do so.
  4280  func TestAutoGenAddrWithOpaqueIID(t *testing.T) {
  4281  	const nicID = 1
  4282  	const nicName = "nic1"
  4283  
  4284  	secretKey := makeSecretKey(t)
  4285  
  4286  	prefix1, subnet1, _ := prefixSubnetAddr(0, linkAddr1)
  4287  	prefix2, subnet2, _ := prefixSubnetAddr(1, linkAddr1)
  4288  	// addr1 and addr2 are the addresses that are expected to be generated when
  4289  	// stack.Stack is configured to generate opaque interface identifiers as
  4290  	// defined by RFC 7217.
  4291  	subnetID := subnet1.ID()
  4292  	addrBytes := subnetID.AsSlice()
  4293  	addr1 := tcpip.AddressWithPrefix{
  4294  		Address:   tcpip.AddrFromSlice(header.AppendOpaqueInterfaceIdentifier(addrBytes[:header.IIDOffsetInIPv6Address], subnet1, nicName, 0, secretKey)),
  4295  		PrefixLen: 64,
  4296  	}
  4297  	subnetID = subnet2.ID()
  4298  	addrBytes = subnetID.AsSlice()
  4299  	addr2 := tcpip.AddressWithPrefix{
  4300  		Address:   tcpip.AddrFromSlice(header.AppendOpaqueInterfaceIdentifier(addrBytes[:header.IIDOffsetInIPv6Address], subnet2, nicName, 0, secretKey)),
  4301  		PrefixLen: 64,
  4302  	}
  4303  
  4304  	const autoGenAddrCount = 1
  4305  	ndpDisp := ndpDispatcher{
  4306  		autoGenAddrNewC: make(chan ndpAutoGenAddrNewEvent, autoGenAddrCount),
  4307  		autoGenAddrC:    make(chan ndpAutoGenAddrEvent, autoGenAddrCount),
  4308  	}
  4309  	e := channel.New(0, 1280, linkAddr1)
  4310  	clock := faketime.NewManualClock()
  4311  	s := stack.New(stack.Options{
  4312  		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
  4313  			NDPConfigs: ipv6.NDPConfigurations{
  4314  				HandleRAs:              ipv6.HandlingRAsEnabledWhenForwardingDisabled,
  4315  				AutoGenGlobalAddresses: true,
  4316  			},
  4317  			NDPDisp: &ndpDisp,
  4318  			OpaqueIIDOpts: ipv6.OpaqueInterfaceIdentifierOptions{
  4319  				NICNameFromID: func(_ tcpip.NICID, nicName string) string {
  4320  					return nicName
  4321  				},
  4322  				SecretKey: secretKey,
  4323  			},
  4324  		})},
  4325  		Clock: clock,
  4326  	})
  4327  	opts := stack.NICOptions{Name: nicName}
  4328  	if err := s.CreateNICWithOptions(nicID, e, opts); err != nil {
  4329  		t.Fatalf("CreateNICWithOptions(%d, _, %+v, _) = %s", nicID, opts, err)
  4330  	}
  4331  
  4332  	// Receive an RA with prefix1 in a PI.
  4333  	const validLifetimeSecondPrefix1 = 1
  4334  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, validLifetimeSecondPrefix1, 0))
  4335  	if _, err := expectAutoGenAddrNewEvent(&ndpDisp, addr1); err != nil {
  4336  		t.Fatalf("error expecting prefix1 stable auto-gen address generated event: %s", err)
  4337  	}
  4338  	if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr1) {
  4339  		t.Fatalf("should have %s in the list of addresses", addr1)
  4340  	}
  4341  
  4342  	// Receive an RA with prefix2 in a PI with a large valid lifetime.
  4343  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix2, true, true, 100, 0))
  4344  	if _, err := expectAutoGenAddrNewEvent(&ndpDisp, addr2); err != nil {
  4345  		t.Fatalf("error expecting prefix2 stable auto-gen address generated event: %s", err)
  4346  	}
  4347  	if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr1) {
  4348  		t.Fatalf("should have %s in the list of addresses", addr1)
  4349  	}
  4350  	if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr2) {
  4351  		t.Fatalf("should have %s in the list of addresses", addr2)
  4352  	}
  4353  
  4354  	// Wait for addr of prefix1 to be invalidated.
  4355  	clock.Advance(validLifetimeSecondPrefix1 * time.Second)
  4356  	select {
  4357  	case e := <-ndpDisp.autoGenAddrC:
  4358  		if diff := checkAutoGenAddrEvent(e, addr1, invalidatedAddr); diff != "" {
  4359  			t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
  4360  		}
  4361  	default:
  4362  		t.Fatal("timed out waiting for addr auto gen event")
  4363  	}
  4364  	if containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr1) {
  4365  		t.Fatalf("should not have %s in the list of addresses", addr1)
  4366  	}
  4367  	if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr2) {
  4368  		t.Fatalf("should have %s in the list of addresses", addr2)
  4369  	}
  4370  }
  4371  
  4372  func TestAutoGenAddrInResponseToDADConflicts(t *testing.T) {
  4373  	const nicID = 1
  4374  	const nicName = "nic"
  4375  	const dadTransmits = 1
  4376  	const retransmitTimer = time.Second
  4377  	const maxMaxRetries = 3
  4378  	const lifetimeSeconds = 10
  4379  
  4380  	secretKey := makeSecretKey(t)
  4381  
  4382  	prefix, subnet, _ := prefixSubnetAddr(0, linkAddr1)
  4383  
  4384  	addrForSubnet := func(subnet tcpip.Subnet, dadCounter uint8) tcpip.AddressWithPrefix {
  4385  		subnetID := subnet.ID()
  4386  		addrBytes := subnetID.AsSlice()
  4387  		return tcpip.AddressWithPrefix{
  4388  			Address:   tcpip.AddrFromSlice(header.AppendOpaqueInterfaceIdentifier(addrBytes[:header.IIDOffsetInIPv6Address], subnet, nicName, dadCounter, secretKey)),
  4389  			PrefixLen: 64,
  4390  		}
  4391  	}
  4392  
  4393  	expectDADEvent := func(t *testing.T, clock *faketime.ManualClock, ndpDisp *ndpDispatcher, addr tcpip.Address, res stack.DADResult) {
  4394  		t.Helper()
  4395  
  4396  		clock.RunImmediatelyScheduledJobs()
  4397  		select {
  4398  		case e := <-ndpDisp.dadC:
  4399  			if diff := checkDADEvent(e, nicID, addr, res); diff != "" {
  4400  				t.Errorf("DAD event mismatch (-want +got):\n%s", diff)
  4401  			}
  4402  		default:
  4403  			t.Fatal("expected DAD event")
  4404  		}
  4405  	}
  4406  
  4407  	expectDADEventAsync := func(t *testing.T, clock *faketime.ManualClock, ndpDisp *ndpDispatcher, addr tcpip.Address, res stack.DADResult) {
  4408  		t.Helper()
  4409  
  4410  		clock.Advance(dadTransmits * retransmitTimer)
  4411  		select {
  4412  		case e := <-ndpDisp.dadC:
  4413  			if diff := checkDADEvent(e, nicID, addr, res); diff != "" {
  4414  				t.Errorf("DAD event mismatch (-want +got):\n%s", diff)
  4415  			}
  4416  		default:
  4417  			t.Fatal("timed out waiting for DAD event")
  4418  		}
  4419  	}
  4420  
  4421  	stableAddrForTempAddrTest := addrForSubnet(subnet, 0)
  4422  
  4423  	addrTypes := []struct {
  4424  		name             string
  4425  		ndpConfigs       ipv6.NDPConfigurations
  4426  		autoGenLinkLocal bool
  4427  		prepareFn        func(t *testing.T, clock *faketime.ManualClock, ndpDisp *ndpDispatcher, e *channel.Endpoint, tempIIDHistory []byte) []tcpip.AddressWithPrefix
  4428  		addrGenFn        func(dadCounter uint8, tempIIDHistory []byte) tcpip.AddressWithPrefix
  4429  	}{
  4430  		{
  4431  			name: "Global address",
  4432  			ndpConfigs: ipv6.NDPConfigurations{
  4433  				HandleRAs:              ipv6.HandlingRAsEnabledWhenForwardingDisabled,
  4434  				AutoGenGlobalAddresses: true,
  4435  			},
  4436  			prepareFn: func(_ *testing.T, _ *faketime.ManualClock, _ *ndpDispatcher, e *channel.Endpoint, _ []byte) []tcpip.AddressWithPrefix {
  4437  				// Receive an RA with prefix1 in a PI.
  4438  				e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, lifetimeSeconds, lifetimeSeconds))
  4439  				return nil
  4440  
  4441  			},
  4442  			addrGenFn: func(dadCounter uint8, _ []byte) tcpip.AddressWithPrefix {
  4443  				return addrForSubnet(subnet, dadCounter)
  4444  			},
  4445  		},
  4446  		{
  4447  			name:             "LinkLocal address",
  4448  			ndpConfigs:       ipv6.NDPConfigurations{},
  4449  			autoGenLinkLocal: true,
  4450  			prepareFn: func(*testing.T, *faketime.ManualClock, *ndpDispatcher, *channel.Endpoint, []byte) []tcpip.AddressWithPrefix {
  4451  				return nil
  4452  			},
  4453  			addrGenFn: func(dadCounter uint8, _ []byte) tcpip.AddressWithPrefix {
  4454  				return addrForSubnet(header.IPv6LinkLocalPrefix.Subnet(), dadCounter)
  4455  			},
  4456  		},
  4457  		{
  4458  			name: "Temporary address",
  4459  			ndpConfigs: ipv6.NDPConfigurations{
  4460  				HandleRAs:                  ipv6.HandlingRAsEnabledWhenForwardingDisabled,
  4461  				AutoGenGlobalAddresses:     true,
  4462  				AutoGenTempGlobalAddresses: true,
  4463  			},
  4464  			prepareFn: func(t *testing.T, clock *faketime.ManualClock, ndpDisp *ndpDispatcher, e *channel.Endpoint, tempIIDHistory []byte) []tcpip.AddressWithPrefix {
  4465  				header.InitialTempIID(tempIIDHistory, nil, nicID)
  4466  
  4467  				// Generate a stable SLAAC address so temporary addresses will be
  4468  				// generated.
  4469  				e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, 100, 100))
  4470  				if _, err := expectAutoGenAddrNewEvent(ndpDisp, stableAddrForTempAddrTest); err != nil {
  4471  					t.Fatalf("error expecting stable auto-gen address generated event: %s", err)
  4472  				}
  4473  				expectDADEventAsync(t, clock, ndpDisp, stableAddrForTempAddrTest.Address, &stack.DADSucceeded{})
  4474  
  4475  				// The stable address will be assigned throughout the test.
  4476  				return []tcpip.AddressWithPrefix{stableAddrForTempAddrTest}
  4477  			},
  4478  			addrGenFn: func(_ uint8, tempIIDHistory []byte) tcpip.AddressWithPrefix {
  4479  				return header.GenerateTempIPv6SLAACAddr(tempIIDHistory, stableAddrForTempAddrTest.Address)
  4480  			},
  4481  		},
  4482  	}
  4483  
  4484  	for _, addrType := range addrTypes {
  4485  		t.Run(addrType.name, func(t *testing.T) {
  4486  			for maxRetries := uint8(0); maxRetries <= maxMaxRetries; maxRetries++ {
  4487  				for numFailures := uint8(0); numFailures <= maxRetries+1; numFailures++ {
  4488  					maxRetries := maxRetries
  4489  					numFailures := numFailures
  4490  					addrType := addrType
  4491  
  4492  					t.Run(fmt.Sprintf("%d max retries and %d failures", maxRetries, numFailures), func(t *testing.T) {
  4493  						const autoGenAddrCount = 2
  4494  						ndpDisp := ndpDispatcher{
  4495  							dadC:            make(chan ndpDADEvent, 1),
  4496  							autoGenAddrNewC: make(chan ndpAutoGenAddrNewEvent, autoGenAddrCount),
  4497  							autoGenAddrC:    make(chan ndpAutoGenAddrEvent, autoGenAddrCount),
  4498  						}
  4499  						e := channel.New(0, 1280, linkAddr1)
  4500  						ndpConfigs := addrType.ndpConfigs
  4501  						ndpConfigs.AutoGenAddressConflictRetries = maxRetries
  4502  						clock := faketime.NewManualClock()
  4503  						s := stack.New(stack.Options{
  4504  							NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
  4505  								AutoGenLinkLocal: addrType.autoGenLinkLocal,
  4506  								DADConfigs: stack.DADConfigurations{
  4507  									DupAddrDetectTransmits: dadTransmits,
  4508  									RetransmitTimer:        retransmitTimer,
  4509  								},
  4510  								NDPConfigs: ndpConfigs,
  4511  								NDPDisp:    &ndpDisp,
  4512  								OpaqueIIDOpts: ipv6.OpaqueInterfaceIdentifierOptions{
  4513  									NICNameFromID: func(_ tcpip.NICID, nicName string) string {
  4514  										return nicName
  4515  									},
  4516  									SecretKey: secretKey,
  4517  								},
  4518  							})},
  4519  							Clock: clock,
  4520  						})
  4521  						opts := stack.NICOptions{Name: nicName}
  4522  						if err := s.CreateNICWithOptions(nicID, e, opts); err != nil {
  4523  							t.Fatalf("CreateNICWithOptions(%d, _, %+v) = %s", nicID, opts, err)
  4524  						}
  4525  
  4526  						var tempIIDHistory [header.IIDSize]byte
  4527  						stableAddrs := addrType.prepareFn(t, clock, &ndpDisp, e, tempIIDHistory[:])
  4528  
  4529  						// Simulate DAD conflicts so the address is regenerated.
  4530  						for i := uint8(0); i < numFailures; i++ {
  4531  							addr := addrType.addrGenFn(i, tempIIDHistory[:])
  4532  							clock.RunImmediatelyScheduledJobs()
  4533  							if _, err := expectAutoGenAddrNewEvent(&ndpDisp, addr); err != nil {
  4534  								t.Fatalf("error expecting auto-gen address generated event after %d failure(s): %s", i, err)
  4535  							}
  4536  
  4537  							// Should not have any new addresses assigned to the NIC.
  4538  							if mismatch := addressCheck(s.NICInfo()[nicID].ProtocolAddresses, stableAddrs, nil); mismatch != "" {
  4539  								t.Fatal(mismatch)
  4540  							}
  4541  
  4542  							// Simulate a DAD conflict.
  4543  							rxNDPSolicit(e, addr.Address)
  4544  							expectAutoGenAddrEvent(t, &ndpDisp, addr, invalidatedAddr)
  4545  							expectDADEvent(t, clock, &ndpDisp, addr.Address, &stack.DADDupAddrDetected{})
  4546  
  4547  							// Attempting to add the address manually should not fail if the
  4548  							// address's state was cleaned up when DAD failed.
  4549  							protocolAddr := tcpip.ProtocolAddress{
  4550  								Protocol:          header.IPv6ProtocolNumber,
  4551  								AddressWithPrefix: addr,
  4552  							}
  4553  							if err := s.AddProtocolAddress(nicID, protocolAddr, stack.AddressProperties{}); err != nil {
  4554  								t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", nicID, protocolAddr, err)
  4555  							}
  4556  							if err := s.RemoveAddress(nicID, addr.Address); err != nil {
  4557  								t.Fatalf("RemoveAddress(%d, %s) = %s", nicID, addr.Address, err)
  4558  							}
  4559  							expectDADEvent(t, clock, &ndpDisp, addr.Address, &stack.DADAborted{})
  4560  						}
  4561  
  4562  						// Should not have any new addresses assigned to the NIC.
  4563  						if mismatch := addressCheck(s.NICInfo()[nicID].ProtocolAddresses, stableAddrs, nil); mismatch != "" {
  4564  							t.Fatal(mismatch)
  4565  						}
  4566  
  4567  						// If we had less failures than generation attempts, we should have
  4568  						// an address after DAD resolves.
  4569  						if maxRetries+1 > numFailures {
  4570  							addr := addrType.addrGenFn(numFailures, tempIIDHistory[:])
  4571  							clock.RunImmediatelyScheduledJobs()
  4572  							if _, err := expectAutoGenAddrNewEvent(&ndpDisp, addr); err != nil {
  4573  								t.Fatalf("error expecting final auto-gen address generated event: %s", err)
  4574  							}
  4575  							expectDADEventAsync(t, clock, &ndpDisp, addr.Address, &stack.DADSucceeded{})
  4576  							if mismatch := addressCheck(s.NICInfo()[nicID].ProtocolAddresses, append(stableAddrs, addr), nil); mismatch != "" {
  4577  								t.Fatal(mismatch)
  4578  							}
  4579  						}
  4580  
  4581  						// Should not attempt address generation again.
  4582  						select {
  4583  						case e := <-ndpDisp.autoGenAddrC:
  4584  							t.Fatalf("unexpectedly got an auto-generated address event = %+v", e)
  4585  						default:
  4586  						}
  4587  					})
  4588  				}
  4589  			}
  4590  		})
  4591  	}
  4592  }
  4593  
  4594  // TestAutoGenAddrWithEUI64IIDNoDADRetries tests that a regeneration attempt is
  4595  // not made for SLAAC addresses generated with an IID based on the NIC's link
  4596  // address.
  4597  func TestAutoGenAddrWithEUI64IIDNoDADRetries(t *testing.T) {
  4598  	const nicID = 1
  4599  	const dadTransmits = 1
  4600  	const retransmitTimer = time.Second
  4601  	const maxRetries = 3
  4602  	const lifetimeSeconds = 10
  4603  
  4604  	prefix, subnet, _ := prefixSubnetAddr(0, linkAddr1)
  4605  
  4606  	addrTypes := []struct {
  4607  		name             string
  4608  		ndpConfigs       ipv6.NDPConfigurations
  4609  		autoGenLinkLocal bool
  4610  		subnet           tcpip.Subnet
  4611  		triggerSLAACFn   func(e *channel.Endpoint)
  4612  	}{
  4613  		{
  4614  			name: "Global address",
  4615  			ndpConfigs: ipv6.NDPConfigurations{
  4616  				HandleRAs:                     ipv6.HandlingRAsEnabledWhenForwardingDisabled,
  4617  				AutoGenGlobalAddresses:        true,
  4618  				AutoGenAddressConflictRetries: maxRetries,
  4619  			},
  4620  			subnet: subnet,
  4621  			triggerSLAACFn: func(e *channel.Endpoint) {
  4622  				// Receive an RA with prefix1 in a PI.
  4623  				e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, lifetimeSeconds, lifetimeSeconds))
  4624  
  4625  			},
  4626  		},
  4627  		{
  4628  			name: "LinkLocal address",
  4629  			ndpConfigs: ipv6.NDPConfigurations{
  4630  				AutoGenAddressConflictRetries: maxRetries,
  4631  			},
  4632  			autoGenLinkLocal: true,
  4633  			subnet:           header.IPv6LinkLocalPrefix.Subnet(),
  4634  			triggerSLAACFn:   func(e *channel.Endpoint) {},
  4635  		},
  4636  	}
  4637  
  4638  	for _, addrType := range addrTypes {
  4639  		addrType := addrType
  4640  
  4641  		t.Run(addrType.name, func(t *testing.T) {
  4642  			const autoGenAddrCount = 2
  4643  			ndpDisp := ndpDispatcher{
  4644  				dadC:            make(chan ndpDADEvent, 1),
  4645  				autoGenAddrNewC: make(chan ndpAutoGenAddrNewEvent, autoGenAddrCount),
  4646  				autoGenAddrC:    make(chan ndpAutoGenAddrEvent, autoGenAddrCount),
  4647  			}
  4648  			e := channel.New(0, 1280, linkAddr1)
  4649  			clock := faketime.NewManualClock()
  4650  			s := stack.New(stack.Options{
  4651  				NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
  4652  					AutoGenLinkLocal: addrType.autoGenLinkLocal,
  4653  					NDPConfigs:       addrType.ndpConfigs,
  4654  					NDPDisp:          &ndpDisp,
  4655  					DADConfigs: stack.DADConfigurations{
  4656  						DupAddrDetectTransmits: dadTransmits,
  4657  						RetransmitTimer:        retransmitTimer,
  4658  					},
  4659  				})},
  4660  				Clock: clock,
  4661  			})
  4662  			if err := s.CreateNIC(nicID, e); err != nil {
  4663  				t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
  4664  			}
  4665  
  4666  			addrType.triggerSLAACFn(e)
  4667  
  4668  			subnetID := addrType.subnet.ID()
  4669  			addrBytes := subnetID.AsSlice()
  4670  			header.EthernetAdddressToModifiedEUI64IntoBuf(linkAddr1, addrBytes[header.IIDOffsetInIPv6Address:])
  4671  			addr := tcpip.AddressWithPrefix{
  4672  				Address:   tcpip.AddrFromSlice(addrBytes),
  4673  				PrefixLen: 64,
  4674  			}
  4675  			if _, err := expectAutoGenAddrNewEvent(&ndpDisp, addr); err != nil {
  4676  				t.Fatalf("error expecting stable auto-gen address generated event: %s", err)
  4677  			}
  4678  
  4679  			// Simulate a DAD conflict.
  4680  			rxNDPSolicit(e, addr.Address)
  4681  			expectAutoGenAddrEvent(t, &ndpDisp, addr, invalidatedAddr)
  4682  			select {
  4683  			case e := <-ndpDisp.dadC:
  4684  				if diff := checkDADEvent(e, nicID, addr.Address, &stack.DADDupAddrDetected{}); diff != "" {
  4685  					t.Errorf("DAD event mismatch (-want +got):\n%s", diff)
  4686  				}
  4687  			default:
  4688  				t.Fatal("expected DAD event")
  4689  			}
  4690  
  4691  			// Should not attempt address regeneration.
  4692  			select {
  4693  			case e := <-ndpDisp.autoGenAddrC:
  4694  				t.Fatalf("unexpectedly got an auto-generated address event = %+v", e)
  4695  			default:
  4696  			}
  4697  		})
  4698  	}
  4699  }
  4700  
  4701  // TestAutoGenAddrContinuesLifetimesAfterRetry tests that retrying address
  4702  // generation in response to DAD conflicts does not refresh the lifetimes.
  4703  func TestAutoGenAddrContinuesLifetimesAfterRetry(t *testing.T) {
  4704  	const nicID = 1
  4705  	const nicName = "nic"
  4706  	const dadTransmits = 1
  4707  	const retransmitTimer = 2 * time.Second
  4708  	const failureTimer = time.Second
  4709  	const maxRetries = 1
  4710  	const lifetimeSeconds = 5
  4711  
  4712  	secretKey := makeSecretKey(t)
  4713  
  4714  	prefix, subnet, _ := prefixSubnetAddr(0, linkAddr1)
  4715  
  4716  	const autoGenAddrCount = 2
  4717  	ndpDisp := ndpDispatcher{
  4718  		dadC:               make(chan ndpDADEvent, 1),
  4719  		autoGenAddrNewC:    make(chan ndpAutoGenAddrNewEvent, autoGenAddrCount),
  4720  		autoGenAddrC:       make(chan ndpAutoGenAddrEvent, autoGenAddrCount),
  4721  		autoGenInstallDisp: true,
  4722  	}
  4723  	e := channel.New(0, 1280, linkAddr1)
  4724  	clock := faketime.NewManualClock()
  4725  	s := stack.New(stack.Options{
  4726  		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
  4727  			DADConfigs: stack.DADConfigurations{
  4728  				DupAddrDetectTransmits: dadTransmits,
  4729  				RetransmitTimer:        retransmitTimer,
  4730  			},
  4731  			NDPConfigs: ipv6.NDPConfigurations{
  4732  				HandleRAs:                     ipv6.HandlingRAsEnabledWhenForwardingDisabled,
  4733  				AutoGenGlobalAddresses:        true,
  4734  				AutoGenAddressConflictRetries: maxRetries,
  4735  			},
  4736  			NDPDisp: &ndpDisp,
  4737  			OpaqueIIDOpts: ipv6.OpaqueInterfaceIdentifierOptions{
  4738  				NICNameFromID: func(_ tcpip.NICID, nicName string) string {
  4739  					return nicName
  4740  				},
  4741  				SecretKey: secretKey,
  4742  			},
  4743  		})},
  4744  		Clock: clock,
  4745  	})
  4746  	opts := stack.NICOptions{Name: nicName}
  4747  	if err := s.CreateNICWithOptions(nicID, e, opts); err != nil {
  4748  		t.Fatalf("CreateNICWithOptions(%d, _, %+v) = %s", nicID, opts, err)
  4749  	}
  4750  
  4751  	// Receive an RA with prefix in a PI.
  4752  	received := clock.NowMonotonic()
  4753  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, lifetimeSeconds, lifetimeSeconds))
  4754  
  4755  	subnetID := subnet.ID()
  4756  	addrBytes := subnetID.AsSlice()
  4757  	addr := tcpip.AddressWithPrefix{
  4758  		Address:   tcpip.AddrFromSlice(header.AppendOpaqueInterfaceIdentifier(addrBytes[:header.IIDOffsetInIPv6Address], subnet, nicName, 0, secretKey)),
  4759  		PrefixLen: 64,
  4760  	}
  4761  	addrDisp, err := expectAutoGenAddrNewEvent(&ndpDisp, addr)
  4762  	if err != nil {
  4763  		t.Fatalf("error expecting stable auto-gen address (DAD will not resolve) generated event: %s", err)
  4764  	}
  4765  	if err := addrDisp.expectChanged(addressLifetimes(received, lifetimeSeconds, lifetimeSeconds), stack.AddressTentative); err != nil {
  4766  		t.Error(err)
  4767  	}
  4768  
  4769  	// Simulate a DAD conflict after some time has passed.
  4770  	clock.Advance(failureTimer)
  4771  	rxNDPSolicit(e, addr.Address)
  4772  	expectAutoGenAddrEvent(t, &ndpDisp, addr, invalidatedAddr)
  4773  	if err := addrDisp.expectRemoved(stack.AddressRemovalDADFailed); err != nil {
  4774  		t.Error(err)
  4775  	}
  4776  	select {
  4777  	case e := <-ndpDisp.dadC:
  4778  		if diff := checkDADEvent(e, nicID, addr.Address, &stack.DADDupAddrDetected{}); diff != "" {
  4779  			t.Errorf("DAD event mismatch (-want +got):\n%s", diff)
  4780  		}
  4781  	default:
  4782  		t.Fatal("expected DAD event")
  4783  	}
  4784  
  4785  	// Let the next address resolve.
  4786  	addr.Address = tcpip.AddrFromSlice(header.AppendOpaqueInterfaceIdentifier(addrBytes[:header.IIDOffsetInIPv6Address], subnet, nicName, 1, secretKey))
  4787  	addrDisp, err = expectAutoGenAddrNewEvent(&ndpDisp, addr)
  4788  	if err != nil {
  4789  		t.Fatalf("error expecting stable auto-gen address generated event: %s", err)
  4790  	}
  4791  	if err := addrDisp.expectChanged(addressLifetimes(received, lifetimeSeconds, lifetimeSeconds), stack.AddressTentative); err != nil {
  4792  		t.Error(err)
  4793  	}
  4794  	clock.Advance(dadTransmits * retransmitTimer)
  4795  	select {
  4796  	case e := <-ndpDisp.dadC:
  4797  		if diff := checkDADEvent(e, nicID, addr.Address, &stack.DADSucceeded{}); diff != "" {
  4798  			t.Errorf("DAD event mismatch (-want +got):\n%s", diff)
  4799  		}
  4800  	default:
  4801  		t.Fatal("timed out waiting for DAD event")
  4802  	}
  4803  	if err := addrDisp.expectStateChanged(stack.AddressAssigned); err != nil {
  4804  		t.Error(err)
  4805  	}
  4806  
  4807  	// Address should be deprecated/invalidated after the lifetime expires.
  4808  	//
  4809  	// Note, the remaining lifetime is calculated from when the PI was first
  4810  	// processed. Since we wait for some time before simulating a DAD conflict
  4811  	// and more time for the new address to resolve, the new address is only
  4812  	// expected to be valid for the remaining time. The DAD conflict should
  4813  	// not have reset the lifetimes.
  4814  	//
  4815  	// We expect either just the invalidation event or the deprecation event
  4816  	// followed by the invalidation event.
  4817  	clock.Advance(lifetimeSeconds*time.Second - failureTimer - dadTransmits*retransmitTimer)
  4818  	select {
  4819  	case e := <-ndpDisp.autoGenAddrC:
  4820  		if e.eventType == deprecatedAddr {
  4821  			if diff := checkAutoGenAddrEvent(e, addr, deprecatedAddr); diff != "" {
  4822  				t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
  4823  			}
  4824  
  4825  			select {
  4826  			case e := <-ndpDisp.autoGenAddrC:
  4827  				if diff := checkAutoGenAddrEvent(e, addr, invalidatedAddr); diff != "" {
  4828  					t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
  4829  				}
  4830  			default:
  4831  				t.Fatal("timed out waiting for invalidated auto gen addr event after deprecation")
  4832  			}
  4833  		} else {
  4834  			if diff := checkAutoGenAddrEvent(e, addr, invalidatedAddr); diff != "" {
  4835  				t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
  4836  			}
  4837  		}
  4838  	default:
  4839  		t.Fatal("timed out waiting for auto gen addr event")
  4840  	}
  4841  	if err := addrDisp.expectRemoved(stack.AddressRemovalInvalidated); err != nil {
  4842  		t.Error(err)
  4843  	}
  4844  }
  4845  
  4846  // TestNDPRecursiveDNSServerDispatch tests that we properly dispatch an event
  4847  // to the integrator when an RA is received with the NDP Recursive DNS Server
  4848  // option with at least one valid address.
  4849  func TestNDPRecursiveDNSServerDispatch(t *testing.T) {
  4850  	tests := []struct {
  4851  		name     string
  4852  		opt      header.NDPRecursiveDNSServer
  4853  		expected *ndpRDNSS
  4854  	}{
  4855  		{
  4856  			"Unspecified",
  4857  			header.NDPRecursiveDNSServer([]byte{
  4858  				0, 0,
  4859  				0, 0, 0, 2,
  4860  				0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  4861  			}),
  4862  			nil,
  4863  		},
  4864  		{
  4865  			"Multicast",
  4866  			header.NDPRecursiveDNSServer([]byte{
  4867  				0, 0,
  4868  				0, 0, 0, 2,
  4869  				255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
  4870  			}),
  4871  			nil,
  4872  		},
  4873  		{
  4874  			"OptionTooSmall",
  4875  			header.NDPRecursiveDNSServer([]byte{
  4876  				0, 0,
  4877  				0, 0, 0, 2,
  4878  				1, 2, 3, 4, 5, 6, 7, 8,
  4879  			}),
  4880  			nil,
  4881  		},
  4882  		{
  4883  			"0Addresses",
  4884  			header.NDPRecursiveDNSServer([]byte{
  4885  				0, 0,
  4886  				0, 0, 0, 2,
  4887  			}),
  4888  			nil,
  4889  		},
  4890  		{
  4891  			"Valid1Address",
  4892  			header.NDPRecursiveDNSServer([]byte{
  4893  				0, 0,
  4894  				0, 0, 0, 2,
  4895  				1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 1,
  4896  			}),
  4897  			&ndpRDNSS{
  4898  				[]tcpip.Address{
  4899  					tcpip.AddrFromSlice([]byte("\x01\x02\x03\x04\x05\x06\x07\x08\x00\x00\x00\x00\x00\x00\x00\x01")),
  4900  				},
  4901  				2 * time.Second,
  4902  			},
  4903  		},
  4904  		{
  4905  			"Valid2Addresses",
  4906  			header.NDPRecursiveDNSServer([]byte{
  4907  				0, 0,
  4908  				0, 0, 0, 1,
  4909  				1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 1,
  4910  				1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 2,
  4911  			}),
  4912  			&ndpRDNSS{
  4913  				[]tcpip.Address{
  4914  					tcpip.AddrFromSlice([]byte("\x01\x02\x03\x04\x05\x06\x07\x08\x00\x00\x00\x00\x00\x00\x00\x01")),
  4915  					tcpip.AddrFromSlice([]byte("\x01\x02\x03\x04\x05\x06\x07\x08\x00\x00\x00\x00\x00\x00\x00\x02")),
  4916  				},
  4917  				time.Second,
  4918  			},
  4919  		},
  4920  		{
  4921  			"Valid3Addresses",
  4922  			header.NDPRecursiveDNSServer([]byte{
  4923  				0, 0,
  4924  				0, 0, 0, 0,
  4925  				1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 1,
  4926  				1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 2,
  4927  				1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 3,
  4928  			}),
  4929  			&ndpRDNSS{
  4930  				[]tcpip.Address{
  4931  					tcpip.AddrFromSlice([]byte("\x01\x02\x03\x04\x05\x06\x07\x08\x00\x00\x00\x00\x00\x00\x00\x01")),
  4932  					tcpip.AddrFromSlice([]byte("\x01\x02\x03\x04\x05\x06\x07\x08\x00\x00\x00\x00\x00\x00\x00\x02")),
  4933  					tcpip.AddrFromSlice([]byte("\x01\x02\x03\x04\x05\x06\x07\x08\x00\x00\x00\x00\x00\x00\x00\x03")),
  4934  				},
  4935  				0,
  4936  			},
  4937  		},
  4938  	}
  4939  
  4940  	for _, test := range tests {
  4941  		t.Run(test.name, func(t *testing.T) {
  4942  			ndpDisp := ndpDispatcher{
  4943  				// We do not expect more than a single RDNSS
  4944  				// event at any time for this test.
  4945  				rdnssC: make(chan ndpRDNSSEvent, 1),
  4946  			}
  4947  			e := channel.New(0, 1280, linkAddr1)
  4948  			s := stack.New(stack.Options{
  4949  				NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
  4950  					NDPConfigs: ipv6.NDPConfigurations{
  4951  						HandleRAs: ipv6.HandlingRAsEnabledWhenForwardingDisabled,
  4952  					},
  4953  					NDPDisp: &ndpDisp,
  4954  				})},
  4955  			})
  4956  			if err := s.CreateNIC(1, e); err != nil {
  4957  				t.Fatalf("CreateNIC(1) = %s", err)
  4958  			}
  4959  
  4960  			e.InjectInbound(header.IPv6ProtocolNumber, raBufWithOpts(llAddr1, 0, header.NDPOptionsSerializer{test.opt}))
  4961  
  4962  			if test.expected != nil {
  4963  				select {
  4964  				case e := <-ndpDisp.rdnssC:
  4965  					if e.nicID != 1 {
  4966  						t.Errorf("got rdnss nicID = %d, want = 1", e.nicID)
  4967  					}
  4968  					if diff := cmp.Diff(e.rdnss.addrs, test.expected.addrs); diff != "" {
  4969  						t.Errorf("rdnss addrs mismatch (-want +got):\n%s", diff)
  4970  					}
  4971  					if e.rdnss.lifetime != test.expected.lifetime {
  4972  						t.Errorf("got rdnss lifetime = %s, want = %s", e.rdnss.lifetime, test.expected.lifetime)
  4973  					}
  4974  				default:
  4975  					t.Fatal("expected an RDNSS option event")
  4976  				}
  4977  			}
  4978  
  4979  			// Should have no more RDNSS options.
  4980  			select {
  4981  			case e := <-ndpDisp.rdnssC:
  4982  				t.Fatalf("unexpectedly got a new RDNSS option event: %+v", e)
  4983  			default:
  4984  			}
  4985  		})
  4986  	}
  4987  }
  4988  
  4989  // TestNDPDNSSearchListDispatch tests that the integrator is informed when an
  4990  // NDP DNS Search List option is received with at least one domain name in the
  4991  // search list.
  4992  func TestNDPDNSSearchListDispatch(t *testing.T) {
  4993  	const nicID = 1
  4994  
  4995  	ndpDisp := ndpDispatcher{
  4996  		dnsslC: make(chan ndpDNSSLEvent, 3),
  4997  	}
  4998  	e := channel.New(0, 1280, linkAddr1)
  4999  	s := stack.New(stack.Options{
  5000  		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
  5001  			NDPConfigs: ipv6.NDPConfigurations{
  5002  				HandleRAs: ipv6.HandlingRAsEnabledWhenForwardingDisabled,
  5003  			},
  5004  			NDPDisp: &ndpDisp,
  5005  		})},
  5006  	})
  5007  	if err := s.CreateNIC(nicID, e); err != nil {
  5008  		t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
  5009  	}
  5010  
  5011  	optSer := header.NDPOptionsSerializer{
  5012  		header.NDPDNSSearchList([]byte{
  5013  			0, 0,
  5014  			0, 0, 0, 0,
  5015  			2, 'h', 'i',
  5016  			0,
  5017  		}),
  5018  		header.NDPDNSSearchList([]byte{
  5019  			0, 0,
  5020  			0, 0, 0, 1,
  5021  			1, 'i',
  5022  			0,
  5023  			2, 'a', 'm',
  5024  			2, 'm', 'e',
  5025  			0,
  5026  		}),
  5027  		header.NDPDNSSearchList([]byte{
  5028  			0, 0,
  5029  			0, 0, 1, 0,
  5030  			3, 'x', 'y', 'z',
  5031  			0,
  5032  			5, 'h', 'e', 'l', 'l', 'o',
  5033  			5, 'w', 'o', 'r', 'l', 'd',
  5034  			0,
  5035  			4, 't', 'h', 'i', 's',
  5036  			2, 'i', 's',
  5037  			1, 'a',
  5038  			4, 't', 'e', 's', 't',
  5039  			0,
  5040  		}),
  5041  	}
  5042  	expected := []struct {
  5043  		domainNames []string
  5044  		lifetime    time.Duration
  5045  	}{
  5046  		{
  5047  			domainNames: []string{
  5048  				"hi",
  5049  			},
  5050  			lifetime: 0,
  5051  		},
  5052  		{
  5053  			domainNames: []string{
  5054  				"i",
  5055  				"am.me",
  5056  			},
  5057  			lifetime: time.Second,
  5058  		},
  5059  		{
  5060  			domainNames: []string{
  5061  				"xyz",
  5062  				"hello.world",
  5063  				"this.is.a.test",
  5064  			},
  5065  			lifetime: 256 * time.Second,
  5066  		},
  5067  	}
  5068  
  5069  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithOpts(llAddr1, 0, optSer))
  5070  
  5071  	for i, expected := range expected {
  5072  		select {
  5073  		case dnssl := <-ndpDisp.dnsslC:
  5074  			if dnssl.nicID != nicID {
  5075  				t.Errorf("got %d-th dnssl nicID = %d, want = %d", i, dnssl.nicID, nicID)
  5076  			}
  5077  			if diff := cmp.Diff(dnssl.domainNames, expected.domainNames); diff != "" {
  5078  				t.Errorf("%d-th dnssl domain names mismatch (-want +got):\n%s", i, diff)
  5079  			}
  5080  			if dnssl.lifetime != expected.lifetime {
  5081  				t.Errorf("got %d-th dnssl lifetime = %s, want = %s", i, dnssl.lifetime, expected.lifetime)
  5082  			}
  5083  		default:
  5084  			t.Fatal("expected a DNSSL event")
  5085  		}
  5086  	}
  5087  
  5088  	// Should have no more DNSSL options.
  5089  	select {
  5090  	case <-ndpDisp.dnsslC:
  5091  		t.Fatal("unexpectedly got a DNSSL event")
  5092  	default:
  5093  	}
  5094  }
  5095  
  5096  func TestNoCleanupNDPStateWhenForwardingEnabled(t *testing.T) {
  5097  	const (
  5098  		lifetimeSeconds = 999
  5099  		nicID           = 1
  5100  	)
  5101  
  5102  	const autoGenAddrCount = 1
  5103  	ndpDisp := ndpDispatcher{
  5104  		offLinkRouteC:   make(chan ndpOffLinkRouteEvent, 1),
  5105  		prefixC:         make(chan ndpPrefixEvent, 1),
  5106  		autoGenAddrC:    make(chan ndpAutoGenAddrEvent, autoGenAddrCount),
  5107  		autoGenAddrNewC: make(chan ndpAutoGenAddrNewEvent, autoGenAddrCount),
  5108  	}
  5109  	s := stack.New(stack.Options{
  5110  		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
  5111  			AutoGenLinkLocal: true,
  5112  			NDPConfigs: ipv6.NDPConfigurations{
  5113  				HandleRAs:              ipv6.HandlingRAsEnabledWhenForwardingDisabled,
  5114  				DiscoverDefaultRouters: true,
  5115  				DiscoverOnLinkPrefixes: true,
  5116  				AutoGenGlobalAddresses: true,
  5117  			},
  5118  			NDPDisp: &ndpDisp,
  5119  		})},
  5120  	})
  5121  
  5122  	e1 := channel.New(0, header.IPv6MinimumMTU, linkAddr1)
  5123  	if err := s.CreateNIC(nicID, e1); err != nil {
  5124  		t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
  5125  	}
  5126  	llAddr := tcpip.AddressWithPrefix{Address: llAddr1, PrefixLen: header.IPv6LinkLocalPrefix.PrefixLen}
  5127  	if _, err := expectAutoGenAddrNewEvent(&ndpDisp, llAddr); err != nil {
  5128  		t.Fatalf("error expecting link-local auto-gen address generated event: %s", err)
  5129  	}
  5130  
  5131  	prefix, subnet, addr := prefixSubnetAddr(0, linkAddr1)
  5132  	e1.InjectInbound(
  5133  		header.IPv6ProtocolNumber,
  5134  		raBufWithPI(
  5135  			llAddr3,
  5136  			lifetimeSeconds,
  5137  			prefix,
  5138  			true, /* onLink */
  5139  			true, /* auto */
  5140  			lifetimeSeconds,
  5141  			lifetimeSeconds,
  5142  		),
  5143  	)
  5144  	select {
  5145  	case e := <-ndpDisp.offLinkRouteC:
  5146  		if diff := checkOffLinkRouteEvent(e, nicID, header.IPv6EmptySubnet, llAddr3, header.MediumRoutePreference, true /* discovered */); diff != "" {
  5147  			t.Errorf("off-link route event mismatch (-want +got):\n%s", diff)
  5148  		}
  5149  	default:
  5150  		t.Errorf("expected off-link route event for %s on NIC(%d)", llAddr3, nicID)
  5151  	}
  5152  	select {
  5153  	case e := <-ndpDisp.prefixC:
  5154  		if diff := checkPrefixEvent(e, subnet, true /* discovered */); diff != "" {
  5155  			t.Errorf("off-link route event mismatch (-want +got):\n%s", diff)
  5156  		}
  5157  	default:
  5158  		t.Errorf("expected prefix event for %s on NIC(%d)", prefix, nicID)
  5159  	}
  5160  	if _, err := expectAutoGenAddrNewEvent(&ndpDisp, addr); err != nil {
  5161  		t.Fatalf("error expecting stable auto-gen address generated event: %s", err)
  5162  	}
  5163  
  5164  	// Enabling or disabling forwarding should not invalidate discovered prefixes
  5165  	// or routers, or auto-generated address.
  5166  	for _, forwarding := range [...]bool{true, false} {
  5167  		t.Run(fmt.Sprintf("Transition forwarding to %t", forwarding), func(t *testing.T) {
  5168  			if err := s.SetForwardingDefaultAndAllNICs(ipv6.ProtocolNumber, forwarding); err != nil {
  5169  				t.Fatalf("SetForwardingDefaultAndAllNICs(%d, %t): %s", ipv6.ProtocolNumber, forwarding, err)
  5170  			}
  5171  			select {
  5172  			case e := <-ndpDisp.offLinkRouteC:
  5173  				t.Errorf("unexpected off-link route event = %#v", e)
  5174  			default:
  5175  			}
  5176  			select {
  5177  			case e := <-ndpDisp.prefixC:
  5178  				t.Errorf("unexpected prefix event = %#v", e)
  5179  			default:
  5180  			}
  5181  			select {
  5182  			case e := <-ndpDisp.autoGenAddrC:
  5183  				t.Errorf("unexpected auto-gen addr event = %#v", e)
  5184  			default:
  5185  			}
  5186  			select {
  5187  			case e := <-ndpDisp.autoGenAddrNewC:
  5188  				t.Errorf("unexpected new auto-gen addr event = %#v", e)
  5189  			default:
  5190  			}
  5191  		})
  5192  	}
  5193  }
  5194  
  5195  func TestCleanupNDPState(t *testing.T) {
  5196  	const (
  5197  		lifetimeSeconds          = 5
  5198  		maxRouterAndPrefixEvents = 4
  5199  		nicID1                   = 1
  5200  		nicID2                   = 2
  5201  	)
  5202  
  5203  	prefix1, subnet1, e1Addr1 := prefixSubnetAddr(0, linkAddr1)
  5204  	prefix2, subnet2, e1Addr2 := prefixSubnetAddr(1, linkAddr1)
  5205  	e2Addr1 := addrForSubnet(subnet1, linkAddr2)
  5206  	e2Addr2 := addrForSubnet(subnet2, linkAddr2)
  5207  	llAddrWithPrefix1 := tcpip.AddressWithPrefix{
  5208  		Address:   llAddr1,
  5209  		PrefixLen: 64,
  5210  	}
  5211  	llAddrWithPrefix2 := tcpip.AddressWithPrefix{
  5212  		Address:   llAddr2,
  5213  		PrefixLen: 64,
  5214  	}
  5215  
  5216  	tests := []struct {
  5217  		name                 string
  5218  		cleanupFn            func(t *testing.T, s *stack.Stack)
  5219  		keepAutoGenLinkLocal bool
  5220  		maxAutoGenAddrEvents int
  5221  		skipFinalAddrCheck   bool
  5222  	}{
  5223  		// A NIC should cleanup all NDP state when it is disabled.
  5224  		{
  5225  			name: "Disable NIC",
  5226  			cleanupFn: func(t *testing.T, s *stack.Stack) {
  5227  				t.Helper()
  5228  
  5229  				if err := s.DisableNIC(nicID1); err != nil {
  5230  					t.Fatalf("s.DisableNIC(%d): %s", nicID1, err)
  5231  				}
  5232  				if err := s.DisableNIC(nicID2); err != nil {
  5233  					t.Fatalf("s.DisableNIC(%d): %s", nicID2, err)
  5234  				}
  5235  			},
  5236  			keepAutoGenLinkLocal: false,
  5237  			maxAutoGenAddrEvents: 6,
  5238  		},
  5239  
  5240  		// A NIC should cleanup all NDP state when it is removed.
  5241  		{
  5242  			name: "Remove NIC",
  5243  			cleanupFn: func(t *testing.T, s *stack.Stack) {
  5244  				t.Helper()
  5245  
  5246  				if err := s.RemoveNIC(nicID1); err != nil {
  5247  					t.Fatalf("s.RemoveNIC(%d): %s", nicID1, err)
  5248  				}
  5249  				if err := s.RemoveNIC(nicID2); err != nil {
  5250  					t.Fatalf("s.RemoveNIC(%d): %s", nicID2, err)
  5251  				}
  5252  			},
  5253  			keepAutoGenLinkLocal: false,
  5254  			maxAutoGenAddrEvents: 6,
  5255  			// The NICs are removed so we can't check their addresses after calling
  5256  			// stopFn.
  5257  			skipFinalAddrCheck: true,
  5258  		},
  5259  	}
  5260  
  5261  	for _, test := range tests {
  5262  		t.Run(test.name, func(t *testing.T) {
  5263  			ndpDisp := ndpDispatcher{
  5264  				offLinkRouteC:   make(chan ndpOffLinkRouteEvent, maxRouterAndPrefixEvents),
  5265  				prefixC:         make(chan ndpPrefixEvent, maxRouterAndPrefixEvents),
  5266  				autoGenAddrNewC: make(chan ndpAutoGenAddrNewEvent, test.maxAutoGenAddrEvents),
  5267  				autoGenAddrC:    make(chan ndpAutoGenAddrEvent, test.maxAutoGenAddrEvents),
  5268  			}
  5269  			clock := faketime.NewManualClock()
  5270  			s := stack.New(stack.Options{
  5271  				NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
  5272  					AutoGenLinkLocal: true,
  5273  					NDPConfigs: ipv6.NDPConfigurations{
  5274  						HandleRAs:              ipv6.HandlingRAsEnabledWhenForwardingDisabled,
  5275  						DiscoverDefaultRouters: true,
  5276  						DiscoverOnLinkPrefixes: true,
  5277  						AutoGenGlobalAddresses: true,
  5278  					},
  5279  					NDPDisp: &ndpDisp,
  5280  				})},
  5281  				Clock: clock,
  5282  			})
  5283  
  5284  			expectOffLinkRouteEvent := func() (bool, ndpOffLinkRouteEvent) {
  5285  				select {
  5286  				case e := <-ndpDisp.offLinkRouteC:
  5287  					return true, e
  5288  				default:
  5289  				}
  5290  
  5291  				return false, ndpOffLinkRouteEvent{}
  5292  			}
  5293  
  5294  			expectPrefixEvent := func() (bool, ndpPrefixEvent) {
  5295  				select {
  5296  				case e := <-ndpDisp.prefixC:
  5297  					return true, e
  5298  				default:
  5299  				}
  5300  
  5301  				return false, ndpPrefixEvent{}
  5302  			}
  5303  
  5304  			expectAutoGenAddrEvent := func() (bool, ndpAutoGenAddrEvent) {
  5305  				select {
  5306  				case e := <-ndpDisp.autoGenAddrC:
  5307  					return true, e
  5308  				default:
  5309  				}
  5310  
  5311  				return false, ndpAutoGenAddrEvent{}
  5312  			}
  5313  
  5314  			expectAutoGenAddrNewEvent := func() (bool, ndpAutoGenAddrNewEvent) {
  5315  				select {
  5316  				case e := <-ndpDisp.autoGenAddrNewC:
  5317  					return true, e
  5318  				default:
  5319  				}
  5320  				return false, ndpAutoGenAddrNewEvent{}
  5321  			}
  5322  
  5323  			e1 := channel.New(0, 1280, linkAddr1)
  5324  			if err := s.CreateNIC(nicID1, e1); err != nil {
  5325  				t.Fatalf("CreateNIC(%d, _) = %s", nicID1, err)
  5326  			}
  5327  			// We have other tests that make sure we receive the *correct* events
  5328  			// on normal discovery of routers/prefixes, and auto-generated
  5329  			// addresses. Here we just make sure we get an event and let other tests
  5330  			// handle the correctness check.
  5331  			expectAutoGenAddrNewEvent()
  5332  
  5333  			e2 := channel.New(0, 1280, linkAddr2)
  5334  			if err := s.CreateNIC(nicID2, e2); err != nil {
  5335  				t.Fatalf("CreateNIC(%d, _) = %s", nicID2, err)
  5336  			}
  5337  			expectAutoGenAddrNewEvent()
  5338  
  5339  			// Receive RAs on NIC(1) and NIC(2) from default routers (llAddr3 and
  5340  			// llAddr4) w/ PI (for prefix1 in RA from llAddr3 and prefix2 in RA from
  5341  			// llAddr4) to discover multiple routers and prefixes, and auto-gen
  5342  			// multiple addresses.
  5343  
  5344  			e1.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr3, lifetimeSeconds, prefix1, true, true, lifetimeSeconds, lifetimeSeconds))
  5345  			if ok, _ := expectOffLinkRouteEvent(); !ok {
  5346  				t.Errorf("expected off-link route event for %s on NIC(%d)", llAddr3, nicID1)
  5347  			}
  5348  			if ok, _ := expectPrefixEvent(); !ok {
  5349  				t.Errorf("expected prefix event for %s on NIC(%d)", prefix1, nicID1)
  5350  			}
  5351  			if ok, _ := expectAutoGenAddrNewEvent(); !ok {
  5352  				t.Errorf("expected auto-gen addr event for %s on NIC(%d)", e1Addr1, nicID1)
  5353  			}
  5354  
  5355  			e1.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr4, lifetimeSeconds, prefix2, true, true, lifetimeSeconds, lifetimeSeconds))
  5356  			if ok, _ := expectOffLinkRouteEvent(); !ok {
  5357  				t.Errorf("expected off-link route event for %s on NIC(%d)", llAddr4, nicID1)
  5358  			}
  5359  			if ok, _ := expectPrefixEvent(); !ok {
  5360  				t.Errorf("expected prefix event for %s on NIC(%d)", prefix2, nicID1)
  5361  			}
  5362  			if ok, _ := expectAutoGenAddrNewEvent(); !ok {
  5363  				t.Errorf("expected auto-gen addr event for %s on NIC(%d)", e1Addr2, nicID1)
  5364  			}
  5365  
  5366  			e2.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr3, lifetimeSeconds, prefix1, true, true, lifetimeSeconds, lifetimeSeconds))
  5367  			if ok, _ := expectOffLinkRouteEvent(); !ok {
  5368  				t.Errorf("expected off-link route event for %s on NIC(%d)", llAddr3, nicID2)
  5369  			}
  5370  			if ok, _ := expectPrefixEvent(); !ok {
  5371  				t.Errorf("expected prefix event for %s on NIC(%d)", prefix1, nicID2)
  5372  			}
  5373  			if ok, _ := expectAutoGenAddrNewEvent(); !ok {
  5374  				t.Errorf("expected auto-gen addr event for %s on NIC(%d)", e1Addr2, nicID2)
  5375  			}
  5376  
  5377  			e2.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr4, lifetimeSeconds, prefix2, true, true, lifetimeSeconds, lifetimeSeconds))
  5378  			if ok, _ := expectOffLinkRouteEvent(); !ok {
  5379  				t.Errorf("expected off-link route event for %s on NIC(%d)", llAddr4, nicID2)
  5380  			}
  5381  			if ok, _ := expectPrefixEvent(); !ok {
  5382  				t.Errorf("expected prefix event for %s on NIC(%d)", prefix2, nicID2)
  5383  			}
  5384  			if ok, _ := expectAutoGenAddrNewEvent(); !ok {
  5385  				t.Errorf("expected auto-gen addr event for %s on NIC(%d)", e2Addr2, nicID2)
  5386  			}
  5387  
  5388  			// We should have the auto-generated addresses added.
  5389  			nicinfo := s.NICInfo()
  5390  			nic1Addrs := nicinfo[nicID1].ProtocolAddresses
  5391  			nic2Addrs := nicinfo[nicID2].ProtocolAddresses
  5392  			if !containsV6Addr(nic1Addrs, llAddrWithPrefix1) {
  5393  				t.Errorf("missing %s from the list of addresses for NIC(%d): %+v", llAddrWithPrefix1, nicID1, nic1Addrs)
  5394  			}
  5395  			if !containsV6Addr(nic1Addrs, e1Addr1) {
  5396  				t.Errorf("missing %s from the list of addresses for NIC(%d): %+v", e1Addr1, nicID1, nic1Addrs)
  5397  			}
  5398  			if !containsV6Addr(nic1Addrs, e1Addr2) {
  5399  				t.Errorf("missing %s from the list of addresses for NIC(%d): %+v", e1Addr2, nicID1, nic1Addrs)
  5400  			}
  5401  			if !containsV6Addr(nic2Addrs, llAddrWithPrefix2) {
  5402  				t.Errorf("missing %s from the list of addresses for NIC(%d): %+v", llAddrWithPrefix2, nicID2, nic2Addrs)
  5403  			}
  5404  			if !containsV6Addr(nic2Addrs, e2Addr1) {
  5405  				t.Errorf("missing %s from the list of addresses for NIC(%d): %+v", e2Addr1, nicID2, nic2Addrs)
  5406  			}
  5407  			if !containsV6Addr(nic2Addrs, e2Addr2) {
  5408  				t.Errorf("missing %s from the list of addresses for NIC(%d): %+v", e2Addr2, nicID2, nic2Addrs)
  5409  			}
  5410  
  5411  			// We can't proceed any further if we already failed the test (missing
  5412  			// some discovery/auto-generated address events or addresses).
  5413  			if t.Failed() {
  5414  				t.FailNow()
  5415  			}
  5416  
  5417  			test.cleanupFn(t, s)
  5418  
  5419  			// Collect invalidation events after having NDP state cleaned up.
  5420  			gotOffLinkRouteEvents := make(map[ndpOffLinkRouteEvent]int)
  5421  			for i := 0; i < maxRouterAndPrefixEvents; i++ {
  5422  				ok, e := expectOffLinkRouteEvent()
  5423  				if !ok {
  5424  					t.Errorf("expected %d off-link route events after becoming a router; got = %d", maxRouterAndPrefixEvents, i)
  5425  					break
  5426  				}
  5427  				gotOffLinkRouteEvents[e]++
  5428  			}
  5429  			gotPrefixEvents := make(map[ndpPrefixEvent]int)
  5430  			for i := 0; i < maxRouterAndPrefixEvents; i++ {
  5431  				ok, e := expectPrefixEvent()
  5432  				if !ok {
  5433  					t.Errorf("expected %d prefix events after becoming a router; got = %d", maxRouterAndPrefixEvents, i)
  5434  					break
  5435  				}
  5436  				gotPrefixEvents[e]++
  5437  			}
  5438  			gotAutoGenAddrEvents := make(map[ndpAutoGenAddrEvent]int)
  5439  			for i := 0; i < test.maxAutoGenAddrEvents; i++ {
  5440  				ok, e := expectAutoGenAddrEvent()
  5441  				if !ok {
  5442  					t.Errorf("expected %d auto-generated address events after becoming a router; got = %d", test.maxAutoGenAddrEvents, i)
  5443  					break
  5444  				}
  5445  				gotAutoGenAddrEvents[e]++
  5446  			}
  5447  
  5448  			// No need to proceed any further if we already failed the test (missing
  5449  			// some invalidation events).
  5450  			if t.Failed() {
  5451  				t.FailNow()
  5452  			}
  5453  
  5454  			expectedOffLinkRouteEvents := map[ndpOffLinkRouteEvent]int{
  5455  				{nicID: nicID1, subnet: header.IPv6EmptySubnet, router: llAddr3, updated: false}: 1,
  5456  				{nicID: nicID1, subnet: header.IPv6EmptySubnet, router: llAddr4, updated: false}: 1,
  5457  				{nicID: nicID2, subnet: header.IPv6EmptySubnet, router: llAddr3, updated: false}: 1,
  5458  				{nicID: nicID2, subnet: header.IPv6EmptySubnet, router: llAddr4, updated: false}: 1,
  5459  			}
  5460  			if diff := cmp.Diff(expectedOffLinkRouteEvents, gotOffLinkRouteEvents); diff != "" {
  5461  				t.Errorf("off-link route events mismatch (-want +got):\n%s", diff)
  5462  			}
  5463  			expectedPrefixEvents := map[ndpPrefixEvent]int{
  5464  				{nicID: nicID1, prefix: subnet1, discovered: false}: 1,
  5465  				{nicID: nicID1, prefix: subnet2, discovered: false}: 1,
  5466  				{nicID: nicID2, prefix: subnet1, discovered: false}: 1,
  5467  				{nicID: nicID2, prefix: subnet2, discovered: false}: 1,
  5468  			}
  5469  			if diff := cmp.Diff(expectedPrefixEvents, gotPrefixEvents); diff != "" {
  5470  				t.Errorf("prefix events mismatch (-want +got):\n%s", diff)
  5471  			}
  5472  			expectedAutoGenAddrEvents := map[ndpAutoGenAddrEvent]int{
  5473  				{nicID: nicID1, addr: e1Addr1, eventType: invalidatedAddr}: 1,
  5474  				{nicID: nicID1, addr: e1Addr2, eventType: invalidatedAddr}: 1,
  5475  				{nicID: nicID2, addr: e2Addr1, eventType: invalidatedAddr}: 1,
  5476  				{nicID: nicID2, addr: e2Addr2, eventType: invalidatedAddr}: 1,
  5477  			}
  5478  
  5479  			if !test.keepAutoGenLinkLocal {
  5480  				expectedAutoGenAddrEvents[ndpAutoGenAddrEvent{nicID: nicID1, addr: llAddrWithPrefix1, eventType: invalidatedAddr}] = 1
  5481  				expectedAutoGenAddrEvents[ndpAutoGenAddrEvent{nicID: nicID2, addr: llAddrWithPrefix2, eventType: invalidatedAddr}] = 1
  5482  			}
  5483  
  5484  			if diff := cmp.Diff(expectedAutoGenAddrEvents, gotAutoGenAddrEvents); diff != "" {
  5485  				t.Errorf("auto-generated address events mismatch (-want +got):\n%s", diff)
  5486  			}
  5487  
  5488  			if !test.skipFinalAddrCheck {
  5489  				// Make sure the auto-generated addresses got removed.
  5490  				nicinfo = s.NICInfo()
  5491  				nic1Addrs = nicinfo[nicID1].ProtocolAddresses
  5492  				nic2Addrs = nicinfo[nicID2].ProtocolAddresses
  5493  				if containsV6Addr(nic1Addrs, llAddrWithPrefix1) != test.keepAutoGenLinkLocal {
  5494  					if test.keepAutoGenLinkLocal {
  5495  						t.Errorf("missing %s from the list of addresses for NIC(%d): %+v", llAddrWithPrefix1, nicID1, nic1Addrs)
  5496  					} else {
  5497  						t.Errorf("still have %s in the list of addresses for NIC(%d): %+v", llAddrWithPrefix1, nicID1, nic1Addrs)
  5498  					}
  5499  				}
  5500  				if containsV6Addr(nic1Addrs, e1Addr1) {
  5501  					t.Errorf("still have %s in the list of addresses for NIC(%d): %+v", e1Addr1, nicID1, nic1Addrs)
  5502  				}
  5503  				if containsV6Addr(nic1Addrs, e1Addr2) {
  5504  					t.Errorf("still have %s in the list of addresses for NIC(%d): %+v", e1Addr2, nicID1, nic1Addrs)
  5505  				}
  5506  				if containsV6Addr(nic2Addrs, llAddrWithPrefix2) != test.keepAutoGenLinkLocal {
  5507  					if test.keepAutoGenLinkLocal {
  5508  						t.Errorf("missing %s from the list of addresses for NIC(%d): %+v", llAddrWithPrefix2, nicID2, nic2Addrs)
  5509  					} else {
  5510  						t.Errorf("still have %s in the list of addresses for NIC(%d): %+v", llAddrWithPrefix2, nicID2, nic2Addrs)
  5511  					}
  5512  				}
  5513  				if containsV6Addr(nic2Addrs, e2Addr1) {
  5514  					t.Errorf("still have %s in the list of addresses for NIC(%d): %+v", e2Addr1, nicID2, nic2Addrs)
  5515  				}
  5516  				if containsV6Addr(nic2Addrs, e2Addr2) {
  5517  					t.Errorf("still have %s in the list of addresses for NIC(%d): %+v", e2Addr2, nicID2, nic2Addrs)
  5518  				}
  5519  			}
  5520  
  5521  			// Should not get any more events (invalidation timers should have been
  5522  			// cancelled when the NDP state was cleaned up).
  5523  			clock.Advance(lifetimeSeconds * time.Second)
  5524  			select {
  5525  			case <-ndpDisp.offLinkRouteC:
  5526  				t.Error("unexpected off-link route event")
  5527  			default:
  5528  			}
  5529  			select {
  5530  			case <-ndpDisp.prefixC:
  5531  				t.Error("unexpected prefix event")
  5532  			default:
  5533  			}
  5534  			select {
  5535  			case <-ndpDisp.autoGenAddrC:
  5536  				t.Error("unexpected auto-generated address event")
  5537  			default:
  5538  			}
  5539  			select {
  5540  			case <-ndpDisp.autoGenAddrNewC:
  5541  				t.Error("unexpected auto-generated address event")
  5542  			default:
  5543  			}
  5544  		})
  5545  	}
  5546  }
  5547  
  5548  // TestDHCPv6ConfigurationFromNDPDA tests that the NDPDispatcher is properly
  5549  // informed when new information about what configurations are available via
  5550  // DHCPv6 is learned.
  5551  func TestDHCPv6ConfigurationFromNDPDA(t *testing.T) {
  5552  	const nicID = 1
  5553  
  5554  	ndpDisp := ndpDispatcher{
  5555  		dhcpv6ConfigurationC: make(chan ndpDHCPv6Event, 1),
  5556  	}
  5557  	e := channel.New(0, 1280, linkAddr1)
  5558  	s := stack.New(stack.Options{
  5559  		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
  5560  			NDPConfigs: ipv6.NDPConfigurations{
  5561  				HandleRAs: ipv6.HandlingRAsEnabledWhenForwardingDisabled,
  5562  			},
  5563  			NDPDisp: &ndpDisp,
  5564  		})},
  5565  	})
  5566  
  5567  	if err := s.CreateNIC(nicID, e); err != nil {
  5568  		t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
  5569  	}
  5570  
  5571  	expectDHCPv6Event := func(configuration ipv6.DHCPv6ConfigurationFromNDPRA) {
  5572  		t.Helper()
  5573  		select {
  5574  		case e := <-ndpDisp.dhcpv6ConfigurationC:
  5575  			if diff := cmp.Diff(ndpDHCPv6Event{nicID: nicID, configuration: configuration}, e, cmp.AllowUnexported(e)); diff != "" {
  5576  				t.Errorf("dhcpv6 event mismatch (-want +got):\n%s", diff)
  5577  			}
  5578  		default:
  5579  			t.Fatal("expected DHCPv6 configuration event")
  5580  		}
  5581  	}
  5582  
  5583  	expectNoDHCPv6Event := func() {
  5584  		t.Helper()
  5585  		select {
  5586  		case <-ndpDisp.dhcpv6ConfigurationC:
  5587  			t.Fatal("unexpected DHCPv6 configuration event")
  5588  		default:
  5589  		}
  5590  	}
  5591  
  5592  	// Even if the first RA reports no DHCPv6 configurations are available, the
  5593  	// dispatcher should get an event.
  5594  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, false, false))
  5595  	expectDHCPv6Event(ipv6.DHCPv6NoConfiguration)
  5596  	// Receiving the same update again should not result in an event to the
  5597  	// dispatcher.
  5598  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, false, false))
  5599  	expectNoDHCPv6Event()
  5600  
  5601  	// Receive an RA that updates the DHCPv6 configuration to Other
  5602  	// Configurations.
  5603  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, false, true))
  5604  	expectDHCPv6Event(ipv6.DHCPv6OtherConfigurations)
  5605  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, false, true))
  5606  	expectNoDHCPv6Event()
  5607  
  5608  	// Receive an RA that updates the DHCPv6 configuration to Managed Address.
  5609  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, true, false))
  5610  	expectDHCPv6Event(ipv6.DHCPv6ManagedAddress)
  5611  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, true, false))
  5612  	expectNoDHCPv6Event()
  5613  
  5614  	// Receive an RA that updates the DHCPv6 configuration to none.
  5615  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, false, false))
  5616  	expectDHCPv6Event(ipv6.DHCPv6NoConfiguration)
  5617  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, false, false))
  5618  	expectNoDHCPv6Event()
  5619  
  5620  	// Receive an RA that updates the DHCPv6 configuration to Managed Address.
  5621  	//
  5622  	// Note, when the M flag is set, the O flag is redundant.
  5623  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, true, true))
  5624  	expectDHCPv6Event(ipv6.DHCPv6ManagedAddress)
  5625  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, true, true))
  5626  	expectNoDHCPv6Event()
  5627  	// Even though the DHCPv6 flags are different, the effective configuration is
  5628  	// the same so we should not receive a new event.
  5629  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, true, false))
  5630  	expectNoDHCPv6Event()
  5631  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, true, true))
  5632  	expectNoDHCPv6Event()
  5633  
  5634  	// Receive an RA that updates the DHCPv6 configuration to Other
  5635  	// Configurations.
  5636  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, false, true))
  5637  	expectDHCPv6Event(ipv6.DHCPv6OtherConfigurations)
  5638  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, false, true))
  5639  	expectNoDHCPv6Event()
  5640  
  5641  	// Cycling the NIC should cause the last DHCPv6 configuration to be cleared.
  5642  	if err := s.DisableNIC(nicID); err != nil {
  5643  		t.Fatalf("s.DisableNIC(%d): %s", nicID, err)
  5644  	}
  5645  	if err := s.EnableNIC(nicID); err != nil {
  5646  		t.Fatalf("s.EnableNIC(%d): %s", nicID, err)
  5647  	}
  5648  
  5649  	// Receive an RA that updates the DHCPv6 configuration to Other
  5650  	// Configurations.
  5651  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, false, true))
  5652  	expectDHCPv6Event(ipv6.DHCPv6OtherConfigurations)
  5653  	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, false, true))
  5654  	expectNoDHCPv6Event()
  5655  }
  5656  
  5657  var _ rand.Source = (*savingRandSource)(nil)
  5658  
  5659  type savingRandSource struct {
  5660  	s rand.Source
  5661  
  5662  	lastInt63 int64
  5663  }
  5664  
  5665  func (d *savingRandSource) Int63() int64 {
  5666  	i := d.s.Int63()
  5667  	d.lastInt63 = i
  5668  	return i
  5669  }
  5670  func (d *savingRandSource) Seed(seed int64) {
  5671  	d.s.Seed(seed)
  5672  }
  5673  
  5674  // TestRouterSolicitation tests the initial Router Solicitations that are sent
  5675  // when a NIC newly becomes enabled.
  5676  func TestRouterSolicitation(t *testing.T) {
  5677  	const nicID = 1
  5678  
  5679  	tests := []struct {
  5680  		name                        string
  5681  		linkHeaderLen               uint16
  5682  		linkAddr                    tcpip.LinkAddress
  5683  		nicAddr                     tcpip.Address
  5684  		expectedSrcAddr             tcpip.Address
  5685  		expectedNDPOpts             []header.NDPOption
  5686  		maxRtrSolicit               uint8
  5687  		rtrSolicitInt               time.Duration
  5688  		effectiveRtrSolicitInt      time.Duration
  5689  		maxRtrSolicitDelay          time.Duration
  5690  		effectiveMaxRtrSolicitDelay time.Duration
  5691  	}{
  5692  		{
  5693  			name:                        "Single RS with 2s delay and interval",
  5694  			expectedSrcAddr:             header.IPv6Any,
  5695  			maxRtrSolicit:               1,
  5696  			rtrSolicitInt:               2 * time.Second,
  5697  			effectiveRtrSolicitInt:      2 * time.Second,
  5698  			maxRtrSolicitDelay:          2 * time.Second,
  5699  			effectiveMaxRtrSolicitDelay: 2 * time.Second,
  5700  		},
  5701  		{
  5702  			name:                        "Single RS with 4s delay and interval",
  5703  			expectedSrcAddr:             header.IPv6Any,
  5704  			maxRtrSolicit:               1,
  5705  			rtrSolicitInt:               4 * time.Second,
  5706  			effectiveRtrSolicitInt:      4 * time.Second,
  5707  			maxRtrSolicitDelay:          4 * time.Second,
  5708  			effectiveMaxRtrSolicitDelay: 4 * time.Second,
  5709  		},
  5710  		{
  5711  			name:                        "Two RS with delay",
  5712  			linkHeaderLen:               1,
  5713  			nicAddr:                     llAddr1,
  5714  			expectedSrcAddr:             llAddr1,
  5715  			maxRtrSolicit:               2,
  5716  			rtrSolicitInt:               2 * time.Second,
  5717  			effectiveRtrSolicitInt:      2 * time.Second,
  5718  			maxRtrSolicitDelay:          500 * time.Millisecond,
  5719  			effectiveMaxRtrSolicitDelay: 500 * time.Millisecond,
  5720  		},
  5721  		{
  5722  			name:            "Single RS without delay",
  5723  			linkHeaderLen:   2,
  5724  			linkAddr:        linkAddr1,
  5725  			nicAddr:         llAddr1,
  5726  			expectedSrcAddr: llAddr1,
  5727  			expectedNDPOpts: []header.NDPOption{
  5728  				header.NDPSourceLinkLayerAddressOption(linkAddr1),
  5729  			},
  5730  			maxRtrSolicit:               1,
  5731  			rtrSolicitInt:               2 * time.Second,
  5732  			effectiveRtrSolicitInt:      2 * time.Second,
  5733  			maxRtrSolicitDelay:          0,
  5734  			effectiveMaxRtrSolicitDelay: 0,
  5735  		},
  5736  		{
  5737  			name:                        "Two RS without delay and invalid zero interval",
  5738  			linkHeaderLen:               3,
  5739  			linkAddr:                    linkAddr1,
  5740  			expectedSrcAddr:             header.IPv6Any,
  5741  			maxRtrSolicit:               2,
  5742  			rtrSolicitInt:               0,
  5743  			effectiveRtrSolicitInt:      4 * time.Second,
  5744  			maxRtrSolicitDelay:          0,
  5745  			effectiveMaxRtrSolicitDelay: 0,
  5746  		},
  5747  		{
  5748  			name:                        "Three RS without delay",
  5749  			linkAddr:                    linkAddr1,
  5750  			expectedSrcAddr:             header.IPv6Any,
  5751  			maxRtrSolicit:               3,
  5752  			rtrSolicitInt:               500 * time.Millisecond,
  5753  			effectiveRtrSolicitInt:      500 * time.Millisecond,
  5754  			maxRtrSolicitDelay:          0,
  5755  			effectiveMaxRtrSolicitDelay: 0,
  5756  		},
  5757  		{
  5758  			name:                        "Two RS with invalid negative delay",
  5759  			linkAddr:                    linkAddr1,
  5760  			expectedSrcAddr:             header.IPv6Any,
  5761  			maxRtrSolicit:               2,
  5762  			rtrSolicitInt:               time.Second,
  5763  			effectiveRtrSolicitInt:      time.Second,
  5764  			maxRtrSolicitDelay:          -3 * time.Second,
  5765  			effectiveMaxRtrSolicitDelay: time.Second,
  5766  		},
  5767  	}
  5768  
  5769  	subTests := []struct {
  5770  		name         string
  5771  		handleRAs    ipv6.HandleRAsConfiguration
  5772  		afterFirstRS func(*testing.T, *stack.Stack)
  5773  	}{
  5774  		{
  5775  			name:         "Handle RAs when forwarding disabled",
  5776  			handleRAs:    ipv6.HandlingRAsEnabledWhenForwardingDisabled,
  5777  			afterFirstRS: func(*testing.T, *stack.Stack) {},
  5778  		},
  5779  
  5780  		// Enabling forwarding when RAs are always configured to be handled
  5781  		// should not stop router solicitations.
  5782  		{
  5783  			name:      "Handle RAs always",
  5784  			handleRAs: ipv6.HandlingRAsAlwaysEnabled,
  5785  			afterFirstRS: func(t *testing.T, s *stack.Stack) {
  5786  				if err := s.SetForwardingDefaultAndAllNICs(ipv6.ProtocolNumber, true); err != nil {
  5787  					t.Fatalf("SetForwardingDefaultAndAllNICs(%d, true): %s", ipv6.ProtocolNumber, err)
  5788  				}
  5789  			},
  5790  		},
  5791  	}
  5792  
  5793  	for _, test := range tests {
  5794  		t.Run(test.name, func(t *testing.T) {
  5795  			for _, subTest := range subTests {
  5796  				t.Run(subTest.name, func(t *testing.T) {
  5797  					clock := faketime.NewManualClock()
  5798  					e := channelLinkWithHeaderLength{
  5799  						Endpoint:     channel.New(int(test.maxRtrSolicit), 1280, test.linkAddr),
  5800  						headerLength: test.linkHeaderLen,
  5801  					}
  5802  					e.Endpoint.LinkEPCapabilities |= stack.CapabilityResolutionRequired
  5803  					waitForPkt := func(timeout time.Duration) {
  5804  						t.Helper()
  5805  
  5806  						clock.Advance(timeout)
  5807  						p := e.Read()
  5808  						if p == nil {
  5809  							t.Fatal("expected router solicitation packet")
  5810  						}
  5811  						defer p.DecRef()
  5812  
  5813  						if p.NetworkProtocolNumber != header.IPv6ProtocolNumber {
  5814  							t.Fatalf("got Proto = %d, want = %d", p.NetworkProtocolNumber, header.IPv6ProtocolNumber)
  5815  						}
  5816  
  5817  						// Make sure the right remote link address is used.
  5818  						if want := header.EthernetAddressFromMulticastIPv6Address(header.IPv6AllRoutersLinkLocalMulticastAddress); p.EgressRoute.RemoteLinkAddress != want {
  5819  							t.Errorf("got remote link address = %s, want = %s", p.EgressRoute.RemoteLinkAddress, want)
  5820  						}
  5821  
  5822  						checker.IPv6(t, stack.PayloadSince(p.NetworkHeader()),
  5823  							checker.SrcAddr(test.expectedSrcAddr),
  5824  							checker.DstAddr(header.IPv6AllRoutersLinkLocalMulticastAddress),
  5825  							checker.TTL(header.NDPHopLimit),
  5826  							checker.NDPRS(checker.NDPRSOptions(test.expectedNDPOpts)),
  5827  						)
  5828  
  5829  						if l, want := p.AvailableHeaderBytes(), int(test.linkHeaderLen); l != want {
  5830  							t.Errorf("got p.AvailableHeaderBytes() = %d; want = %d", l, want)
  5831  						}
  5832  					}
  5833  					waitForNothing := func(timeout time.Duration) {
  5834  						t.Helper()
  5835  
  5836  						clock.Advance(timeout)
  5837  						if p := e.Read(); p != nil {
  5838  							t.Fatalf("unexpectedly got a packet = %#v", p)
  5839  						}
  5840  					}
  5841  					randSource := savingRandSource{
  5842  						s: rand.NewSource(time.Now().UnixNano()),
  5843  					}
  5844  					s := stack.New(stack.Options{
  5845  						NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
  5846  							NDPConfigs: ipv6.NDPConfigurations{
  5847  								HandleRAs:               subTest.handleRAs,
  5848  								MaxRtrSolicitations:     test.maxRtrSolicit,
  5849  								RtrSolicitationInterval: test.rtrSolicitInt,
  5850  								MaxRtrSolicitationDelay: test.maxRtrSolicitDelay,
  5851  							},
  5852  						})},
  5853  						Clock:      clock,
  5854  						RandSource: &randSource,
  5855  					})
  5856  
  5857  					opts := stack.NICOptions{Disabled: true}
  5858  					if err := s.CreateNICWithOptions(nicID, &e, opts); err != nil {
  5859  						t.Fatalf("CreateNICWithOptions(%d, _, %#v) = %s", nicID, opts, err)
  5860  					}
  5861  
  5862  					if addr := test.nicAddr; addr != (tcpip.Address{}) {
  5863  						protocolAddr := tcpip.ProtocolAddress{
  5864  							Protocol:          header.IPv6ProtocolNumber,
  5865  							AddressWithPrefix: addr.WithPrefix(),
  5866  						}
  5867  						if err := s.AddProtocolAddress(nicID, protocolAddr, stack.AddressProperties{}); err != nil {
  5868  							t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", nicID, protocolAddr, err)
  5869  						}
  5870  					}
  5871  
  5872  					if err := s.EnableNIC(nicID); err != nil {
  5873  						t.Fatalf("EnableNIC(%d): %s", nicID, err)
  5874  					}
  5875  
  5876  					// Make sure each RS is sent at the right time.
  5877  					remaining := test.maxRtrSolicit
  5878  					if remaining != 0 {
  5879  						maxRtrSolicitDelay := test.maxRtrSolicitDelay
  5880  						if maxRtrSolicitDelay < 0 {
  5881  							maxRtrSolicitDelay = ipv6.DefaultNDPConfigurations().MaxRtrSolicitationDelay
  5882  						}
  5883  						var actualRtrSolicitDelay time.Duration
  5884  						if maxRtrSolicitDelay != 0 {
  5885  							actualRtrSolicitDelay = time.Duration(randSource.lastInt63) % maxRtrSolicitDelay
  5886  						}
  5887  						waitForPkt(actualRtrSolicitDelay)
  5888  						remaining--
  5889  					}
  5890  
  5891  					subTest.afterFirstRS(t, s)
  5892  
  5893  					for ; remaining != 0; remaining-- {
  5894  						if test.effectiveRtrSolicitInt != 0 {
  5895  							waitForNothing(test.effectiveRtrSolicitInt - time.Nanosecond)
  5896  							waitForPkt(time.Nanosecond)
  5897  						} else {
  5898  							waitForPkt(0)
  5899  						}
  5900  					}
  5901  
  5902  					// Make sure no more RS.
  5903  					if test.effectiveRtrSolicitInt > test.effectiveMaxRtrSolicitDelay {
  5904  						waitForNothing(test.effectiveRtrSolicitInt)
  5905  					} else {
  5906  						waitForNothing(test.effectiveMaxRtrSolicitDelay)
  5907  					}
  5908  
  5909  					if got, want := s.Stats().ICMP.V6.PacketsSent.RouterSolicit.Value(), uint64(test.maxRtrSolicit); got != want {
  5910  						t.Fatalf("got sent RouterSolicit = %d, want = %d", got, want)
  5911  					}
  5912  				})
  5913  			}
  5914  		})
  5915  	}
  5916  }
  5917  
  5918  func TestStopStartSolicitingRouters(t *testing.T) {
  5919  	const nicID = 1
  5920  	const delay = 0
  5921  	const interval = 500 * time.Millisecond
  5922  	const maxRtrSolicitations = 3
  5923  
  5924  	tests := []struct {
  5925  		name    string
  5926  		startFn func(t *testing.T, s *stack.Stack)
  5927  		// first is used to tell stopFn that it is being called for the first time
  5928  		// after router solicitations were last enabled.
  5929  		stopFn func(t *testing.T, s *stack.Stack, first bool)
  5930  	}{
  5931  		// Tests that when forwarding is enabled or disabled, router solicitations
  5932  		// are stopped or started, respectively.
  5933  		{
  5934  			name: "Enable and disable forwarding",
  5935  			startFn: func(t *testing.T, s *stack.Stack) {
  5936  				t.Helper()
  5937  
  5938  				if err := s.SetForwardingDefaultAndAllNICs(ipv6.ProtocolNumber, false); err != nil {
  5939  					t.Fatalf("SetForwardingDefaultAndAllNICs(%d, false): %s", ipv6.ProtocolNumber, err)
  5940  				}
  5941  			},
  5942  			stopFn: func(t *testing.T, s *stack.Stack, _ bool) {
  5943  				t.Helper()
  5944  
  5945  				if err := s.SetForwardingDefaultAndAllNICs(ipv6.ProtocolNumber, true); err != nil {
  5946  					t.Fatalf("SetForwardingDefaultAndAllNICs(%d, true): %s", ipv6.ProtocolNumber, err)
  5947  				}
  5948  			},
  5949  		},
  5950  
  5951  		// Tests that when a NIC is enabled or disabled, router solicitations
  5952  		// are started or stopped, respectively.
  5953  		{
  5954  			name: "Enable and disable NIC",
  5955  			startFn: func(t *testing.T, s *stack.Stack) {
  5956  				t.Helper()
  5957  
  5958  				if err := s.EnableNIC(nicID); err != nil {
  5959  					t.Fatalf("s.EnableNIC(%d): %s", nicID, err)
  5960  				}
  5961  			},
  5962  			stopFn: func(t *testing.T, s *stack.Stack, _ bool) {
  5963  				t.Helper()
  5964  
  5965  				if err := s.DisableNIC(nicID); err != nil {
  5966  					t.Fatalf("s.DisableNIC(%d): %s", nicID, err)
  5967  				}
  5968  			},
  5969  		},
  5970  
  5971  		// Tests that when a NIC is removed, router solicitations are stopped. We
  5972  		// cannot start router solicitations on a removed NIC.
  5973  		{
  5974  			name: "Remove NIC",
  5975  			stopFn: func(t *testing.T, s *stack.Stack, first bool) {
  5976  				t.Helper()
  5977  
  5978  				// Only try to remove the NIC the first time stopFn is called since it's
  5979  				// impossible to remove an already removed NIC.
  5980  				if !first {
  5981  					return
  5982  				}
  5983  
  5984  				if err := s.RemoveNIC(nicID); err != nil {
  5985  					t.Fatalf("s.RemoveNIC(%d): %s", nicID, err)
  5986  				}
  5987  			},
  5988  		},
  5989  	}
  5990  
  5991  	for _, test := range tests {
  5992  		t.Run(test.name, func(t *testing.T) {
  5993  			e := channel.New(maxRtrSolicitations, 1280, linkAddr1)
  5994  			waitForPkt := func(clock *faketime.ManualClock, timeout time.Duration) {
  5995  				t.Helper()
  5996  
  5997  				clock.Advance(timeout)
  5998  				p := e.Read()
  5999  				if p == nil {
  6000  					t.Fatal("timed out waiting for packet")
  6001  				}
  6002  
  6003  				if p.NetworkProtocolNumber != header.IPv6ProtocolNumber {
  6004  					t.Fatalf("got Proto = %d, want = %d", p.NetworkProtocolNumber, header.IPv6ProtocolNumber)
  6005  				}
  6006  				checker.IPv6(t, stack.PayloadSince(p.NetworkHeader()),
  6007  					checker.SrcAddr(header.IPv6Any),
  6008  					checker.DstAddr(header.IPv6AllRoutersLinkLocalMulticastAddress),
  6009  					checker.TTL(header.NDPHopLimit),
  6010  					checker.NDPRS())
  6011  				p.DecRef()
  6012  			}
  6013  			clock := faketime.NewManualClock()
  6014  			s := stack.New(stack.Options{
  6015  				NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
  6016  					NDPConfigs: ipv6.NDPConfigurations{
  6017  						HandleRAs:               ipv6.HandlingRAsEnabledWhenForwardingDisabled,
  6018  						MaxRtrSolicitations:     maxRtrSolicitations,
  6019  						RtrSolicitationInterval: interval,
  6020  						MaxRtrSolicitationDelay: delay,
  6021  					},
  6022  				})},
  6023  				Clock: clock,
  6024  			})
  6025  			if err := s.CreateNIC(nicID, e); err != nil {
  6026  				t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
  6027  			}
  6028  
  6029  			// Stop soliciting routers.
  6030  			test.stopFn(t, s, true /* first */)
  6031  			clock.Advance(delay)
  6032  			if p := e.Read(); p != nil {
  6033  				p.DecRef()
  6034  				// A single RS may have been sent before solicitations were stopped.
  6035  				clock.Advance(interval)
  6036  				if pb := e.Read(); pb != nil {
  6037  					t.Fatal("should not have sent more than one RS message")
  6038  				}
  6039  			}
  6040  
  6041  			// Stopping router solicitations after it has already been stopped should
  6042  			// do nothing.
  6043  			test.stopFn(t, s, false /* first */)
  6044  			clock.Advance(delay)
  6045  			if pb := e.Read(); pb != nil {
  6046  				t.Fatal("unexpectedly got a packet after router solicitation has been stopepd")
  6047  			}
  6048  
  6049  			// If test.startFn is nil, there is no way to restart router solicitations.
  6050  			if test.startFn == nil {
  6051  				return
  6052  			}
  6053  
  6054  			// Start soliciting routers.
  6055  			test.startFn(t, s)
  6056  			waitForPkt(clock, delay)
  6057  			waitForPkt(clock, interval)
  6058  			waitForPkt(clock, interval)
  6059  			clock.Advance(interval)
  6060  			if pb := e.Read(); pb != nil {
  6061  				t.Fatal("unexpectedly got an extra packet after sending out the expected RSs")
  6062  			}
  6063  
  6064  			// Starting router solicitations after it has already completed should do
  6065  			// nothing.
  6066  			test.startFn(t, s)
  6067  			clock.Advance(interval)
  6068  			if pb := e.Read(); pb != nil {
  6069  				t.Fatal("unexpectedly got a packet after finishing router solicitations")
  6070  			}
  6071  		})
  6072  	}
  6073  }