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

     1  // Copyright 2018 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 contains tests for the stack. It is in its own package so
    16  // that the tests can also validate that all definitions needed to implement
    17  // transport and network protocols are properly exported by the stack package.
    18  package stack_test
    19  
    20  import (
    21  	"bytes"
    22  	"fmt"
    23  	"math"
    24  	"net"
    25  	"sort"
    26  	"testing"
    27  	"time"
    28  
    29  	"github.com/google/go-cmp/cmp"
    30  	"github.com/google/go-cmp/cmp/cmpopts"
    31  	"gvisor.dev/gvisor/pkg/buffer"
    32  	"gvisor.dev/gvisor/pkg/rand"
    33  	"gvisor.dev/gvisor/pkg/sync"
    34  	"gvisor.dev/gvisor/pkg/tcpip"
    35  	"gvisor.dev/gvisor/pkg/tcpip/faketime"
    36  	"gvisor.dev/gvisor/pkg/tcpip/header"
    37  	"gvisor.dev/gvisor/pkg/tcpip/link/channel"
    38  	"gvisor.dev/gvisor/pkg/tcpip/link/loopback"
    39  	"gvisor.dev/gvisor/pkg/tcpip/network/arp"
    40  	"gvisor.dev/gvisor/pkg/tcpip/network/ipv4"
    41  	"gvisor.dev/gvisor/pkg/tcpip/network/ipv6"
    42  	"gvisor.dev/gvisor/pkg/tcpip/stack"
    43  	"gvisor.dev/gvisor/pkg/tcpip/testutil"
    44  	"gvisor.dev/gvisor/pkg/tcpip/transport/udp"
    45  )
    46  
    47  const (
    48  	fakeNetNumber        tcpip.NetworkProtocolNumber = math.MaxUint32
    49  	fakeNetHeaderLen                                 = 12
    50  	fakeDefaultPrefixLen                             = 32
    51  
    52  	// fakeControlProtocol is used for control packets that represent
    53  	// destination port unreachable.
    54  	fakeControlProtocol tcpip.TransportProtocolNumber = 2
    55  
    56  	// defaultMTU is the MTU, in bytes, used throughout the tests, except
    57  	// where another value is explicitly used. It is chosen to match the MTU
    58  	// of loopback interfaces on linux systems.
    59  	defaultMTU = 65536
    60  
    61  	dstAddrOffset        = 0
    62  	srcAddrOffset        = 4
    63  	protocolNumberOffset = 8
    64  )
    65  
    66  func checkGetMainNICAddress(s *stack.Stack, nicID tcpip.NICID, proto tcpip.NetworkProtocolNumber, want tcpip.AddressWithPrefix) error {
    67  	if addr, err := s.GetMainNICAddress(nicID, proto); err != nil {
    68  		return fmt.Errorf("stack.GetMainNICAddress(%d, %d): %s", nicID, proto, err)
    69  	} else if addr != want {
    70  		return fmt.Errorf("got stack.GetMainNICAddress(%d, %d) = %s, want = %s", nicID, proto, addr, want)
    71  	}
    72  	return nil
    73  }
    74  
    75  // fakeNetworkEndpoint is a network-layer protocol endpoint. It counts sent and
    76  // received packets; the counts of all endpoints are aggregated in the protocol
    77  // descriptor.
    78  //
    79  // Headers of this protocol are fakeNetHeaderLen bytes. Addresses are 4 bytes,
    80  // but we only use the first byte.
    81  type fakeNetworkEndpoint struct {
    82  	stack.AddressableEndpointState
    83  
    84  	mu struct {
    85  		sync.RWMutex
    86  
    87  		enabled             bool
    88  		forwarding          bool
    89  		multicastForwarding bool
    90  	}
    91  
    92  	nic        stack.NetworkInterface
    93  	proto      *fakeNetworkProtocol
    94  	dispatcher stack.TransportDispatcher
    95  }
    96  
    97  func (f *fakeNetworkEndpoint) Enable() tcpip.Error {
    98  	f.mu.Lock()
    99  	defer f.mu.Unlock()
   100  	f.mu.enabled = true
   101  	return nil
   102  }
   103  
   104  func (f *fakeNetworkEndpoint) Enabled() bool {
   105  	f.mu.RLock()
   106  	defer f.mu.RUnlock()
   107  	return f.mu.enabled
   108  }
   109  
   110  func (f *fakeNetworkEndpoint) Disable() {
   111  	f.mu.Lock()
   112  	defer f.mu.Unlock()
   113  	f.mu.enabled = false
   114  }
   115  
   116  func (f *fakeNetworkEndpoint) MTU() uint32 {
   117  	return f.nic.MTU() - uint32(f.MaxHeaderLength())
   118  }
   119  
   120  func (*fakeNetworkEndpoint) DefaultTTL() uint8 {
   121  	return 123
   122  }
   123  
   124  func (f *fakeNetworkEndpoint) HandlePacket(pkt *stack.PacketBuffer) {
   125  	if _, _, ok := f.proto.Parse(pkt); !ok {
   126  		return
   127  	}
   128  
   129  	// Increment the received packet count in the protocol descriptor.
   130  	netHdr := pkt.NetworkHeader().Slice()
   131  
   132  	dst := tcpip.AddrFromSlice(netHdr[dstAddrOffset:][:header.IPv4AddressSize])
   133  	addressEndpoint := f.AcquireAssignedAddress(dst, f.nic.Promiscuous(), stack.CanBePrimaryEndpoint, true /* readOnly */)
   134  	if addressEndpoint == nil {
   135  		return
   136  	}
   137  
   138  	f.proto.packetCount[int(dst.AsSlice()[0])%len(f.proto.packetCount)]++
   139  
   140  	// Handle control packets.
   141  	if netHdr[protocolNumberOffset] == uint8(fakeControlProtocol) {
   142  		hdr, ok := pkt.Data().Consume(fakeNetHeaderLen)
   143  		if !ok {
   144  			return
   145  		}
   146  		f.dispatcher.DeliverTransportError(
   147  			tcpip.AddrFrom4Slice(hdr[srcAddrOffset:srcAddrOffset+header.IPv4AddressSize]),
   148  			tcpip.AddrFrom4Slice(hdr[dstAddrOffset:dstAddrOffset+header.IPv4AddressSize]),
   149  			fakeNetNumber,
   150  			tcpip.TransportProtocolNumber(hdr[protocolNumberOffset]),
   151  			// Nothing checks the error.
   152  			nil, /* transport error */
   153  			pkt,
   154  		)
   155  		return
   156  	}
   157  
   158  	transProtoNum := tcpip.TransportProtocolNumber(netHdr[protocolNumberOffset])
   159  	switch err := f.proto.stack.ParsePacketBufferTransport(transProtoNum, pkt); err {
   160  	case stack.ParsedOK:
   161  	case stack.UnknownTransportProtocol, stack.TransportLayerParseError:
   162  		// The transport layer will handle unknown protocols and transport layer
   163  		// parsing errors.
   164  	default:
   165  		panic(fmt.Sprintf("unexpected error parsing transport header = %d", err))
   166  	}
   167  
   168  	// Dispatch the packet to the transport protocol.
   169  	f.dispatcher.DeliverTransportPacket(transProtoNum, pkt)
   170  }
   171  
   172  func (f *fakeNetworkEndpoint) MaxHeaderLength() uint16 {
   173  	return f.nic.MaxHeaderLength() + fakeNetHeaderLen
   174  }
   175  
   176  func (f *fakeNetworkEndpoint) NetworkProtocolNumber() tcpip.NetworkProtocolNumber {
   177  	return f.proto.Number()
   178  }
   179  
   180  func (f *fakeNetworkEndpoint) WritePacket(r *stack.Route, params stack.NetworkHeaderParams, pkt *stack.PacketBuffer) tcpip.Error {
   181  	// Increment the sent packet count in the protocol descriptor.
   182  	remote := r.RemoteAddress()
   183  	f.proto.sendPacketCount[int(remote.AsSlice()[0])%len(f.proto.sendPacketCount)]++
   184  
   185  	// Add the protocol's header to the packet and send it to the link
   186  	// endpoint.
   187  	hdr := pkt.NetworkHeader().Push(fakeNetHeaderLen)
   188  	pkt.NetworkProtocolNumber = fakeNetNumber
   189  	copy(hdr[dstAddrOffset:], remote.AsSlice())
   190  	local := r.LocalAddress()
   191  	copy(hdr[srcAddrOffset:], local.AsSlice())
   192  	hdr[protocolNumberOffset] = byte(params.Protocol)
   193  
   194  	if r.Loop()&stack.PacketLoop != 0 {
   195  		f.HandlePacket(pkt.Clone())
   196  	}
   197  	if r.Loop()&stack.PacketOut == 0 {
   198  		return nil
   199  	}
   200  
   201  	return f.nic.WritePacket(r, pkt)
   202  }
   203  
   204  // WritePackets implements stack.LinkEndpoint.WritePackets.
   205  func (*fakeNetworkEndpoint) WritePackets(*stack.Route, stack.PacketBufferList, stack.NetworkHeaderParams) (int, tcpip.Error) {
   206  	panic("not implemented")
   207  }
   208  
   209  func (*fakeNetworkEndpoint) WriteHeaderIncludedPacket(*stack.Route, *stack.PacketBuffer) tcpip.Error {
   210  	return &tcpip.ErrNotSupported{}
   211  }
   212  
   213  func (f *fakeNetworkEndpoint) Close() {
   214  	f.AddressableEndpointState.Cleanup()
   215  }
   216  
   217  // Stats implements NetworkEndpoint.
   218  func (*fakeNetworkEndpoint) Stats() stack.NetworkEndpointStats {
   219  	return &fakeNetworkEndpointStats{}
   220  }
   221  
   222  var _ stack.NetworkEndpointStats = (*fakeNetworkEndpointStats)(nil)
   223  
   224  type fakeNetworkEndpointStats struct{}
   225  
   226  // IsNetworkEndpointStats implements stack.NetworkEndpointStats.
   227  func (*fakeNetworkEndpointStats) IsNetworkEndpointStats() {}
   228  
   229  type addMulticastRouteData struct {
   230  	addresses stack.UnicastSourceAndMulticastDestination
   231  	route     stack.MulticastRoute
   232  }
   233  
   234  type enableMulticastForwardingForProtocolResult struct {
   235  	AlreadyEnabled bool
   236  	Err            tcpip.Error
   237  }
   238  
   239  // fakeNetworkProtocol is a network-layer protocol descriptor. It aggregates the
   240  // number of packets sent and received via endpoints of this protocol. The index
   241  // where packets are added is given by the packet's destination address MOD 10.
   242  type fakeNetworkProtocol struct {
   243  	stack *stack.Stack
   244  
   245  	packetCount     [10]int
   246  	sendPacketCount [10]int
   247  	defaultTTL      uint8
   248  
   249  	addMulticastRouteData          addMulticastRouteData
   250  	multicastRouteLastUsedTimeData stack.UnicastSourceAndMulticastDestination
   251  	removeMulticastRouteData       stack.UnicastSourceAndMulticastDestination
   252  
   253  	enableMulticastForwardingForProtocolResult  enableMulticastForwardingForProtocolResult
   254  	disableMulticastForwardingForProtocolCalled bool
   255  }
   256  
   257  func (*fakeNetworkProtocol) Number() tcpip.NetworkProtocolNumber {
   258  	return fakeNetNumber
   259  }
   260  
   261  func (*fakeNetworkProtocol) MinimumPacketSize() int {
   262  	return fakeNetHeaderLen
   263  }
   264  
   265  func (f *fakeNetworkProtocol) PacketCount(intfAddr byte) int {
   266  	return f.packetCount[int(intfAddr)%len(f.packetCount)]
   267  }
   268  
   269  func (*fakeNetworkProtocol) ParseAddresses(v []byte) (src, dst tcpip.Address) {
   270  	return tcpip.AddrFrom4Slice(v[srcAddrOffset:][:header.IPv4AddressSize]), tcpip.AddrFrom4Slice(v[dstAddrOffset:][:header.IPv4AddressSize])
   271  }
   272  
   273  func (f *fakeNetworkProtocol) NewEndpoint(nic stack.NetworkInterface, dispatcher stack.TransportDispatcher) stack.NetworkEndpoint {
   274  	e := &fakeNetworkEndpoint{
   275  		nic:        nic,
   276  		proto:      f,
   277  		dispatcher: dispatcher,
   278  	}
   279  	e.AddressableEndpointState.Init(e, stack.AddressableEndpointStateOptions{HiddenWhileDisabled: false})
   280  	return e
   281  }
   282  
   283  func (f *fakeNetworkProtocol) SetOption(option tcpip.SettableNetworkProtocolOption) tcpip.Error {
   284  	switch v := option.(type) {
   285  	case *tcpip.DefaultTTLOption:
   286  		f.defaultTTL = uint8(*v)
   287  		return nil
   288  	default:
   289  		return &tcpip.ErrUnknownProtocolOption{}
   290  	}
   291  }
   292  
   293  func (f *fakeNetworkProtocol) Option(option tcpip.GettableNetworkProtocolOption) tcpip.Error {
   294  	switch v := option.(type) {
   295  	case *tcpip.DefaultTTLOption:
   296  		*v = tcpip.DefaultTTLOption(f.defaultTTL)
   297  		return nil
   298  	default:
   299  		return &tcpip.ErrUnknownProtocolOption{}
   300  	}
   301  }
   302  
   303  // Close implements NetworkProtocol.Close.
   304  func (*fakeNetworkProtocol) Close() {}
   305  
   306  // Wait implements NetworkProtocol.Wait.
   307  func (*fakeNetworkProtocol) Wait() {}
   308  
   309  // Parse implements NetworkProtocol.Parse.
   310  func (*fakeNetworkProtocol) Parse(pkt *stack.PacketBuffer) (tcpip.TransportProtocolNumber, bool, bool) {
   311  	hdr, ok := pkt.NetworkHeader().Consume(fakeNetHeaderLen)
   312  	if !ok {
   313  		return 0, false, false
   314  	}
   315  	pkt.NetworkProtocolNumber = fakeNetNumber
   316  	return tcpip.TransportProtocolNumber(hdr[protocolNumberOffset]), true, true
   317  }
   318  
   319  // AddMulticastRoute implements
   320  // MulticastForwardingNetworkProtocol.AddMulticastRoute.
   321  func (f *fakeNetworkProtocol) AddMulticastRoute(addresses stack.UnicastSourceAndMulticastDestination, route stack.MulticastRoute) tcpip.Error {
   322  	f.addMulticastRouteData = addMulticastRouteData{addresses, route}
   323  	return nil
   324  }
   325  
   326  // RemoveMulticastRoute implements
   327  // MulticastForwardingNetworkProtocol.RemoveMulticastRoute.
   328  func (f *fakeNetworkProtocol) RemoveMulticastRoute(addresses stack.UnicastSourceAndMulticastDestination) tcpip.Error {
   329  	f.removeMulticastRouteData = addresses
   330  	return nil
   331  }
   332  
   333  // MulticastRouteLastUsedTime implements
   334  // MulticastForwardingNetworkProtocol.MulticastRouteLastUsedTime.
   335  func (f *fakeNetworkProtocol) MulticastRouteLastUsedTime(addresses stack.UnicastSourceAndMulticastDestination) (tcpip.MonotonicTime, tcpip.Error) {
   336  	f.multicastRouteLastUsedTimeData = addresses
   337  	return tcpip.MonotonicTime{}, nil
   338  }
   339  
   340  // EnableMulticastForwarding implements
   341  // MulticastForwardingNetworkProtocol.EnableMulticastForwarding.
   342  func (f *fakeNetworkProtocol) EnableMulticastForwarding(stack.MulticastForwardingEventDispatcher) (bool, tcpip.Error) {
   343  	return f.enableMulticastForwardingForProtocolResult.AlreadyEnabled, f.enableMulticastForwardingForProtocolResult.Err
   344  }
   345  
   346  // DisableMulticastForwarding implements
   347  // MulticastForwardingNetworkProtocol.DisableMulticastForwarding.
   348  func (f *fakeNetworkProtocol) DisableMulticastForwarding() {
   349  	f.disableMulticastForwardingForProtocolCalled = true
   350  }
   351  
   352  // Forwarding implements stack.ForwardingNetworkEndpoint.
   353  func (f *fakeNetworkEndpoint) Forwarding() bool {
   354  	f.mu.RLock()
   355  	defer f.mu.RUnlock()
   356  	return f.mu.forwarding
   357  }
   358  
   359  // SetForwarding implements stack.ForwardingNetworkEndpoint.
   360  func (f *fakeNetworkEndpoint) SetForwarding(v bool) bool {
   361  	f.mu.Lock()
   362  	defer f.mu.Unlock()
   363  	prev := f.mu.forwarding
   364  	f.mu.forwarding = v
   365  	return prev
   366  }
   367  
   368  // MulticastForwarding implements stack.MulticastForwardingNetworkEndpoint.
   369  func (f *fakeNetworkEndpoint) MulticastForwarding() bool {
   370  	f.mu.RLock()
   371  	defer f.mu.RUnlock()
   372  	return f.mu.multicastForwarding
   373  }
   374  
   375  // SetMulticastForwarding implements stack.MulticastForwardingNetworkEndpoint.
   376  func (f *fakeNetworkEndpoint) SetMulticastForwarding(v bool) bool {
   377  	f.mu.Lock()
   378  	defer f.mu.Unlock()
   379  	prev := f.mu.multicastForwarding
   380  	f.mu.multicastForwarding = v
   381  	return prev
   382  }
   383  
   384  func fakeNetFactory(s *stack.Stack) stack.NetworkProtocol {
   385  	return &fakeNetworkProtocol{stack: s}
   386  }
   387  
   388  // linkEPWithMockedAttach is a stack.LinkEndpoint that tests can use to verify
   389  // that LinkEndpoint.Attach was called.
   390  type linkEPWithMockedAttach struct {
   391  	stack.LinkEndpoint
   392  	attached bool
   393  }
   394  
   395  // Attach implements stack.LinkEndpoint.Attach.
   396  func (l *linkEPWithMockedAttach) Attach(d stack.NetworkDispatcher) {
   397  	l.LinkEndpoint.Attach(d)
   398  	l.attached = d != nil
   399  }
   400  
   401  func (l *linkEPWithMockedAttach) isAttached() bool {
   402  	return l.attached
   403  }
   404  
   405  var _ stack.MulticastForwardingEventDispatcher = (*fakeMulticastEventDispatcher)(nil)
   406  
   407  type fakeMulticastEventDispatcher struct {
   408  }
   409  
   410  func (m *fakeMulticastEventDispatcher) OnMissingRoute(context stack.MulticastPacketContext) {
   411  }
   412  
   413  func (m *fakeMulticastEventDispatcher) OnUnexpectedInputInterface(context stack.MulticastPacketContext, expectedInputInterface tcpip.NICID) {
   414  }
   415  
   416  // Checks to see if list contains an address.
   417  func containsAddr(list []tcpip.ProtocolAddress, item tcpip.ProtocolAddress) bool {
   418  	for _, i := range list {
   419  		if i == item {
   420  			return true
   421  		}
   422  	}
   423  
   424  	return false
   425  }
   426  
   427  type addressChangedEvent struct {
   428  	lifetimes stack.AddressLifetimes
   429  	state     stack.AddressAssignmentState
   430  }
   431  
   432  // An implementation of AddressDispatcher which forwards data from callbacks
   433  // to channels to be asserted against in tests.
   434  type addressDispatcher struct {
   435  	changedCh chan addressChangedEvent
   436  	removedCh chan stack.AddressRemovalReason
   437  	nicid     tcpip.NICID
   438  	addr      tcpip.AddressWithPrefix
   439  	lifetimes stack.AddressLifetimes
   440  	state     stack.AddressAssignmentState
   441  }
   442  
   443  var _ stack.AddressDispatcher = (*addressDispatcher)(nil)
   444  
   445  // OnChanged implements stack.AddressDispatcher.
   446  func (ad *addressDispatcher) OnChanged(lifetimes stack.AddressLifetimes, state stack.AddressAssignmentState) {
   447  	if ad.changedCh != nil {
   448  		ad.changedCh <- addressChangedEvent{
   449  			lifetimes: lifetimes,
   450  			state:     state,
   451  		}
   452  	}
   453  }
   454  
   455  // OnRemoved implements stack.AddressDispatcher.
   456  func (ad *addressDispatcher) OnRemoved(reason stack.AddressRemovalReason) {
   457  	if ad.removedCh != nil {
   458  		ad.removedCh <- reason
   459  	}
   460  }
   461  
   462  func (ad *addressDispatcher) disable() {
   463  	ad.changedCh = nil
   464  	ad.removedCh = nil
   465  }
   466  
   467  func (ad *addressDispatcher) expectNoEvent() error {
   468  	select {
   469  	case e := <-ad.changedCh:
   470  		return fmt.Errorf("dispatcher for nic=%d addr=%s unexpectedly received changed event: %#v", ad.nicid, ad.addr, e)
   471  	case e := <-ad.removedCh:
   472  		return fmt.Errorf("dispatcher for nic=%d addr=%s unexpectedly received removed event: %#v", ad.nicid, ad.addr, e)
   473  	default:
   474  		return nil
   475  	}
   476  }
   477  
   478  func (ad *addressDispatcher) expectChanged(lifetimes stack.AddressLifetimes, state stack.AddressAssignmentState) error {
   479  	select {
   480  	case e := <-ad.changedCh:
   481  		ad.lifetimes = e.lifetimes
   482  		ad.state = e.state
   483  		if diff := cmp.Diff(e, addressChangedEvent{
   484  			lifetimes: lifetimes,
   485  			state:     state,
   486  		}, cmp.AllowUnexported(e, tcpip.MonotonicTime{})); diff != "" {
   487  			return fmt.Errorf("dispatcher for nic=%d addr=%s address changed event mismatch (-got +want):\n%s", ad.nicid, ad.addr, diff)
   488  		}
   489  	default:
   490  		return fmt.Errorf("dispatcher for nic=%d addr=%s address changed event not immediately ready", ad.nicid, ad.addr)
   491  	}
   492  	return nil
   493  }
   494  
   495  func (ad *addressDispatcher) expectDeprecated() error {
   496  	return ad.expectChanged(stack.AddressLifetimes{
   497  		Deprecated: true,
   498  		ValidUntil: ad.lifetimes.ValidUntil,
   499  	}, ad.state)
   500  }
   501  
   502  func (ad *addressDispatcher) expectValidUntilChanged(validUntil tcpip.MonotonicTime) error {
   503  	return ad.expectChanged(stack.AddressLifetimes{
   504  		Deprecated:     ad.lifetimes.Deprecated,
   505  		PreferredUntil: ad.lifetimes.PreferredUntil,
   506  		ValidUntil:     validUntil,
   507  	}, ad.state)
   508  }
   509  
   510  func (ad *addressDispatcher) expectLifetimesChanged(lifetimes stack.AddressLifetimes) error {
   511  	return ad.expectChanged(lifetimes, ad.state)
   512  }
   513  
   514  func (ad *addressDispatcher) expectStateChanged(state stack.AddressAssignmentState) error {
   515  	return ad.expectChanged(ad.lifetimes, state)
   516  }
   517  
   518  func (ad *addressDispatcher) expectRemoved(want stack.AddressRemovalReason) error {
   519  	select {
   520  	case got := <-ad.removedCh:
   521  		if want != got {
   522  			return fmt.Errorf("dispatcher for nic=%d addr=%s got removal reason = %s, want = %s", ad.nicid, ad.addr, got, want)
   523  		}
   524  	default:
   525  		return fmt.Errorf("dispatcher for nic=%d addr=%s address removed event not immediately ready", ad.nicid, ad.addr)
   526  	}
   527  	return nil
   528  }
   529  
   530  func infiniteLifetimes() stack.AddressLifetimes {
   531  	return stack.AddressLifetimes{
   532  		Deprecated:     false,
   533  		ValidUntil:     tcpip.MonotonicTimeInfinite(),
   534  		PreferredUntil: tcpip.MonotonicTimeInfinite(),
   535  	}
   536  }
   537  
   538  func TestNetworkReceive(t *testing.T) {
   539  	// Create a stack with the fake network protocol, one nic, and two
   540  	// addresses attached to it: 1 & 2.
   541  	ep := channel.New(10, defaultMTU, "")
   542  	s := stack.New(stack.Options{
   543  		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
   544  	})
   545  	if err := s.CreateNIC(1, ep); err != nil {
   546  		t.Fatal("CreateNIC failed:", err)
   547  	}
   548  
   549  	protocolAddr1 := tcpip.ProtocolAddress{
   550  		Protocol: fakeNetNumber,
   551  		AddressWithPrefix: tcpip.AddressWithPrefix{
   552  			Address:   tcpip.AddrFrom4Slice([]byte("\x01\x00\x00\x00")),
   553  			PrefixLen: fakeDefaultPrefixLen,
   554  		},
   555  	}
   556  	if err := s.AddProtocolAddress(1, protocolAddr1, stack.AddressProperties{}); err != nil {
   557  		t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", 1, protocolAddr1, err)
   558  	}
   559  
   560  	protocolAddr2 := tcpip.ProtocolAddress{
   561  		Protocol: fakeNetNumber,
   562  		AddressWithPrefix: tcpip.AddressWithPrefix{
   563  			Address:   tcpip.AddrFrom4Slice([]byte("\x02\x00\x00\x00")),
   564  			PrefixLen: fakeDefaultPrefixLen,
   565  		},
   566  	}
   567  	if err := s.AddProtocolAddress(1, protocolAddr2, stack.AddressProperties{}); err != nil {
   568  		t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", 1, protocolAddr2, err)
   569  	}
   570  
   571  	fakeNet := s.NetworkProtocolInstance(fakeNetNumber).(*fakeNetworkProtocol)
   572  
   573  	buf := make([]byte, 30)
   574  
   575  	// Make sure packet with wrong address is not delivered.
   576  	buf[dstAddrOffset] = 3
   577  	ep.InjectInbound(fakeNetNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
   578  		Payload: buffer.MakeWithData(buf),
   579  	}))
   580  	if fakeNet.packetCount[1] != 0 {
   581  		t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 0)
   582  	}
   583  	if fakeNet.packetCount[2] != 0 {
   584  		t.Errorf("packetCount[2] = %d, want %d", fakeNet.packetCount[2], 0)
   585  	}
   586  
   587  	// Make sure packet is delivered to first endpoint.
   588  	buf[dstAddrOffset] = 1
   589  	ep.InjectInbound(fakeNetNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
   590  		Payload: buffer.MakeWithData(buf),
   591  	}))
   592  	if fakeNet.packetCount[1] != 1 {
   593  		t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 1)
   594  	}
   595  	if fakeNet.packetCount[2] != 0 {
   596  		t.Errorf("packetCount[2] = %d, want %d", fakeNet.packetCount[2], 0)
   597  	}
   598  
   599  	// Make sure packet is delivered to second endpoint.
   600  	buf[dstAddrOffset] = 2
   601  	ep.InjectInbound(fakeNetNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
   602  		Payload: buffer.MakeWithData(buf),
   603  	}))
   604  	if fakeNet.packetCount[1] != 1 {
   605  		t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 1)
   606  	}
   607  	if fakeNet.packetCount[2] != 1 {
   608  		t.Errorf("packetCount[2] = %d, want %d", fakeNet.packetCount[2], 1)
   609  	}
   610  
   611  	// Make sure packet is not delivered if protocol number is wrong.
   612  	ep.InjectInbound(fakeNetNumber-1, stack.NewPacketBuffer(stack.PacketBufferOptions{
   613  		Payload: buffer.MakeWithData(buf),
   614  	}))
   615  	if fakeNet.packetCount[1] != 1 {
   616  		t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 1)
   617  	}
   618  	if fakeNet.packetCount[2] != 1 {
   619  		t.Errorf("packetCount[2] = %d, want %d", fakeNet.packetCount[2], 1)
   620  	}
   621  
   622  	// Make sure packet that is too small is dropped.
   623  	buf = buf[:2]
   624  	ep.InjectInbound(fakeNetNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
   625  		Payload: buffer.MakeWithData(buf),
   626  	}))
   627  	if fakeNet.packetCount[1] != 1 {
   628  		t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 1)
   629  	}
   630  	if fakeNet.packetCount[2] != 1 {
   631  		t.Errorf("packetCount[2] = %d, want %d", fakeNet.packetCount[2], 1)
   632  	}
   633  }
   634  
   635  func sendTo(s *stack.Stack, addr tcpip.Address, payload []byte) tcpip.Error {
   636  	r, err := s.FindRoute(0, tcpip.Address{}, addr, fakeNetNumber, false /* multicastLoop */)
   637  	if err != nil {
   638  		return err
   639  	}
   640  	defer r.Release()
   641  	return send(r, payload)
   642  }
   643  
   644  func send(r *stack.Route, payload []byte) tcpip.Error {
   645  	return r.WritePacket(stack.NetworkHeaderParams{Protocol: fakeTransNumber, TTL: 123, TOS: stack.DefaultTOS}, stack.NewPacketBuffer(stack.PacketBufferOptions{
   646  		ReserveHeaderBytes: int(r.MaxHeaderLength()),
   647  		Payload:            buffer.MakeWithData(payload),
   648  	}))
   649  }
   650  
   651  func testSendTo(t *testing.T, s *stack.Stack, addrStr string, ep *channel.Endpoint, payload []byte) {
   652  	t.Helper()
   653  	ep.Drain()
   654  	addr := tcpip.AddrFromSlice([]byte(addrStr))
   655  	if err := sendTo(s, addr, payload); err != nil {
   656  		t.Error("sendTo failed:", err)
   657  	}
   658  	if got, want := ep.Drain(), 1; got != want {
   659  		t.Errorf("sendTo packet count: got = %d, want %d", got, want)
   660  	}
   661  }
   662  
   663  func testSend(t *testing.T, r *stack.Route, ep *channel.Endpoint, payload []byte) {
   664  	t.Helper()
   665  	ep.Drain()
   666  	if err := send(r, payload); err != nil {
   667  		t.Error("send failed:", err)
   668  	}
   669  	if got, want := ep.Drain(), 1; got != want {
   670  		t.Errorf("send packet count: got = %d, want %d", got, want)
   671  	}
   672  }
   673  
   674  func testFailingSend(t *testing.T, r *stack.Route, payload []byte, wantErr tcpip.Error) {
   675  	t.Helper()
   676  	if gotErr := send(r, payload); gotErr != wantErr {
   677  		t.Errorf("send failed: got = %s, want = %s ", gotErr, wantErr)
   678  	}
   679  }
   680  
   681  func testFailingSendTo(t *testing.T, s *stack.Stack, addr tcpip.Address, payload []byte, wantErr tcpip.Error) {
   682  	t.Helper()
   683  	if gotErr := sendTo(s, addr, payload); gotErr != wantErr {
   684  		t.Errorf("sendto failed: got = %s, want = %s ", gotErr, wantErr)
   685  	}
   686  }
   687  
   688  func testRecv(t *testing.T, fakeNet *fakeNetworkProtocol, localAddrByte byte, ep *channel.Endpoint, buf []byte) {
   689  	t.Helper()
   690  	// testRecvInternal injects one packet, and we expect to receive it.
   691  	want := fakeNet.PacketCount(localAddrByte) + 1
   692  	testRecvInternal(t, fakeNet, localAddrByte, ep, buf, want)
   693  }
   694  
   695  func testFailingRecv(t *testing.T, fakeNet *fakeNetworkProtocol, localAddrByte byte, ep *channel.Endpoint, buf []byte) {
   696  	t.Helper()
   697  	// testRecvInternal injects one packet, and we do NOT expect to receive it.
   698  	want := fakeNet.PacketCount(localAddrByte)
   699  	testRecvInternal(t, fakeNet, localAddrByte, ep, buf, want)
   700  }
   701  
   702  func testRecvInternal(t *testing.T, fakeNet *fakeNetworkProtocol, localAddrByte byte, ep *channel.Endpoint, buf []byte, want int) {
   703  	t.Helper()
   704  	ep.InjectInbound(fakeNetNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
   705  		Payload: buffer.MakeWithData(buf),
   706  	}))
   707  	if got := fakeNet.PacketCount(localAddrByte); got != want {
   708  		t.Errorf("receive packet count: got = %d, want %d", got, want)
   709  	}
   710  }
   711  
   712  func TestNetworkSend(t *testing.T) {
   713  	// Create a stack with the fake network protocol, one nic, and one
   714  	// address: 1. The route table sends all packets through the only
   715  	// existing nic.
   716  	ep := channel.New(10, defaultMTU, "")
   717  	s := stack.New(stack.Options{
   718  		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
   719  	})
   720  	if err := s.CreateNIC(1, ep); err != nil {
   721  		t.Fatal("NewNIC failed:", err)
   722  	}
   723  
   724  	{
   725  		subnet, err := tcpip.NewSubnet(tcpip.AddrFrom4Slice([]byte("\x00\x00\x00\x00")), tcpip.MaskFrom("\x00\x00\x00\x00"))
   726  		if err != nil {
   727  			t.Fatal(err)
   728  		}
   729  		s.SetRouteTable([]tcpip.Route{{Destination: subnet, Gateway: tcpip.AddrFrom4Slice([]byte("\x00\x00\x00\x00")), NIC: 1}})
   730  	}
   731  
   732  	protocolAddr := tcpip.ProtocolAddress{
   733  		Protocol: fakeNetNumber,
   734  		AddressWithPrefix: tcpip.AddressWithPrefix{
   735  			Address:   tcpip.AddrFromSlice([]byte("\x01\x00\x00\x00")),
   736  			PrefixLen: fakeDefaultPrefixLen,
   737  		},
   738  	}
   739  	if err := s.AddProtocolAddress(1, protocolAddr, stack.AddressProperties{}); err != nil {
   740  		t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", 1, protocolAddr, err)
   741  	}
   742  
   743  	// Make sure that the link-layer endpoint received the outbound packet.
   744  	testSendTo(t, s, "\x03\x00\x00\x00", ep, nil)
   745  }
   746  
   747  func TestNetworkSendMultiRoute(t *testing.T) {
   748  	// Create a stack with the fake network protocol, two nics, and two
   749  	// addresses per nic, the first nic has odd address, the second one has
   750  	// even addresses.
   751  	s := stack.New(stack.Options{
   752  		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
   753  	})
   754  
   755  	ep1 := channel.New(10, defaultMTU, "")
   756  	if err := s.CreateNIC(1, ep1); err != nil {
   757  		t.Fatal("CreateNIC failed:", err)
   758  	}
   759  
   760  	protocolAddr1 := tcpip.ProtocolAddress{
   761  		Protocol: fakeNetNumber,
   762  		AddressWithPrefix: tcpip.AddressWithPrefix{
   763  			Address:   tcpip.AddrFromSlice([]byte("\x01\x00\x00\x00")),
   764  			PrefixLen: fakeDefaultPrefixLen,
   765  		},
   766  	}
   767  	if err := s.AddProtocolAddress(1, protocolAddr1, stack.AddressProperties{}); err != nil {
   768  		t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", 1, protocolAddr1, err)
   769  	}
   770  
   771  	protocolAddr3 := tcpip.ProtocolAddress{
   772  		Protocol: fakeNetNumber,
   773  		AddressWithPrefix: tcpip.AddressWithPrefix{
   774  			Address:   tcpip.AddrFromSlice([]byte("\x03\x00\x00\x00")),
   775  			PrefixLen: fakeDefaultPrefixLen,
   776  		},
   777  	}
   778  	if err := s.AddProtocolAddress(1, protocolAddr3, stack.AddressProperties{}); err != nil {
   779  		t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", 1, protocolAddr3, err)
   780  	}
   781  
   782  	ep2 := channel.New(10, defaultMTU, "")
   783  	if err := s.CreateNIC(2, ep2); err != nil {
   784  		t.Fatal("CreateNIC failed:", err)
   785  	}
   786  
   787  	protocolAddr2 := tcpip.ProtocolAddress{
   788  		Protocol: fakeNetNumber,
   789  		AddressWithPrefix: tcpip.AddressWithPrefix{
   790  			Address:   tcpip.AddrFromSlice([]byte("\x02\x00\x00\x00")),
   791  			PrefixLen: fakeDefaultPrefixLen,
   792  		},
   793  	}
   794  	if err := s.AddProtocolAddress(2, protocolAddr2, stack.AddressProperties{}); err != nil {
   795  		t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", 2, protocolAddr2, err)
   796  	}
   797  
   798  	protocolAddr4 := tcpip.ProtocolAddress{
   799  		Protocol: fakeNetNumber,
   800  		AddressWithPrefix: tcpip.AddressWithPrefix{
   801  			Address:   tcpip.AddrFromSlice([]byte("\x04\x00\x00\x00")),
   802  			PrefixLen: fakeDefaultPrefixLen,
   803  		},
   804  	}
   805  	if err := s.AddProtocolAddress(2, protocolAddr4, stack.AddressProperties{}); err != nil {
   806  		t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", 2, protocolAddr4, err)
   807  	}
   808  
   809  	// Set a route table that sends all packets with odd destination
   810  	// addresses through the first NIC, and all even destination address
   811  	// through the second one.
   812  	{
   813  		subnet0, err := tcpip.NewSubnet(tcpip.AddrFrom4Slice([]byte("\x00\x00\x00\x00")), tcpip.MaskFrom("\x01\x00\x00\x00"))
   814  		if err != nil {
   815  			t.Fatal(err)
   816  		}
   817  		subnet1, err := tcpip.NewSubnet(tcpip.AddrFrom4Slice([]byte("\x01\x00\x00\x00")), tcpip.MaskFrom("\x01\x00\x00\x00"))
   818  		if err != nil {
   819  			t.Fatal(err)
   820  		}
   821  		s.SetRouteTable([]tcpip.Route{
   822  			{Destination: subnet1, Gateway: tcpip.AddrFromSlice([]byte("\x00\x00\x00\x00")), NIC: 1},
   823  			{Destination: subnet0, Gateway: tcpip.AddrFromSlice([]byte("\x00\x00\x00\x00")), NIC: 2},
   824  		})
   825  	}
   826  
   827  	// Send a packet to an odd destination.
   828  	testSendTo(t, s, "\x05\x00\x00\x00", ep1, nil)
   829  
   830  	// Send a packet to an even destination.
   831  	testSendTo(t, s, "\x06\x00\x00\x00", ep2, nil)
   832  }
   833  
   834  func testRoute(t *testing.T, s *stack.Stack, nic tcpip.NICID, srcAddr, dstAddr, expectedSrcAddr tcpip.Address) {
   835  	r, err := s.FindRoute(nic, srcAddr, dstAddr, fakeNetNumber, false /* multicastLoop */)
   836  	if err != nil {
   837  		t.Fatal("FindRoute failed:", err)
   838  	}
   839  
   840  	defer r.Release()
   841  
   842  	if r.LocalAddress() != expectedSrcAddr {
   843  		t.Fatalf("got Route.LocalAddress() = %s, want = %s", expectedSrcAddr, r.LocalAddress())
   844  	}
   845  
   846  	if r.RemoteAddress() != dstAddr {
   847  		t.Fatalf("got Route.RemoteAddress() = %s, want = %s", dstAddr, r.RemoteAddress())
   848  	}
   849  }
   850  
   851  func testNoRoute(t *testing.T, s *stack.Stack, nic tcpip.NICID, srcAddr, dstAddr tcpip.Address) {
   852  	_, err := s.FindRoute(nic, srcAddr, dstAddr, fakeNetNumber, false /* multicastLoop */)
   853  	if _, ok := err.(*tcpip.ErrHostUnreachable); !ok {
   854  		t.Fatalf("FindRoute returned unexpected error, got = %v, want = %s", err, &tcpip.ErrHostUnreachable{})
   855  	}
   856  }
   857  
   858  // TestAttachToLinkEndpointImmediately tests that a LinkEndpoint is attached to
   859  // a NetworkDispatcher when the NIC is created.
   860  func TestAttachToLinkEndpointImmediately(t *testing.T) {
   861  	const nicID = 1
   862  
   863  	tests := []struct {
   864  		name    string
   865  		nicOpts stack.NICOptions
   866  	}{
   867  		{
   868  			name:    "Create enabled NIC",
   869  			nicOpts: stack.NICOptions{Disabled: false},
   870  		},
   871  		{
   872  			name:    "Create disabled NIC",
   873  			nicOpts: stack.NICOptions{Disabled: true},
   874  		},
   875  	}
   876  
   877  	for _, test := range tests {
   878  		t.Run(test.name, func(t *testing.T) {
   879  			s := stack.New(stack.Options{
   880  				NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
   881  			})
   882  
   883  			e := linkEPWithMockedAttach{
   884  				LinkEndpoint: loopback.New(),
   885  			}
   886  
   887  			if err := s.CreateNICWithOptions(nicID, &e, test.nicOpts); err != nil {
   888  				t.Fatalf("CreateNICWithOptions(%d, _, %+v) = %s", nicID, test.nicOpts, err)
   889  			}
   890  			if !e.isAttached() {
   891  				t.Fatal("link endpoint not attached to a network dispatcher")
   892  			}
   893  		})
   894  	}
   895  }
   896  
   897  func TestDisableUnknownNIC(t *testing.T) {
   898  	s := stack.New(stack.Options{
   899  		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
   900  	})
   901  
   902  	err := s.DisableNIC(1)
   903  	if _, ok := err.(*tcpip.ErrUnknownNICID); !ok {
   904  		t.Fatalf("got s.DisableNIC(1) = %v, want = %s", err, &tcpip.ErrUnknownNICID{})
   905  	}
   906  }
   907  
   908  func TestDisabledNICsNICInfoAndCheckNIC(t *testing.T) {
   909  	const nicID = 1
   910  
   911  	s := stack.New(stack.Options{
   912  		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
   913  	})
   914  
   915  	e := loopback.New()
   916  	nicOpts := stack.NICOptions{Disabled: true}
   917  	if err := s.CreateNICWithOptions(nicID, e, nicOpts); err != nil {
   918  		t.Fatalf("CreateNICWithOptions(%d, _, %+v) = %s", nicID, nicOpts, err)
   919  	}
   920  
   921  	checkNIC := func(enabled bool) {
   922  		t.Helper()
   923  
   924  		allNICInfo := s.NICInfo()
   925  		nicInfo, ok := allNICInfo[nicID]
   926  		if !ok {
   927  			t.Errorf("entry for %d missing from allNICInfo = %+v", nicID, allNICInfo)
   928  		} else if nicInfo.Flags.Running != enabled {
   929  			t.Errorf("got nicInfo.Flags.Running = %t, want = %t", nicInfo.Flags.Running, enabled)
   930  		}
   931  
   932  		if got := s.CheckNIC(nicID); got != enabled {
   933  			t.Errorf("got s.CheckNIC(%d) = %t, want = %t", nicID, got, enabled)
   934  		}
   935  	}
   936  
   937  	// NIC should initially report itself as disabled.
   938  	checkNIC(false)
   939  
   940  	if err := s.EnableNIC(nicID); err != nil {
   941  		t.Fatalf("s.EnableNIC(%d): %s", nicID, err)
   942  	}
   943  	checkNIC(true)
   944  
   945  	// If the NIC is not reporting a correct enabled status, we cannot trust the
   946  	// next check so end the test here.
   947  	if t.Failed() {
   948  		t.FailNow()
   949  	}
   950  
   951  	if err := s.DisableNIC(nicID); err != nil {
   952  		t.Fatalf("s.DisableNIC(%d): %s", nicID, err)
   953  	}
   954  	checkNIC(false)
   955  }
   956  
   957  func TestRemoveUnknownNIC(t *testing.T) {
   958  	s := stack.New(stack.Options{
   959  		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
   960  	})
   961  
   962  	err := s.RemoveNIC(1)
   963  	if _, ok := err.(*tcpip.ErrUnknownNICID); !ok {
   964  		t.Fatalf("got s.RemoveNIC(1) = %v, want = %s", err, &tcpip.ErrUnknownNICID{})
   965  	}
   966  }
   967  
   968  func TestRemoveNIC(t *testing.T) {
   969  	for _, tt := range []struct {
   970  		name   string
   971  		linkep stack.LinkEndpoint
   972  	}{
   973  		{
   974  			name:   "loopback",
   975  			linkep: loopback.New(),
   976  		},
   977  		{
   978  			name:   "channel",
   979  			linkep: channel.New(0, defaultMTU, ""),
   980  		},
   981  	} {
   982  		t.Run(tt.name, func(t *testing.T) {
   983  			const nicID = 1
   984  
   985  			s := stack.New(stack.Options{
   986  				NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
   987  			})
   988  
   989  			e := linkEPWithMockedAttach{
   990  				LinkEndpoint: tt.linkep,
   991  			}
   992  			if err := s.CreateNIC(nicID, &e); err != nil {
   993  				t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
   994  			}
   995  
   996  			// NIC should be present in NICInfo and attached to a NetworkDispatcher.
   997  			allNICInfo := s.NICInfo()
   998  			if _, ok := allNICInfo[nicID]; !ok {
   999  				t.Errorf("entry for %d missing from allNICInfo = %+v", nicID, allNICInfo)
  1000  			}
  1001  			if !e.isAttached() {
  1002  				t.Fatal("link endpoint not attached to a network dispatcher")
  1003  			}
  1004  
  1005  			// Removing a NIC should remove it from NICInfo and e should be detached from
  1006  			// the NetworkDispatcher.
  1007  			if err := s.RemoveNIC(nicID); err != nil {
  1008  				t.Fatalf("s.RemoveNIC(%d): %s", nicID, err)
  1009  			}
  1010  			if nicInfo, ok := s.NICInfo()[nicID]; ok {
  1011  				t.Errorf("got unexpected NICInfo entry for deleted NIC %d = %+v", nicID, nicInfo)
  1012  			}
  1013  			if e.isAttached() {
  1014  				t.Error("link endpoint for removed NIC still attached to a network dispatcher")
  1015  			}
  1016  		})
  1017  	}
  1018  }
  1019  
  1020  func TestRouteWithDownNIC(t *testing.T) {
  1021  	tests := []struct {
  1022  		name   string
  1023  		downFn func(s *stack.Stack, nicID tcpip.NICID) tcpip.Error
  1024  		upFn   func(s *stack.Stack, nicID tcpip.NICID) tcpip.Error
  1025  	}{
  1026  		{
  1027  			name:   "Disabled NIC",
  1028  			downFn: (*stack.Stack).DisableNIC,
  1029  			upFn:   (*stack.Stack).EnableNIC,
  1030  		},
  1031  
  1032  		// Once a NIC is removed, it cannot be brought up.
  1033  		{
  1034  			name:   "Removed NIC",
  1035  			downFn: (*stack.Stack).RemoveNIC,
  1036  		},
  1037  	}
  1038  
  1039  	const unspecifiedNIC = 0
  1040  	const nicID1 = 1
  1041  	const nicID2 = 2
  1042  	var addr1 = tcpip.AddrFrom4Slice([]byte("\x01\x00\x00\x00"))
  1043  	var addr2 = tcpip.AddrFrom4Slice([]byte("\x02\x00\x00\x00"))
  1044  	var nic1Dst = tcpip.AddrFrom4Slice([]byte("\x05\x00\x00\x00"))
  1045  	var nic2Dst = tcpip.AddrFrom4Slice([]byte("\x06\x00\x00\x00"))
  1046  
  1047  	setup := func(t *testing.T) (*stack.Stack, *channel.Endpoint, *channel.Endpoint) {
  1048  		s := stack.New(stack.Options{
  1049  			NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
  1050  		})
  1051  
  1052  		ep1 := channel.New(1, defaultMTU, "")
  1053  		if err := s.CreateNIC(nicID1, ep1); err != nil {
  1054  			t.Fatalf("CreateNIC(%d, _): %s", nicID1, err)
  1055  		}
  1056  
  1057  		protocolAddr1 := tcpip.ProtocolAddress{
  1058  			Protocol: fakeNetNumber,
  1059  			AddressWithPrefix: tcpip.AddressWithPrefix{
  1060  				Address:   addr1,
  1061  				PrefixLen: fakeDefaultPrefixLen,
  1062  			},
  1063  		}
  1064  		if err := s.AddProtocolAddress(nicID1, protocolAddr1, stack.AddressProperties{}); err != nil {
  1065  			t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", nicID1, protocolAddr1, err)
  1066  		}
  1067  
  1068  		ep2 := channel.New(1, defaultMTU, "")
  1069  		if err := s.CreateNIC(nicID2, ep2); err != nil {
  1070  			t.Fatalf("CreateNIC(%d, _): %s", nicID2, err)
  1071  		}
  1072  
  1073  		protocolAddr2 := tcpip.ProtocolAddress{
  1074  			Protocol: fakeNetNumber,
  1075  			AddressWithPrefix: tcpip.AddressWithPrefix{
  1076  				Address:   addr2,
  1077  				PrefixLen: fakeDefaultPrefixLen,
  1078  			},
  1079  		}
  1080  		if err := s.AddProtocolAddress(nicID2, protocolAddr2, stack.AddressProperties{}); err != nil {
  1081  			t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", nicID2, protocolAddr2, err)
  1082  		}
  1083  
  1084  		// Set a route table that sends all packets with odd destination
  1085  		// addresses through the first NIC, and all even destination address
  1086  		// through the second one.
  1087  		{
  1088  			subnet0, err := tcpip.NewSubnet(tcpip.AddrFrom4Slice([]byte("\x00\x00\x00\x00")), tcpip.MaskFrom("\x01\x00\x00\x00"))
  1089  			if err != nil {
  1090  				t.Fatal(err)
  1091  			}
  1092  			subnet1, err := tcpip.NewSubnet(tcpip.AddrFrom4Slice([]byte("\x01\x00\x00\x00")), tcpip.MaskFrom("\x01\x00\x00\x00"))
  1093  			if err != nil {
  1094  				t.Fatal(err)
  1095  			}
  1096  			s.SetRouteTable([]tcpip.Route{
  1097  				{Destination: subnet1, Gateway: tcpip.AddrFrom4Slice([]byte("\x00\x00\x00\x00")), NIC: nicID1},
  1098  				{Destination: subnet0, Gateway: tcpip.AddrFrom4Slice([]byte("\x00\x00\x00\x00")), NIC: nicID2},
  1099  			})
  1100  		}
  1101  
  1102  		return s, ep1, ep2
  1103  	}
  1104  
  1105  	// Tests that routes through a down NIC are not used when looking up a route
  1106  	// for a destination.
  1107  	t.Run("Find", func(t *testing.T) {
  1108  		for _, test := range tests {
  1109  			t.Run(test.name, func(t *testing.T) {
  1110  				s, _, _ := setup(t)
  1111  
  1112  				// Test routes to odd address.
  1113  				testRoute(t, s, unspecifiedNIC, tcpip.Address{}, tcpip.AddrFromSlice([]byte("\x05\x00\x00\x00")), addr1)
  1114  				testRoute(t, s, unspecifiedNIC, addr1, tcpip.AddrFromSlice([]byte("\x05\x00\x00\x00")), addr1)
  1115  				testRoute(t, s, nicID1, addr1, tcpip.AddrFromSlice([]byte("\x05\x00\x00\x00")), addr1)
  1116  
  1117  				// Test routes to even address.
  1118  				testRoute(t, s, unspecifiedNIC, tcpip.Address{}, tcpip.AddrFromSlice([]byte("\x06\x00\x00\x00")), addr2)
  1119  				testRoute(t, s, unspecifiedNIC, addr2, tcpip.AddrFromSlice([]byte("\x06\x00\x00\x00")), addr2)
  1120  				testRoute(t, s, nicID2, addr2, tcpip.AddrFromSlice([]byte("\x06\x00\x00\x00")), addr2)
  1121  
  1122  				// Bringing NIC1 down should result in no routes to odd addresses. Routes to
  1123  				// even addresses should continue to be available as NIC2 is still up.
  1124  				if err := test.downFn(s, nicID1); err != nil {
  1125  					t.Fatalf("test.downFn(_, %d): %s", nicID1, err)
  1126  				}
  1127  				testNoRoute(t, s, unspecifiedNIC, tcpip.Address{}, nic1Dst)
  1128  				testNoRoute(t, s, unspecifiedNIC, addr1, nic1Dst)
  1129  				testNoRoute(t, s, nicID1, addr1, nic1Dst)
  1130  				testRoute(t, s, unspecifiedNIC, tcpip.Address{}, nic2Dst, addr2)
  1131  				testRoute(t, s, unspecifiedNIC, addr2, nic2Dst, addr2)
  1132  				testRoute(t, s, nicID2, addr2, nic2Dst, addr2)
  1133  
  1134  				// Bringing NIC2 down should result in no routes to even addresses. No
  1135  				// route should be available to any address as routes to odd addresses
  1136  				// were made unavailable by bringing NIC1 down above.
  1137  				if err := test.downFn(s, nicID2); err != nil {
  1138  					t.Fatalf("test.downFn(_, %d): %s", nicID2, err)
  1139  				}
  1140  				testNoRoute(t, s, unspecifiedNIC, tcpip.Address{}, nic1Dst)
  1141  				testNoRoute(t, s, unspecifiedNIC, addr1, nic1Dst)
  1142  				testNoRoute(t, s, nicID1, addr1, nic1Dst)
  1143  				testNoRoute(t, s, unspecifiedNIC, tcpip.Address{}, nic2Dst)
  1144  				testNoRoute(t, s, unspecifiedNIC, addr2, nic2Dst)
  1145  				testNoRoute(t, s, nicID2, addr2, nic2Dst)
  1146  
  1147  				if upFn := test.upFn; upFn != nil {
  1148  					// Bringing NIC1 up should make routes to odd addresses available
  1149  					// again. Routes to even addresses should continue to be unavailable
  1150  					// as NIC2 is still down.
  1151  					if err := upFn(s, nicID1); err != nil {
  1152  						t.Fatalf("test.upFn(_, %d): %s", nicID1, err)
  1153  					}
  1154  					testRoute(t, s, unspecifiedNIC, tcpip.Address{}, nic1Dst, addr1)
  1155  					testRoute(t, s, unspecifiedNIC, addr1, nic1Dst, addr1)
  1156  					testRoute(t, s, nicID1, addr1, nic1Dst, addr1)
  1157  					testNoRoute(t, s, unspecifiedNIC, tcpip.Address{}, nic2Dst)
  1158  					testNoRoute(t, s, unspecifiedNIC, addr2, nic2Dst)
  1159  					testNoRoute(t, s, nicID2, addr2, nic2Dst)
  1160  				}
  1161  			})
  1162  		}
  1163  	})
  1164  
  1165  	// Tests that writing a packet using a Route through a down NIC fails.
  1166  	t.Run("WritePacket", func(t *testing.T) {
  1167  		for _, test := range tests {
  1168  			t.Run(test.name, func(t *testing.T) {
  1169  				s, ep1, ep2 := setup(t)
  1170  
  1171  				r1, err := s.FindRoute(nicID1, addr1, nic1Dst, fakeNetNumber, false /* multicastLoop */)
  1172  				if err != nil {
  1173  					t.Errorf("FindRoute(%d, %s, %s, %d, false): %s", nicID1, addr1, nic1Dst, fakeNetNumber, err)
  1174  				}
  1175  				defer r1.Release()
  1176  
  1177  				r2, err := s.FindRoute(nicID2, addr2, nic2Dst, fakeNetNumber, false /* multicastLoop */)
  1178  				if err != nil {
  1179  					t.Errorf("FindRoute(%d, %s, %s, %d, false): %s", nicID2, addr2, nic2Dst, fakeNetNumber, err)
  1180  				}
  1181  				defer r2.Release()
  1182  
  1183  				// If we failed to get routes r1 or r2, we cannot proceed with the test.
  1184  				if t.Failed() {
  1185  					t.FailNow()
  1186  				}
  1187  
  1188  				buf := []byte{1}
  1189  				testSend(t, r1, ep1, buf)
  1190  				testSend(t, r2, ep2, buf)
  1191  
  1192  				// Writes with Routes that use NIC1 after being brought down should fail.
  1193  				if err := test.downFn(s, nicID1); err != nil {
  1194  					t.Fatalf("test.downFn(_, %d): %s", nicID1, err)
  1195  				}
  1196  				testFailingSend(t, r1, buf, &tcpip.ErrInvalidEndpointState{})
  1197  				testSend(t, r2, ep2, buf)
  1198  
  1199  				// Writes with Routes that use NIC2 after being brought down should fail.
  1200  				if err := test.downFn(s, nicID2); err != nil {
  1201  					t.Fatalf("test.downFn(_, %d): %s", nicID2, err)
  1202  				}
  1203  				testFailingSend(t, r1, buf, &tcpip.ErrInvalidEndpointState{})
  1204  				testFailingSend(t, r2, buf, &tcpip.ErrInvalidEndpointState{})
  1205  
  1206  				if upFn := test.upFn; upFn != nil {
  1207  					// Writes with Routes that use NIC1 after being brought up should
  1208  					// succeed.
  1209  					//
  1210  					// TODO(gvisor.dev/issue/1491): Should we instead completely
  1211  					// invalidate all Routes that were bound to a NIC that was brought
  1212  					// down at some point?
  1213  					if err := upFn(s, nicID1); err != nil {
  1214  						t.Fatalf("test.upFn(_, %d): %s", nicID1, err)
  1215  					}
  1216  					testSend(t, r1, ep1, buf)
  1217  					testFailingSend(t, r2, buf, &tcpip.ErrInvalidEndpointState{})
  1218  				}
  1219  			})
  1220  		}
  1221  	})
  1222  }
  1223  
  1224  func TestRoutes(t *testing.T) {
  1225  	// Create a stack with the fake network protocol, two nics, and two
  1226  	// addresses per nic, the first nic has odd address, the second one has
  1227  	// even addresses.
  1228  	s := stack.New(stack.Options{
  1229  		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
  1230  	})
  1231  
  1232  	ep1 := channel.New(10, defaultMTU, "")
  1233  	if err := s.CreateNIC(1, ep1); err != nil {
  1234  		t.Fatal("CreateNIC failed:", err)
  1235  	}
  1236  
  1237  	protocolAddr1 := tcpip.ProtocolAddress{
  1238  		Protocol: fakeNetNumber,
  1239  		AddressWithPrefix: tcpip.AddressWithPrefix{
  1240  			Address:   tcpip.AddrFromSlice([]byte("\x01\x00\x00\x00")),
  1241  			PrefixLen: fakeDefaultPrefixLen,
  1242  		},
  1243  	}
  1244  	if err := s.AddProtocolAddress(1, protocolAddr1, stack.AddressProperties{}); err != nil {
  1245  		t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", 1, protocolAddr1, err)
  1246  	}
  1247  
  1248  	protocolAddr3 := tcpip.ProtocolAddress{
  1249  		Protocol: fakeNetNumber,
  1250  		AddressWithPrefix: tcpip.AddressWithPrefix{
  1251  			Address:   tcpip.AddrFromSlice([]byte("\x03\x00\x00\x00")),
  1252  			PrefixLen: fakeDefaultPrefixLen,
  1253  		},
  1254  	}
  1255  	if err := s.AddProtocolAddress(1, protocolAddr3, stack.AddressProperties{}); err != nil {
  1256  		t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", 1, protocolAddr3, err)
  1257  	}
  1258  
  1259  	ep2 := channel.New(10, defaultMTU, "")
  1260  	if err := s.CreateNIC(2, ep2); err != nil {
  1261  		t.Fatal("CreateNIC failed:", err)
  1262  	}
  1263  
  1264  	protocolAddr2 := tcpip.ProtocolAddress{
  1265  		Protocol: fakeNetNumber,
  1266  		AddressWithPrefix: tcpip.AddressWithPrefix{
  1267  			Address:   tcpip.AddrFromSlice([]byte("\x02\x00\x00\x00")),
  1268  			PrefixLen: fakeDefaultPrefixLen,
  1269  		},
  1270  	}
  1271  	if err := s.AddProtocolAddress(2, protocolAddr2, stack.AddressProperties{}); err != nil {
  1272  		t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", 2, protocolAddr2, err)
  1273  	}
  1274  
  1275  	protocolAddr4 := tcpip.ProtocolAddress{
  1276  		Protocol: fakeNetNumber,
  1277  		AddressWithPrefix: tcpip.AddressWithPrefix{
  1278  			Address:   tcpip.AddrFromSlice([]byte("\x04\x00\x00\x00")),
  1279  			PrefixLen: fakeDefaultPrefixLen,
  1280  		},
  1281  	}
  1282  	if err := s.AddProtocolAddress(2, protocolAddr4, stack.AddressProperties{}); err != nil {
  1283  		t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", 2, protocolAddr4, err)
  1284  	}
  1285  
  1286  	// Set a route table that sends all packets with odd destination
  1287  	// addresses through the first NIC, and all even destination address
  1288  	// through the second one.
  1289  	{
  1290  		subnet0, err := tcpip.NewSubnet(tcpip.AddrFromSlice([]byte("\x00\x00\x00\x00")), tcpip.MaskFrom("\x01\x00\x00\x00"))
  1291  		if err != nil {
  1292  			t.Fatal(err)
  1293  		}
  1294  		subnet1, err := tcpip.NewSubnet(tcpip.AddrFromSlice([]byte("\x01\x00\x00\x00")), tcpip.MaskFrom("\x01\x00\x00\x00"))
  1295  		if err != nil {
  1296  			t.Fatal(err)
  1297  		}
  1298  		s.SetRouteTable([]tcpip.Route{
  1299  			{Destination: subnet1, Gateway: tcpip.AddrFromSlice([]byte("\x00\x00\x00\x00")), NIC: 1},
  1300  			{Destination: subnet0, Gateway: tcpip.AddrFromSlice([]byte("\x00\x00\x00\x00")), NIC: 2},
  1301  		})
  1302  	}
  1303  
  1304  	// Test routes to odd address.
  1305  	testRoute(t, s, 0, tcpip.Address{}, tcpip.AddrFromSlice([]byte("\x05\x00\x00\x00")), tcpip.AddrFromSlice([]byte("\x01\x00\x00\x00")))
  1306  	testRoute(t, s, 0, tcpip.AddrFromSlice([]byte("\x01\x00\x00\x00")), tcpip.AddrFromSlice([]byte("\x05\x00\x00\x00")), tcpip.AddrFromSlice([]byte("\x01\x00\x00\x00")))
  1307  	testRoute(t, s, 1, tcpip.AddrFromSlice([]byte("\x01\x00\x00\x00")), tcpip.AddrFromSlice([]byte("\x05\x00\x00\x00")), tcpip.AddrFromSlice([]byte("\x01\x00\x00\x00")))
  1308  	testRoute(t, s, 0, tcpip.AddrFromSlice([]byte("\x03\x00\x00\x00")), tcpip.AddrFromSlice([]byte("\x05\x00\x00\x00")), tcpip.AddrFromSlice([]byte("\x03\x00\x00\x00")))
  1309  	testRoute(t, s, 1, tcpip.AddrFromSlice([]byte("\x03\x00\x00\x00")), tcpip.AddrFromSlice([]byte("\x05\x00\x00\x00")), tcpip.AddrFromSlice([]byte("\x03\x00\x00\x00")))
  1310  
  1311  	// Test routes to even address.
  1312  	testRoute(t, s, 0, tcpip.Address{}, tcpip.AddrFromSlice([]byte("\x06\x00\x00\x00")), tcpip.AddrFromSlice([]byte("\x04\x00\x00\x00")))
  1313  	testRoute(t, s, 0, tcpip.AddrFromSlice([]byte("\x02\x00\x00\x00")), tcpip.AddrFromSlice([]byte("\x06\x00\x00\x00")), tcpip.AddrFromSlice([]byte("\x02\x00\x00\x00")))
  1314  	testRoute(t, s, 2, tcpip.AddrFromSlice([]byte("\x02\x00\x00\x00")), tcpip.AddrFromSlice([]byte("\x06\x00\x00\x00")), tcpip.AddrFromSlice([]byte("\x02\x00\x00\x00")))
  1315  	testRoute(t, s, 0, tcpip.AddrFromSlice([]byte("\x04\x00\x00\x00")), tcpip.AddrFromSlice([]byte("\x06\x00\x00\x00")), tcpip.AddrFromSlice([]byte("\x04\x00\x00\x00")))
  1316  	testRoute(t, s, 2, tcpip.AddrFromSlice([]byte("\x04\x00\x00\x00")), tcpip.AddrFromSlice([]byte("\x06\x00\x00\x00")), tcpip.AddrFromSlice([]byte("\x04\x00\x00\x00")))
  1317  
  1318  	// Try to send to odd numbered address from even numbered ones, then
  1319  	// vice-versa.
  1320  	testNoRoute(t, s, 0, tcpip.AddrFromSlice([]byte("\x02\x00\x00\x00")), tcpip.AddrFromSlice([]byte("\x05\x00\x00\x00")))
  1321  	testNoRoute(t, s, 2, tcpip.AddrFromSlice([]byte("\x02\x00\x00\x00")), tcpip.AddrFromSlice([]byte("\x05\x00\x00\x00")))
  1322  	testNoRoute(t, s, 0, tcpip.AddrFromSlice([]byte("\x04\x00\x00\x00")), tcpip.AddrFromSlice([]byte("\x05\x00\x00\x00")))
  1323  	testNoRoute(t, s, 2, tcpip.AddrFromSlice([]byte("\x04\x00\x00\x00")), tcpip.AddrFromSlice([]byte("\x05\x00\x00\x00")))
  1324  
  1325  	testNoRoute(t, s, 0, tcpip.AddrFromSlice([]byte("\x01\x00\x00\x00")), tcpip.AddrFromSlice([]byte("\x06\x00\x00\x00")))
  1326  	testNoRoute(t, s, 1, tcpip.AddrFromSlice([]byte("\x01\x00\x00\x00")), tcpip.AddrFromSlice([]byte("\x06\x00\x00\x00")))
  1327  	testNoRoute(t, s, 0, tcpip.AddrFromSlice([]byte("\x03\x00\x00\x00")), tcpip.AddrFromSlice([]byte("\x06\x00\x00\x00")))
  1328  	testNoRoute(t, s, 1, tcpip.AddrFromSlice([]byte("\x03\x00\x00\x00")), tcpip.AddrFromSlice([]byte("\x06\x00\x00\x00")))
  1329  }
  1330  
  1331  func TestAddressRemoval(t *testing.T) {
  1332  	const localAddrByte byte = 0x01
  1333  	localAddr := tcpip.AddrFromSlice([]byte{localAddrByte, 0, 0, 0})
  1334  	remoteAddr := tcpip.AddrFromSlice([]byte("\x02\x00\x00\x00"))
  1335  
  1336  	s := stack.New(stack.Options{
  1337  		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
  1338  	})
  1339  
  1340  	ep := channel.New(10, defaultMTU, "")
  1341  	if err := s.CreateNIC(1, ep); err != nil {
  1342  		t.Fatal("CreateNIC failed:", err)
  1343  	}
  1344  
  1345  	protocolAddr := tcpip.ProtocolAddress{
  1346  		Protocol: fakeNetNumber,
  1347  		AddressWithPrefix: tcpip.AddressWithPrefix{
  1348  			Address:   localAddr,
  1349  			PrefixLen: fakeDefaultPrefixLen,
  1350  		},
  1351  	}
  1352  	if err := s.AddProtocolAddress(1, protocolAddr, stack.AddressProperties{}); err != nil {
  1353  		t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", 1, protocolAddr, err)
  1354  	}
  1355  	{
  1356  		subnet, err := tcpip.NewSubnet(tcpip.AddrFromSlice([]byte("\x00\x00\x00\x00")), tcpip.MaskFrom("\x00\x00\x00\x00"))
  1357  		if err != nil {
  1358  			t.Fatal(err)
  1359  		}
  1360  		s.SetRouteTable([]tcpip.Route{{Destination: subnet, Gateway: tcpip.AddrFromSlice([]byte("\x00\x00\x00\x00")), NIC: 1}})
  1361  	}
  1362  
  1363  	fakeNet := s.NetworkProtocolInstance(fakeNetNumber).(*fakeNetworkProtocol)
  1364  
  1365  	buf := make([]byte, 30)
  1366  
  1367  	// Send and receive packets, and verify they are received.
  1368  	buf[dstAddrOffset] = localAddrByte
  1369  	testRecv(t, fakeNet, localAddrByte, ep, buf)
  1370  	testSendTo(t, s, string(remoteAddr.AsSlice()), ep, nil)
  1371  
  1372  	// Remove the address, then check that send/receive doesn't work anymore.
  1373  	if err := s.RemoveAddress(1, localAddr); err != nil {
  1374  		t.Fatal("RemoveAddress failed:", err)
  1375  	}
  1376  	testFailingRecv(t, fakeNet, localAddrByte, ep, buf)
  1377  	testFailingSendTo(t, s, remoteAddr, nil, &tcpip.ErrHostUnreachable{})
  1378  
  1379  	// Check that removing the same address fails.
  1380  	err := s.RemoveAddress(1, localAddr)
  1381  	if _, ok := err.(*tcpip.ErrBadLocalAddress); !ok {
  1382  		t.Fatalf("RemoveAddress returned unexpected error, got = %v, want = %s", err, &tcpip.ErrBadLocalAddress{})
  1383  	}
  1384  }
  1385  
  1386  func TestAddressRemovalWithRouteHeld(t *testing.T) {
  1387  	const localAddrByte byte = 0x01
  1388  	localAddr := tcpip.AddrFromSlice([]byte{localAddrByte, 0, 0, 0})
  1389  	remoteAddr := tcpip.AddrFromSlice([]byte("\x02\x00\x00\x00"))
  1390  
  1391  	s := stack.New(stack.Options{
  1392  		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
  1393  	})
  1394  
  1395  	ep := channel.New(10, defaultMTU, "")
  1396  	if err := s.CreateNIC(1, ep); err != nil {
  1397  		t.Fatalf("CreateNIC failed: %v", err)
  1398  	}
  1399  	fakeNet := s.NetworkProtocolInstance(fakeNetNumber).(*fakeNetworkProtocol)
  1400  	buf := make([]byte, 30)
  1401  
  1402  	protocolAddr := tcpip.ProtocolAddress{
  1403  		Protocol: fakeNetNumber,
  1404  		AddressWithPrefix: tcpip.AddressWithPrefix{
  1405  			Address:   localAddr,
  1406  			PrefixLen: fakeDefaultPrefixLen,
  1407  		},
  1408  	}
  1409  	if err := s.AddProtocolAddress(1, protocolAddr, stack.AddressProperties{}); err != nil {
  1410  		t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", 1, protocolAddr, err)
  1411  	}
  1412  	{
  1413  		subnet, err := tcpip.NewSubnet(tcpip.AddrFromSlice([]byte("\x00\x00\x00\x00")), tcpip.MaskFrom("\x00\x00\x00\x00"))
  1414  		if err != nil {
  1415  			t.Fatal(err)
  1416  		}
  1417  		s.SetRouteTable([]tcpip.Route{{Destination: subnet, Gateway: tcpip.AddrFromSlice([]byte("\x00\x00\x00\x00")), NIC: 1}})
  1418  	}
  1419  
  1420  	r, err := s.FindRoute(0, tcpip.Address{}, remoteAddr, fakeNetNumber, false /* multicastLoop */)
  1421  	if err != nil {
  1422  		t.Fatal("FindRoute failed:", err)
  1423  	}
  1424  
  1425  	// Send and receive packets, and verify they are received.
  1426  	buf[dstAddrOffset] = localAddrByte
  1427  	testRecv(t, fakeNet, localAddrByte, ep, buf)
  1428  	testSend(t, r, ep, nil)
  1429  	testSendTo(t, s, string(remoteAddr.AsSlice()), ep, nil)
  1430  
  1431  	// Remove the address, then check that send/receive doesn't work anymore.
  1432  	if err := s.RemoveAddress(1, localAddr); err != nil {
  1433  		t.Fatal("RemoveAddress failed:", err)
  1434  	}
  1435  	testFailingRecv(t, fakeNet, localAddrByte, ep, buf)
  1436  	testFailingSend(t, r, nil, &tcpip.ErrInvalidEndpointState{})
  1437  	testFailingSendTo(t, s, remoteAddr, nil, &tcpip.ErrHostUnreachable{})
  1438  
  1439  	// Check that removing the same address fails.
  1440  	{
  1441  		err := s.RemoveAddress(1, localAddr)
  1442  		if _, ok := err.(*tcpip.ErrBadLocalAddress); !ok {
  1443  			t.Fatalf("RemoveAddress returned unexpected error, got = %v, want = %s", err, &tcpip.ErrBadLocalAddress{})
  1444  		}
  1445  	}
  1446  }
  1447  
  1448  func verifyAddress(t *testing.T, s *stack.Stack, nicID tcpip.NICID, addr tcpip.Address) {
  1449  	t.Helper()
  1450  	info, ok := s.NICInfo()[nicID]
  1451  	if !ok {
  1452  		t.Fatalf("NICInfo() failed to find nicID=%d", nicID)
  1453  	}
  1454  	if addr.Len() == 0 {
  1455  		// No address given, verify that there is no address assigned to the NIC.
  1456  		for _, a := range info.ProtocolAddresses {
  1457  			if a.Protocol == fakeNetNumber && a.AddressWithPrefix != (tcpip.AddressWithPrefix{}) {
  1458  				t.Errorf("verify no-address: got = %s, want = %s", a.AddressWithPrefix, tcpip.AddressWithPrefix{})
  1459  			}
  1460  		}
  1461  		return
  1462  	}
  1463  	// Address given, verify the address is assigned to the NIC and no other
  1464  	// address is.
  1465  	found := false
  1466  	for _, a := range info.ProtocolAddresses {
  1467  		if a.Protocol == fakeNetNumber {
  1468  			if a.AddressWithPrefix.Address == addr {
  1469  				found = true
  1470  			} else {
  1471  				t.Errorf("verify address: got = %s, want = %s", a.AddressWithPrefix.Address, addr)
  1472  			}
  1473  		}
  1474  	}
  1475  	if !found {
  1476  		t.Errorf("verify address: couldn't find %s on the NIC", addr)
  1477  	}
  1478  }
  1479  
  1480  func TestEndpointExpiration(t *testing.T) {
  1481  	const (
  1482  		localAddrByte byte        = 0x01
  1483  		nicID         tcpip.NICID = 1
  1484  	)
  1485  	var (
  1486  		noAddr     = tcpip.Address{}
  1487  		remoteAddr = tcpip.AddrFromSlice([]byte("\x03\x00\x00\x00"))
  1488  	)
  1489  	localAddr := tcpip.AddrFromSlice([]byte{localAddrByte, 0, 0, 0})
  1490  
  1491  	for _, promiscuous := range []bool{true, false} {
  1492  		for _, spoofing := range []bool{true, false} {
  1493  			t.Run(fmt.Sprintf("promiscuous=%t spoofing=%t", promiscuous, spoofing), func(t *testing.T) {
  1494  				s := stack.New(stack.Options{
  1495  					NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
  1496  				})
  1497  
  1498  				ep := channel.New(10, defaultMTU, "")
  1499  				if err := s.CreateNIC(nicID, ep); err != nil {
  1500  					t.Fatal("CreateNIC failed:", err)
  1501  				}
  1502  
  1503  				{
  1504  					subnet, err := tcpip.NewSubnet(tcpip.AddrFromSlice([]byte("\x00\x00\x00\x00")), tcpip.MaskFrom("\x00\x00\x00\x00"))
  1505  					if err != nil {
  1506  						t.Fatal(err)
  1507  					}
  1508  					s.SetRouteTable([]tcpip.Route{{Destination: subnet, Gateway: tcpip.AddrFromSlice([]byte("\x00\x00\x00\x00")), NIC: 1}})
  1509  				}
  1510  
  1511  				fakeNet := s.NetworkProtocolInstance(fakeNetNumber).(*fakeNetworkProtocol)
  1512  				buf := make([]byte, 30)
  1513  				buf[dstAddrOffset] = localAddrByte
  1514  
  1515  				if promiscuous {
  1516  					if err := s.SetPromiscuousMode(nicID, true); err != nil {
  1517  						t.Fatal("SetPromiscuousMode failed:", err)
  1518  					}
  1519  				}
  1520  
  1521  				if spoofing {
  1522  					if err := s.SetSpoofing(nicID, true); err != nil {
  1523  						t.Fatal("SetSpoofing failed:", err)
  1524  					}
  1525  				}
  1526  
  1527  				// 1. No Address yet, send should only work for spoofing, receive for
  1528  				// promiscuous mode.
  1529  				//-----------------------
  1530  				verifyAddress(t, s, nicID, noAddr)
  1531  				if promiscuous {
  1532  					testRecv(t, fakeNet, localAddrByte, ep, buf)
  1533  				} else {
  1534  					testFailingRecv(t, fakeNet, localAddrByte, ep, buf)
  1535  				}
  1536  				if spoofing {
  1537  					// FIXME(b/139841518):Spoofing doesn't work if there is no primary address.
  1538  					// testSendTo(t, s, remoteAddr, ep, nil)
  1539  				} else {
  1540  					testFailingSendTo(t, s, remoteAddr, nil, &tcpip.ErrHostUnreachable{})
  1541  				}
  1542  
  1543  				// 2. Add Address, everything should work.
  1544  				//-----------------------
  1545  				protocolAddr := tcpip.ProtocolAddress{
  1546  					Protocol: fakeNetNumber,
  1547  					AddressWithPrefix: tcpip.AddressWithPrefix{
  1548  						Address:   localAddr,
  1549  						PrefixLen: fakeDefaultPrefixLen,
  1550  					},
  1551  				}
  1552  				if err := s.AddProtocolAddress(nicID, protocolAddr, stack.AddressProperties{}); err != nil {
  1553  					t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", nicID, protocolAddr, err)
  1554  				}
  1555  				verifyAddress(t, s, nicID, localAddr)
  1556  				testRecv(t, fakeNet, localAddrByte, ep, buf)
  1557  				testSendTo(t, s, string(remoteAddr.AsSlice()), ep, nil)
  1558  
  1559  				// 3. Remove the address, send should only work for spoofing, receive
  1560  				// for promiscuous mode.
  1561  				//-----------------------
  1562  				if err := s.RemoveAddress(nicID, localAddr); err != nil {
  1563  					t.Fatal("RemoveAddress failed:", err)
  1564  				}
  1565  				verifyAddress(t, s, nicID, noAddr)
  1566  				if promiscuous {
  1567  					testRecv(t, fakeNet, localAddrByte, ep, buf)
  1568  				} else {
  1569  					testFailingRecv(t, fakeNet, localAddrByte, ep, buf)
  1570  				}
  1571  				if spoofing {
  1572  					// FIXME(b/139841518):Spoofing doesn't work if there is no primary address.
  1573  					// testSendTo(t, s, remoteAddr, ep, nil)
  1574  				} else {
  1575  					testFailingSendTo(t, s, remoteAddr, nil, &tcpip.ErrHostUnreachable{})
  1576  				}
  1577  
  1578  				// 4. Add Address back, everything should work again.
  1579  				//-----------------------
  1580  				if err := s.AddProtocolAddress(nicID, protocolAddr, stack.AddressProperties{}); err != nil {
  1581  					t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", nicID, protocolAddr, err)
  1582  				}
  1583  				verifyAddress(t, s, nicID, localAddr)
  1584  				testRecv(t, fakeNet, localAddrByte, ep, buf)
  1585  				testSendTo(t, s, string(remoteAddr.AsSlice()), ep, nil)
  1586  
  1587  				// 5. Take a reference to the endpoint by getting a route. Verify that
  1588  				// we can still send/receive, including sending using the route.
  1589  				//-----------------------
  1590  				r, err := s.FindRoute(0, tcpip.Address{}, remoteAddr, fakeNetNumber, false /* multicastLoop */)
  1591  				if err != nil {
  1592  					t.Fatal("FindRoute failed:", err)
  1593  				}
  1594  				testRecv(t, fakeNet, localAddrByte, ep, buf)
  1595  				testSendTo(t, s, string(remoteAddr.AsSlice()), ep, nil)
  1596  				testSend(t, r, ep, nil)
  1597  
  1598  				// 6. Remove the address. Send should only work for spoofing, receive
  1599  				// for promiscuous mode.
  1600  				//-----------------------
  1601  				if err := s.RemoveAddress(nicID, localAddr); err != nil {
  1602  					t.Fatal("RemoveAddress failed:", err)
  1603  				}
  1604  				verifyAddress(t, s, nicID, noAddr)
  1605  				if promiscuous {
  1606  					testRecv(t, fakeNet, localAddrByte, ep, buf)
  1607  				} else {
  1608  					testFailingRecv(t, fakeNet, localAddrByte, ep, buf)
  1609  				}
  1610  				if spoofing {
  1611  					testSend(t, r, ep, nil)
  1612  					testSendTo(t, s, string(remoteAddr.AsSlice()), ep, nil)
  1613  				} else {
  1614  					testFailingSend(t, r, nil, &tcpip.ErrInvalidEndpointState{})
  1615  					testFailingSendTo(t, s, remoteAddr, nil, &tcpip.ErrHostUnreachable{})
  1616  				}
  1617  
  1618  				// 7. Add Address back, everything should work again.
  1619  				//-----------------------
  1620  				if err := s.AddProtocolAddress(nicID, protocolAddr, stack.AddressProperties{}); err != nil {
  1621  					t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", nicID, protocolAddr, err)
  1622  				}
  1623  				verifyAddress(t, s, nicID, localAddr)
  1624  				testRecv(t, fakeNet, localAddrByte, ep, buf)
  1625  				testSendTo(t, s, string(remoteAddr.AsSlice()), ep, nil)
  1626  				testSend(t, r, ep, nil)
  1627  
  1628  				// 8. Remove the route, sendTo/recv should still work.
  1629  				//-----------------------
  1630  				r.Release()
  1631  				verifyAddress(t, s, nicID, localAddr)
  1632  				testRecv(t, fakeNet, localAddrByte, ep, buf)
  1633  				testSendTo(t, s, string(remoteAddr.AsSlice()), ep, nil)
  1634  
  1635  				// 9. Remove the address. Send should only work for spoofing, receive
  1636  				// for promiscuous mode.
  1637  				//-----------------------
  1638  				if err := s.RemoveAddress(nicID, localAddr); err != nil {
  1639  					t.Fatal("RemoveAddress failed:", err)
  1640  				}
  1641  				verifyAddress(t, s, nicID, noAddr)
  1642  				if promiscuous {
  1643  					testRecv(t, fakeNet, localAddrByte, ep, buf)
  1644  				} else {
  1645  					testFailingRecv(t, fakeNet, localAddrByte, ep, buf)
  1646  				}
  1647  				if spoofing {
  1648  					// FIXME(b/139841518):Spoofing doesn't work if there is no primary address.
  1649  					// testSendTo(t, s, remoteAddr, ep, nil)
  1650  				} else {
  1651  					testFailingSendTo(t, s, remoteAddr, nil, &tcpip.ErrHostUnreachable{})
  1652  				}
  1653  			})
  1654  		}
  1655  	}
  1656  }
  1657  
  1658  func TestPromiscuousMode(t *testing.T) {
  1659  	s := stack.New(stack.Options{
  1660  		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
  1661  	})
  1662  
  1663  	ep := channel.New(10, defaultMTU, "")
  1664  	if err := s.CreateNIC(1, ep); err != nil {
  1665  		t.Fatal("CreateNIC failed:", err)
  1666  	}
  1667  
  1668  	{
  1669  		subnet, err := tcpip.NewSubnet(tcpip.AddrFromSlice([]byte("\x00\x00\x00\x00")), tcpip.MaskFrom("\x00\x00\x00\x00"))
  1670  		if err != nil {
  1671  			t.Fatal(err)
  1672  		}
  1673  		s.SetRouteTable([]tcpip.Route{{Destination: subnet, Gateway: tcpip.AddrFromSlice([]byte("\x00\x00\x00\x00")), NIC: 1}})
  1674  	}
  1675  
  1676  	fakeNet := s.NetworkProtocolInstance(fakeNetNumber).(*fakeNetworkProtocol)
  1677  
  1678  	buf := make([]byte, 30)
  1679  
  1680  	// Write a packet, and check that it doesn't get delivered as we don't
  1681  	// have a matching endpoint.
  1682  	const localAddrByte byte = 0x01
  1683  	buf[dstAddrOffset] = localAddrByte
  1684  	testFailingRecv(t, fakeNet, localAddrByte, ep, buf)
  1685  
  1686  	// Set promiscuous mode, then check that packet is delivered.
  1687  	if err := s.SetPromiscuousMode(1, true); err != nil {
  1688  		t.Fatal("SetPromiscuousMode failed:", err)
  1689  	}
  1690  	testRecv(t, fakeNet, localAddrByte, ep, buf)
  1691  
  1692  	// Check that we can't get a route as there is no local address.
  1693  	_, err := s.FindRoute(0, tcpip.Address{}, tcpip.AddrFromSlice([]byte("\x02\x00\x00\x00")), fakeNetNumber, false /* multicastLoop */)
  1694  	if _, ok := err.(*tcpip.ErrHostUnreachable); !ok {
  1695  		t.Fatalf("FindRoute returned unexpected error: got = %v, want = %s", err, &tcpip.ErrHostUnreachable{})
  1696  	}
  1697  
  1698  	// Set promiscuous mode to false, then check that packet can't be
  1699  	// delivered anymore.
  1700  	if err := s.SetPromiscuousMode(1, false); err != nil {
  1701  		t.Fatal("SetPromiscuousMode failed:", err)
  1702  	}
  1703  	testFailingRecv(t, fakeNet, localAddrByte, ep, buf)
  1704  }
  1705  
  1706  // TestExternalSendWithHandleLocal tests that the stack creates a non-local
  1707  // route when spoofing or promiscuous mode are enabled.
  1708  //
  1709  // This test makes sure that packets are transmitted from the stack.
  1710  func TestExternalSendWithHandleLocal(t *testing.T) {
  1711  	const (
  1712  		unspecifiedNICID = 0
  1713  		nicID            = 1
  1714  	)
  1715  	var (
  1716  		localAddr = tcpip.AddrFromSlice([]byte("\x01\x00\x00\x00"))
  1717  		dstAddr   = tcpip.AddrFromSlice([]byte("\x03\x00\x00\x00"))
  1718  	)
  1719  
  1720  	subnet, err := tcpip.NewSubnet(tcpip.AddrFromSlice([]byte("\x00\x00\x00\x00")), tcpip.MaskFrom("\x00\x00\x00\x00"))
  1721  	if err != nil {
  1722  		t.Fatal(err)
  1723  	}
  1724  
  1725  	tests := []struct {
  1726  		name           string
  1727  		configureStack func(*testing.T, *stack.Stack)
  1728  	}{
  1729  		{
  1730  			name:           "Default",
  1731  			configureStack: func(*testing.T, *stack.Stack) {},
  1732  		},
  1733  		{
  1734  			name: "Spoofing",
  1735  			configureStack: func(t *testing.T, s *stack.Stack) {
  1736  				if err := s.SetSpoofing(nicID, true); err != nil {
  1737  					t.Fatalf("s.SetSpoofing(%d, true): %s", nicID, err)
  1738  				}
  1739  			},
  1740  		},
  1741  		{
  1742  			name: "Promiscuous",
  1743  			configureStack: func(t *testing.T, s *stack.Stack) {
  1744  				if err := s.SetPromiscuousMode(nicID, true); err != nil {
  1745  					t.Fatalf("s.SetPromiscuousMode(%d, true): %s", nicID, err)
  1746  				}
  1747  			},
  1748  		},
  1749  	}
  1750  
  1751  	for _, test := range tests {
  1752  		t.Run(test.name, func(t *testing.T) {
  1753  			for _, handleLocal := range []bool{true, false} {
  1754  				t.Run(fmt.Sprintf("HandleLocal=%t", handleLocal), func(t *testing.T) {
  1755  					s := stack.New(stack.Options{
  1756  						NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
  1757  						HandleLocal:      handleLocal,
  1758  					})
  1759  
  1760  					ep := channel.New(1, defaultMTU, "")
  1761  					if err := s.CreateNIC(nicID, ep); err != nil {
  1762  						t.Fatalf("s.CreateNIC(%d, _): %s", nicID, err)
  1763  					}
  1764  					protocolAddr := tcpip.ProtocolAddress{
  1765  						Protocol: fakeNetNumber,
  1766  						AddressWithPrefix: tcpip.AddressWithPrefix{
  1767  							Address:   localAddr,
  1768  							PrefixLen: fakeDefaultPrefixLen,
  1769  						},
  1770  					}
  1771  					if err := s.AddProtocolAddress(nicID, protocolAddr, stack.AddressProperties{}); err != nil {
  1772  						t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", nicID, protocolAddr, err)
  1773  					}
  1774  
  1775  					s.SetRouteTable([]tcpip.Route{{Destination: subnet, NIC: nicID}})
  1776  
  1777  					test.configureStack(t, s)
  1778  
  1779  					r, err := s.FindRoute(unspecifiedNICID, localAddr, dstAddr, fakeNetNumber, false /* multicastLoop */)
  1780  					if err != nil {
  1781  						t.Fatalf("s.FindRoute(%d, %s, %s, %d, false): %s", unspecifiedNICID, localAddr, dstAddr, fakeNetNumber, err)
  1782  					}
  1783  					defer r.Release()
  1784  
  1785  					if r.LocalAddress() != localAddr {
  1786  						t.Errorf("got r.LocalAddress() = %s, want = %s", r.LocalAddress(), localAddr)
  1787  					}
  1788  					if r.RemoteAddress() != dstAddr {
  1789  						t.Errorf("got r.RemoteAddress() = %s, want = %s", r.RemoteAddress(), dstAddr)
  1790  					}
  1791  
  1792  					if n := ep.Drain(); n != 0 {
  1793  						t.Fatalf("got ep.Drain() = %d, want = 0", n)
  1794  					}
  1795  					if err := r.WritePacket(stack.NetworkHeaderParams{
  1796  						Protocol: fakeTransNumber,
  1797  						TTL:      123,
  1798  						TOS:      stack.DefaultTOS,
  1799  					}, stack.NewPacketBuffer(stack.PacketBufferOptions{
  1800  						ReserveHeaderBytes: int(r.MaxHeaderLength()),
  1801  						Payload:            buffer.MakeWithData(make([]byte, 10)),
  1802  					})); err != nil {
  1803  						t.Fatalf("r.WritePacket(nil, _, _): %s", err)
  1804  					}
  1805  					if n := ep.Drain(); n != 1 {
  1806  						t.Fatalf("got ep.Drain() = %d, want = 1", n)
  1807  					}
  1808  				})
  1809  			}
  1810  		})
  1811  	}
  1812  }
  1813  
  1814  func TestSpoofingWithAddress(t *testing.T) {
  1815  	localAddr := tcpip.AddrFromSlice([]byte("\x01\x00\x00\x00"))
  1816  	nonExistentLocalAddr := tcpip.AddrFromSlice([]byte("\x02\x00\x00\x00"))
  1817  	dstAddr := tcpip.AddrFromSlice([]byte("\x03\x00\x00\x00"))
  1818  
  1819  	s := stack.New(stack.Options{
  1820  		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
  1821  	})
  1822  
  1823  	ep := channel.New(10, defaultMTU, "")
  1824  	if err := s.CreateNIC(1, ep); err != nil {
  1825  		t.Fatal("CreateNIC failed:", err)
  1826  	}
  1827  
  1828  	protocolAddr := tcpip.ProtocolAddress{
  1829  		Protocol: fakeNetNumber,
  1830  		AddressWithPrefix: tcpip.AddressWithPrefix{
  1831  			Address:   localAddr,
  1832  			PrefixLen: fakeDefaultPrefixLen,
  1833  		},
  1834  	}
  1835  	if err := s.AddProtocolAddress(1, protocolAddr, stack.AddressProperties{}); err != nil {
  1836  		t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", 1, protocolAddr, err)
  1837  	}
  1838  
  1839  	{
  1840  		subnet, err := tcpip.NewSubnet(tcpip.AddrFromSlice([]byte("\x00\x00\x00\x00")), tcpip.MaskFrom("\x00\x00\x00\x00"))
  1841  		if err != nil {
  1842  			t.Fatal(err)
  1843  		}
  1844  		s.SetRouteTable([]tcpip.Route{{Destination: subnet, Gateway: tcpip.AddrFromSlice([]byte("\x00\x00\x00\x00")), NIC: 1}})
  1845  	}
  1846  
  1847  	// With address spoofing disabled, FindRoute does not permit an address
  1848  	// that was not added to the NIC to be used as the source.
  1849  	r, err := s.FindRoute(0, nonExistentLocalAddr, dstAddr, fakeNetNumber, false /* multicastLoop */)
  1850  	if err == nil {
  1851  		t.Errorf("FindRoute succeeded with route %+v when it should have failed", r)
  1852  	}
  1853  
  1854  	// With address spoofing enabled, FindRoute permits any address to be used
  1855  	// as the source.
  1856  	if err := s.SetSpoofing(1, true); err != nil {
  1857  		t.Fatal("SetSpoofing failed:", err)
  1858  	}
  1859  	r, err = s.FindRoute(0, nonExistentLocalAddr, dstAddr, fakeNetNumber, false /* multicastLoop */)
  1860  	if err != nil {
  1861  		t.Fatal("FindRoute failed:", err)
  1862  	}
  1863  	if r.LocalAddress() != nonExistentLocalAddr {
  1864  		t.Errorf("got Route.LocalAddress() = %s, want = %s", r.LocalAddress(), nonExistentLocalAddr)
  1865  	}
  1866  	if r.RemoteAddress() != dstAddr {
  1867  		t.Errorf("got Route.RemoteAddress() = %s, want = %s", r.RemoteAddress(), dstAddr)
  1868  	}
  1869  	// Sending a packet works.
  1870  	testSendTo(t, s, string(dstAddr.AsSlice()), ep, nil)
  1871  	testSend(t, r, ep, nil)
  1872  
  1873  	// FindRoute should also work with a local address that exists on the NIC.
  1874  	r, err = s.FindRoute(0, localAddr, dstAddr, fakeNetNumber, false /* multicastLoop */)
  1875  	if err != nil {
  1876  		t.Fatal("FindRoute failed:", err)
  1877  	}
  1878  	if r.LocalAddress() != localAddr {
  1879  		t.Errorf("got Route.LocalAddress() = %s, want = %s", r.LocalAddress(), nonExistentLocalAddr)
  1880  	}
  1881  	if r.RemoteAddress() != dstAddr {
  1882  		t.Errorf("got Route.RemoteAddress() = %s, want = %s", r.RemoteAddress(), dstAddr)
  1883  	}
  1884  	// Sending a packet using the route works.
  1885  	testSend(t, r, ep, nil)
  1886  }
  1887  
  1888  func TestSpoofingNoAddress(t *testing.T) {
  1889  	nonExistentLocalAddr := tcpip.AddrFromSlice([]byte("\x01\x00\x00\x00"))
  1890  	dstAddr := tcpip.AddrFromSlice([]byte("\x02\x00\x00\x00"))
  1891  
  1892  	s := stack.New(stack.Options{
  1893  		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
  1894  	})
  1895  
  1896  	ep := channel.New(10, defaultMTU, "")
  1897  	if err := s.CreateNIC(1, ep); err != nil {
  1898  		t.Fatal("CreateNIC failed:", err)
  1899  	}
  1900  
  1901  	{
  1902  		subnet, err := tcpip.NewSubnet(tcpip.AddrFromSlice([]byte("\x00\x00\x00\x00")), tcpip.MaskFrom("\x00\x00\x00\x00"))
  1903  		if err != nil {
  1904  			t.Fatal(err)
  1905  		}
  1906  		s.SetRouteTable([]tcpip.Route{{Destination: subnet, Gateway: tcpip.AddrFromSlice([]byte("\x00\x00\x00\x00")), NIC: 1}})
  1907  	}
  1908  
  1909  	// With address spoofing disabled, FindRoute does not permit an address
  1910  	// that was not added to the NIC to be used as the source.
  1911  	r, err := s.FindRoute(0, nonExistentLocalAddr, dstAddr, fakeNetNumber, false /* multicastLoop */)
  1912  	if err == nil {
  1913  		t.Errorf("FindRoute succeeded with route %+v when it should have failed", r)
  1914  	}
  1915  	// Sending a packet fails.
  1916  	testFailingSendTo(t, s, dstAddr, nil, &tcpip.ErrHostUnreachable{})
  1917  
  1918  	// With address spoofing enabled, FindRoute permits any address to be used
  1919  	// as the source.
  1920  	if err := s.SetSpoofing(1, true); err != nil {
  1921  		t.Fatal("SetSpoofing failed:", err)
  1922  	}
  1923  	r, err = s.FindRoute(0, nonExistentLocalAddr, dstAddr, fakeNetNumber, false /* multicastLoop */)
  1924  	if err != nil {
  1925  		t.Fatal("FindRoute failed:", err)
  1926  	}
  1927  	if r.LocalAddress() != nonExistentLocalAddr {
  1928  		t.Errorf("got Route.LocalAddress() = %s, want = %s", r.LocalAddress(), nonExistentLocalAddr)
  1929  	}
  1930  	if r.RemoteAddress() != dstAddr {
  1931  		t.Errorf("got Route.RemoteAddress() = %s, want = %s", r.RemoteAddress(), dstAddr)
  1932  	}
  1933  	// Sending a packet works.
  1934  	// FIXME(b/139841518):Spoofing doesn't work if there is no primary address.
  1935  	// testSendTo(t, s, remoteAddr, ep, nil)
  1936  }
  1937  
  1938  func TestOutgoingBroadcastWithEmptyRouteTable(t *testing.T) {
  1939  	s := stack.New(stack.Options{
  1940  		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
  1941  	})
  1942  
  1943  	ep := channel.New(10, defaultMTU, "")
  1944  	if err := s.CreateNIC(1, ep); err != nil {
  1945  		t.Fatal("CreateNIC failed:", err)
  1946  	}
  1947  	s.SetRouteTable([]tcpip.Route{})
  1948  
  1949  	// If there is no endpoint, it won't work.
  1950  	{
  1951  		_, err := s.FindRoute(1, header.IPv4Any, header.IPv4Broadcast, fakeNetNumber, false /* multicastLoop */)
  1952  		if _, ok := err.(*tcpip.ErrNetworkUnreachable); !ok {
  1953  			t.Fatalf("got FindRoute(1, %s, %s, %d) = %s, want = %s", header.IPv4Any, header.IPv4Broadcast, fakeNetNumber, err, &tcpip.ErrNetworkUnreachable{})
  1954  		}
  1955  	}
  1956  
  1957  	protoAddr := tcpip.ProtocolAddress{Protocol: fakeNetNumber, AddressWithPrefix: tcpip.AddressWithPrefix{Address: header.IPv4Any}}
  1958  	if err := s.AddProtocolAddress(1, protoAddr, stack.AddressProperties{}); err != nil {
  1959  		t.Fatalf("AddProtocolAddress(1, %+v, {}) failed: %s", protoAddr, err)
  1960  	}
  1961  	r, err := s.FindRoute(1, header.IPv4Any, header.IPv4Broadcast, fakeNetNumber, false /* multicastLoop */)
  1962  	if err != nil {
  1963  		t.Fatalf("FindRoute(1, %v, %v, %d) failed: %v", header.IPv4Any, header.IPv4Broadcast, fakeNetNumber, err)
  1964  	}
  1965  	if r.LocalAddress() != header.IPv4Any {
  1966  		t.Errorf("got Route.LocalAddress() = %s, want = %s", r.LocalAddress(), header.IPv4Any)
  1967  	}
  1968  
  1969  	if r.RemoteAddress() != header.IPv4Broadcast {
  1970  		t.Errorf("got Route.RemoteAddress() = %s, want = %s", r.RemoteAddress(), header.IPv4Broadcast)
  1971  	}
  1972  
  1973  	// If the NIC doesn't exist, it won't work.
  1974  	{
  1975  		_, err := s.FindRoute(2, header.IPv4Any, header.IPv4Broadcast, fakeNetNumber, false /* multicastLoop */)
  1976  		if _, ok := err.(*tcpip.ErrNetworkUnreachable); !ok {
  1977  			t.Fatalf("got FindRoute(2, %v, %v, %d) = %v want = %v", header.IPv4Any, header.IPv4Broadcast, fakeNetNumber, err, &tcpip.ErrNetworkUnreachable{})
  1978  		}
  1979  	}
  1980  }
  1981  
  1982  func TestOutgoingBroadcastWithRouteTable(t *testing.T) {
  1983  	defaultAddr := tcpip.AddressWithPrefix{Address: header.IPv4Any}
  1984  	// Local subnet on NIC1: 192.168.1.58/24, gateway 192.168.1.1.
  1985  	nic1Addr := tcpip.AddressWithPrefix{Address: tcpip.AddrFromSlice([]byte("\xc0\xa8\x01\x3a")), PrefixLen: 24}
  1986  	nic1Gateway := testutil.MustParse4("192.168.1.1")
  1987  	// Local subnet on NIC2: 10.10.10.5/24, gateway 10.10.10.1.
  1988  	nic2Addr := tcpip.AddressWithPrefix{Address: tcpip.AddrFromSlice([]byte("\x0a\x0a\x0a\x05")), PrefixLen: 24}
  1989  	nic2Gateway := testutil.MustParse4("10.10.10.1")
  1990  
  1991  	// Create a new stack with two NICs.
  1992  	s := stack.New(stack.Options{
  1993  		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
  1994  	})
  1995  	ep := channel.New(10, defaultMTU, "")
  1996  	if err := s.CreateNIC(1, ep); err != nil {
  1997  		t.Fatalf("CreateNIC failed: %s", err)
  1998  	}
  1999  	if err := s.CreateNIC(2, ep); err != nil {
  2000  		t.Fatalf("CreateNIC failed: %s", err)
  2001  	}
  2002  	nic1ProtoAddr := tcpip.ProtocolAddress{Protocol: fakeNetNumber, AddressWithPrefix: nic1Addr}
  2003  	if err := s.AddProtocolAddress(1, nic1ProtoAddr, stack.AddressProperties{}); err != nil {
  2004  		t.Fatalf("AddProtocolAddress(1, %+v, {}) failed: %s", nic1ProtoAddr, err)
  2005  	}
  2006  
  2007  	nic2ProtoAddr := tcpip.ProtocolAddress{Protocol: fakeNetNumber, AddressWithPrefix: nic2Addr}
  2008  	if err := s.AddProtocolAddress(2, nic2ProtoAddr, stack.AddressProperties{}); err != nil {
  2009  		t.Fatalf("AddProtocolAddress(2, %+v, {}) failed: %s", nic2ProtoAddr, err)
  2010  	}
  2011  
  2012  	// Set the initial route table.
  2013  	rt := []tcpip.Route{
  2014  		{Destination: nic1Addr.Subnet(), NIC: 1},
  2015  		{Destination: nic2Addr.Subnet(), NIC: 2},
  2016  		{Destination: defaultAddr.Subnet(), Gateway: nic2Gateway, NIC: 2},
  2017  		{Destination: defaultAddr.Subnet(), Gateway: nic1Gateway, NIC: 1},
  2018  	}
  2019  	s.SetRouteTable(rt)
  2020  
  2021  	// When an interface is given, the route for a broadcast goes through it.
  2022  	r, err := s.FindRoute(1, nic1Addr.Address, header.IPv4Broadcast, fakeNetNumber, false /* multicastLoop */)
  2023  	if err != nil {
  2024  		t.Fatalf("FindRoute(1, %v, %v, %d) failed: %v", nic1Addr.Address, header.IPv4Broadcast, fakeNetNumber, err)
  2025  	}
  2026  	if r.LocalAddress() != nic1Addr.Address {
  2027  		t.Errorf("got Route.LocalAddress() = %s, want = %s", r.LocalAddress(), nic1Addr.Address)
  2028  	}
  2029  
  2030  	if r.RemoteAddress() != header.IPv4Broadcast {
  2031  		t.Errorf("got Route.RemoteAddress() = %s, want = %s", r.RemoteAddress(), header.IPv4Broadcast)
  2032  	}
  2033  
  2034  	// When an interface is not given, it consults the route table.
  2035  	// 1. Case: Using the default route.
  2036  	r, err = s.FindRoute(0, tcpip.Address{}, header.IPv4Broadcast, fakeNetNumber, false /* multicastLoop */)
  2037  	if err != nil {
  2038  		t.Fatalf("FindRoute(0, \"\", %s, %d) failed: %s", header.IPv4Broadcast, fakeNetNumber, err)
  2039  	}
  2040  	if r.LocalAddress() != nic2Addr.Address {
  2041  		t.Errorf("got Route.LocalAddress() = %s, want = %s", r.LocalAddress(), nic2Addr.Address)
  2042  	}
  2043  
  2044  	if r.RemoteAddress() != header.IPv4Broadcast {
  2045  		t.Errorf("got Route.RemoteAddress() = %s, want = %s", r.RemoteAddress(), header.IPv4Broadcast)
  2046  	}
  2047  
  2048  	// 2. Case: Having an explicit route for broadcast will select that one.
  2049  	rt = append(
  2050  		[]tcpip.Route{
  2051  			{Destination: header.IPv4Broadcast.WithPrefix().Subnet(), NIC: 1},
  2052  		},
  2053  		rt...,
  2054  	)
  2055  	s.SetRouteTable(rt)
  2056  	r, err = s.FindRoute(0, tcpip.Address{}, header.IPv4Broadcast, fakeNetNumber, false /* multicastLoop */)
  2057  	if err != nil {
  2058  		t.Fatalf("FindRoute(0, \"\", %s, %d) failed: %s", header.IPv4Broadcast, fakeNetNumber, err)
  2059  	}
  2060  	if r.LocalAddress() != nic1Addr.Address {
  2061  		t.Errorf("got Route.LocalAddress() = %s, want = %s", r.LocalAddress(), nic1Addr.Address)
  2062  	}
  2063  
  2064  	if r.RemoteAddress() != header.IPv4Broadcast {
  2065  		t.Errorf("got Route.RemoteAddress() = %s, want = %s", r.RemoteAddress(), header.IPv4Broadcast)
  2066  	}
  2067  }
  2068  
  2069  func TestMulticastOrIPv6LinkLocalNeedsNoRoute(t *testing.T) {
  2070  	for _, tc := range []struct {
  2071  		name        string
  2072  		routeNeeded bool
  2073  		address     string
  2074  	}{
  2075  		// IPv4 multicast address range: 224.0.0.0 - 239.255.255.255
  2076  		//                <=>  0xe0.0x00.0x00.0x00 - 0xef.0xff.0xff.0xff
  2077  		{"IPv4 Multicast 1", false, "\xe0\x00\x00\x00"},
  2078  		{"IPv4 Multicast 2", false, "\xef\xff\xff\xff"},
  2079  		{"IPv4 Unicast 1", true, "\xdf\xff\xff\xff"},
  2080  		{"IPv4 Unicast 2", true, "\xf0\x00\x00\x00"},
  2081  		{"IPv4 Unicast 3", true, "\x00\x00\x00\x00"},
  2082  
  2083  		// IPv6 multicast address is 0xff[8] + flags[4] + scope[4] + groupId[112]
  2084  		{"IPv6 Multicast 1", false, "\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
  2085  		{"IPv6 Multicast 2", false, "\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
  2086  		{"IPv6 Multicast 3", false, "\xff\x0f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"},
  2087  
  2088  		// IPv6 link-local address starts with fe80::/10.
  2089  		{"IPv6 Unicast Link-Local 1", false, "\xfe\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
  2090  		{"IPv6 Unicast Link-Local 2", false, "\xfe\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"},
  2091  		{"IPv6 Unicast Link-Local 3", false, "\xfe\x80\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff"},
  2092  		{"IPv6 Unicast Link-Local 4", false, "\xfe\xbf\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
  2093  		{"IPv6 Unicast Link-Local 5", false, "\xfe\xbf\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"},
  2094  
  2095  		// IPv6 addresses that are neither multicast nor link-local.
  2096  		{"IPv6 Unicast Not Link-Local 1", true, "\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
  2097  		{"IPv6 Unicast Not Link-Local 2", true, "\xf0\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"},
  2098  		{"IPv6 Unicast Not Link-local 3", true, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
  2099  		{"IPv6 Unicast Not Link-Local 4", true, "\xfe\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
  2100  		{"IPv6 Unicast Not Link-Local 5", true, "\xfe\xdf\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
  2101  		{"IPv6 Unicast Not Link-Local 6", true, "\xfd\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
  2102  		{"IPv6 Unicast Not Link-Local 7", true, "\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
  2103  	} {
  2104  		t.Run(tc.name, func(t *testing.T) {
  2105  			s := stack.New(stack.Options{
  2106  				NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
  2107  			})
  2108  
  2109  			ep := channel.New(10, defaultMTU, "")
  2110  			if err := s.CreateNIC(1, ep); err != nil {
  2111  				t.Fatal("CreateNIC failed:", err)
  2112  			}
  2113  
  2114  			s.SetRouteTable([]tcpip.Route{})
  2115  
  2116  			var anyAddr tcpip.Address
  2117  			if len(tc.address) == header.IPv4AddressSize {
  2118  				anyAddr = header.IPv4Any
  2119  			} else {
  2120  				anyAddr = header.IPv6Any
  2121  			}
  2122  
  2123  			var want tcpip.Error = &tcpip.ErrNetworkUnreachable{}
  2124  			if tc.routeNeeded {
  2125  				want = &tcpip.ErrHostUnreachable{}
  2126  			}
  2127  
  2128  			// If there is no endpoint, it won't work.
  2129  			address := tcpip.AddrFromSlice([]byte(tc.address))
  2130  			if _, err := s.FindRoute(1, anyAddr, address, fakeNetNumber, false /* multicastLoop */); err != want {
  2131  				t.Fatalf("got FindRoute(1, %v, %v, %v) = %v, want = %v", anyAddr, address, fakeNetNumber, err, want)
  2132  			}
  2133  
  2134  			protocolAddr := tcpip.ProtocolAddress{
  2135  				Protocol: fakeNetNumber,
  2136  				AddressWithPrefix: tcpip.AddressWithPrefix{
  2137  					Address:   anyAddr,
  2138  					PrefixLen: fakeDefaultPrefixLen,
  2139  				},
  2140  			}
  2141  			if err := s.AddProtocolAddress(1, protocolAddr, stack.AddressProperties{}); err != nil {
  2142  				t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", 1, protocolAddr, err)
  2143  			}
  2144  
  2145  			if r, err := s.FindRoute(1, anyAddr, address, fakeNetNumber, false /* multicastLoop */); tc.routeNeeded {
  2146  				// Route table is empty but we need a route, this should cause an error.
  2147  				if _, ok := err.(*tcpip.ErrHostUnreachable); !ok {
  2148  					t.Fatalf("got FindRoute(1, %v, %v, %v) = %v, want = %v", anyAddr, address, fakeNetNumber, err, &tcpip.ErrHostUnreachable{})
  2149  				}
  2150  			} else {
  2151  				if err != nil {
  2152  					t.Fatalf("FindRoute(1, %v, %v, %v) failed: %v", anyAddr, address, fakeNetNumber, err)
  2153  				}
  2154  				if r.LocalAddress() != anyAddr {
  2155  					t.Errorf("Bad local address: got %v, want = %v", r.LocalAddress(), anyAddr)
  2156  				}
  2157  				if r.RemoteAddress() != address {
  2158  					t.Errorf("Bad remote address: got %v, want = %v", r.RemoteAddress(), address)
  2159  				}
  2160  			}
  2161  			// If the NIC doesn't exist, it won't work.
  2162  			if _, err := s.FindRoute(2, anyAddr, address, fakeNetNumber, false /* multicastLoop */); err != want {
  2163  				t.Fatalf("got FindRoute(2, %v, %v, %v) = %v want = %v", anyAddr, address, fakeNetNumber, err, want)
  2164  			}
  2165  		})
  2166  	}
  2167  }
  2168  
  2169  func TestNetworkOption(t *testing.T) {
  2170  	s := stack.New(stack.Options{
  2171  		NetworkProtocols:   []stack.NetworkProtocolFactory{fakeNetFactory},
  2172  		TransportProtocols: []stack.TransportProtocolFactory{},
  2173  	})
  2174  
  2175  	opt := tcpip.DefaultTTLOption(5)
  2176  	if err := s.SetNetworkProtocolOption(fakeNetNumber, &opt); err != nil {
  2177  		t.Fatalf("s.SetNetworkProtocolOption(%d, &%T(%d)): %s", fakeNetNumber, opt, opt, err)
  2178  	}
  2179  
  2180  	var optGot tcpip.DefaultTTLOption
  2181  	if err := s.NetworkProtocolOption(fakeNetNumber, &optGot); err != nil {
  2182  		t.Fatalf("s.NetworkProtocolOption(%d, &%T): %s", fakeNetNumber, optGot, err)
  2183  	}
  2184  
  2185  	if opt != optGot {
  2186  		t.Errorf("got optGot = %d, want = %d", optGot, opt)
  2187  	}
  2188  }
  2189  
  2190  func TestGetMainNICAddressAddPrimaryNonPrimary(t *testing.T) {
  2191  	const nicID = 1
  2192  
  2193  	for _, addrLen := range []int{4, 16} {
  2194  		t.Run(fmt.Sprintf("addrLen=%d", addrLen), func(t *testing.T) {
  2195  			for canBe := 0; canBe < 3; canBe++ {
  2196  				t.Run(fmt.Sprintf("canBe=%d", canBe), func(t *testing.T) {
  2197  					for never := 0; never < 3; never++ {
  2198  						t.Run(fmt.Sprintf("never=%d", never), func(t *testing.T) {
  2199  							s := stack.New(stack.Options{
  2200  								NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
  2201  							})
  2202  							ep := channel.New(10, defaultMTU, "")
  2203  							if err := s.CreateNIC(nicID, ep); err != nil {
  2204  								t.Fatalf("CreateNIC(%d, _): %s", nicID, err)
  2205  							}
  2206  							// Insert <canBe> primary and <never> never-primary addresses.
  2207  							// Each one will add a network endpoint to the NIC.
  2208  							primaryAddrAdded := make(map[tcpip.AddressWithPrefix]struct{})
  2209  							for i := 0; i < canBe+never; i++ {
  2210  								var behavior stack.PrimaryEndpointBehavior
  2211  								if i < canBe {
  2212  									behavior = stack.CanBePrimaryEndpoint
  2213  								} else {
  2214  									behavior = stack.NeverPrimaryEndpoint
  2215  								}
  2216  								// Add an address and in case of a primary one include a
  2217  								// prefixLen.
  2218  								address := tcpip.AddrFromSlice(bytes.Repeat([]byte{byte(i)}, addrLen))
  2219  								properties := stack.AddressProperties{PEB: behavior}
  2220  								if behavior == stack.CanBePrimaryEndpoint {
  2221  									protocolAddress := tcpip.ProtocolAddress{
  2222  										Protocol:          fakeNetNumber,
  2223  										AddressWithPrefix: address.WithPrefix(),
  2224  									}
  2225  									if err := s.AddProtocolAddress(nicID, protocolAddress, properties); err != nil {
  2226  										t.Fatalf("AddProtocolAddress(%d, %+v, %+v): %s", nicID, protocolAddress, properties, err)
  2227  									}
  2228  									// Remember the address/prefix.
  2229  									primaryAddrAdded[protocolAddress.AddressWithPrefix] = struct{}{}
  2230  								} else {
  2231  									protocolAddress := tcpip.ProtocolAddress{
  2232  										Protocol: fakeNetNumber,
  2233  										AddressWithPrefix: tcpip.AddressWithPrefix{
  2234  											Address:   address,
  2235  											PrefixLen: fakeDefaultPrefixLen,
  2236  										},
  2237  									}
  2238  									if err := s.AddProtocolAddress(nicID, protocolAddress, properties); err != nil {
  2239  										t.Fatalf("AddProtocolAddress(%d, %+v, %+v): %s", nicID, protocolAddress, properties, err)
  2240  									}
  2241  								}
  2242  							}
  2243  							// Check that GetMainNICAddress returns an address if at least
  2244  							// one primary address was added. In that case make sure the
  2245  							// address/prefixLen matches what we added.
  2246  							gotAddr, err := s.GetMainNICAddress(nicID, fakeNetNumber)
  2247  							if err != nil {
  2248  								t.Fatalf("GetMainNICAddress(%d, %d): %s", nicID, fakeNetNumber, err)
  2249  							}
  2250  							if len(primaryAddrAdded) == 0 {
  2251  								// No primary addresses present.
  2252  								if wantAddr := (tcpip.AddressWithPrefix{}); gotAddr != wantAddr {
  2253  									t.Fatalf("got GetMainNICAddress(%d, %d) = %s, want = %s", nicID, fakeNetNumber, gotAddr, wantAddr)
  2254  								}
  2255  							} else {
  2256  								// At least one primary address was added, verify the returned
  2257  								// address is in the list of primary addresses we added.
  2258  								if _, ok := primaryAddrAdded[gotAddr]; !ok {
  2259  									t.Fatalf("got GetMainNICAddress(%d, %d) = %s, want = %s", nicID, fakeNetNumber, gotAddr, primaryAddrAdded)
  2260  								}
  2261  							}
  2262  						})
  2263  					}
  2264  				})
  2265  			}
  2266  		})
  2267  	}
  2268  }
  2269  
  2270  func TestGetMainNICAddressErrors(t *testing.T) {
  2271  	const nicID = 1
  2272  
  2273  	s := stack.New(stack.Options{
  2274  		NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol, arp.NewProtocol},
  2275  	})
  2276  	if err := s.CreateNIC(nicID, loopback.New()); err != nil {
  2277  		t.Fatalf("CreateNIC(%d, _): %s", nicID, err)
  2278  	}
  2279  
  2280  	// Sanity check with a successful call.
  2281  	if addr, err := s.GetMainNICAddress(nicID, ipv4.ProtocolNumber); err != nil {
  2282  		t.Errorf("s.GetMainNICAddress(%d, %d): %s", nicID, ipv4.ProtocolNumber, err)
  2283  	} else if want := (tcpip.AddressWithPrefix{}); addr != want {
  2284  		t.Errorf("got s.GetMainNICAddress(%d, %d) = %s, want = %s", nicID, ipv4.ProtocolNumber, addr, want)
  2285  	}
  2286  
  2287  	const unknownNICID = nicID + 1
  2288  	switch addr, err := s.GetMainNICAddress(unknownNICID, ipv4.ProtocolNumber); err.(type) {
  2289  	case *tcpip.ErrUnknownNICID:
  2290  	default:
  2291  		t.Errorf("got s.GetMainNICAddress(%d, %d) = (%s, %T), want = (_, tcpip.ErrUnknownNICID)", unknownNICID, ipv4.ProtocolNumber, addr, err)
  2292  	}
  2293  
  2294  	// ARP is not an addressable network endpoint.
  2295  	switch addr, err := s.GetMainNICAddress(nicID, arp.ProtocolNumber); err.(type) {
  2296  	case *tcpip.ErrNotSupported:
  2297  	default:
  2298  		t.Errorf("got s.GetMainNICAddress(%d, %d) = (%s, %T), want = (_, tcpip.ErrNotSupported)", nicID, arp.ProtocolNumber, addr, err)
  2299  	}
  2300  
  2301  	const unknownProtocolNumber = 1234
  2302  	switch addr, err := s.GetMainNICAddress(nicID, unknownProtocolNumber); err.(type) {
  2303  	case *tcpip.ErrUnknownProtocol:
  2304  	default:
  2305  		t.Errorf("got s.GetMainNICAddress(%d, %d) = (%s, %T), want = (_, tcpip.ErrUnknownProtocol)", nicID, unknownProtocolNumber, addr, err)
  2306  	}
  2307  }
  2308  
  2309  func TestGetMainNICAddressAddRemove(t *testing.T) {
  2310  	s := stack.New(stack.Options{
  2311  		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
  2312  	})
  2313  	ep := channel.New(10, defaultMTU, "")
  2314  	if err := s.CreateNIC(1, ep); err != nil {
  2315  		t.Fatal("CreateNIC failed:", err)
  2316  	}
  2317  
  2318  	for _, tc := range []struct {
  2319  		name      string
  2320  		address   tcpip.Address
  2321  		prefixLen int
  2322  	}{
  2323  		{"IPv4", tcpip.AddrFromSlice([]byte("\x01\x01\x01\x01")), 24},
  2324  		{"IPv6", tcpip.AddrFromSlice([]byte("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01")), 116},
  2325  	} {
  2326  		t.Run(tc.name, func(t *testing.T) {
  2327  			protocolAddress := tcpip.ProtocolAddress{
  2328  				Protocol: fakeNetNumber,
  2329  				AddressWithPrefix: tcpip.AddressWithPrefix{
  2330  					Address:   tc.address,
  2331  					PrefixLen: tc.prefixLen,
  2332  				},
  2333  			}
  2334  			if err := s.AddProtocolAddress(1, protocolAddress, stack.AddressProperties{}); err != nil {
  2335  				t.Fatalf("AddProtocolAddress(1, %+v, {}): %s", protocolAddress, err)
  2336  			}
  2337  
  2338  			// Check that we get the right initial address and prefix length.
  2339  			if err := checkGetMainNICAddress(s, 1, fakeNetNumber, protocolAddress.AddressWithPrefix); err != nil {
  2340  				t.Fatal(err)
  2341  			}
  2342  
  2343  			if err := s.RemoveAddress(1, protocolAddress.AddressWithPrefix.Address); err != nil {
  2344  				t.Fatal("RemoveAddress failed:", err)
  2345  			}
  2346  
  2347  			// Check that we get no address after removal.
  2348  			if err := checkGetMainNICAddress(s, 1, fakeNetNumber, tcpip.AddressWithPrefix{}); err != nil {
  2349  				t.Fatal(err)
  2350  			}
  2351  		})
  2352  	}
  2353  }
  2354  
  2355  // Simple network address generator. Good for 255 addresses.
  2356  type addressGenerator struct{ cnt byte }
  2357  
  2358  func (g *addressGenerator) next(addrLen int) tcpip.Address {
  2359  	g.cnt++
  2360  	return tcpip.AddrFromSlice(bytes.Repeat([]byte{g.cnt}, addrLen))
  2361  }
  2362  
  2363  func verifyAddresses(t *testing.T, expectedAddresses, gotAddresses []tcpip.ProtocolAddress) {
  2364  	t.Helper()
  2365  
  2366  	if len(gotAddresses) != len(expectedAddresses) {
  2367  		t.Fatalf("got len(addresses) = %d, want = %d", len(gotAddresses), len(expectedAddresses))
  2368  	}
  2369  
  2370  	sort.Slice(gotAddresses, func(i, j int) bool {
  2371  		return string(gotAddresses[i].AddressWithPrefix.Address.AsSlice()) < string(gotAddresses[j].AddressWithPrefix.Address.AsSlice())
  2372  	})
  2373  	sort.Slice(expectedAddresses, func(i, j int) bool {
  2374  		return string(expectedAddresses[i].AddressWithPrefix.Address.AsSlice()) < string(expectedAddresses[j].AddressWithPrefix.Address.AsSlice())
  2375  	})
  2376  
  2377  	for i, gotAddr := range gotAddresses {
  2378  		expectedAddr := expectedAddresses[i]
  2379  		if gotAddr != expectedAddr {
  2380  			t.Errorf("got address = %+v, wanted = %+v", gotAddr, expectedAddr)
  2381  		}
  2382  	}
  2383  }
  2384  
  2385  func TestAddProtocolAddress(t *testing.T) {
  2386  	const nicID = 1
  2387  	s := stack.New(stack.Options{
  2388  		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
  2389  	})
  2390  	ep := channel.New(10, defaultMTU, "")
  2391  	if err := s.CreateNIC(nicID, ep); err != nil {
  2392  		t.Fatal("CreateNIC failed:", err)
  2393  	}
  2394  
  2395  	addrLenRange := []int{4, 16}
  2396  	behaviorRange := []stack.PrimaryEndpointBehavior{stack.CanBePrimaryEndpoint, stack.FirstPrimaryEndpoint, stack.NeverPrimaryEndpoint}
  2397  	configTypeRange := []stack.AddressConfigType{stack.AddressConfigStatic, stack.AddressConfigSlaac}
  2398  	temporaryRange := []bool{false, true}
  2399  	deprecatedRange := []bool{false, true}
  2400  	wantAddresses := make([]tcpip.ProtocolAddress, 0, len(addrLenRange)*len(behaviorRange)*len(configTypeRange)*len(deprecatedRange))
  2401  	var addrGen addressGenerator
  2402  	for _, addrLen := range addrLenRange {
  2403  		for _, behavior := range behaviorRange {
  2404  			for _, configType := range configTypeRange {
  2405  				for _, temporary := range temporaryRange {
  2406  					for _, deprecated := range deprecatedRange {
  2407  						address := addrGen.next(addrLen)
  2408  						properties := stack.AddressProperties{
  2409  							PEB:        behavior,
  2410  							ConfigType: configType,
  2411  							Lifetimes:  stack.AddressLifetimes{Deprecated: deprecated},
  2412  							Temporary:  temporary,
  2413  						}
  2414  						protocolAddr := tcpip.ProtocolAddress{
  2415  							Protocol: fakeNetNumber,
  2416  							AddressWithPrefix: tcpip.AddressWithPrefix{
  2417  								Address:   address,
  2418  								PrefixLen: fakeDefaultPrefixLen,
  2419  							},
  2420  						}
  2421  						if err := s.AddProtocolAddress(nicID, protocolAddr, properties); err != nil {
  2422  							t.Fatalf("AddProtocolAddress(%d, %+v, %+v) failed: %s", nicID, protocolAddr, properties, err)
  2423  						}
  2424  						wantAddresses = append(wantAddresses, tcpip.ProtocolAddress{
  2425  							Protocol:          fakeNetNumber,
  2426  							AddressWithPrefix: tcpip.AddressWithPrefix{Address: address, PrefixLen: fakeDefaultPrefixLen},
  2427  						})
  2428  					}
  2429  				}
  2430  			}
  2431  		}
  2432  	}
  2433  
  2434  	gotAddresses := s.AllAddresses()[nicID]
  2435  	verifyAddresses(t, wantAddresses, gotAddresses)
  2436  }
  2437  
  2438  func TestCreateNICWithOptions(t *testing.T) {
  2439  	type callArgsAndExpect struct {
  2440  		nicID tcpip.NICID
  2441  		opts  stack.NICOptions
  2442  		err   tcpip.Error
  2443  	}
  2444  
  2445  	tests := []struct {
  2446  		desc  string
  2447  		calls []callArgsAndExpect
  2448  	}{
  2449  		{
  2450  			desc: "InvalidNICID",
  2451  			calls: []callArgsAndExpect{
  2452  				{
  2453  					nicID: tcpip.NICID(0),
  2454  					opts:  stack.NICOptions{Name: "eth0"},
  2455  					err:   &tcpip.ErrInvalidNICID{},
  2456  				},
  2457  			},
  2458  		},
  2459  		{
  2460  			desc: "DuplicateNICID",
  2461  			calls: []callArgsAndExpect{
  2462  				{
  2463  					nicID: tcpip.NICID(1),
  2464  					opts:  stack.NICOptions{Name: "eth1"},
  2465  					err:   nil,
  2466  				},
  2467  				{
  2468  					nicID: tcpip.NICID(1),
  2469  					opts:  stack.NICOptions{Name: "eth2"},
  2470  					err:   &tcpip.ErrDuplicateNICID{},
  2471  				},
  2472  			},
  2473  		},
  2474  		{
  2475  			desc: "DuplicateName",
  2476  			calls: []callArgsAndExpect{
  2477  				{
  2478  					nicID: tcpip.NICID(1),
  2479  					opts:  stack.NICOptions{Name: "lo"},
  2480  					err:   nil,
  2481  				},
  2482  				{
  2483  					nicID: tcpip.NICID(2),
  2484  					opts:  stack.NICOptions{Name: "lo"},
  2485  					err:   &tcpip.ErrDuplicateNICID{},
  2486  				},
  2487  			},
  2488  		},
  2489  		{
  2490  			desc: "Unnamed",
  2491  			calls: []callArgsAndExpect{
  2492  				{
  2493  					nicID: tcpip.NICID(1),
  2494  					opts:  stack.NICOptions{},
  2495  					err:   nil,
  2496  				},
  2497  				{
  2498  					nicID: tcpip.NICID(2),
  2499  					opts:  stack.NICOptions{},
  2500  					err:   nil,
  2501  				},
  2502  			},
  2503  		},
  2504  		{
  2505  			desc: "UnnamedDuplicateNICID",
  2506  			calls: []callArgsAndExpect{
  2507  				{
  2508  					nicID: tcpip.NICID(1),
  2509  					opts:  stack.NICOptions{},
  2510  					err:   nil,
  2511  				},
  2512  				{
  2513  					nicID: tcpip.NICID(1),
  2514  					opts:  stack.NICOptions{},
  2515  					err:   &tcpip.ErrDuplicateNICID{},
  2516  				},
  2517  			},
  2518  		},
  2519  	}
  2520  	for _, test := range tests {
  2521  		t.Run(test.desc, func(t *testing.T) {
  2522  			s := stack.New(stack.Options{})
  2523  			ep := channel.New(0, 0, "\x00\x00\x00\x00\x00\x00")
  2524  			for _, call := range test.calls {
  2525  				if got, want := s.CreateNICWithOptions(call.nicID, ep, call.opts), call.err; got != want {
  2526  					t.Fatalf("CreateNICWithOptions(%v, _, %+v) = %v, want %v", call.nicID, call.opts, got, want)
  2527  				}
  2528  			}
  2529  		})
  2530  	}
  2531  }
  2532  
  2533  func TestNICStats(t *testing.T) {
  2534  	s := stack.New(stack.Options{
  2535  		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
  2536  	})
  2537  
  2538  	nics := []struct {
  2539  		addr        tcpip.Address
  2540  		txByteCount int
  2541  		rxByteCount int
  2542  	}{
  2543  		{
  2544  			addr:        tcpip.AddrFromSlice([]byte("\x01\x00\x00\x00")),
  2545  			txByteCount: 30,
  2546  			rxByteCount: 10,
  2547  		},
  2548  		{
  2549  			addr:        tcpip.AddrFromSlice([]byte("\x02\x00\x00\x00")),
  2550  			txByteCount: 50,
  2551  			rxByteCount: 20,
  2552  		},
  2553  	}
  2554  
  2555  	var txBytesTotal, rxBytesTotal, txPacketsTotal, rxPacketsTotal int
  2556  	for i, nic := range nics {
  2557  		nicid := tcpip.NICID(i + 1)
  2558  		ep := channel.New(1, defaultMTU, "")
  2559  		if err := s.CreateNIC(nicid, ep); err != nil {
  2560  			t.Fatal("CreateNIC failed: ", err)
  2561  		}
  2562  		protocolAddr := tcpip.ProtocolAddress{
  2563  			Protocol: fakeNetNumber,
  2564  			AddressWithPrefix: tcpip.AddressWithPrefix{
  2565  				Address:   nic.addr,
  2566  				PrefixLen: fakeDefaultPrefixLen,
  2567  			},
  2568  		}
  2569  		if err := s.AddProtocolAddress(nicid, protocolAddr, stack.AddressProperties{}); err != nil {
  2570  			t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", nicid, protocolAddr, err)
  2571  		}
  2572  
  2573  		{
  2574  			subnet, err := tcpip.NewSubnet(nic.addr, tcpip.MaskFrom("\xff\x00\x00\x00"))
  2575  			if err != nil {
  2576  				t.Fatal(err)
  2577  			}
  2578  			s.SetRouteTable([]tcpip.Route{{Destination: subnet, Gateway: tcpip.AddrFromSlice([]byte("\x00\x00\x00\x00")), NIC: nicid}})
  2579  		}
  2580  
  2581  		nicStats := s.NICInfo()[nicid].Stats
  2582  
  2583  		// Inbound packet.
  2584  		rxBuffer := make([]byte, nic.rxByteCount)
  2585  		ep.InjectInbound(fakeNetNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
  2586  			Payload: buffer.MakeWithData(rxBuffer),
  2587  		}))
  2588  		if got, want := nicStats.Rx.Packets.Value(), uint64(1); got != want {
  2589  			t.Errorf("got Rx.Packets.Value() = %d, want = %d", got, want)
  2590  		}
  2591  		if got, want := nicStats.Rx.Bytes.Value(), uint64(nic.rxByteCount); got != want {
  2592  			t.Errorf("got Rx.Bytes.Value() = %d, want = %d", got, want)
  2593  		}
  2594  		rxPacketsTotal++
  2595  		rxBytesTotal += nic.rxByteCount
  2596  
  2597  		// Outbound packet.
  2598  		txBuffer := make([]byte, nic.txByteCount)
  2599  		actualTxLength := nic.txByteCount + fakeNetHeaderLen
  2600  		if err := sendTo(s, nic.addr, txBuffer); err != nil {
  2601  			t.Fatal("sendTo failed: ", err)
  2602  		}
  2603  		want := ep.Drain()
  2604  		if got := nicStats.Tx.Packets.Value(); got != uint64(want) {
  2605  			t.Errorf("got Tx.Packets.Value() = %d, ep.Drain() = %d", got, want)
  2606  		}
  2607  		if got, want := nicStats.Tx.Bytes.Value(), uint64(actualTxLength); got != want {
  2608  			t.Errorf("got Tx.Bytes.Value() = %d, want = %d", got, want)
  2609  		}
  2610  		txPacketsTotal += want
  2611  		txBytesTotal += actualTxLength
  2612  	}
  2613  
  2614  	// Now verify that each NIC stats was correctly aggregated at the stack level.
  2615  	if got, want := s.Stats().NICs.Rx.Packets.Value(), uint64(rxPacketsTotal); got != want {
  2616  		t.Errorf("got s.Stats().NIC.Rx.Packets.Value() = %d, want = %d", got, want)
  2617  	}
  2618  	if got, want := s.Stats().NICs.Rx.Bytes.Value(), uint64(rxBytesTotal); got != want {
  2619  		t.Errorf("got s.Stats().Rx.Bytes.Value() = %d, want = %d", got, want)
  2620  	}
  2621  	if got, want := s.Stats().NICs.Tx.Packets.Value(), uint64(txPacketsTotal); got != want {
  2622  		t.Errorf("got Tx.Packets.Value() = %d, ep.Drain() = %d", got, want)
  2623  	}
  2624  	if got, want := s.Stats().NICs.Tx.Bytes.Value(), uint64(txBytesTotal); got != want {
  2625  		t.Errorf("got Tx.Bytes.Value() = %d, want = %d", got, want)
  2626  	}
  2627  }
  2628  
  2629  // TestNICContextPreservation tests that you can read out via stack.NICInfo the
  2630  // Context data you pass via NICContext.Context in stack.CreateNICWithOptions.
  2631  func TestNICContextPreservation(t *testing.T) {
  2632  	var ctx *int
  2633  	tests := []struct {
  2634  		name string
  2635  		opts stack.NICOptions
  2636  		want stack.NICContext
  2637  	}{
  2638  		{
  2639  			"context_set",
  2640  			stack.NICOptions{Context: ctx},
  2641  			ctx,
  2642  		},
  2643  		{
  2644  			"context_not_set",
  2645  			stack.NICOptions{},
  2646  			nil,
  2647  		},
  2648  	}
  2649  	for _, test := range tests {
  2650  		t.Run(test.name, func(t *testing.T) {
  2651  			s := stack.New(stack.Options{})
  2652  			id := tcpip.NICID(1)
  2653  			ep := channel.New(0, 0, "\x00\x00\x00\x00\x00\x00")
  2654  			if err := s.CreateNICWithOptions(id, ep, test.opts); err != nil {
  2655  				t.Fatalf("got stack.CreateNICWithOptions(%d, %+v, %+v) = %s, want nil", id, ep, test.opts, err)
  2656  			}
  2657  			nicinfos := s.NICInfo()
  2658  			nicinfo, ok := nicinfos[id]
  2659  			if !ok {
  2660  				t.Fatalf("got nicinfos[%d] = _, %t, want _, true; nicinfos = %+v", id, ok, nicinfos)
  2661  			}
  2662  			if got, want := nicinfo.Context == test.want, true; got != want {
  2663  				t.Fatalf("got nicinfo.Context == ctx = %t, want %t; nicinfo.Context = %p, ctx = %p", got, want, nicinfo.Context, test.want)
  2664  			}
  2665  		})
  2666  	}
  2667  }
  2668  
  2669  // TestNICAutoGenLinkLocalAddr tests the auto-generation of IPv6 link-local
  2670  // addresses.
  2671  func TestNICAutoGenLinkLocalAddr(t *testing.T) {
  2672  	const nicID = 1
  2673  
  2674  	var secretKey [header.OpaqueIIDSecretKeyMinBytes]byte
  2675  	n, err := rand.Read(secretKey[:])
  2676  	if err != nil {
  2677  		t.Fatalf("rand.Read(_): %s", err)
  2678  	}
  2679  	if n != header.OpaqueIIDSecretKeyMinBytes {
  2680  		t.Fatalf("expected rand.Read to read %d bytes, read %d bytes", header.OpaqueIIDSecretKeyMinBytes, n)
  2681  	}
  2682  
  2683  	nicNameFunc := func(_ tcpip.NICID, name string) string {
  2684  		return name
  2685  	}
  2686  
  2687  	tests := []struct {
  2688  		name         string
  2689  		nicName      string
  2690  		autoGen      bool
  2691  		linkAddr     tcpip.LinkAddress
  2692  		iidOpts      ipv6.OpaqueInterfaceIdentifierOptions
  2693  		shouldGen    bool
  2694  		expectedAddr tcpip.Address
  2695  	}{
  2696  		{
  2697  			name:      "Disabled",
  2698  			nicName:   "nic1",
  2699  			autoGen:   false,
  2700  			linkAddr:  linkAddr1,
  2701  			shouldGen: false,
  2702  		},
  2703  		{
  2704  			name:     "Disabled without OIID options",
  2705  			nicName:  "nic1",
  2706  			autoGen:  false,
  2707  			linkAddr: linkAddr1,
  2708  			iidOpts: ipv6.OpaqueInterfaceIdentifierOptions{
  2709  				NICNameFromID: nicNameFunc,
  2710  				SecretKey:     secretKey[:],
  2711  			},
  2712  			shouldGen: false,
  2713  		},
  2714  
  2715  		// Tests for EUI64 based addresses.
  2716  		{
  2717  			name:         "EUI64 Enabled",
  2718  			autoGen:      true,
  2719  			linkAddr:     linkAddr1,
  2720  			shouldGen:    true,
  2721  			expectedAddr: header.LinkLocalAddr(linkAddr1),
  2722  		},
  2723  		{
  2724  			name:      "EUI64 Empty MAC",
  2725  			autoGen:   true,
  2726  			shouldGen: false,
  2727  		},
  2728  		{
  2729  			name:      "EUI64 Invalid MAC",
  2730  			autoGen:   true,
  2731  			linkAddr:  "\x01\x02\x03",
  2732  			shouldGen: false,
  2733  		},
  2734  		{
  2735  			name:      "EUI64 Multicast MAC",
  2736  			autoGen:   true,
  2737  			linkAddr:  "\x01\x02\x03\x04\x05\x06",
  2738  			shouldGen: false,
  2739  		},
  2740  		{
  2741  			name:      "EUI64 Unspecified MAC",
  2742  			autoGen:   true,
  2743  			linkAddr:  "\x00\x00\x00\x00\x00\x00",
  2744  			shouldGen: false,
  2745  		},
  2746  
  2747  		// Tests for Opaque IID based addresses.
  2748  		{
  2749  			name:     "OIID Enabled",
  2750  			nicName:  "nic1",
  2751  			autoGen:  true,
  2752  			linkAddr: linkAddr1,
  2753  			iidOpts: ipv6.OpaqueInterfaceIdentifierOptions{
  2754  				NICNameFromID: nicNameFunc,
  2755  				SecretKey:     secretKey[:],
  2756  			},
  2757  			shouldGen:    true,
  2758  			expectedAddr: header.LinkLocalAddrWithOpaqueIID("nic1", 0, secretKey[:]),
  2759  		},
  2760  		// These are all cases where we would not have generated a
  2761  		// link-local address if opaque IIDs were disabled.
  2762  		{
  2763  			name:    "OIID Empty MAC and empty nicName",
  2764  			autoGen: true,
  2765  			iidOpts: ipv6.OpaqueInterfaceIdentifierOptions{
  2766  				NICNameFromID: nicNameFunc,
  2767  				SecretKey:     secretKey[:1],
  2768  			},
  2769  			shouldGen:    true,
  2770  			expectedAddr: header.LinkLocalAddrWithOpaqueIID("", 0, secretKey[:1]),
  2771  		},
  2772  		{
  2773  			name:     "OIID Invalid MAC",
  2774  			nicName:  "test",
  2775  			autoGen:  true,
  2776  			linkAddr: "\x01\x02\x03",
  2777  			iidOpts: ipv6.OpaqueInterfaceIdentifierOptions{
  2778  				NICNameFromID: nicNameFunc,
  2779  				SecretKey:     secretKey[:2],
  2780  			},
  2781  			shouldGen:    true,
  2782  			expectedAddr: header.LinkLocalAddrWithOpaqueIID("test", 0, secretKey[:2]),
  2783  		},
  2784  		{
  2785  			name:     "OIID Multicast MAC",
  2786  			nicName:  "test2",
  2787  			autoGen:  true,
  2788  			linkAddr: "\x01\x02\x03\x04\x05\x06",
  2789  			iidOpts: ipv6.OpaqueInterfaceIdentifierOptions{
  2790  				NICNameFromID: nicNameFunc,
  2791  				SecretKey:     secretKey[:3],
  2792  			},
  2793  			shouldGen:    true,
  2794  			expectedAddr: header.LinkLocalAddrWithOpaqueIID("test2", 0, secretKey[:3]),
  2795  		},
  2796  		{
  2797  			name:     "OIID Unspecified MAC and nil SecretKey",
  2798  			nicName:  "test3",
  2799  			autoGen:  true,
  2800  			linkAddr: "\x00\x00\x00\x00\x00\x00",
  2801  			iidOpts: ipv6.OpaqueInterfaceIdentifierOptions{
  2802  				NICNameFromID: nicNameFunc,
  2803  			},
  2804  			shouldGen:    true,
  2805  			expectedAddr: header.LinkLocalAddrWithOpaqueIID("test3", 0, nil),
  2806  		},
  2807  	}
  2808  
  2809  	for _, test := range tests {
  2810  		t.Run(test.name, func(t *testing.T) {
  2811  			const autoGenAddrCount = 1
  2812  			ndpDisp := ndpDispatcher{
  2813  				autoGenAddrC:    make(chan ndpAutoGenAddrEvent, autoGenAddrCount),
  2814  				autoGenAddrNewC: make(chan ndpAutoGenAddrNewEvent, autoGenAddrCount),
  2815  			}
  2816  			opts := stack.Options{
  2817  				NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
  2818  					AutoGenLinkLocal: test.autoGen,
  2819  					NDPDisp:          &ndpDisp,
  2820  					OpaqueIIDOpts:    test.iidOpts,
  2821  				})},
  2822  			}
  2823  
  2824  			e := channel.New(0, 1280, test.linkAddr)
  2825  			s := stack.New(opts)
  2826  			nicOpts := stack.NICOptions{Name: test.nicName, Disabled: true}
  2827  			if err := s.CreateNICWithOptions(nicID, e, nicOpts); err != nil {
  2828  				t.Fatalf("CreateNICWithOptions(%d, _, %+v) = %s", nicID, opts, err)
  2829  			}
  2830  
  2831  			// A new disabled NIC should not have any address, even if auto generation
  2832  			// was enabled.
  2833  			allStackAddrs := s.AllAddresses()
  2834  			allNICAddrs, ok := allStackAddrs[nicID]
  2835  			if !ok {
  2836  				t.Fatalf("entry for %d missing from allStackAddrs = %+v", nicID, allStackAddrs)
  2837  			}
  2838  			if l := len(allNICAddrs); l != 0 {
  2839  				t.Fatalf("got len(allNICAddrs) = %d, want = 0", l)
  2840  			}
  2841  
  2842  			// Enabling the NIC should attempt auto-generation of a link-local
  2843  			// address.
  2844  			if err := s.EnableNIC(nicID); err != nil {
  2845  				t.Fatalf("s.EnableNIC(%d): %s", nicID, err)
  2846  			}
  2847  
  2848  			var expectedMainAddr tcpip.AddressWithPrefix
  2849  			if test.shouldGen {
  2850  				expectedMainAddr = tcpip.AddressWithPrefix{
  2851  					Address:   test.expectedAddr,
  2852  					PrefixLen: header.IPv6LinkLocalPrefix.PrefixLen,
  2853  				}
  2854  
  2855  				// Should have auto-generated an address and resolved immediately (DAD
  2856  				// is disabled).
  2857  				if _, err := expectAutoGenAddrNewEvent(&ndpDisp, expectedMainAddr); err != nil {
  2858  					t.Fatalf("error expecting link-local auto-gen address generated event: %s", err)
  2859  				}
  2860  			} else {
  2861  				// Should not have auto-generated an address.
  2862  				select {
  2863  				case <-ndpDisp.autoGenAddrC:
  2864  					t.Fatal("unexpectedly auto-generated an address")
  2865  				default:
  2866  				}
  2867  			}
  2868  
  2869  			if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, expectedMainAddr); err != nil {
  2870  				t.Fatal(err)
  2871  			}
  2872  
  2873  			// Disabling the NIC should remove the auto-generated address.
  2874  			if err := s.DisableNIC(nicID); err != nil {
  2875  				t.Fatalf("s.DisableNIC(%d): %s", nicID, err)
  2876  			}
  2877  			if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil {
  2878  				t.Fatal(err)
  2879  			}
  2880  		})
  2881  	}
  2882  }
  2883  
  2884  // TestNoLinkLocalAutoGenForLoopbackNIC tests that IPv6 link-local addresses are
  2885  // not auto-generated for loopback NICs.
  2886  func TestNoLinkLocalAutoGenForLoopbackNIC(t *testing.T) {
  2887  	const nicID = 1
  2888  	const nicName = "nicName"
  2889  
  2890  	tests := []struct {
  2891  		name          string
  2892  		opaqueIIDOpts ipv6.OpaqueInterfaceIdentifierOptions
  2893  	}{
  2894  		{
  2895  			name:          "IID From MAC",
  2896  			opaqueIIDOpts: ipv6.OpaqueInterfaceIdentifierOptions{},
  2897  		},
  2898  		{
  2899  			name: "Opaque IID",
  2900  			opaqueIIDOpts: ipv6.OpaqueInterfaceIdentifierOptions{
  2901  				NICNameFromID: func(_ tcpip.NICID, nicName string) string {
  2902  					return nicName
  2903  				},
  2904  			},
  2905  		},
  2906  	}
  2907  
  2908  	for _, test := range tests {
  2909  		t.Run(test.name, func(t *testing.T) {
  2910  			opts := stack.Options{
  2911  				NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
  2912  					AutoGenLinkLocal: true,
  2913  					OpaqueIIDOpts:    test.opaqueIIDOpts,
  2914  				})},
  2915  			}
  2916  
  2917  			e := loopback.New()
  2918  			s := stack.New(opts)
  2919  			nicOpts := stack.NICOptions{Name: nicName}
  2920  			if err := s.CreateNICWithOptions(nicID, e, nicOpts); err != nil {
  2921  				t.Fatalf("CreateNICWithOptions(%d, _, %+v) = %s", nicID, nicOpts, err)
  2922  			}
  2923  
  2924  			if err := checkGetMainNICAddress(s, 1, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil {
  2925  				t.Fatal(err)
  2926  			}
  2927  		})
  2928  	}
  2929  }
  2930  
  2931  // TestNICAutoGenAddrDoesDAD tests that the successful auto-generation of IPv6
  2932  // link-local addresses will only be assigned after the DAD process resolves.
  2933  func TestNICAutoGenAddrDoesDAD(t *testing.T) {
  2934  	const nicID = 1
  2935  
  2936  	ndpDisp := ndpDispatcher{
  2937  		dadC: make(chan ndpDADEvent, 1),
  2938  	}
  2939  	dadConfigs := stack.DefaultDADConfigurations()
  2940  	clock := faketime.NewManualClock()
  2941  	opts := stack.Options{
  2942  		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
  2943  			AutoGenLinkLocal: true,
  2944  			NDPDisp:          &ndpDisp,
  2945  			DADConfigs:       dadConfigs,
  2946  		})},
  2947  		Clock: clock,
  2948  	}
  2949  
  2950  	e := channel.New(int(dadConfigs.DupAddrDetectTransmits), 1280, linkAddr1)
  2951  	s := stack.New(opts)
  2952  	if err := s.CreateNIC(nicID, e); err != nil {
  2953  		t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
  2954  	}
  2955  
  2956  	// Address should not be considered bound to the
  2957  	// NIC yet (DAD ongoing).
  2958  	if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil {
  2959  		t.Fatal(err)
  2960  	}
  2961  
  2962  	linkLocalAddr := header.LinkLocalAddr(linkAddr1)
  2963  
  2964  	// Wait for DAD to resolve.
  2965  	clock.Advance(time.Duration(dadConfigs.DupAddrDetectTransmits) * dadConfigs.RetransmitTimer)
  2966  	select {
  2967  	case e := <-ndpDisp.dadC:
  2968  		if diff := checkDADEvent(e, nicID, linkLocalAddr, &stack.DADSucceeded{}); diff != "" {
  2969  			t.Errorf("dad event mismatch (-want +got):\n%s", diff)
  2970  		}
  2971  	default:
  2972  		// We should get a resolution event after 1s (default time to
  2973  		// resolve as per default NDP configurations). Waiting for that
  2974  		// resolution time + an extra 1s without a resolution event
  2975  		// means something is wrong.
  2976  		t.Fatal("timed out waiting for DAD resolution")
  2977  	}
  2978  	if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{Address: linkLocalAddr, PrefixLen: header.IPv6LinkLocalPrefix.PrefixLen}); err != nil {
  2979  		t.Fatal(err)
  2980  	}
  2981  }
  2982  
  2983  // TestNewPEB tests that a new PrimaryEndpointBehavior value (peb) is respected
  2984  // when an address's kind gets "promoted" to permanent from permanentExpired.
  2985  func TestNewPEBOnPromotionToPermanent(t *testing.T) {
  2986  	const nicID = 1
  2987  
  2988  	pebs := []stack.PrimaryEndpointBehavior{
  2989  		stack.NeverPrimaryEndpoint,
  2990  		stack.CanBePrimaryEndpoint,
  2991  		stack.FirstPrimaryEndpoint,
  2992  	}
  2993  
  2994  	for _, pi := range pebs {
  2995  		for _, ps := range pebs {
  2996  			t.Run(fmt.Sprintf("%d-to-%d", pi, ps), func(t *testing.T) {
  2997  				s := stack.New(stack.Options{
  2998  					NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
  2999  				})
  3000  				ep1 := channel.New(10, defaultMTU, "")
  3001  				if err := s.CreateNIC(nicID, ep1); err != nil {
  3002  					t.Fatalf("CreateNIC(%d, _): %s", nicID, err)
  3003  				}
  3004  
  3005  				// Add a permanent address with initial
  3006  				// PrimaryEndpointBehavior (peb), pi. If pi is
  3007  				// NeverPrimaryEndpoint, the address should not
  3008  				// be returned by a call to GetMainNICAddress;
  3009  				// else, it should.
  3010  				address1 := tcpip.AddrFromSlice([]byte("\x01\x00\x00\x00"))
  3011  				properties := stack.AddressProperties{PEB: pi}
  3012  				protocolAddr := tcpip.ProtocolAddress{
  3013  					Protocol: fakeNetNumber,
  3014  					AddressWithPrefix: tcpip.AddressWithPrefix{
  3015  						Address:   address1,
  3016  						PrefixLen: fakeDefaultPrefixLen,
  3017  					},
  3018  				}
  3019  				if err := s.AddProtocolAddress(nicID, protocolAddr, properties); err != nil {
  3020  					t.Fatalf("AddProtocolAddress(%d, %+v, %+v): %s", nicID, protocolAddr, properties, err)
  3021  				}
  3022  				addr, err := s.GetMainNICAddress(nicID, fakeNetNumber)
  3023  				if err != nil {
  3024  					t.Fatalf("GetMainNICAddress(%d, %d): %s", nicID, fakeNetNumber, err)
  3025  				}
  3026  				if pi == stack.NeverPrimaryEndpoint {
  3027  					if want := (tcpip.AddressWithPrefix{}); addr != want {
  3028  						t.Fatalf("got GetMainNICAddress(%d, %d) = %s, want = %s", nicID, fakeNetNumber, addr, want)
  3029  
  3030  					}
  3031  				} else if addr.Address != address1 {
  3032  					t.Fatalf("got GetMainNICAddress(%d, %d) = %s, want = %s", nicID, fakeNetNumber, addr.Address, address1)
  3033  				}
  3034  
  3035  				{
  3036  					subnet, err := tcpip.NewSubnet(tcpip.AddrFromSlice([]byte("\x00\x00\x00\x00")), tcpip.MaskFrom("\x00\x00\x00\x00"))
  3037  					if err != nil {
  3038  						t.Fatalf("NewSubnet failed: %v", err)
  3039  					}
  3040  					s.SetRouteTable([]tcpip.Route{{Destination: subnet, Gateway: tcpip.AddrFromSlice([]byte("\x00\x00\x00\x00")), NIC: 1}})
  3041  				}
  3042  
  3043  				// Take a route through the address so its ref
  3044  				// count gets incremented and does not actually
  3045  				// get deleted when RemoveAddress is called
  3046  				// below. This is because we want to test that a
  3047  				// new peb is respected when an address gets
  3048  				// "promoted" to permanent from a
  3049  				// permanentExpired kind.
  3050  				address2 := tcpip.AddrFromSlice([]byte("\x02\x00\x00\x00"))
  3051  				r, err := s.FindRoute(nicID, address1, address2, fakeNetNumber, false)
  3052  				if err != nil {
  3053  					t.Fatalf("FindRoute(%d, %s, %s, %d, false): %s", nicID, address1, address2, fakeNetNumber, err)
  3054  				}
  3055  				defer r.Release()
  3056  				if err := s.RemoveAddress(nicID, address1); err != nil {
  3057  					t.Fatalf("RemoveAddress(%d, %s): %s", nicID, address1, err)
  3058  				}
  3059  
  3060  				//
  3061  				// At this point, the address should still be
  3062  				// known by the NIC, but have its
  3063  				// kind = permanentExpired.
  3064  				//
  3065  
  3066  				// Add some other address with peb set to
  3067  				// FirstPrimaryEndpoint.
  3068  				address3 := tcpip.AddrFromSlice([]byte("\x03\x00\x00\x00"))
  3069  				protocolAddr3 := tcpip.ProtocolAddress{
  3070  					Protocol: fakeNetNumber,
  3071  					AddressWithPrefix: tcpip.AddressWithPrefix{
  3072  						Address:   address3,
  3073  						PrefixLen: fakeDefaultPrefixLen,
  3074  					},
  3075  				}
  3076  				properties = stack.AddressProperties{PEB: stack.FirstPrimaryEndpoint}
  3077  				if err := s.AddProtocolAddress(nicID, protocolAddr3, properties); err != nil {
  3078  					t.Fatalf("AddProtocolAddress(%d, %+v, %+v): %s", nicID, protocolAddr3, properties, err)
  3079  				}
  3080  
  3081  				// Add back the address we removed earlier and
  3082  				// make sure the new peb was respected.
  3083  				// (The address should just be promoted now).
  3084  				protocolAddr1 := tcpip.ProtocolAddress{
  3085  					Protocol: fakeNetNumber,
  3086  					AddressWithPrefix: tcpip.AddressWithPrefix{
  3087  						Address:   address1,
  3088  						PrefixLen: fakeDefaultPrefixLen,
  3089  					},
  3090  				}
  3091  				properties = stack.AddressProperties{PEB: ps}
  3092  				if err := s.AddProtocolAddress(nicID, protocolAddr1, properties); err != nil {
  3093  					t.Fatalf("AddProtocolAddress(%d, %+v, %+v): %s", nicID, protocolAddr1, properties, err)
  3094  				}
  3095  				var primaryAddrs []tcpip.Address
  3096  				for _, pa := range s.NICInfo()[nicID].ProtocolAddresses {
  3097  					primaryAddrs = append(primaryAddrs, pa.AddressWithPrefix.Address)
  3098  				}
  3099  				var expectedList []tcpip.Address
  3100  				switch ps {
  3101  				case stack.FirstPrimaryEndpoint:
  3102  					expectedList = []tcpip.Address{
  3103  						tcpip.AddrFromSlice([]byte("\x01\x00\x00\x00")),
  3104  						tcpip.AddrFromSlice([]byte("\x03\x00\x00\x00")),
  3105  					}
  3106  				case stack.CanBePrimaryEndpoint:
  3107  					expectedList = []tcpip.Address{
  3108  						tcpip.AddrFromSlice([]byte("\x03\x00\x00\x00")),
  3109  						tcpip.AddrFromSlice([]byte("\x01\x00\x00\x00")),
  3110  					}
  3111  				case stack.NeverPrimaryEndpoint:
  3112  					expectedList = []tcpip.Address{
  3113  						tcpip.AddrFromSlice([]byte("\x03\x00\x00\x00")),
  3114  					}
  3115  				}
  3116  				if !cmp.Equal(primaryAddrs, expectedList) {
  3117  					t.Fatalf("got NIC's primary addresses = %v, want = %v", primaryAddrs, expectedList)
  3118  				}
  3119  
  3120  				// Once we remove the other address, if the new
  3121  				// peb, ps, was NeverPrimaryEndpoint, no address
  3122  				// should be returned by a call to
  3123  				// GetMainNICAddress; else, our original address
  3124  				// should be returned.
  3125  				if err := s.RemoveAddress(nicID, address3); err != nil {
  3126  					t.Fatalf("RemoveAddress(%d, %s): %s", nicID, address3, err)
  3127  				}
  3128  				addr, err = s.GetMainNICAddress(nicID, fakeNetNumber)
  3129  				if err != nil {
  3130  					t.Fatalf("GetMainNICAddress(%d, %d): %s", nicID, fakeNetNumber, err)
  3131  				}
  3132  				if ps == stack.NeverPrimaryEndpoint {
  3133  					if want := (tcpip.AddressWithPrefix{}); addr != want {
  3134  						t.Fatalf("got GetMainNICAddress(%d, %d) = %s, want = %s", nicID, fakeNetNumber, addr, want)
  3135  					}
  3136  				} else {
  3137  					if addr.Address != address1 {
  3138  						t.Fatalf("got GetMainNICAddress(%d, %d) = %s, want = %s", nicID, fakeNetNumber, addr.Address, address1)
  3139  					}
  3140  				}
  3141  			})
  3142  		}
  3143  	}
  3144  }
  3145  
  3146  func TestIPv6SourceAddressSelectionScopeAndSameAddress(t *testing.T) {
  3147  	const (
  3148  		nicID           = 1
  3149  		lifetimeSeconds = 9999
  3150  	)
  3151  
  3152  	var (
  3153  		linkLocalAddr1         = testutil.MustParse6("fe80::1")
  3154  		linkLocalAddr2         = testutil.MustParse6("fe80::2")
  3155  		linkLocalMulticastAddr = testutil.MustParse6("ff02::1")
  3156  		uniqueLocalAddr1       = testutil.MustParse6("fc00::1")
  3157  		uniqueLocalAddr2       = testutil.MustParse6("fd00::2")
  3158  		globalAddr1            = testutil.MustParse6("a000::1")
  3159  		globalAddr2            = testutil.MustParse6("a000::2")
  3160  		globalAddr3            = testutil.MustParse6("a000::3")
  3161  		ipv4MappedIPv6Addr1    = testutil.MustParse6("::ffff:0.0.0.1")
  3162  		ipv4MappedIPv6Addr2    = testutil.MustParse6("::ffff:0.0.0.2")
  3163  		toredoAddr1            = testutil.MustParse6("2001::1")
  3164  		toredoAddr2            = testutil.MustParse6("2001::2")
  3165  		ipv6ToIPv4Addr1        = testutil.MustParse6("2002::1")
  3166  		ipv6ToIPv4Addr2        = testutil.MustParse6("2002::2")
  3167  	)
  3168  
  3169  	prefix1, _, stableGlobalAddr1 := prefixSubnetAddr(0, linkAddr1)
  3170  	prefix2, _, stableGlobalAddr2 := prefixSubnetAddr(1, linkAddr1)
  3171  
  3172  	var tempIIDHistory [header.IIDSize]byte
  3173  	header.InitialTempIID(tempIIDHistory[:], nil, nicID)
  3174  	tempGlobalAddr1 := header.GenerateTempIPv6SLAACAddr(tempIIDHistory[:], stableGlobalAddr1.Address).Address
  3175  	tempGlobalAddr2 := header.GenerateTempIPv6SLAACAddr(tempIIDHistory[:], stableGlobalAddr2.Address).Address
  3176  
  3177  	type addressWithProperties struct {
  3178  		addr       tcpip.Address
  3179  		properties stack.AddressProperties
  3180  	}
  3181  
  3182  	// Rule 3 is also tested by NDP's AutoGenAddr test.
  3183  	tests := []struct {
  3184  		name                                   string
  3185  		slaacPrefixForTempAddrBeforeNICAddrAdd tcpip.AddressWithPrefix
  3186  		nicAddrs                               []addressWithProperties
  3187  		slaacPrefixForTempAddrAfterNICAddrAdd  tcpip.AddressWithPrefix
  3188  		remoteAddr                             tcpip.Address
  3189  		expectedLocalAddr                      tcpip.Address
  3190  	}{
  3191  		// Test Rule 1 of RFC 6724 section 5 (prefer same address).
  3192  		{
  3193  			name: "Same Global most preferred (last address)",
  3194  			nicAddrs: []addressWithProperties{
  3195  				{addr: linkLocalAddr1},
  3196  				{addr: globalAddr1},
  3197  			},
  3198  			remoteAddr:        globalAddr1,
  3199  			expectedLocalAddr: globalAddr1,
  3200  		},
  3201  		{
  3202  			name: "Same Global most preferred (first address)",
  3203  			nicAddrs: []addressWithProperties{
  3204  				{addr: globalAddr1},
  3205  				{addr: uniqueLocalAddr1},
  3206  			},
  3207  			remoteAddr:        globalAddr1,
  3208  			expectedLocalAddr: globalAddr1,
  3209  		},
  3210  		{
  3211  			name: "Same Link Local most preferred (last address)",
  3212  			nicAddrs: []addressWithProperties{
  3213  				{addr: globalAddr1},
  3214  				{addr: linkLocalAddr1},
  3215  			},
  3216  			remoteAddr:        linkLocalAddr1,
  3217  			expectedLocalAddr: linkLocalAddr1,
  3218  		},
  3219  		{
  3220  			name: "Same Link Local most preferred (first address)",
  3221  			nicAddrs: []addressWithProperties{
  3222  				{addr: linkLocalAddr1},
  3223  				{addr: globalAddr1},
  3224  			},
  3225  			remoteAddr:        linkLocalAddr1,
  3226  			expectedLocalAddr: linkLocalAddr1,
  3227  		},
  3228  		{
  3229  			name: "Same Unique Local most preferred (last address)",
  3230  			nicAddrs: []addressWithProperties{
  3231  				{addr: uniqueLocalAddr1},
  3232  				{addr: globalAddr1},
  3233  			},
  3234  			remoteAddr:        uniqueLocalAddr1,
  3235  			expectedLocalAddr: uniqueLocalAddr1,
  3236  		},
  3237  		{
  3238  			name: "Same Unique Local most preferred (first address)",
  3239  			nicAddrs: []addressWithProperties{
  3240  				{addr: globalAddr1},
  3241  				{addr: uniqueLocalAddr1},
  3242  			},
  3243  			remoteAddr:        uniqueLocalAddr1,
  3244  			expectedLocalAddr: uniqueLocalAddr1,
  3245  		},
  3246  
  3247  		// Test Rule 2 of RFC 6724 section 5 (prefer appropriate scope).
  3248  		{
  3249  			name: "Global most preferred (last address)",
  3250  			nicAddrs: []addressWithProperties{
  3251  				{addr: linkLocalAddr1},
  3252  				{addr: globalAddr1},
  3253  			},
  3254  			remoteAddr:        globalAddr2,
  3255  			expectedLocalAddr: globalAddr1,
  3256  		},
  3257  		{
  3258  			name: "Global most preferred (first address)",
  3259  			nicAddrs: []addressWithProperties{
  3260  				{addr: globalAddr1},
  3261  				{addr: linkLocalAddr1},
  3262  			},
  3263  			remoteAddr:        globalAddr2,
  3264  			expectedLocalAddr: globalAddr1,
  3265  		},
  3266  		{
  3267  			name: "Link Local most preferred (last address)",
  3268  			nicAddrs: []addressWithProperties{
  3269  				{addr: globalAddr1},
  3270  				{addr: linkLocalAddr1},
  3271  			},
  3272  			remoteAddr:        linkLocalAddr2,
  3273  			expectedLocalAddr: linkLocalAddr1,
  3274  		},
  3275  		{
  3276  			name: "Link Local most preferred (first address)",
  3277  			nicAddrs: []addressWithProperties{
  3278  				{addr: linkLocalAddr1},
  3279  				{addr: globalAddr1},
  3280  			},
  3281  			remoteAddr:        linkLocalAddr2,
  3282  			expectedLocalAddr: linkLocalAddr1,
  3283  		},
  3284  		{
  3285  			name: "Link Local most preferred for link local multicast (last address)",
  3286  			nicAddrs: []addressWithProperties{
  3287  				{addr: globalAddr1},
  3288  				{addr: linkLocalAddr1},
  3289  			},
  3290  			remoteAddr:        linkLocalMulticastAddr,
  3291  			expectedLocalAddr: linkLocalAddr1,
  3292  		},
  3293  		{
  3294  			name: "Link Local most preferred for link local multicast (first address)",
  3295  			nicAddrs: []addressWithProperties{
  3296  				{addr: linkLocalAddr1},
  3297  				{addr: globalAddr1},
  3298  			},
  3299  			remoteAddr:        linkLocalMulticastAddr,
  3300  			expectedLocalAddr: linkLocalAddr1,
  3301  		},
  3302  
  3303  		// Test Rule 3 of RFC 6724 section 5 (avoid deprecated addresses).
  3304  		{
  3305  			name: "Deprecated least preferred (last address)",
  3306  			nicAddrs: []addressWithProperties{
  3307  				{addr: globalAddr1},
  3308  				{
  3309  					addr: globalAddr2,
  3310  					properties: stack.AddressProperties{
  3311  						Lifetimes: stack.AddressLifetimes{Deprecated: true},
  3312  					},
  3313  				},
  3314  			},
  3315  			remoteAddr:        globalAddr3,
  3316  			expectedLocalAddr: globalAddr1,
  3317  		},
  3318  		{
  3319  			name: "Deprecated least preferred (first address)",
  3320  			nicAddrs: []addressWithProperties{
  3321  				{
  3322  					addr: globalAddr2,
  3323  					properties: stack.AddressProperties{
  3324  						Lifetimes: stack.AddressLifetimes{Deprecated: true},
  3325  					},
  3326  				},
  3327  				{addr: globalAddr1},
  3328  			},
  3329  			remoteAddr:        globalAddr3,
  3330  			expectedLocalAddr: globalAddr1,
  3331  		},
  3332  		// Test Rule 6 of 6724 section 5 (prefer matching label).
  3333  		{
  3334  			name: "Unique Local most preferred (last address)",
  3335  			nicAddrs: []addressWithProperties{
  3336  				{addr: uniqueLocalAddr1},
  3337  				{addr: globalAddr1},
  3338  				{addr: ipv4MappedIPv6Addr1},
  3339  				{addr: toredoAddr1},
  3340  				{addr: ipv6ToIPv4Addr1},
  3341  			},
  3342  			remoteAddr:        uniqueLocalAddr2,
  3343  			expectedLocalAddr: uniqueLocalAddr1,
  3344  		},
  3345  		{
  3346  			name: "Unique Local most preferred (first address)",
  3347  			nicAddrs: []addressWithProperties{
  3348  				{addr: globalAddr1},
  3349  				{addr: ipv4MappedIPv6Addr1},
  3350  				{addr: toredoAddr1},
  3351  				{addr: ipv6ToIPv4Addr1},
  3352  				{addr: uniqueLocalAddr1},
  3353  			},
  3354  			remoteAddr:        uniqueLocalAddr2,
  3355  			expectedLocalAddr: uniqueLocalAddr1,
  3356  		},
  3357  		{
  3358  			name: "Toredo most preferred (first address)",
  3359  			nicAddrs: []addressWithProperties{
  3360  				{addr: toredoAddr1},
  3361  				{addr: uniqueLocalAddr1},
  3362  				{addr: globalAddr1},
  3363  				{addr: ipv4MappedIPv6Addr1},
  3364  				{addr: ipv6ToIPv4Addr1},
  3365  			},
  3366  			remoteAddr:        toredoAddr2,
  3367  			expectedLocalAddr: toredoAddr1,
  3368  		},
  3369  		{
  3370  			name: "Toredo most preferred (last address)",
  3371  			nicAddrs: []addressWithProperties{
  3372  				{addr: globalAddr1},
  3373  				{addr: ipv4MappedIPv6Addr1},
  3374  				{addr: ipv6ToIPv4Addr1},
  3375  				{addr: uniqueLocalAddr1},
  3376  				{addr: toredoAddr1},
  3377  			},
  3378  			remoteAddr:        toredoAddr2,
  3379  			expectedLocalAddr: toredoAddr1,
  3380  		},
  3381  		{
  3382  			name: "6To4 most preferred (first address)",
  3383  			nicAddrs: []addressWithProperties{
  3384  				{addr: ipv6ToIPv4Addr1},
  3385  				{addr: toredoAddr1},
  3386  				{addr: uniqueLocalAddr1},
  3387  				{addr: globalAddr1},
  3388  				{addr: ipv4MappedIPv6Addr1},
  3389  			},
  3390  			remoteAddr:        ipv6ToIPv4Addr2,
  3391  			expectedLocalAddr: ipv6ToIPv4Addr1,
  3392  		},
  3393  		{
  3394  			name: "6To4 most preferred (last address)",
  3395  			nicAddrs: []addressWithProperties{
  3396  				{addr: globalAddr1},
  3397  				{addr: ipv4MappedIPv6Addr1},
  3398  				{addr: uniqueLocalAddr1},
  3399  				{addr: toredoAddr1},
  3400  				{addr: ipv6ToIPv4Addr1},
  3401  			},
  3402  			remoteAddr:        ipv6ToIPv4Addr2,
  3403  			expectedLocalAddr: ipv6ToIPv4Addr1,
  3404  		},
  3405  		{
  3406  			name: "IPv4 mapped IPv6 most preferred (first address)",
  3407  			nicAddrs: []addressWithProperties{
  3408  				{addr: ipv4MappedIPv6Addr1},
  3409  				{addr: ipv6ToIPv4Addr1},
  3410  				{addr: toredoAddr1},
  3411  				{addr: uniqueLocalAddr1},
  3412  				{addr: globalAddr1},
  3413  			},
  3414  			remoteAddr:        ipv4MappedIPv6Addr2,
  3415  			expectedLocalAddr: ipv4MappedIPv6Addr1,
  3416  		},
  3417  		{
  3418  			name: "IPv4 mapped IPv6 most preferred (last address)",
  3419  			nicAddrs: []addressWithProperties{
  3420  				{addr: globalAddr1},
  3421  				{addr: ipv6ToIPv4Addr1},
  3422  				{addr: uniqueLocalAddr1},
  3423  				{addr: toredoAddr1},
  3424  				{addr: ipv4MappedIPv6Addr1},
  3425  			},
  3426  			remoteAddr:        ipv4MappedIPv6Addr2,
  3427  			expectedLocalAddr: ipv4MappedIPv6Addr1,
  3428  		},
  3429  
  3430  		// Test Rule 7 of RFC 6724 section 5 (prefer temporary addresses).
  3431  		{
  3432  			name:                                   "Temp Global most preferred (prefix before addr add)",
  3433  			slaacPrefixForTempAddrBeforeNICAddrAdd: prefix1,
  3434  			nicAddrs: []addressWithProperties{
  3435  				{addr: linkLocalAddr1},
  3436  				{addr: uniqueLocalAddr1},
  3437  				{addr: globalAddr1},
  3438  			},
  3439  			remoteAddr:        globalAddr2,
  3440  			expectedLocalAddr: tempGlobalAddr1,
  3441  		},
  3442  		{
  3443  			name: "Temp Global most preferred (prefix after addr add)",
  3444  			nicAddrs: []addressWithProperties{
  3445  				{addr: linkLocalAddr1},
  3446  				{addr: uniqueLocalAddr1},
  3447  				{addr: globalAddr1},
  3448  			},
  3449  			slaacPrefixForTempAddrAfterNICAddrAdd: prefix1,
  3450  			remoteAddr:                            globalAddr2,
  3451  			expectedLocalAddr:                     tempGlobalAddr1,
  3452  		},
  3453  		{
  3454  			name: "Temp Static most preferred (last address)",
  3455  			nicAddrs: []addressWithProperties{
  3456  				{addr: globalAddr2},
  3457  				{
  3458  					addr: globalAddr1,
  3459  					properties: stack.AddressProperties{
  3460  						ConfigType: stack.AddressConfigStatic,
  3461  						Temporary:  true,
  3462  					},
  3463  				},
  3464  			},
  3465  			remoteAddr:        globalAddr3,
  3466  			expectedLocalAddr: globalAddr1,
  3467  		},
  3468  		{
  3469  			name: "Temp Static most preferred (first address)",
  3470  			nicAddrs: []addressWithProperties{
  3471  				{
  3472  					addr: globalAddr1,
  3473  					properties: stack.AddressProperties{
  3474  						ConfigType: stack.AddressConfigStatic,
  3475  						Temporary:  true,
  3476  					},
  3477  				},
  3478  				{addr: globalAddr2},
  3479  			},
  3480  			remoteAddr:        globalAddr3,
  3481  			expectedLocalAddr: globalAddr1,
  3482  		},
  3483  
  3484  		// Test Rule 8 of RFC 6724 section 5 (use longest matching prefix).
  3485  		{
  3486  			name: "Longest prefix matched most preferred (first address)",
  3487  			nicAddrs: []addressWithProperties{
  3488  				{addr: globalAddr2},
  3489  				{addr: globalAddr1},
  3490  			},
  3491  			remoteAddr:        globalAddr3,
  3492  			expectedLocalAddr: globalAddr2,
  3493  		},
  3494  		{
  3495  			name: "Longest prefix matched most preferred (last address)",
  3496  			nicAddrs: []addressWithProperties{
  3497  				{addr: globalAddr1},
  3498  				{addr: globalAddr2},
  3499  			},
  3500  			remoteAddr:        globalAddr3,
  3501  			expectedLocalAddr: globalAddr2,
  3502  		},
  3503  
  3504  		// Test returning the endpoint that is closest to the front when
  3505  		// candidate addresses are "equal" from the perspective of RFC 6724
  3506  		// section 5.
  3507  		{
  3508  			name: "Unique Local for Global",
  3509  			nicAddrs: []addressWithProperties{
  3510  				{addr: linkLocalAddr1},
  3511  				{addr: uniqueLocalAddr1},
  3512  				{addr: uniqueLocalAddr2},
  3513  			},
  3514  			remoteAddr:        globalAddr2,
  3515  			expectedLocalAddr: uniqueLocalAddr1,
  3516  		},
  3517  		{
  3518  			name: "Link Local for Global",
  3519  			nicAddrs: []addressWithProperties{
  3520  				{addr: linkLocalAddr1},
  3521  				{addr: linkLocalAddr2},
  3522  			},
  3523  			remoteAddr:        globalAddr2,
  3524  			expectedLocalAddr: linkLocalAddr1,
  3525  		},
  3526  		{
  3527  			name: "Link Local for Unique Local",
  3528  			nicAddrs: []addressWithProperties{
  3529  				{addr: linkLocalAddr1},
  3530  				{addr: linkLocalAddr2},
  3531  			},
  3532  			remoteAddr:        uniqueLocalAddr2,
  3533  			expectedLocalAddr: linkLocalAddr1,
  3534  		},
  3535  		{
  3536  			name:                                   "Temp Global for Global",
  3537  			slaacPrefixForTempAddrBeforeNICAddrAdd: prefix1,
  3538  			slaacPrefixForTempAddrAfterNICAddrAdd:  prefix2,
  3539  			remoteAddr:                             globalAddr1,
  3540  			expectedLocalAddr:                      tempGlobalAddr2,
  3541  		},
  3542  	}
  3543  
  3544  	for _, test := range tests {
  3545  		t.Run(test.name, func(t *testing.T) {
  3546  			e := channel.New(0, 1280, linkAddr1)
  3547  			s := stack.New(stack.Options{
  3548  				NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
  3549  					NDPConfigs: ipv6.NDPConfigurations{
  3550  						HandleRAs:                  ipv6.HandlingRAsEnabledWhenForwardingDisabled,
  3551  						AutoGenGlobalAddresses:     true,
  3552  						AutoGenTempGlobalAddresses: true,
  3553  					},
  3554  					NDPDisp: &ndpDispatcher{},
  3555  				})},
  3556  				TransportProtocols: []stack.TransportProtocolFactory{udp.NewProtocol},
  3557  			})
  3558  			if err := s.CreateNIC(nicID, e); err != nil {
  3559  				t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
  3560  			}
  3561  
  3562  			if test.slaacPrefixForTempAddrBeforeNICAddrAdd != (tcpip.AddressWithPrefix{}) {
  3563  				e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr3, 0, test.slaacPrefixForTempAddrBeforeNICAddrAdd, true, true, lifetimeSeconds, lifetimeSeconds))
  3564  			}
  3565  
  3566  			for _, a := range test.nicAddrs {
  3567  				protocolAddr := tcpip.ProtocolAddress{
  3568  					Protocol:          ipv6.ProtocolNumber,
  3569  					AddressWithPrefix: a.addr.WithPrefix(),
  3570  				}
  3571  				if err := s.AddProtocolAddress(nicID, protocolAddr, a.properties); err != nil {
  3572  					t.Fatalf("AddProtocolAddress(%d, %+v, %+v): %s", nicID, protocolAddr, a.properties, err)
  3573  				}
  3574  			}
  3575  
  3576  			if test.slaacPrefixForTempAddrAfterNICAddrAdd != (tcpip.AddressWithPrefix{}) {
  3577  				e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr3, 0, test.slaacPrefixForTempAddrAfterNICAddrAdd, true, true, lifetimeSeconds, lifetimeSeconds))
  3578  			}
  3579  
  3580  			if t.Failed() {
  3581  				t.FailNow()
  3582  			}
  3583  
  3584  			netEP, err := s.GetNetworkEndpoint(nicID, header.IPv6ProtocolNumber)
  3585  			if err != nil {
  3586  				t.Fatalf("s.GetNetworkEndpoint(%d, %d): %s", nicID, header.IPv6ProtocolNumber, err)
  3587  			}
  3588  
  3589  			addressableEndpoint, ok := netEP.(stack.AddressableEndpoint)
  3590  			if !ok {
  3591  				t.Fatal("network endpoint is not addressable")
  3592  			}
  3593  
  3594  			addressEP := addressableEndpoint.AcquireOutgoingPrimaryAddress(test.remoteAddr, tcpip.Address{} /* srcHint */, false /* allowExpired */)
  3595  			if addressEP == nil {
  3596  				t.Fatal("expected a non-nil address endpoint")
  3597  			}
  3598  			defer addressEP.DecRef()
  3599  
  3600  			if got := addressEP.AddressWithPrefix().Address; got != test.expectedLocalAddr {
  3601  				t.Errorf("got local address = %s, want = %s", got, test.expectedLocalAddr)
  3602  			}
  3603  		})
  3604  	}
  3605  }
  3606  
  3607  func TestAddRemoveIPv4BroadcastAddressOnNICEnableDisable(t *testing.T) {
  3608  	const nicID = 1
  3609  	broadcastAddr := tcpip.ProtocolAddress{
  3610  		Protocol: header.IPv4ProtocolNumber,
  3611  		AddressWithPrefix: tcpip.AddressWithPrefix{
  3612  			Address:   header.IPv4Broadcast,
  3613  			PrefixLen: 32,
  3614  		},
  3615  	}
  3616  
  3617  	e := loopback.New()
  3618  	s := stack.New(stack.Options{
  3619  		NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol},
  3620  	})
  3621  	nicOpts := stack.NICOptions{Disabled: true}
  3622  	if err := s.CreateNICWithOptions(nicID, e, nicOpts); err != nil {
  3623  		t.Fatalf("CreateNIC(%d, _, %+v) = %s", nicID, nicOpts, err)
  3624  	}
  3625  
  3626  	{
  3627  		allStackAddrs := s.AllAddresses()
  3628  		if allNICAddrs, ok := allStackAddrs[nicID]; !ok {
  3629  			t.Fatalf("entry for %d missing from allStackAddrs = %+v", nicID, allStackAddrs)
  3630  		} else if containsAddr(allNICAddrs, broadcastAddr) {
  3631  			t.Fatalf("got allNICAddrs = %+v, don't want = %+v", allNICAddrs, broadcastAddr)
  3632  		}
  3633  	}
  3634  
  3635  	// Enabling the NIC should add the IPv4 broadcast address.
  3636  	if err := s.EnableNIC(nicID); err != nil {
  3637  		t.Fatalf("s.EnableNIC(%d): %s", nicID, err)
  3638  	}
  3639  
  3640  	{
  3641  		allStackAddrs := s.AllAddresses()
  3642  		if allNICAddrs, ok := allStackAddrs[nicID]; !ok {
  3643  			t.Fatalf("entry for %d missing from allStackAddrs = %+v", nicID, allStackAddrs)
  3644  		} else if !containsAddr(allNICAddrs, broadcastAddr) {
  3645  			t.Fatalf("got allNICAddrs = %+v, want = %+v", allNICAddrs, broadcastAddr)
  3646  		}
  3647  	}
  3648  
  3649  	// Disabling the NIC should remove the IPv4 broadcast address.
  3650  	if err := s.DisableNIC(nicID); err != nil {
  3651  		t.Fatalf("s.DisableNIC(%d): %s", nicID, err)
  3652  	}
  3653  
  3654  	{
  3655  		allStackAddrs := s.AllAddresses()
  3656  		if allNICAddrs, ok := allStackAddrs[nicID]; !ok {
  3657  			t.Fatalf("entry for %d missing from allStackAddrs = %+v", nicID, allStackAddrs)
  3658  		} else if containsAddr(allNICAddrs, broadcastAddr) {
  3659  			t.Fatalf("got allNICAddrs = %+v, don't want = %+v", allNICAddrs, broadcastAddr)
  3660  		}
  3661  	}
  3662  }
  3663  
  3664  // TestLeaveIPv6SolicitedNodeAddrBeforeAddrRemoval tests that removing an IPv6
  3665  // address after leaving its solicited node multicast address does not result in
  3666  // an error.
  3667  func TestLeaveIPv6SolicitedNodeAddrBeforeAddrRemoval(t *testing.T) {
  3668  	const nicID = 1
  3669  
  3670  	s := stack.New(stack.Options{
  3671  		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocol},
  3672  	})
  3673  	e := channel.New(10, 1280, linkAddr1)
  3674  	if err := s.CreateNIC(1, e); err != nil {
  3675  		t.Fatalf("CreateNIC(%d, _): %s", nicID, err)
  3676  	}
  3677  
  3678  	protocolAddr := tcpip.ProtocolAddress{
  3679  		Protocol:          ipv6.ProtocolNumber,
  3680  		AddressWithPrefix: addr1.WithPrefix(),
  3681  	}
  3682  	if err := s.AddProtocolAddress(nicID, protocolAddr, stack.AddressProperties{}); err != nil {
  3683  		t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", nicID, protocolAddr, err)
  3684  	}
  3685  
  3686  	// The NIC should have joined addr1's solicited node multicast address.
  3687  	snmc := header.SolicitedNodeAddr(addr1)
  3688  	in, err := s.IsInGroup(nicID, snmc)
  3689  	if err != nil {
  3690  		t.Fatalf("IsInGroup(%d, %s): %s", nicID, snmc, err)
  3691  	}
  3692  	if !in {
  3693  		t.Fatalf("got IsInGroup(%d, %s) = false, want = true", nicID, snmc)
  3694  	}
  3695  
  3696  	if err := s.LeaveGroup(ipv6.ProtocolNumber, nicID, snmc); err != nil {
  3697  		t.Fatalf("LeaveGroup(%d, %d, %s): %s", ipv6.ProtocolNumber, nicID, snmc, err)
  3698  	}
  3699  	in, err = s.IsInGroup(nicID, snmc)
  3700  	if err != nil {
  3701  		t.Fatalf("IsInGroup(%d, %s): %s", nicID, snmc, err)
  3702  	}
  3703  	if in {
  3704  		t.Fatalf("got IsInGroup(%d, %s) = true, want = false", nicID, snmc)
  3705  	}
  3706  
  3707  	if err := s.RemoveAddress(nicID, addr1); err != nil {
  3708  		t.Fatalf("RemoveAddress(%d, %s) = %s", nicID, addr1, err)
  3709  	}
  3710  }
  3711  
  3712  func TestJoinLeaveMulticastOnNICEnableDisable(t *testing.T) {
  3713  	const nicID = 1
  3714  
  3715  	tests := []struct {
  3716  		name  string
  3717  		proto tcpip.NetworkProtocolNumber
  3718  		addr  tcpip.Address
  3719  	}{
  3720  		{
  3721  			name:  "IPv6 All-Nodes",
  3722  			proto: header.IPv6ProtocolNumber,
  3723  			addr:  header.IPv6AllNodesMulticastAddress,
  3724  		},
  3725  		{
  3726  			name:  "IPv4 All-Systems",
  3727  			proto: header.IPv4ProtocolNumber,
  3728  			addr:  header.IPv4AllSystems,
  3729  		},
  3730  	}
  3731  
  3732  	for _, test := range tests {
  3733  		t.Run(test.name, func(t *testing.T) {
  3734  			e := loopback.New()
  3735  			s := stack.New(stack.Options{
  3736  				NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol, ipv6.NewProtocol},
  3737  			})
  3738  			nicOpts := stack.NICOptions{Disabled: true}
  3739  			if err := s.CreateNICWithOptions(nicID, e, nicOpts); err != nil {
  3740  				t.Fatalf("CreateNIC(%d, _, %+v) = %s", nicID, nicOpts, err)
  3741  			}
  3742  
  3743  			// Should not be in the multicast group yet because the NIC has not been
  3744  			// enabled yet.
  3745  			if isInGroup, err := s.IsInGroup(nicID, test.addr); err != nil {
  3746  				t.Fatalf("IsInGroup(%d, %s): %s", nicID, test.addr, err)
  3747  			} else if isInGroup {
  3748  				t.Fatalf("got IsInGroup(%d, %s) = true, want = false", nicID, test.addr)
  3749  			}
  3750  
  3751  			// The all-nodes multicast group should be joined when the NIC is enabled.
  3752  			if err := s.EnableNIC(nicID); err != nil {
  3753  				t.Fatalf("s.EnableNIC(%d): %s", nicID, err)
  3754  			}
  3755  
  3756  			if isInGroup, err := s.IsInGroup(nicID, test.addr); err != nil {
  3757  				t.Fatalf("IsInGroup(%d, %s): %s", nicID, test.addr, err)
  3758  			} else if !isInGroup {
  3759  				t.Fatalf("got IsInGroup(%d, %s) = false, want = true", nicID, test.addr)
  3760  			}
  3761  
  3762  			// The multicast group should be left when the NIC is disabled.
  3763  			if err := s.DisableNIC(nicID); err != nil {
  3764  				t.Fatalf("s.DisableNIC(%d): %s", nicID, err)
  3765  			}
  3766  
  3767  			if isInGroup, err := s.IsInGroup(nicID, test.addr); err != nil {
  3768  				t.Fatalf("IsInGroup(%d, %s): %s", nicID, test.addr, err)
  3769  			} else if isInGroup {
  3770  				t.Fatalf("got IsInGroup(%d, %s) = true, want = false", nicID, test.addr)
  3771  			}
  3772  
  3773  			// The all-nodes multicast group should be joined when the NIC is enabled.
  3774  			if err := s.EnableNIC(nicID); err != nil {
  3775  				t.Fatalf("s.EnableNIC(%d): %s", nicID, err)
  3776  			}
  3777  
  3778  			if isInGroup, err := s.IsInGroup(nicID, test.addr); err != nil {
  3779  				t.Fatalf("IsInGroup(%d, %s): %s", nicID, test.addr, err)
  3780  			} else if !isInGroup {
  3781  				t.Fatalf("got IsInGroup(%d, %s) = false, want = true", nicID, test.addr)
  3782  			}
  3783  
  3784  			// Leaving the group before disabling the NIC should not cause an error.
  3785  			if err := s.LeaveGroup(test.proto, nicID, test.addr); err != nil {
  3786  				t.Fatalf("s.LeaveGroup(%d, %d, %s): %s", test.proto, nicID, test.addr, err)
  3787  			}
  3788  
  3789  			if err := s.DisableNIC(nicID); err != nil {
  3790  				t.Fatalf("s.DisableNIC(%d): %s", nicID, err)
  3791  			}
  3792  
  3793  			if isInGroup, err := s.IsInGroup(nicID, test.addr); err != nil {
  3794  				t.Fatalf("IsInGroup(%d, %s): %s", nicID, test.addr, err)
  3795  			} else if isInGroup {
  3796  				t.Fatalf("got IsInGroup(%d, %s) = true, want = false", nicID, test.addr)
  3797  			}
  3798  		})
  3799  	}
  3800  }
  3801  
  3802  // TestDoDADWhenNICEnabled tests that IPv6 endpoints that were added while a NIC
  3803  // was disabled have DAD performed on them when the NIC is enabled.
  3804  func TestDoDADWhenNICEnabled(t *testing.T) {
  3805  	const dadTransmits = 1
  3806  	const retransmitTimer = time.Second
  3807  	const nicID = 1
  3808  
  3809  	ndpDisp := ndpDispatcher{
  3810  		dadC: make(chan ndpDADEvent, 1),
  3811  	}
  3812  	clock := faketime.NewManualClock()
  3813  	opts := stack.Options{
  3814  		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
  3815  			DADConfigs: stack.DADConfigurations{
  3816  				DupAddrDetectTransmits: dadTransmits,
  3817  				RetransmitTimer:        retransmitTimer,
  3818  			},
  3819  			NDPDisp: &ndpDisp,
  3820  		})},
  3821  		Clock: clock,
  3822  	}
  3823  
  3824  	e := channel.New(dadTransmits, 1280, linkAddr1)
  3825  	s := stack.New(opts)
  3826  	nicOpts := stack.NICOptions{Disabled: true}
  3827  	if err := s.CreateNICWithOptions(nicID, e, nicOpts); err != nil {
  3828  		t.Fatalf("CreateNIC(%d, _, %+v) = %s", nicID, nicOpts, err)
  3829  	}
  3830  
  3831  	addr := tcpip.ProtocolAddress{
  3832  		Protocol: header.IPv6ProtocolNumber,
  3833  		AddressWithPrefix: tcpip.AddressWithPrefix{
  3834  			Address:   llAddr1,
  3835  			PrefixLen: 128,
  3836  		},
  3837  	}
  3838  	if err := s.AddProtocolAddress(nicID, addr, stack.AddressProperties{}); err != nil {
  3839  		t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", nicID, addr, err)
  3840  	}
  3841  
  3842  	// Address should be in the list of all addresses.
  3843  	if addrs := s.AllAddresses()[nicID]; !containsV6Addr(addrs, addr.AddressWithPrefix) {
  3844  		t.Fatalf("got s.AllAddresses()[%d] = %+v, want = %+v", nicID, addrs, addr)
  3845  	}
  3846  
  3847  	// Address should be tentative so it should not be a main address.
  3848  	if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil {
  3849  		t.Fatal(err)
  3850  	}
  3851  
  3852  	// Enabling the NIC should start DAD for the address.
  3853  	if err := s.EnableNIC(nicID); err != nil {
  3854  		t.Fatalf("s.EnableNIC(%d): %s", nicID, err)
  3855  	}
  3856  	if addrs := s.AllAddresses()[nicID]; !containsV6Addr(addrs, addr.AddressWithPrefix) {
  3857  		t.Fatalf("got s.AllAddresses()[%d] = %+v, want = %+v", nicID, addrs, addr)
  3858  	}
  3859  
  3860  	// Address should not be considered bound to the NIC yet (DAD ongoing).
  3861  	if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil {
  3862  		t.Fatal(err)
  3863  	}
  3864  
  3865  	// Wait for DAD to resolve.
  3866  	clock.Advance(dadTransmits * retransmitTimer)
  3867  	select {
  3868  	case e := <-ndpDisp.dadC:
  3869  		if diff := checkDADEvent(e, nicID, addr.AddressWithPrefix.Address, &stack.DADSucceeded{}); diff != "" {
  3870  			t.Errorf("dad event mismatch (-want +got):\n%s", diff)
  3871  		}
  3872  	default:
  3873  		t.Fatal("timed out waiting for DAD resolution")
  3874  	}
  3875  	if addrs := s.AllAddresses()[nicID]; !containsV6Addr(addrs, addr.AddressWithPrefix) {
  3876  		t.Fatalf("got s.AllAddresses()[%d] = %+v, want = %+v", nicID, addrs, addr)
  3877  	}
  3878  	if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, addr.AddressWithPrefix); err != nil {
  3879  		t.Fatal(err)
  3880  	}
  3881  
  3882  	// Enabling the NIC again should be a no-op.
  3883  	if err := s.EnableNIC(nicID); err != nil {
  3884  		t.Fatalf("s.EnableNIC(%d): %s", nicID, err)
  3885  	}
  3886  	if addrs := s.AllAddresses()[nicID]; !containsV6Addr(addrs, addr.AddressWithPrefix) {
  3887  		t.Fatalf("got s.AllAddresses()[%d] = %+v, want = %+v", nicID, addrs, addr)
  3888  	}
  3889  	if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, addr.AddressWithPrefix); err != nil {
  3890  		t.Fatal(err)
  3891  	}
  3892  }
  3893  
  3894  func TestStackReceiveBufferSizeOption(t *testing.T) {
  3895  	const sMin = stack.MinBufferSize
  3896  	testCases := []struct {
  3897  		name string
  3898  		rs   tcpip.ReceiveBufferSizeOption
  3899  		err  tcpip.Error
  3900  	}{
  3901  		// Invalid configurations.
  3902  		{"min_below_zero", tcpip.ReceiveBufferSizeOption{Min: -1, Default: sMin, Max: sMin}, &tcpip.ErrInvalidOptionValue{}},
  3903  		{"min_zero", tcpip.ReceiveBufferSizeOption{Min: 0, Default: sMin, Max: sMin}, &tcpip.ErrInvalidOptionValue{}},
  3904  		{"default_below_min", tcpip.ReceiveBufferSizeOption{Min: sMin, Default: sMin - 1, Max: sMin - 1}, &tcpip.ErrInvalidOptionValue{}},
  3905  		{"default_above_max", tcpip.ReceiveBufferSizeOption{Min: sMin, Default: sMin + 1, Max: sMin}, &tcpip.ErrInvalidOptionValue{}},
  3906  		{"max_below_min", tcpip.ReceiveBufferSizeOption{Min: sMin, Default: sMin + 1, Max: sMin - 1}, &tcpip.ErrInvalidOptionValue{}},
  3907  
  3908  		// Valid Configurations
  3909  		{"in_ascending_order", tcpip.ReceiveBufferSizeOption{Min: sMin, Default: sMin + 1, Max: sMin + 2}, nil},
  3910  		{"all_equal", tcpip.ReceiveBufferSizeOption{Min: sMin, Default: sMin, Max: sMin}, nil},
  3911  		{"min_default_equal", tcpip.ReceiveBufferSizeOption{Min: sMin, Default: sMin, Max: sMin + 1}, nil},
  3912  		{"default_max_equal", tcpip.ReceiveBufferSizeOption{Min: sMin, Default: sMin + 1, Max: sMin + 1}, nil},
  3913  	}
  3914  	for _, tc := range testCases {
  3915  		t.Run(tc.name, func(t *testing.T) {
  3916  			s := stack.New(stack.Options{})
  3917  			defer s.Close()
  3918  			if err := s.SetOption(tc.rs); err != tc.err {
  3919  				t.Fatalf("s.SetOption(%#v) = %v, want: %v", tc.rs, err, tc.err)
  3920  			}
  3921  			var rs tcpip.ReceiveBufferSizeOption
  3922  			if tc.err == nil {
  3923  				if err := s.Option(&rs); err != nil {
  3924  					t.Fatalf("s.Option(%#v) = %v, want: nil", rs, err)
  3925  				}
  3926  				if got, want := rs, tc.rs; got != want {
  3927  					t.Fatalf("s.Option(..) returned unexpected value got: %#v, want: %#v", got, want)
  3928  				}
  3929  			}
  3930  		})
  3931  	}
  3932  }
  3933  
  3934  func TestStackSendBufferSizeOption(t *testing.T) {
  3935  	const sMin = stack.MinBufferSize
  3936  	testCases := []struct {
  3937  		name string
  3938  		ss   tcpip.SendBufferSizeOption
  3939  		err  tcpip.Error
  3940  	}{
  3941  		// Invalid configurations.
  3942  		{"min_below_zero", tcpip.SendBufferSizeOption{Min: -1, Default: sMin, Max: sMin}, &tcpip.ErrInvalidOptionValue{}},
  3943  		{"min_zero", tcpip.SendBufferSizeOption{Min: 0, Default: sMin, Max: sMin}, &tcpip.ErrInvalidOptionValue{}},
  3944  		{"default_below_min", tcpip.SendBufferSizeOption{Min: 0, Default: sMin - 1, Max: sMin - 1}, &tcpip.ErrInvalidOptionValue{}},
  3945  		{"default_above_max", tcpip.SendBufferSizeOption{Min: 0, Default: sMin + 1, Max: sMin}, &tcpip.ErrInvalidOptionValue{}},
  3946  		{"max_below_min", tcpip.SendBufferSizeOption{Min: sMin, Default: sMin + 1, Max: sMin - 1}, &tcpip.ErrInvalidOptionValue{}},
  3947  
  3948  		// Valid Configurations
  3949  		{"in_ascending_order", tcpip.SendBufferSizeOption{Min: sMin, Default: sMin + 1, Max: sMin + 2}, nil},
  3950  		{"all_equal", tcpip.SendBufferSizeOption{Min: sMin, Default: sMin, Max: sMin}, nil},
  3951  		{"min_default_equal", tcpip.SendBufferSizeOption{Min: sMin, Default: sMin, Max: sMin + 1}, nil},
  3952  		{"default_max_equal", tcpip.SendBufferSizeOption{Min: sMin, Default: sMin + 1, Max: sMin + 1}, nil},
  3953  	}
  3954  	for _, tc := range testCases {
  3955  		t.Run(tc.name, func(t *testing.T) {
  3956  			s := stack.New(stack.Options{})
  3957  			defer s.Close()
  3958  			err := s.SetOption(tc.ss)
  3959  			if diff := cmp.Diff(tc.err, err); diff != "" {
  3960  				t.Fatalf("unexpected error from s.SetOption(%+v), (-want, +got):\n%s", tc.ss, diff)
  3961  			}
  3962  			if tc.err == nil {
  3963  				var ss tcpip.SendBufferSizeOption
  3964  				if err := s.Option(&ss); err != nil {
  3965  					t.Fatalf("s.Option(%+v) = %v, want: nil", ss, err)
  3966  				}
  3967  				if got, want := ss, tc.ss; got != want {
  3968  					t.Fatalf("s.Option(..) returned unexpected value got: %#v, want: %#v", got, want)
  3969  				}
  3970  			}
  3971  		})
  3972  	}
  3973  }
  3974  
  3975  func TestOutgoingSubnetBroadcast(t *testing.T) {
  3976  	const (
  3977  		unspecifiedNICID = 0
  3978  		nicID1           = 1
  3979  	)
  3980  
  3981  	defaultAddr := tcpip.AddressWithPrefix{
  3982  		Address:   header.IPv4Any,
  3983  		PrefixLen: 0,
  3984  	}
  3985  	defaultSubnet := defaultAddr.Subnet()
  3986  	ipv4Addr := tcpip.AddressWithPrefix{
  3987  		Address:   tcpip.AddrFromSlice([]byte("\xc0\xa8\x01\x3a")),
  3988  		PrefixLen: 24,
  3989  	}
  3990  	ipv4Subnet := ipv4Addr.Subnet()
  3991  	ipv4SubnetBcast := ipv4Subnet.Broadcast()
  3992  	ipv4Gateway := testutil.MustParse4("192.168.1.1")
  3993  	ipv4AddrPrefix31 := tcpip.AddressWithPrefix{
  3994  		Address:   tcpip.AddrFromSlice([]byte("\xc0\xa8\x01\x3a")),
  3995  		PrefixLen: 31,
  3996  	}
  3997  	ipv4Subnet31 := ipv4AddrPrefix31.Subnet()
  3998  	ipv4Subnet31Bcast := ipv4Subnet31.Broadcast()
  3999  	ipv4AddrPrefix32 := tcpip.AddressWithPrefix{
  4000  		Address:   tcpip.AddrFromSlice([]byte("\xc0\xa8\x01\x3a")),
  4001  		PrefixLen: 32,
  4002  	}
  4003  	ipv4Subnet32 := ipv4AddrPrefix32.Subnet()
  4004  	ipv4Subnet32Bcast := ipv4Subnet32.Broadcast()
  4005  	ipv6Addr := tcpip.AddressWithPrefix{
  4006  		Address:   tcpip.AddrFromSlice([]byte("\x20\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01")),
  4007  		PrefixLen: 64,
  4008  	}
  4009  	ipv6Subnet := ipv6Addr.Subnet()
  4010  	ipv6SubnetBcast := ipv6Subnet.Broadcast()
  4011  	remNetAddr := tcpip.AddressWithPrefix{
  4012  		Address:   tcpip.AddrFromSlice([]byte("\x64\x0a\x7b\x18")),
  4013  		PrefixLen: 24,
  4014  	}
  4015  	remNetSubnet := remNetAddr.Subnet()
  4016  	remNetSubnetBcast := remNetSubnet.Broadcast()
  4017  
  4018  	tests := []struct {
  4019  		name                      string
  4020  		nicAddr                   tcpip.ProtocolAddress
  4021  		routes                    []tcpip.Route
  4022  		remoteAddr                tcpip.Address
  4023  		expectedLocalAddress      tcpip.Address
  4024  		expectedRemoteAddress     tcpip.Address
  4025  		expectedRemoteLinkAddress tcpip.LinkAddress
  4026  		expectedNextHop           tcpip.Address
  4027  		expectedNetProto          tcpip.NetworkProtocolNumber
  4028  		expectedLoop              stack.PacketLooping
  4029  	}{
  4030  		// Broadcast to a locally attached subnet populates the broadcast MAC.
  4031  		{
  4032  			name: "IPv4 Broadcast to local subnet",
  4033  			nicAddr: tcpip.ProtocolAddress{
  4034  				Protocol:          header.IPv4ProtocolNumber,
  4035  				AddressWithPrefix: ipv4Addr,
  4036  			},
  4037  			routes: []tcpip.Route{
  4038  				{
  4039  					Destination: ipv4Subnet,
  4040  					NIC:         nicID1,
  4041  				},
  4042  			},
  4043  			remoteAddr:                ipv4SubnetBcast,
  4044  			expectedLocalAddress:      ipv4Addr.Address,
  4045  			expectedRemoteAddress:     ipv4SubnetBcast,
  4046  			expectedRemoteLinkAddress: header.EthernetBroadcastAddress,
  4047  			expectedNetProto:          header.IPv4ProtocolNumber,
  4048  			expectedLoop:              stack.PacketOut | stack.PacketLoop,
  4049  		},
  4050  		// Broadcast to a locally attached /31 subnet does not populate the
  4051  		// broadcast MAC.
  4052  		{
  4053  			name: "IPv4 Broadcast to local /31 subnet",
  4054  			nicAddr: tcpip.ProtocolAddress{
  4055  				Protocol:          header.IPv4ProtocolNumber,
  4056  				AddressWithPrefix: ipv4AddrPrefix31,
  4057  			},
  4058  			routes: []tcpip.Route{
  4059  				{
  4060  					Destination: ipv4Subnet31,
  4061  					NIC:         nicID1,
  4062  				},
  4063  			},
  4064  			remoteAddr:            ipv4Subnet31Bcast,
  4065  			expectedLocalAddress:  ipv4AddrPrefix31.Address,
  4066  			expectedRemoteAddress: ipv4Subnet31Bcast,
  4067  			expectedNetProto:      header.IPv4ProtocolNumber,
  4068  			expectedLoop:          stack.PacketOut,
  4069  		},
  4070  		// Broadcast to a locally attached /32 subnet does not populate the
  4071  		// broadcast MAC.
  4072  		{
  4073  			name: "IPv4 Broadcast to local /32 subnet",
  4074  			nicAddr: tcpip.ProtocolAddress{
  4075  				Protocol:          header.IPv4ProtocolNumber,
  4076  				AddressWithPrefix: ipv4AddrPrefix32,
  4077  			},
  4078  			routes: []tcpip.Route{
  4079  				{
  4080  					Destination: ipv4Subnet32,
  4081  					NIC:         nicID1,
  4082  				},
  4083  			},
  4084  			remoteAddr:            ipv4Subnet32Bcast,
  4085  			expectedLocalAddress:  ipv4AddrPrefix32.Address,
  4086  			expectedRemoteAddress: ipv4Subnet32Bcast,
  4087  			expectedNetProto:      header.IPv4ProtocolNumber,
  4088  			expectedLoop:          stack.PacketOut,
  4089  		},
  4090  		// IPv6 has no notion of a broadcast.
  4091  		{
  4092  			name: "IPv6 'Broadcast' to local subnet",
  4093  			nicAddr: tcpip.ProtocolAddress{
  4094  				Protocol:          header.IPv6ProtocolNumber,
  4095  				AddressWithPrefix: ipv6Addr,
  4096  			},
  4097  			routes: []tcpip.Route{
  4098  				{
  4099  					Destination: ipv6Subnet,
  4100  					NIC:         nicID1,
  4101  				},
  4102  			},
  4103  			remoteAddr:            ipv6SubnetBcast,
  4104  			expectedLocalAddress:  ipv6Addr.Address,
  4105  			expectedRemoteAddress: ipv6SubnetBcast,
  4106  			expectedNetProto:      header.IPv6ProtocolNumber,
  4107  			expectedLoop:          stack.PacketOut,
  4108  		},
  4109  		// Broadcast to a remote subnet in the route table is send to the next-hop
  4110  		// gateway.
  4111  		{
  4112  			name: "IPv4 Broadcast to remote subnet",
  4113  			nicAddr: tcpip.ProtocolAddress{
  4114  				Protocol:          header.IPv4ProtocolNumber,
  4115  				AddressWithPrefix: ipv4Addr,
  4116  			},
  4117  			routes: []tcpip.Route{
  4118  				{
  4119  					Destination: remNetSubnet,
  4120  					Gateway:     ipv4Gateway,
  4121  					NIC:         nicID1,
  4122  				},
  4123  			},
  4124  			remoteAddr:            remNetSubnetBcast,
  4125  			expectedLocalAddress:  ipv4Addr.Address,
  4126  			expectedRemoteAddress: remNetSubnetBcast,
  4127  			expectedNextHop:       ipv4Gateway,
  4128  			expectedNetProto:      header.IPv4ProtocolNumber,
  4129  			expectedLoop:          stack.PacketOut,
  4130  		},
  4131  		// Broadcast to an unknown subnet follows the default route. Note that this
  4132  		// is essentially just routing an unknown destination IP, because w/o any
  4133  		// subnet prefix information a subnet broadcast address is just a normal IP.
  4134  		{
  4135  			name: "IPv4 Broadcast to unknown subnet",
  4136  			nicAddr: tcpip.ProtocolAddress{
  4137  				Protocol:          header.IPv4ProtocolNumber,
  4138  				AddressWithPrefix: ipv4Addr,
  4139  			},
  4140  			routes: []tcpip.Route{
  4141  				{
  4142  					Destination: defaultSubnet,
  4143  					Gateway:     ipv4Gateway,
  4144  					NIC:         nicID1,
  4145  				},
  4146  			},
  4147  			remoteAddr:            remNetSubnetBcast,
  4148  			expectedLocalAddress:  ipv4Addr.Address,
  4149  			expectedRemoteAddress: remNetSubnetBcast,
  4150  			expectedNextHop:       ipv4Gateway,
  4151  			expectedNetProto:      header.IPv4ProtocolNumber,
  4152  			expectedLoop:          stack.PacketOut,
  4153  		},
  4154  	}
  4155  
  4156  	for _, test := range tests {
  4157  		t.Run(test.name, func(t *testing.T) {
  4158  			s := stack.New(stack.Options{
  4159  				NetworkProtocols: []stack.NetworkProtocolFactory{arp.NewProtocol, ipv4.NewProtocol, ipv6.NewProtocol},
  4160  			})
  4161  			ep := channel.New(0, defaultMTU, "")
  4162  			ep.LinkEPCapabilities |= stack.CapabilityResolutionRequired
  4163  			if err := s.CreateNIC(nicID1, ep); err != nil {
  4164  				t.Fatalf("CreateNIC(%d, _): %s", nicID1, err)
  4165  			}
  4166  			if err := s.AddProtocolAddress(nicID1, test.nicAddr, stack.AddressProperties{}); err != nil {
  4167  				t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", nicID1, test.nicAddr, err)
  4168  			}
  4169  
  4170  			s.SetRouteTable(test.routes)
  4171  
  4172  			var netProto tcpip.NetworkProtocolNumber
  4173  			switch l := test.remoteAddr.Len(); l {
  4174  			case header.IPv4AddressSize:
  4175  				netProto = header.IPv4ProtocolNumber
  4176  			case header.IPv6AddressSize:
  4177  				netProto = header.IPv6ProtocolNumber
  4178  			default:
  4179  				t.Fatalf("got unexpected address length = %d bytes", l)
  4180  			}
  4181  
  4182  			r, err := s.FindRoute(unspecifiedNICID, tcpip.Address{} /* localAddr */, test.remoteAddr, netProto, false /* multicastLoop */)
  4183  			if err != nil {
  4184  				t.Fatalf("FindRoute(%d, '', %s, %d): %s", unspecifiedNICID, test.remoteAddr, netProto, err)
  4185  			}
  4186  			if r.LocalAddress() != test.expectedLocalAddress {
  4187  				t.Errorf("got r.LocalAddress() = %s, want = %s", r.LocalAddress(), test.expectedLocalAddress)
  4188  			}
  4189  			if r.RemoteAddress() != test.expectedRemoteAddress {
  4190  				t.Errorf("got r.RemoteAddress = %s, want = %s", r.RemoteAddress(), test.expectedRemoteAddress)
  4191  			}
  4192  			if got := r.RemoteLinkAddress(); got != test.expectedRemoteLinkAddress {
  4193  				t.Errorf("got r.RemoteLinkAddress() = %s, want = %s", got, test.expectedRemoteLinkAddress)
  4194  			}
  4195  			if r.NextHop() != test.expectedNextHop {
  4196  				t.Errorf("got r.NextHop() = %s, want = %s", r.NextHop(), test.expectedNextHop)
  4197  			}
  4198  			if r.NetProto() != test.expectedNetProto {
  4199  				t.Errorf("got r.NetProto() = %d, want = %d", r.NetProto(), test.expectedNetProto)
  4200  			}
  4201  			if r.Loop() != test.expectedLoop {
  4202  				t.Errorf("got r.Loop() = %x, want = %x", r.Loop(), test.expectedLoop)
  4203  			}
  4204  		})
  4205  	}
  4206  }
  4207  
  4208  func TestResolveWith(t *testing.T) {
  4209  	const (
  4210  		unspecifiedNICID = 0
  4211  		nicID            = 1
  4212  	)
  4213  
  4214  	s := stack.New(stack.Options{
  4215  		NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol, arp.NewProtocol},
  4216  	})
  4217  	ep := channel.New(0, defaultMTU, "")
  4218  	ep.LinkEPCapabilities |= stack.CapabilityResolutionRequired
  4219  	if err := s.CreateNIC(nicID, ep); err != nil {
  4220  		t.Fatalf("CreateNIC(%d, _): %s", nicID, err)
  4221  	}
  4222  	addr := tcpip.ProtocolAddress{
  4223  		Protocol: header.IPv4ProtocolNumber,
  4224  		AddressWithPrefix: tcpip.AddressWithPrefix{
  4225  			Address:   tcpip.AddrFrom4Slice([]byte{192, 168, 1, 58}),
  4226  			PrefixLen: 24,
  4227  		},
  4228  	}
  4229  	if err := s.AddProtocolAddress(nicID, addr, stack.AddressProperties{}); err != nil {
  4230  		t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", nicID, addr, err)
  4231  	}
  4232  
  4233  	s.SetRouteTable([]tcpip.Route{{Destination: header.IPv4EmptySubnet, NIC: nicID}})
  4234  
  4235  	remoteAddr := tcpip.AddrFrom4Slice([]byte{192, 168, 1, 59})
  4236  	r, err := s.FindRoute(unspecifiedNICID, tcpip.Address{} /* localAddr */, remoteAddr, header.IPv4ProtocolNumber, false /* multicastLoop */)
  4237  	if err != nil {
  4238  		t.Fatalf("FindRoute(%d, '', %s, %d): %s", unspecifiedNICID, remoteAddr, header.IPv4ProtocolNumber, err)
  4239  	}
  4240  	defer r.Release()
  4241  
  4242  	// Should initially require resolution.
  4243  	if !r.IsResolutionRequired() {
  4244  		t.Fatal("got r.IsResolutionRequired() = false, want = true")
  4245  	}
  4246  
  4247  	// Manually resolving the route should no longer require resolution.
  4248  	r.ResolveWith("\x01")
  4249  	if r.IsResolutionRequired() {
  4250  		t.Fatal("got r.IsResolutionRequired() = true, want = false")
  4251  	}
  4252  }
  4253  
  4254  // TestRouteReleaseAfterAddrRemoval tests that releasing a Route after its
  4255  // associated address is removed should not cause a panic.
  4256  func TestRouteReleaseAfterAddrRemoval(t *testing.T) {
  4257  	const (
  4258  		nicID = 1
  4259  	)
  4260  	var (
  4261  		localAddr  = tcpip.AddrFromSlice([]byte("\x01\x00\x00\x00"))
  4262  		remoteAddr = tcpip.AddrFromSlice([]byte("\x02\x00\x00\x00"))
  4263  	)
  4264  
  4265  	s := stack.New(stack.Options{
  4266  		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
  4267  	})
  4268  
  4269  	ep := channel.New(0, defaultMTU, "")
  4270  	if err := s.CreateNIC(nicID, ep); err != nil {
  4271  		t.Fatalf("CreateNIC(%d, _): %s", nicID, err)
  4272  	}
  4273  	protocolAddr := tcpip.ProtocolAddress{
  4274  		Protocol: fakeNetNumber,
  4275  		AddressWithPrefix: tcpip.AddressWithPrefix{
  4276  			Address:   localAddr,
  4277  			PrefixLen: fakeDefaultPrefixLen,
  4278  		},
  4279  	}
  4280  	if err := s.AddProtocolAddress(nicID, protocolAddr, stack.AddressProperties{}); err != nil {
  4281  		t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", nicID, protocolAddr, err)
  4282  	}
  4283  	{
  4284  		subnet, err := tcpip.NewSubnet(tcpip.AddrFromSlice([]byte("\x00\x00\x00\x00")), tcpip.MaskFrom("\x00\x00\x00\x00"))
  4285  		if err != nil {
  4286  			t.Fatal(err)
  4287  		}
  4288  		s.SetRouteTable([]tcpip.Route{{Destination: subnet, Gateway: tcpip.AddrFromSlice([]byte("\x00\x00\x00\x00")), NIC: 1}})
  4289  	}
  4290  
  4291  	r, err := s.FindRoute(nicID, localAddr, remoteAddr, fakeNetNumber, false /* multicastLoop */)
  4292  	if err != nil {
  4293  		t.Fatalf("s.FindRoute(%d, %s, %s, %d, false): %s", nicID, localAddr, remoteAddr, fakeNetNumber, err)
  4294  	}
  4295  	// Should not panic.
  4296  	defer r.Release()
  4297  
  4298  	// Check that removing the same address fails.
  4299  	if err := s.RemoveAddress(nicID, localAddr); err != nil {
  4300  		t.Fatalf("s.RemoveAddress(%d, %s): %s", nicID, localAddr, err)
  4301  	}
  4302  }
  4303  
  4304  func TestGetNetworkEndpoint(t *testing.T) {
  4305  	const nicID = 1
  4306  
  4307  	tests := []struct {
  4308  		name         string
  4309  		protoFactory stack.NetworkProtocolFactory
  4310  		protoNum     tcpip.NetworkProtocolNumber
  4311  	}{
  4312  		{
  4313  			name:         "IPv4",
  4314  			protoFactory: ipv4.NewProtocol,
  4315  			protoNum:     ipv4.ProtocolNumber,
  4316  		},
  4317  		{
  4318  			name:         "IPv6",
  4319  			protoFactory: ipv6.NewProtocol,
  4320  			protoNum:     ipv6.ProtocolNumber,
  4321  		},
  4322  	}
  4323  
  4324  	factories := make([]stack.NetworkProtocolFactory, 0, len(tests))
  4325  	for _, test := range tests {
  4326  		factories = append(factories, test.protoFactory)
  4327  	}
  4328  
  4329  	s := stack.New(stack.Options{
  4330  		NetworkProtocols: factories,
  4331  	})
  4332  
  4333  	if err := s.CreateNIC(nicID, channel.New(0, defaultMTU, "")); err != nil {
  4334  		t.Fatalf("CreateNIC(%d, _): %s", nicID, err)
  4335  	}
  4336  
  4337  	for _, test := range tests {
  4338  		t.Run(test.name, func(t *testing.T) {
  4339  			ep, err := s.GetNetworkEndpoint(nicID, test.protoNum)
  4340  			if err != nil {
  4341  				t.Fatalf("s.GetNetworkEndpoint(%d, %d): %s", nicID, test.protoNum, err)
  4342  			}
  4343  
  4344  			if got := ep.NetworkProtocolNumber(); got != test.protoNum {
  4345  				t.Fatalf("got ep.NetworkProtocolNumber() = %d, want = %d", got, test.protoNum)
  4346  			}
  4347  		})
  4348  	}
  4349  }
  4350  
  4351  func TestGetMainNICAddressWhenNICDisabled(t *testing.T) {
  4352  	const nicID = 1
  4353  
  4354  	s := stack.New(stack.Options{
  4355  		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
  4356  	})
  4357  
  4358  	if err := s.CreateNIC(nicID, channel.New(0, defaultMTU, "")); err != nil {
  4359  		t.Fatalf("CreateNIC(%d, _): %s", nicID, err)
  4360  	}
  4361  
  4362  	protocolAddress := tcpip.ProtocolAddress{
  4363  		Protocol: fakeNetNumber,
  4364  		AddressWithPrefix: tcpip.AddressWithPrefix{
  4365  			Address:   tcpip.AddrFromSlice([]byte("\x01\x00\x00\x00")),
  4366  			PrefixLen: 32,
  4367  		},
  4368  	}
  4369  	if err := s.AddProtocolAddress(nicID, protocolAddress, stack.AddressProperties{}); err != nil {
  4370  		t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", nicID, protocolAddress, err)
  4371  	}
  4372  
  4373  	// Check that we get the right initial address and prefix length.
  4374  	if err := checkGetMainNICAddress(s, nicID, fakeNetNumber, protocolAddress.AddressWithPrefix); err != nil {
  4375  		t.Fatal(err)
  4376  	}
  4377  
  4378  	// Should still get the address when the NIC is disabled.
  4379  	if err := s.DisableNIC(nicID); err != nil {
  4380  		t.Fatalf("DisableNIC(%d): %s", nicID, err)
  4381  	}
  4382  	if err := checkGetMainNICAddress(s, nicID, fakeNetNumber, protocolAddress.AddressWithPrefix); err != nil {
  4383  		t.Fatal(err)
  4384  	}
  4385  }
  4386  
  4387  // TestAddRoute tests Stack.AddRoute
  4388  func TestAddRoute(t *testing.T) {
  4389  	s := stack.New(stack.Options{})
  4390  
  4391  	subnet1, err := tcpip.NewSubnet(tcpip.AddrFromSlice([]byte("\x00\x00\x00\x00")), tcpip.MaskFrom("\x00\x00\x00\x00"))
  4392  	if err != nil {
  4393  		t.Fatal(err)
  4394  	}
  4395  
  4396  	subnet2, err := tcpip.NewSubnet(tcpip.AddrFromSlice([]byte("\x01\x00\x00\x00")), tcpip.MaskFrom("\x01\x00\x00\x00"))
  4397  	if err != nil {
  4398  		t.Fatal(err)
  4399  	}
  4400  
  4401  	expected := []tcpip.Route{
  4402  		{Destination: subnet1, Gateway: tcpip.AddrFromSlice([]byte("\x00\x00\x00\x00")), NIC: 1},
  4403  		{Destination: subnet2, Gateway: tcpip.AddrFromSlice([]byte("\x00\x00\x00\x00")), NIC: 1},
  4404  	}
  4405  
  4406  	// Initialize the route table with one route.
  4407  	s.SetRouteTable([]tcpip.Route{expected[0]})
  4408  
  4409  	// Add another route.
  4410  	s.AddRoute(expected[1])
  4411  
  4412  	rt := s.GetRouteTable()
  4413  	if got, want := len(rt), len(expected); got != want {
  4414  		t.Fatalf("Unexpected route table length got = %d, want = %d", got, want)
  4415  	}
  4416  	for i, route := range rt {
  4417  		if got, want := route, expected[i]; got != want {
  4418  			t.Fatalf("Unexpected route got = %#v, want = %#v", got, want)
  4419  		}
  4420  	}
  4421  }
  4422  
  4423  // TestRemoveRoutes tests Stack.RemoveRoutes
  4424  func TestRemoveRoutes(t *testing.T) {
  4425  	s := stack.New(stack.Options{})
  4426  
  4427  	addressToRemove := tcpip.AddrFromSlice([]byte("\x01\x00\x00\x00"))
  4428  	subnet1, err := tcpip.NewSubnet(addressToRemove, tcpip.MaskFrom("\x01\x00\x00\x00"))
  4429  	if err != nil {
  4430  		t.Fatal(err)
  4431  	}
  4432  
  4433  	subnet2, err := tcpip.NewSubnet(addressToRemove, tcpip.MaskFrom("\x01\x00\x00\x00"))
  4434  	if err != nil {
  4435  		t.Fatal(err)
  4436  	}
  4437  
  4438  	subnet3, err := tcpip.NewSubnet(tcpip.AddrFromSlice([]byte("\x02\x00\x00\x00")), tcpip.MaskFrom("\x02\x00\x00\x00"))
  4439  	if err != nil {
  4440  		t.Fatal(err)
  4441  	}
  4442  
  4443  	// Initialize the route table with three routes.
  4444  	s.SetRouteTable([]tcpip.Route{
  4445  		{Destination: subnet1, Gateway: tcpip.AddrFromSlice([]byte("\x00\x00\x00\x00")), NIC: 1},
  4446  		{Destination: subnet2, Gateway: tcpip.AddrFromSlice([]byte("\x00\x00\x00\x00")), NIC: 1},
  4447  		{Destination: subnet3, Gateway: tcpip.AddrFromSlice([]byte("\x00\x00\x00\x00")), NIC: 1},
  4448  	})
  4449  
  4450  	// Remove routes with the specific address.
  4451  	s.RemoveRoutes(func(r tcpip.Route) bool {
  4452  		return r.Destination.ID() == addressToRemove
  4453  	})
  4454  
  4455  	expected := []tcpip.Route{{Destination: subnet3, Gateway: tcpip.AddrFromSlice([]byte("\x00\x00\x00\x00")), NIC: 1}}
  4456  	rt := s.GetRouteTable()
  4457  	if got, want := len(rt), len(expected); got != want {
  4458  		t.Fatalf("Unexpected route table length got = %d, want = %d", got, want)
  4459  	}
  4460  	for i, route := range rt {
  4461  		if got, want := route, expected[i]; got != want {
  4462  			t.Fatalf("Unexpected route got = %#v, want = %#v", got, want)
  4463  		}
  4464  	}
  4465  }
  4466  
  4467  func TestFindRouteWithForwarding(t *testing.T) {
  4468  	const (
  4469  		nicID1 = 1
  4470  		nicID2 = 2
  4471  	)
  4472  	var (
  4473  		nic1Addr   = tcpip.AddrFromSlice([]byte("\x01\x00\x00\x00"))
  4474  		nic2Addr   = tcpip.AddrFromSlice([]byte("\x02\x00\x00\x00"))
  4475  		remoteAddr = tcpip.AddrFromSlice([]byte("\x03\x00\x00\x00"))
  4476  	)
  4477  
  4478  	type netCfg struct {
  4479  		proto              tcpip.NetworkProtocolNumber
  4480  		factory            stack.NetworkProtocolFactory
  4481  		nic1AddrWithPrefix tcpip.AddressWithPrefix
  4482  		nic2AddrWithPrefix tcpip.AddressWithPrefix
  4483  		remoteAddr         tcpip.Address
  4484  	}
  4485  
  4486  	fakeNetCfg := netCfg{
  4487  		proto:              fakeNetNumber,
  4488  		factory:            fakeNetFactory,
  4489  		nic1AddrWithPrefix: tcpip.AddressWithPrefix{Address: nic1Addr, PrefixLen: fakeDefaultPrefixLen},
  4490  		nic2AddrWithPrefix: tcpip.AddressWithPrefix{Address: nic2Addr, PrefixLen: fakeDefaultPrefixLen},
  4491  		remoteAddr:         remoteAddr,
  4492  	}
  4493  
  4494  	globalIPv6Addr1 := tcpip.AddrFrom16Slice(net.ParseIP("a::1").To16())
  4495  	globalIPv6Addr2 := tcpip.AddrFrom16Slice(net.ParseIP("a::2").To16())
  4496  
  4497  	ipv6LinkLocalNIC1WithGlobalRemote := netCfg{
  4498  		proto:              ipv6.ProtocolNumber,
  4499  		factory:            ipv6.NewProtocol,
  4500  		nic1AddrWithPrefix: llAddr1.WithPrefix(),
  4501  		nic2AddrWithPrefix: globalIPv6Addr2.WithPrefix(),
  4502  		remoteAddr:         globalIPv6Addr1,
  4503  	}
  4504  	ipv6GlobalNIC1WithLinkLocalRemote := netCfg{
  4505  		proto:              ipv6.ProtocolNumber,
  4506  		factory:            ipv6.NewProtocol,
  4507  		nic1AddrWithPrefix: globalIPv6Addr1.WithPrefix(),
  4508  		nic2AddrWithPrefix: llAddr1.WithPrefix(),
  4509  		remoteAddr:         llAddr2,
  4510  	}
  4511  	ipv6GlobalNIC1WithLinkLocalMulticastRemote := netCfg{
  4512  		proto:              ipv6.ProtocolNumber,
  4513  		factory:            ipv6.NewProtocol,
  4514  		nic1AddrWithPrefix: globalIPv6Addr1.WithPrefix(),
  4515  		nic2AddrWithPrefix: globalIPv6Addr2.WithPrefix(),
  4516  		remoteAddr:         tcpip.AddrFromSlice([]byte("\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01")),
  4517  	}
  4518  
  4519  	tests := []struct {
  4520  		name string
  4521  
  4522  		netCfg            netCfg
  4523  		forwardingEnabled bool
  4524  
  4525  		addrNIC             tcpip.NICID
  4526  		localAddrWithPrefix tcpip.AddressWithPrefix
  4527  
  4528  		findRouteErr          tcpip.Error
  4529  		dependentOnForwarding bool
  4530  	}{
  4531  		{
  4532  			name:                  "forwarding disabled and localAddr not on specified NIC but route from different NIC",
  4533  			netCfg:                fakeNetCfg,
  4534  			forwardingEnabled:     false,
  4535  			addrNIC:               nicID1,
  4536  			localAddrWithPrefix:   fakeNetCfg.nic2AddrWithPrefix,
  4537  			findRouteErr:          &tcpip.ErrHostUnreachable{},
  4538  			dependentOnForwarding: false,
  4539  		},
  4540  		{
  4541  			name:                  "forwarding enabled and localAddr not on specified NIC but route from different NIC",
  4542  			netCfg:                fakeNetCfg,
  4543  			forwardingEnabled:     true,
  4544  			addrNIC:               nicID1,
  4545  			localAddrWithPrefix:   fakeNetCfg.nic2AddrWithPrefix,
  4546  			findRouteErr:          &tcpip.ErrHostUnreachable{},
  4547  			dependentOnForwarding: false,
  4548  		},
  4549  		{
  4550  			name:                  "forwarding disabled and localAddr on specified NIC but route from different NIC",
  4551  			netCfg:                fakeNetCfg,
  4552  			forwardingEnabled:     false,
  4553  			addrNIC:               nicID1,
  4554  			localAddrWithPrefix:   fakeNetCfg.nic1AddrWithPrefix,
  4555  			findRouteErr:          &tcpip.ErrHostUnreachable{},
  4556  			dependentOnForwarding: false,
  4557  		},
  4558  		{
  4559  			name:                  "forwarding enabled and localAddr on specified NIC but route from different NIC",
  4560  			netCfg:                fakeNetCfg,
  4561  			forwardingEnabled:     true,
  4562  			addrNIC:               nicID1,
  4563  			localAddrWithPrefix:   fakeNetCfg.nic1AddrWithPrefix,
  4564  			findRouteErr:          nil,
  4565  			dependentOnForwarding: true,
  4566  		},
  4567  		{
  4568  			name:                  "forwarding disabled and localAddr on specified NIC and route from same NIC",
  4569  			netCfg:                fakeNetCfg,
  4570  			forwardingEnabled:     false,
  4571  			addrNIC:               nicID2,
  4572  			localAddrWithPrefix:   fakeNetCfg.nic2AddrWithPrefix,
  4573  			findRouteErr:          nil,
  4574  			dependentOnForwarding: false,
  4575  		},
  4576  		{
  4577  			name:                  "forwarding enabled and localAddr on specified NIC and route from same NIC",
  4578  			netCfg:                fakeNetCfg,
  4579  			forwardingEnabled:     true,
  4580  			addrNIC:               nicID2,
  4581  			localAddrWithPrefix:   fakeNetCfg.nic2AddrWithPrefix,
  4582  			findRouteErr:          nil,
  4583  			dependentOnForwarding: false,
  4584  		},
  4585  		{
  4586  			name:                  "forwarding disabled and localAddr not on specified NIC but route from same NIC",
  4587  			netCfg:                fakeNetCfg,
  4588  			forwardingEnabled:     false,
  4589  			addrNIC:               nicID2,
  4590  			localAddrWithPrefix:   fakeNetCfg.nic1AddrWithPrefix,
  4591  			findRouteErr:          &tcpip.ErrHostUnreachable{},
  4592  			dependentOnForwarding: false,
  4593  		},
  4594  		{
  4595  			name:                  "forwarding enabled and localAddr not on specified NIC but route from same NIC",
  4596  			netCfg:                fakeNetCfg,
  4597  			forwardingEnabled:     true,
  4598  			addrNIC:               nicID2,
  4599  			localAddrWithPrefix:   fakeNetCfg.nic1AddrWithPrefix,
  4600  			findRouteErr:          &tcpip.ErrHostUnreachable{},
  4601  			dependentOnForwarding: false,
  4602  		},
  4603  		{
  4604  			name:                  "forwarding disabled and localAddr on same NIC as route",
  4605  			netCfg:                fakeNetCfg,
  4606  			forwardingEnabled:     false,
  4607  			localAddrWithPrefix:   fakeNetCfg.nic2AddrWithPrefix,
  4608  			findRouteErr:          nil,
  4609  			dependentOnForwarding: false,
  4610  		},
  4611  		{
  4612  			name:                  "forwarding enabled and localAddr on same NIC as route",
  4613  			netCfg:                fakeNetCfg,
  4614  			forwardingEnabled:     false,
  4615  			localAddrWithPrefix:   fakeNetCfg.nic2AddrWithPrefix,
  4616  			findRouteErr:          nil,
  4617  			dependentOnForwarding: false,
  4618  		},
  4619  		{
  4620  			name:                  "forwarding disabled and localAddr on different NIC as route",
  4621  			netCfg:                fakeNetCfg,
  4622  			forwardingEnabled:     false,
  4623  			localAddrWithPrefix:   fakeNetCfg.nic1AddrWithPrefix,
  4624  			findRouteErr:          &tcpip.ErrHostUnreachable{},
  4625  			dependentOnForwarding: false,
  4626  		},
  4627  		{
  4628  			name:                  "forwarding enabled and localAddr on different NIC as route",
  4629  			netCfg:                fakeNetCfg,
  4630  			forwardingEnabled:     true,
  4631  			localAddrWithPrefix:   fakeNetCfg.nic1AddrWithPrefix,
  4632  			findRouteErr:          nil,
  4633  			dependentOnForwarding: true,
  4634  		},
  4635  		{
  4636  			name:                  "forwarding disabled and specified NIC only has link-local addr with route on different NIC",
  4637  			netCfg:                ipv6LinkLocalNIC1WithGlobalRemote,
  4638  			forwardingEnabled:     false,
  4639  			addrNIC:               nicID1,
  4640  			findRouteErr:          &tcpip.ErrHostUnreachable{},
  4641  			dependentOnForwarding: false,
  4642  		},
  4643  		{
  4644  			name:                  "forwarding enabled and specified NIC only has link-local addr with route on different NIC",
  4645  			netCfg:                ipv6LinkLocalNIC1WithGlobalRemote,
  4646  			forwardingEnabled:     true,
  4647  			addrNIC:               nicID1,
  4648  			findRouteErr:          &tcpip.ErrHostUnreachable{},
  4649  			dependentOnForwarding: false,
  4650  		},
  4651  		{
  4652  			name:                  "forwarding disabled and link-local local addr with route on different NIC",
  4653  			netCfg:                ipv6LinkLocalNIC1WithGlobalRemote,
  4654  			forwardingEnabled:     false,
  4655  			localAddrWithPrefix:   ipv6LinkLocalNIC1WithGlobalRemote.nic1AddrWithPrefix,
  4656  			findRouteErr:          &tcpip.ErrHostUnreachable{},
  4657  			dependentOnForwarding: false,
  4658  		},
  4659  		{
  4660  			name:                  "forwarding enabled and link-local local addr with route on same NIC",
  4661  			netCfg:                ipv6LinkLocalNIC1WithGlobalRemote,
  4662  			forwardingEnabled:     true,
  4663  			localAddrWithPrefix:   ipv6LinkLocalNIC1WithGlobalRemote.nic1AddrWithPrefix,
  4664  			findRouteErr:          &tcpip.ErrHostUnreachable{},
  4665  			dependentOnForwarding: false,
  4666  		},
  4667  		{
  4668  			name:                  "forwarding disabled and global local addr with route on same NIC",
  4669  			netCfg:                ipv6LinkLocalNIC1WithGlobalRemote,
  4670  			forwardingEnabled:     true,
  4671  			localAddrWithPrefix:   ipv6LinkLocalNIC1WithGlobalRemote.nic2AddrWithPrefix,
  4672  			findRouteErr:          nil,
  4673  			dependentOnForwarding: false,
  4674  		},
  4675  		{
  4676  			name:                  "forwarding disabled and link-local local addr with route on same NIC",
  4677  			netCfg:                ipv6GlobalNIC1WithLinkLocalRemote,
  4678  			forwardingEnabled:     false,
  4679  			localAddrWithPrefix:   ipv6GlobalNIC1WithLinkLocalRemote.nic2AddrWithPrefix,
  4680  			findRouteErr:          nil,
  4681  			dependentOnForwarding: false,
  4682  		},
  4683  		{
  4684  			name:                  "forwarding enabled and link-local local addr with route on same NIC",
  4685  			netCfg:                ipv6GlobalNIC1WithLinkLocalRemote,
  4686  			forwardingEnabled:     true,
  4687  			localAddrWithPrefix:   ipv6GlobalNIC1WithLinkLocalRemote.nic2AddrWithPrefix,
  4688  			findRouteErr:          nil,
  4689  			dependentOnForwarding: false,
  4690  		},
  4691  		{
  4692  			name:                  "forwarding disabled and global local addr with link-local remote on different NIC",
  4693  			netCfg:                ipv6GlobalNIC1WithLinkLocalRemote,
  4694  			forwardingEnabled:     false,
  4695  			localAddrWithPrefix:   ipv6GlobalNIC1WithLinkLocalRemote.nic1AddrWithPrefix,
  4696  			findRouteErr:          &tcpip.ErrNetworkUnreachable{},
  4697  			dependentOnForwarding: false,
  4698  		},
  4699  		{
  4700  			name:                  "forwarding enabled and global local addr with link-local remote on different NIC",
  4701  			netCfg:                ipv6GlobalNIC1WithLinkLocalRemote,
  4702  			forwardingEnabled:     true,
  4703  			localAddrWithPrefix:   ipv6GlobalNIC1WithLinkLocalRemote.nic1AddrWithPrefix,
  4704  			findRouteErr:          &tcpip.ErrNetworkUnreachable{},
  4705  			dependentOnForwarding: false,
  4706  		},
  4707  		{
  4708  			name:                  "forwarding disabled and global local addr with link-local multicast remote on different NIC",
  4709  			netCfg:                ipv6GlobalNIC1WithLinkLocalMulticastRemote,
  4710  			forwardingEnabled:     false,
  4711  			localAddrWithPrefix:   ipv6GlobalNIC1WithLinkLocalMulticastRemote.nic1AddrWithPrefix,
  4712  			findRouteErr:          &tcpip.ErrNetworkUnreachable{},
  4713  			dependentOnForwarding: false,
  4714  		},
  4715  		{
  4716  			name:                  "forwarding enabled and global local addr with link-local multicast remote on different NIC",
  4717  			netCfg:                ipv6GlobalNIC1WithLinkLocalMulticastRemote,
  4718  			forwardingEnabled:     true,
  4719  			localAddrWithPrefix:   ipv6GlobalNIC1WithLinkLocalMulticastRemote.nic1AddrWithPrefix,
  4720  			findRouteErr:          &tcpip.ErrNetworkUnreachable{},
  4721  			dependentOnForwarding: false,
  4722  		},
  4723  		{
  4724  			name:                  "forwarding disabled and global local addr with link-local multicast remote on same NIC",
  4725  			netCfg:                ipv6GlobalNIC1WithLinkLocalMulticastRemote,
  4726  			forwardingEnabled:     false,
  4727  			localAddrWithPrefix:   ipv6GlobalNIC1WithLinkLocalMulticastRemote.nic2AddrWithPrefix,
  4728  			findRouteErr:          nil,
  4729  			dependentOnForwarding: false,
  4730  		},
  4731  		{
  4732  			name:                  "forwarding enabled and global local addr with link-local multicast remote on same NIC",
  4733  			netCfg:                ipv6GlobalNIC1WithLinkLocalMulticastRemote,
  4734  			forwardingEnabled:     true,
  4735  			localAddrWithPrefix:   ipv6GlobalNIC1WithLinkLocalMulticastRemote.nic2AddrWithPrefix,
  4736  			findRouteErr:          nil,
  4737  			dependentOnForwarding: false,
  4738  		},
  4739  	}
  4740  
  4741  	for _, test := range tests {
  4742  		t.Run(test.name, func(t *testing.T) {
  4743  			s := stack.New(stack.Options{
  4744  				NetworkProtocols: []stack.NetworkProtocolFactory{test.netCfg.factory},
  4745  			})
  4746  
  4747  			ep1 := channel.New(1, defaultMTU, "")
  4748  			if err := s.CreateNIC(nicID1, ep1); err != nil {
  4749  				t.Fatalf("CreateNIC(%d, _): %s:", nicID1, err)
  4750  			}
  4751  
  4752  			ep2 := channel.New(1, defaultMTU, "")
  4753  			if err := s.CreateNIC(nicID2, ep2); err != nil {
  4754  				t.Fatalf("CreateNIC(%d, _): %s:", nicID2, err)
  4755  			}
  4756  
  4757  			protocolAddr1 := tcpip.ProtocolAddress{
  4758  				Protocol:          test.netCfg.proto,
  4759  				AddressWithPrefix: test.netCfg.nic1AddrWithPrefix,
  4760  			}
  4761  			if err := s.AddProtocolAddress(nicID1, protocolAddr1, stack.AddressProperties{}); err != nil {
  4762  				t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", nicID1, protocolAddr1, err)
  4763  			}
  4764  
  4765  			protocolAddr2 := tcpip.ProtocolAddress{
  4766  				Protocol:          test.netCfg.proto,
  4767  				AddressWithPrefix: test.netCfg.nic2AddrWithPrefix,
  4768  			}
  4769  			if err := s.AddProtocolAddress(nicID2, protocolAddr2, stack.AddressProperties{}); err != nil {
  4770  				t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", nicID2, protocolAddr2, err)
  4771  			}
  4772  
  4773  			if err := s.SetForwardingDefaultAndAllNICs(test.netCfg.proto, test.forwardingEnabled); err != nil {
  4774  				t.Fatalf("SetForwardingDefaultAndAllNICs(%d, %t): %s", test.netCfg.proto, test.forwardingEnabled, err)
  4775  			}
  4776  
  4777  			s.SetRouteTable([]tcpip.Route{{Destination: test.netCfg.remoteAddr.WithPrefix().Subnet(), NIC: nicID2}})
  4778  
  4779  			r, err := s.FindRoute(test.addrNIC, test.localAddrWithPrefix.Address, test.netCfg.remoteAddr, test.netCfg.proto, false /* multicastLoop */)
  4780  			if err == nil {
  4781  				defer r.Release()
  4782  			}
  4783  			if diff := cmp.Diff(test.findRouteErr, err); diff != "" {
  4784  				t.Fatalf("unexpected error from FindRoute(%d, %s, %s, %d, false), (-want, +got):\n%s", test.addrNIC, test.localAddrWithPrefix.Address, test.netCfg.remoteAddr, test.netCfg.proto, diff)
  4785  			}
  4786  
  4787  			if test.findRouteErr != nil {
  4788  				return
  4789  			}
  4790  
  4791  			if r.LocalAddress() != test.localAddrWithPrefix.Address {
  4792  				t.Errorf("got r.LocalAddress() = %s, want = %s", r.LocalAddress(), test.localAddrWithPrefix.Address)
  4793  			}
  4794  			if r.RemoteAddress() != test.netCfg.remoteAddr {
  4795  				t.Errorf("got r.RemoteAddress() = %s, want = %s", r.RemoteAddress(), test.netCfg.remoteAddr)
  4796  			}
  4797  
  4798  			if t.Failed() {
  4799  				t.FailNow()
  4800  			}
  4801  
  4802  			// Sending a packet should always go through NIC2 since we only install a
  4803  			// route to test.netCfg.remoteAddr through NIC2.
  4804  			data := []byte{1, 2, 3, 4}
  4805  			if err := send(r, data); err != nil {
  4806  				t.Fatalf("send(_, _): %s", err)
  4807  			}
  4808  			if n := ep1.Drain(); n != 0 {
  4809  				t.Errorf("got %d unexpected packets from ep1", n)
  4810  			}
  4811  			pkt := ep2.Read()
  4812  			if pkt == nil {
  4813  				t.Fatal("packet not sent through ep2")
  4814  			}
  4815  			defer pkt.DecRef()
  4816  			if pkt.EgressRoute.LocalAddress != test.localAddrWithPrefix.Address {
  4817  				t.Errorf("got pkt.EgressRoute.LocalAddress = %s, want = %s", pkt.EgressRoute.LocalAddress, test.localAddrWithPrefix.Address)
  4818  			}
  4819  			if pkt.EgressRoute.RemoteAddress != test.netCfg.remoteAddr {
  4820  				t.Errorf("got pkt.EgressRoute.RemoteAddress = %s, want = %s", pkt.EgressRoute.RemoteAddress, test.netCfg.remoteAddr)
  4821  			}
  4822  
  4823  			if !test.forwardingEnabled || !test.dependentOnForwarding {
  4824  				return
  4825  			}
  4826  
  4827  			// Disabling forwarding when the route is dependent on forwarding being
  4828  			// enabled should make the route invalid.
  4829  			if err := s.SetForwardingDefaultAndAllNICs(test.netCfg.proto, false); err != nil {
  4830  				t.Fatalf("SetForwardingDefaultAndAllNICs(%d, false): %s", test.netCfg.proto, err)
  4831  			}
  4832  			{
  4833  				err := send(r, data)
  4834  				if _, ok := err.(*tcpip.ErrInvalidEndpointState); !ok {
  4835  					t.Fatalf("got send(_, _) = %s, want = %s", err, &tcpip.ErrInvalidEndpointState{})
  4836  				}
  4837  			}
  4838  			if n := ep1.Drain(); n != 0 {
  4839  				t.Errorf("got %d unexpected packets from ep1", n)
  4840  			}
  4841  			if n := ep2.Drain(); n != 0 {
  4842  				t.Errorf("got %d unexpected packets from ep2", n)
  4843  			}
  4844  		})
  4845  	}
  4846  }
  4847  
  4848  func TestFindRoutePrefersLocalAddrOnlyForLocallyGeneratedTraffic(t *testing.T) {
  4849  	const (
  4850  		nicID1 = 1
  4851  		nicID2 = 2
  4852  	)
  4853  	var (
  4854  		nic1Addr    = tcpip.AddrFromSlice([]byte("\x01\x00\x00\x00"))
  4855  		nic2Addr    = tcpip.AddrFromSlice([]byte("\x02\x00\x00\x00"))
  4856  		gatewayAddr = tcpip.AddrFromSlice([]byte("\x03\x00\x00\x00"))
  4857  	)
  4858  
  4859  	tests := []struct {
  4860  		name            string
  4861  		localAddr       tcpip.Address
  4862  		remoteAddr      tcpip.Address
  4863  		wantOutgoingNIC tcpip.NICID
  4864  	}{
  4865  		{
  4866  			name:            "locally generated traffic routed through default gateway because we prefer local address on outgoing interface",
  4867  			localAddr:       nic1Addr,
  4868  			remoteAddr:      nic2Addr,
  4869  			wantOutgoingNIC: nicID1,
  4870  		},
  4871  		{
  4872  			name:            "forwarded traffic routed through NIC 2 because local address preference only applies to locally generated traffic",
  4873  			localAddr:       tcpip.Address{},
  4874  			remoteAddr:      nic2Addr,
  4875  			wantOutgoingNIC: nicID2,
  4876  		},
  4877  	}
  4878  
  4879  	for _, test := range tests {
  4880  		t.Run(test.name, func(t *testing.T) {
  4881  			s := stack.New(stack.Options{
  4882  				NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
  4883  			})
  4884  
  4885  			ep1 := channel.New(1, defaultMTU, "")
  4886  			if err := s.CreateNIC(nicID1, ep1); err != nil {
  4887  				t.Fatalf("CreateNIC(%d, _): %s:", nicID1, err)
  4888  			}
  4889  
  4890  			ep2 := channel.New(1, defaultMTU, "")
  4891  			if err := s.CreateNIC(nicID2, ep2); err != nil {
  4892  				t.Fatalf("CreateNIC(%d, _): %s:", nicID2, err)
  4893  			}
  4894  
  4895  			// NB: we do *not* assign nic2Addr on NIC 2. We are exercising the scenario when we are forwarding
  4896  			// traffic to an address that we do not own.
  4897  			protocolAddr1 := tcpip.ProtocolAddress{
  4898  				Protocol:          fakeNetNumber,
  4899  				AddressWithPrefix: tcpip.AddressWithPrefix{Address: nic1Addr, PrefixLen: fakeDefaultPrefixLen},
  4900  			}
  4901  			if err := s.AddProtocolAddress(nicID1, protocolAddr1, stack.AddressProperties{}); err != nil {
  4902  				t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", nicID1, protocolAddr1, err)
  4903  			}
  4904  
  4905  			if err := s.SetForwardingDefaultAndAllNICs(fakeNetNumber, true); err != nil {
  4906  				t.Fatalf("SetForwardingDefaultAndAllNICs(%d, %t): %s", fakeNetNumber, true, err)
  4907  			}
  4908  
  4909  			unspecifiedSubnet := func() tcpip.Subnet {
  4910  				unspecifiedSubnet, err := tcpip.NewSubnet(tcpip.AddrFrom4Slice([]byte("\x00\x00\x00\x00")), tcpip.MaskFrom("\x00\x00\x00\x00"))
  4911  				if err != nil {
  4912  					t.Fatal(err)
  4913  				}
  4914  				return unspecifiedSubnet
  4915  			}()
  4916  			s.SetRouteTable([]tcpip.Route{{Destination: nic2Addr.WithPrefix().Subnet(), NIC: nicID2}, {Destination: unspecifiedSubnet, Gateway: gatewayAddr, NIC: nicID1}})
  4917  
  4918  			r, err := s.FindRoute(0, test.localAddr, test.remoteAddr, fakeNetNumber, false /* multicastLoop */)
  4919  			if err != nil {
  4920  				t.Fatalf("FindRoute(0, %s, %s, %d, false): got %s, want nil", test.localAddr, test.remoteAddr, fakeNetNumber, err)
  4921  			}
  4922  			if r.NICID() != test.wantOutgoingNIC {
  4923  				t.Errorf("got r.NICID() = %d, want = %d", r.NICID(), test.wantOutgoingNIC)
  4924  			}
  4925  
  4926  			if t.Failed() {
  4927  				t.FailNow()
  4928  			}
  4929  		})
  4930  	}
  4931  }
  4932  
  4933  func TestAddMulticastRoute(t *testing.T) {
  4934  	const (
  4935  		incomingNICID = 1
  4936  		outgoingNICID = 2
  4937  	)
  4938  	address := testutil.MustParse4("192.168.1.1")
  4939  	outgoingInterfaces := []stack.MulticastRouteOutgoingInterface{{ID: outgoingNICID, MinTTL: 3}}
  4940  	addresses := stack.UnicastSourceAndMulticastDestination{Source: address, Destination: address}
  4941  
  4942  	tests := []struct {
  4943  		name     string
  4944  		netProto tcpip.NetworkProtocolNumber
  4945  		factory  stack.NetworkProtocolFactory
  4946  		wantErr  tcpip.Error
  4947  	}{
  4948  		{
  4949  			name:     "valid",
  4950  			netProto: fakeNetNumber,
  4951  			factory:  fakeNetFactory,
  4952  			wantErr:  nil,
  4953  		},
  4954  		{
  4955  			name:     "unknown protocol",
  4956  			factory:  fakeNetFactory,
  4957  			netProto: arp.ProtocolNumber,
  4958  			wantErr:  &tcpip.ErrUnknownProtocol{},
  4959  		},
  4960  		{
  4961  			name:     "not supported",
  4962  			factory:  arp.NewProtocol,
  4963  			netProto: arp.ProtocolNumber,
  4964  			wantErr:  &tcpip.ErrNotSupported{},
  4965  		},
  4966  	}
  4967  	for _, test := range tests {
  4968  		t.Run(test.name, func(t *testing.T) {
  4969  			s := stack.New(stack.Options{
  4970  				NetworkProtocols: []stack.NetworkProtocolFactory{test.factory},
  4971  			})
  4972  
  4973  			route := stack.MulticastRoute{
  4974  				ExpectedInputInterface: incomingNICID,
  4975  				OutgoingInterfaces:     outgoingInterfaces,
  4976  			}
  4977  
  4978  			err := s.AddMulticastRoute(test.netProto, addresses, route)
  4979  
  4980  			if !cmp.Equal(err, test.wantErr, cmpopts.EquateErrors()) {
  4981  				t.Errorf("s.AddMulticastRoute(%d, %#v, %#v) = %s, want %s", test.netProto, addresses, route, err, test.wantErr)
  4982  			}
  4983  
  4984  			if test.wantErr == nil {
  4985  				fakeNet := s.NetworkProtocolInstance(fakeNetNumber).(*fakeNetworkProtocol)
  4986  
  4987  				expectedAddMulticastRouteData := addMulticastRouteData{addresses, route}
  4988  				if !cmp.Equal(fakeNet.addMulticastRouteData, expectedAddMulticastRouteData, cmp.AllowUnexported(addMulticastRouteData{}, stack.MulticastRoute{})) {
  4989  					t.Errorf("fakeNet.addMulticastRouteData = %#v, want = %#v", fakeNet.addMulticastRouteData, expectedAddMulticastRouteData)
  4990  				}
  4991  			}
  4992  		})
  4993  	}
  4994  }
  4995  
  4996  func TestRemoveMulticastRoute(t *testing.T) {
  4997  	const nicID = 1
  4998  	address := testutil.MustParse4("192.168.1.1")
  4999  	addresses := stack.UnicastSourceAndMulticastDestination{Source: address, Destination: address}
  5000  
  5001  	tests := []struct {
  5002  		name     string
  5003  		netProto tcpip.NetworkProtocolNumber
  5004  		factory  stack.NetworkProtocolFactory
  5005  		wantErr  tcpip.Error
  5006  	}{
  5007  		{
  5008  			name:     "valid",
  5009  			netProto: fakeNetNumber,
  5010  			factory:  fakeNetFactory,
  5011  			wantErr:  nil,
  5012  		},
  5013  		{
  5014  			name:     "unknown protocol",
  5015  			factory:  fakeNetFactory,
  5016  			netProto: arp.ProtocolNumber,
  5017  			wantErr:  &tcpip.ErrUnknownProtocol{},
  5018  		},
  5019  		{
  5020  			name:     "not supported",
  5021  			factory:  arp.NewProtocol,
  5022  			netProto: arp.ProtocolNumber,
  5023  			wantErr:  &tcpip.ErrNotSupported{},
  5024  		},
  5025  	}
  5026  	for _, test := range tests {
  5027  		t.Run(test.name, func(t *testing.T) {
  5028  			s := stack.New(stack.Options{
  5029  				NetworkProtocols: []stack.NetworkProtocolFactory{test.factory},
  5030  			})
  5031  
  5032  			err := s.RemoveMulticastRoute(test.netProto, addresses)
  5033  
  5034  			if !cmp.Equal(err, test.wantErr, cmpopts.EquateErrors()) {
  5035  				t.Errorf("s.RemoveMulticastRoute(%d, %#v) = %s, want %s", test.netProto, addresses, err, test.wantErr)
  5036  			}
  5037  
  5038  			if test.wantErr == nil {
  5039  				fakeNet := s.NetworkProtocolInstance(fakeNetNumber).(*fakeNetworkProtocol)
  5040  				if !cmp.Equal(fakeNet.removeMulticastRouteData, addresses) {
  5041  					t.Errorf("fakeNet.removeMulticastRouteData = %#v, want = %#v", fakeNet.removeMulticastRouteData, addresses)
  5042  				}
  5043  			}
  5044  		})
  5045  	}
  5046  }
  5047  
  5048  func TestMulticastRouteLastUsedTime(t *testing.T) {
  5049  	address := testutil.MustParse4("192.168.1.1")
  5050  	addresses := stack.UnicastSourceAndMulticastDestination{Source: address, Destination: address}
  5051  
  5052  	tests := []struct {
  5053  		name     string
  5054  		netProto tcpip.NetworkProtocolNumber
  5055  		factory  stack.NetworkProtocolFactory
  5056  		wantErr  tcpip.Error
  5057  	}{
  5058  		{
  5059  			name:     "valid",
  5060  			netProto: fakeNetNumber,
  5061  			factory:  fakeNetFactory,
  5062  			wantErr:  nil,
  5063  		},
  5064  		{
  5065  			name:     "unknown protocol",
  5066  			factory:  fakeNetFactory,
  5067  			netProto: arp.ProtocolNumber,
  5068  			wantErr:  &tcpip.ErrUnknownProtocol{},
  5069  		},
  5070  		{
  5071  			name:     "not supported",
  5072  			factory:  arp.NewProtocol,
  5073  			netProto: arp.ProtocolNumber,
  5074  			wantErr:  &tcpip.ErrNotSupported{},
  5075  		},
  5076  	}
  5077  	for _, test := range tests {
  5078  		t.Run(test.name, func(t *testing.T) {
  5079  			s := stack.New(stack.Options{
  5080  				NetworkProtocols: []stack.NetworkProtocolFactory{test.factory},
  5081  			})
  5082  
  5083  			_, err := s.MulticastRouteLastUsedTime(test.netProto, addresses)
  5084  
  5085  			if !cmp.Equal(err, test.wantErr, cmpopts.EquateErrors()) {
  5086  				t.Errorf("s.MulticastRouteLastUsedTime(%d, %#v) = %v, want %v", test.netProto, addresses, err, test.wantErr)
  5087  			}
  5088  
  5089  			if test.wantErr == nil {
  5090  				fakeNet := s.NetworkProtocolInstance(fakeNetNumber).(*fakeNetworkProtocol)
  5091  
  5092  				if !cmp.Equal(fakeNet.multicastRouteLastUsedTimeData, addresses) {
  5093  					t.Errorf("fakeNet.multicastRouteLastUsedTimeData = %#v, want = %#v", fakeNet.multicastRouteLastUsedTimeData, addresses)
  5094  				}
  5095  			}
  5096  		})
  5097  	}
  5098  }
  5099  
  5100  func TestEnableMulticastForwardingForProtocol(t *testing.T) {
  5101  	tests := []struct {
  5102  		name           string
  5103  		netProto       tcpip.NetworkProtocolNumber
  5104  		factory        stack.NetworkProtocolFactory
  5105  		delegateOutput enableMulticastForwardingForProtocolResult
  5106  		wantResult     enableMulticastForwardingForProtocolResult
  5107  	}{
  5108  		{
  5109  			name:           "impl returns previously enabled",
  5110  			netProto:       fakeNetNumber,
  5111  			factory:        fakeNetFactory,
  5112  			delegateOutput: enableMulticastForwardingForProtocolResult{true, nil},
  5113  			wantResult:     enableMulticastForwardingForProtocolResult{true, nil},
  5114  		},
  5115  		{
  5116  			name:           "impl returns previously disabled",
  5117  			netProto:       fakeNetNumber,
  5118  			factory:        fakeNetFactory,
  5119  			delegateOutput: enableMulticastForwardingForProtocolResult{false, nil},
  5120  			wantResult:     enableMulticastForwardingForProtocolResult{false, nil},
  5121  		},
  5122  		{
  5123  			name:           "impl returns error",
  5124  			netProto:       fakeNetNumber,
  5125  			factory:        fakeNetFactory,
  5126  			delegateOutput: enableMulticastForwardingForProtocolResult{false, &tcpip.ErrUnknownDevice{}},
  5127  			wantResult:     enableMulticastForwardingForProtocolResult{false, &tcpip.ErrUnknownDevice{}},
  5128  		},
  5129  		{
  5130  			name:       "unknown protocol",
  5131  			factory:    fakeNetFactory,
  5132  			netProto:   arp.ProtocolNumber,
  5133  			wantResult: enableMulticastForwardingForProtocolResult{false, &tcpip.ErrUnknownProtocol{}},
  5134  		},
  5135  		{
  5136  			name:       "not supported",
  5137  			factory:    arp.NewProtocol,
  5138  			netProto:   arp.ProtocolNumber,
  5139  			wantResult: enableMulticastForwardingForProtocolResult{false, &tcpip.ErrNotSupported{}},
  5140  		},
  5141  	}
  5142  	for _, test := range tests {
  5143  		t.Run(test.name, func(t *testing.T) {
  5144  			s := stack.New(stack.Options{
  5145  				NetworkProtocols: []stack.NetworkProtocolFactory{test.factory},
  5146  			})
  5147  
  5148  			if test.netProto == fakeNetNumber {
  5149  				fakeNet := s.NetworkProtocolInstance(fakeNetNumber).(*fakeNetworkProtocol)
  5150  				fakeNet.enableMulticastForwardingForProtocolResult = test.delegateOutput
  5151  			}
  5152  
  5153  			alreadyEnabled, err := s.EnableMulticastForwardingForProtocol(test.netProto, &fakeMulticastEventDispatcher{})
  5154  
  5155  			if !cmp.Equal(enableMulticastForwardingForProtocolResult{alreadyEnabled, err}, test.wantResult, cmpopts.EquateErrors()) {
  5156  				t.Errorf("s.EnableMulticastForwardingForProtocol(%d, _) = (%t, %s), want = (%t, %s)", test.netProto, alreadyEnabled, err, test.wantResult.AlreadyEnabled, test.wantResult.Err)
  5157  			}
  5158  		})
  5159  	}
  5160  }
  5161  
  5162  func TestDisableMulticastForwardingForProtocol(t *testing.T) {
  5163  	tests := []struct {
  5164  		name     string
  5165  		netProto tcpip.NetworkProtocolNumber
  5166  		factory  stack.NetworkProtocolFactory
  5167  		wantErr  tcpip.Error
  5168  	}{
  5169  		{
  5170  			name:     "valid",
  5171  			netProto: fakeNetNumber,
  5172  			factory:  fakeNetFactory,
  5173  			wantErr:  nil,
  5174  		},
  5175  		{
  5176  			name:     "unknown protocol",
  5177  			factory:  fakeNetFactory,
  5178  			netProto: arp.ProtocolNumber,
  5179  			wantErr:  &tcpip.ErrUnknownProtocol{},
  5180  		},
  5181  		{
  5182  			name:     "not supported",
  5183  			factory:  arp.NewProtocol,
  5184  			netProto: arp.ProtocolNumber,
  5185  			wantErr:  &tcpip.ErrNotSupported{},
  5186  		},
  5187  	}
  5188  	for _, test := range tests {
  5189  		t.Run(test.name, func(t *testing.T) {
  5190  			s := stack.New(stack.Options{
  5191  				NetworkProtocols: []stack.NetworkProtocolFactory{test.factory},
  5192  			})
  5193  
  5194  			err := s.DisableMulticastForwardingForProtocol(test.netProto)
  5195  
  5196  			if !cmp.Equal(err, test.wantErr, cmpopts.EquateErrors()) {
  5197  				t.Errorf("s.DisableMulticastForwardingForProtocol(%d) = %s, want = %s", test.netProto, err, test.wantErr)
  5198  			}
  5199  
  5200  			if err == nil {
  5201  				fakeNet := s.NetworkProtocolInstance(fakeNetNumber).(*fakeNetworkProtocol)
  5202  				if !fakeNet.disableMulticastForwardingForProtocolCalled {
  5203  					t.Errorf("fakeNet.disableMulticastForwardingForProtocolCalled = false, want = true")
  5204  				}
  5205  			}
  5206  		})
  5207  	}
  5208  }
  5209  
  5210  func TestNICForwarding(t *testing.T) {
  5211  	const nicID = 1
  5212  
  5213  	tests := []struct {
  5214  		name     string
  5215  		factory  stack.NetworkProtocolFactory
  5216  		netProto tcpip.NetworkProtocolNumber
  5217  	}{
  5218  		{
  5219  			name:     "Fake Network",
  5220  			factory:  fakeNetFactory,
  5221  			netProto: fakeNetNumber,
  5222  		},
  5223  		{
  5224  			name:     "IPv4",
  5225  			factory:  ipv4.NewProtocol,
  5226  			netProto: ipv4.ProtocolNumber,
  5227  		},
  5228  		{
  5229  			name:     "IPv6",
  5230  			factory:  ipv6.NewProtocol,
  5231  			netProto: ipv6.ProtocolNumber,
  5232  		},
  5233  	}
  5234  
  5235  	subTests := []struct {
  5236  		name                     string
  5237  		getForwardingFunc        func(*stack.Stack, tcpip.NICID, tcpip.NetworkProtocolNumber) (bool, tcpip.Error)
  5238  		getForwardingFuncName    string
  5239  		setForwardingFunc        func(*stack.Stack, tcpip.NICID, tcpip.NetworkProtocolNumber, bool) (bool, tcpip.Error)
  5240  		setForwardingFuncName    string
  5241  		getNicInfoForwardingMap  func(stack.NICInfo) map[tcpip.NetworkProtocolNumber]bool
  5242  		nicInfoForwardingMapName string
  5243  	}{
  5244  		{
  5245  			name:                     "unicast",
  5246  			getForwardingFunc:        (*stack.Stack).NICForwarding,
  5247  			getForwardingFuncName:    "NICForwarding",
  5248  			setForwardingFunc:        (*stack.Stack).SetNICForwarding,
  5249  			setForwardingFuncName:    "SetNICForwarding",
  5250  			getNicInfoForwardingMap:  func(info stack.NICInfo) map[tcpip.NetworkProtocolNumber]bool { return info.Forwarding },
  5251  			nicInfoForwardingMapName: "Forwarding",
  5252  		},
  5253  		{
  5254  			name:                     "multicast",
  5255  			getForwardingFunc:        (*stack.Stack).NICMulticastForwarding,
  5256  			getForwardingFuncName:    "NICMulticastForwarding",
  5257  			setForwardingFunc:        (*stack.Stack).SetNICMulticastForwarding,
  5258  			setForwardingFuncName:    "SetNICMulticastForwarding",
  5259  			getNicInfoForwardingMap:  func(info stack.NICInfo) map[tcpip.NetworkProtocolNumber]bool { return info.MulticastForwarding },
  5260  			nicInfoForwardingMapName: "MulticastForwarding",
  5261  		},
  5262  	}
  5263  
  5264  	for _, test := range tests {
  5265  		t.Run(test.name, func(t *testing.T) {
  5266  			for _, subTest := range subTests {
  5267  				t.Run(subTest.name, func(t *testing.T) {
  5268  					s := stack.New(stack.Options{
  5269  						NetworkProtocols: []stack.NetworkProtocolFactory{test.factory},
  5270  					})
  5271  					if err := s.CreateNIC(nicID, channel.New(0, defaultMTU, "")); err != nil {
  5272  						t.Fatalf("CreateNIC(%d, _): %s", nicID, err)
  5273  					}
  5274  
  5275  					// Forwarding should initially be disabled.
  5276  					if forwarding, err := subTest.getForwardingFunc(s, nicID, test.netProto); err != nil {
  5277  						t.Fatalf("s.%s(%d, %d): %s", subTest.getForwardingFuncName, nicID, test.netProto, err)
  5278  					} else if forwarding {
  5279  						t.Errorf("got s.%s(%d, %d) = true, want = false", subTest.getForwardingFuncName, nicID, test.netProto)
  5280  					}
  5281  
  5282  					// Setting forwarding to be enabled should return the previous
  5283  					// configuration of false. Enabling it a second time should be a
  5284  					// no-op.
  5285  					for _, wantPrevForwarding := range [...]bool{false, true} {
  5286  						if prevForwarding, err := subTest.setForwardingFunc(s, nicID, test.netProto, true); err != nil {
  5287  							t.Fatalf("s.%s(%d, %d, true): %s", subTest.setForwardingFuncName, nicID, test.netProto, err)
  5288  						} else if prevForwarding != wantPrevForwarding {
  5289  							t.Errorf("got s.%s(%d, %d, true) = %t, want = %t", subTest.setForwardingFuncName, nicID, test.netProto, prevForwarding, wantPrevForwarding)
  5290  						}
  5291  						if forwarding, err := subTest.getForwardingFunc(s, nicID, test.netProto); err != nil {
  5292  							t.Fatalf("s.%s(%d, %d): %s", subTest.getForwardingFuncName, nicID, test.netProto, err)
  5293  						} else if !forwarding {
  5294  							t.Errorf("got s.%s(%d, %d) = false, want = true", subTest.getForwardingFuncName, nicID, test.netProto)
  5295  						}
  5296  						// Verify that the NICInfo also contains the expected value.
  5297  						allNICInfo := s.NICInfo()
  5298  						if info, ok := allNICInfo[nicID]; !ok {
  5299  							t.Fatalf("entry for %d missing from allNICInfo = %+v", nicID, allNICInfo)
  5300  						} else {
  5301  							forwardingMap := subTest.getNicInfoForwardingMap(info)
  5302  							if forward, ok := forwardingMap[test.netProto]; !ok {
  5303  								t.Fatalf("entry for %d missing from info.%s = %+v", test.netProto, subTest.nicInfoForwardingMapName, forwardingMap)
  5304  							} else if !forward {
  5305  								t.Errorf("got info.%s[%d] = %t, want = true", subTest.nicInfoForwardingMapName, test.netProto, forward)
  5306  							}
  5307  						}
  5308  					}
  5309  
  5310  					// Setting forwarding to be disabled should return the previous
  5311  					// configuration of true. Disabling it a second time should be a
  5312  					// no-op.
  5313  					for _, wantPrevForwarding := range [...]bool{true, false} {
  5314  						if prevForwarding, err := subTest.setForwardingFunc(s, nicID, test.netProto, false); err != nil {
  5315  							t.Fatalf("s.%s(%d, %d, false): %s", subTest.setForwardingFuncName, nicID, test.netProto, err)
  5316  						} else if prevForwarding != wantPrevForwarding {
  5317  							t.Errorf("got s.%s(%d, %d, false) = %t, want = %t", subTest.setForwardingFuncName, nicID, test.netProto, prevForwarding, wantPrevForwarding)
  5318  						}
  5319  						if forwarding, err := subTest.getForwardingFunc(s, nicID, test.netProto); err != nil {
  5320  							t.Fatalf("s.%s(%d, %d): %s", subTest.getForwardingFuncName, nicID, test.netProto, err)
  5321  						} else if forwarding {
  5322  							t.Errorf("got s.%s(%d, %d) = true, want = false", subTest.getForwardingFuncName, nicID, test.netProto)
  5323  						}
  5324  						// Verify that the NICInfo also contains the expected value.
  5325  						allNICInfo := s.NICInfo()
  5326  						if info, ok := allNICInfo[nicID]; !ok {
  5327  							t.Fatalf("entry for %d missing from allNICInfo = %+v", nicID, allNICInfo)
  5328  						} else {
  5329  							forwardingMap := subTest.getNicInfoForwardingMap(info)
  5330  							if forward, ok := forwardingMap[test.netProto]; !ok {
  5331  								t.Fatalf("entry for %d missing from info.%s = %+v", test.netProto, subTest.nicInfoForwardingMapName, forwardingMap)
  5332  							} else if forward {
  5333  								t.Errorf("got info.%s[%d] = %t, want = false", subTest.nicInfoForwardingMapName, test.netProto, forward)
  5334  							}
  5335  						}
  5336  					}
  5337  
  5338  				})
  5339  			}
  5340  		})
  5341  	}
  5342  }
  5343  
  5344  func TestWritePacketToRemote(t *testing.T) {
  5345  	const nicID = 1
  5346  	const MTU = 1280
  5347  	e := channel.New(1, MTU, linkAddr1)
  5348  	s := stack.New(stack.Options{})
  5349  	if err := s.CreateNIC(nicID, e); err != nil {
  5350  		t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
  5351  	}
  5352  	if err := s.EnableNIC(nicID); err != nil {
  5353  		t.Fatalf("CreateNIC(%d) = %s", nicID, err)
  5354  	}
  5355  	tests := []struct {
  5356  		name     string
  5357  		protocol tcpip.NetworkProtocolNumber
  5358  		payload  []byte
  5359  	}{
  5360  		{
  5361  			name:     "SuccessIPv4",
  5362  			protocol: header.IPv4ProtocolNumber,
  5363  			payload:  []byte{1, 2, 3, 4},
  5364  		},
  5365  		{
  5366  			name:     "SuccessIPv6",
  5367  			protocol: header.IPv6ProtocolNumber,
  5368  			payload:  []byte{5, 6, 7, 8},
  5369  		},
  5370  	}
  5371  	for _, test := range tests {
  5372  		t.Run(test.name, func(t *testing.T) {
  5373  			if err := s.WritePacketToRemote(nicID, linkAddr2, test.protocol, buffer.MakeWithData(test.payload)); err != nil {
  5374  				t.Fatalf("s.WritePacketToRemote(_, _, _, _) = %s", err)
  5375  			}
  5376  
  5377  			pkt := e.Read()
  5378  			if got, want := pkt != nil, true; got != want {
  5379  				t.Fatalf("e.Read() = %t, want %t", got, want)
  5380  			}
  5381  			defer pkt.DecRef()
  5382  			if got, want := pkt.NetworkProtocolNumber, test.protocol; got != want {
  5383  				t.Fatalf("pkt.NetworkProtocolNumber = %d, want %d", got, want)
  5384  			}
  5385  			if pkt.EgressRoute.RemoteLinkAddress != linkAddr2 {
  5386  				t.Fatalf("pkt.EgressRoute.RemoteAddress = %s, want %s", pkt.EgressRoute.RemoteLinkAddress, linkAddr2)
  5387  			}
  5388  			if diff := cmp.Diff(pkt.Data().AsRange().ToSlice(), test.payload); diff != "" {
  5389  				t.Errorf("pkt.Data mismatch (-want +got):\n%s", diff)
  5390  			}
  5391  		})
  5392  	}
  5393  
  5394  	t.Run("InvalidNICID", func(t *testing.T) {
  5395  		err := s.WritePacketToRemote(234, linkAddr2, header.IPv4ProtocolNumber, buffer.MakeWithData([]byte{1}))
  5396  		if _, ok := err.(*tcpip.ErrUnknownDevice); !ok {
  5397  			t.Fatalf("s.WritePacketToRemote(_, _, _, _) = %s, want = %s", err, &tcpip.ErrUnknownDevice{})
  5398  		}
  5399  		pkt := e.Read()
  5400  		if got, want := pkt != nil, false; got != want {
  5401  			t.Fatalf("e.Read() = %t, %v; want %t", got, pkt, want)
  5402  		}
  5403  	})
  5404  }
  5405  
  5406  func TestClearNeighborCacheOnNICDisable(t *testing.T) {
  5407  	const (
  5408  		nicID    = 1
  5409  		linkAddr = tcpip.LinkAddress("\x02\x02\x03\x04\x05\x06")
  5410  	)
  5411  
  5412  	var (
  5413  		ipv4Addr = testutil.MustParse4("1.2.3.4")
  5414  		ipv6Addr = testutil.MustParse6("102:304:102:304:102:304:102:304")
  5415  	)
  5416  
  5417  	clock := faketime.NewManualClock()
  5418  	s := stack.New(stack.Options{
  5419  		NetworkProtocols: []stack.NetworkProtocolFactory{arp.NewProtocol, ipv4.NewProtocol, ipv6.NewProtocol},
  5420  		Clock:            clock,
  5421  	})
  5422  	e := channel.New(0, 0, "")
  5423  	e.LinkEPCapabilities |= stack.CapabilityResolutionRequired
  5424  	if err := s.CreateNIC(nicID, e); err != nil {
  5425  		t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
  5426  	}
  5427  
  5428  	addrs := []struct {
  5429  		proto tcpip.NetworkProtocolNumber
  5430  		addr  tcpip.Address
  5431  	}{
  5432  		{
  5433  			proto: ipv4.ProtocolNumber,
  5434  			addr:  ipv4Addr,
  5435  		},
  5436  		{
  5437  			proto: ipv6.ProtocolNumber,
  5438  			addr:  ipv6Addr,
  5439  		},
  5440  	}
  5441  	for _, addr := range addrs {
  5442  		if err := s.AddStaticNeighbor(nicID, addr.proto, addr.addr, linkAddr); err != nil {
  5443  			t.Fatalf("s.AddStaticNeighbor(%d, %d, %s, %s): %s", nicID, addr.proto, addr.addr, linkAddr, err)
  5444  		}
  5445  
  5446  		if neighbors, err := s.Neighbors(nicID, addr.proto); err != nil {
  5447  			t.Fatalf("s.Neighbors(%d, %d): %s", nicID, addr.proto, err)
  5448  		} else if diff := cmp.Diff(
  5449  			[]stack.NeighborEntry{{Addr: addr.addr, LinkAddr: linkAddr, State: stack.Static, UpdatedAt: clock.NowMonotonic()}},
  5450  			neighbors,
  5451  			cmp.AllowUnexported(tcpip.MonotonicTime{}),
  5452  		); diff != "" {
  5453  			t.Fatalf("proto=%d neighbors mismatch (-want +got):\n%s", addr.proto, diff)
  5454  		}
  5455  	}
  5456  
  5457  	// Disabling the NIC should clear the neighbor table.
  5458  	if err := s.DisableNIC(nicID); err != nil {
  5459  		t.Fatalf("s.DisableNIC(%d): %s", nicID, err)
  5460  	}
  5461  	for _, addr := range addrs {
  5462  		if neighbors, err := s.Neighbors(nicID, addr.proto); err != nil {
  5463  			t.Fatalf("s.Neighbors(%d, %d): %s", nicID, addr.proto, err)
  5464  		} else if len(neighbors) != 0 {
  5465  			t.Fatalf("got proto=%d len(neighbors) = %d, want = 0; neighbors = %#v", addr.proto, len(neighbors), neighbors)
  5466  		}
  5467  	}
  5468  
  5469  	// Enabling the NIC should have an empty neighbor table.
  5470  	if err := s.EnableNIC(nicID); err != nil {
  5471  		t.Fatalf("s.EnableNIC(%d): %s", nicID, err)
  5472  	}
  5473  	for _, addr := range addrs {
  5474  		if neighbors, err := s.Neighbors(nicID, addr.proto); err != nil {
  5475  			t.Fatalf("s.Neighbors(%d, %d): %s", nicID, addr.proto, err)
  5476  		} else if len(neighbors) != 0 {
  5477  			t.Fatalf("got proto=%d len(neighbors) = %d, want = 0; neighbors = %#v", addr.proto, len(neighbors), neighbors)
  5478  		}
  5479  	}
  5480  }
  5481  
  5482  func TestGetLinkAddressErrors(t *testing.T) {
  5483  	const (
  5484  		nicID        = 1
  5485  		unknownNICID = nicID + 1
  5486  	)
  5487  
  5488  	s := stack.New(stack.Options{
  5489  		NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol},
  5490  	})
  5491  	if err := s.CreateNIC(nicID, channel.New(0, 0, "")); err != nil {
  5492  		t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
  5493  	}
  5494  
  5495  	{
  5496  		err := s.GetLinkAddress(unknownNICID, tcpip.Address{}, tcpip.Address{}, ipv4.ProtocolNumber, nil)
  5497  		if _, ok := err.(*tcpip.ErrUnknownNICID); !ok {
  5498  			t.Errorf("got s.GetLinkAddress(%d, '', '', %d, nil) = %s, want = %s", unknownNICID, ipv4.ProtocolNumber, err, &tcpip.ErrUnknownNICID{})
  5499  		}
  5500  	}
  5501  	{
  5502  		err := s.GetLinkAddress(nicID, tcpip.Address{}, tcpip.Address{}, ipv4.ProtocolNumber, nil)
  5503  		if _, ok := err.(*tcpip.ErrNotSupported); !ok {
  5504  			t.Errorf("got s.GetLinkAddress(%d, '', '', %d, nil) = %s, want = %s", unknownNICID, ipv4.ProtocolNumber, err, &tcpip.ErrNotSupported{})
  5505  		}
  5506  	}
  5507  }
  5508  
  5509  func TestStaticGetLinkAddress(t *testing.T) {
  5510  	const (
  5511  		nicID = 1
  5512  	)
  5513  
  5514  	s := stack.New(stack.Options{
  5515  		NetworkProtocols: []stack.NetworkProtocolFactory{arp.NewProtocol, ipv4.NewProtocol, ipv6.NewProtocol},
  5516  	})
  5517  	e := channel.New(0, 0, "")
  5518  	e.LinkEPCapabilities |= stack.CapabilityResolutionRequired
  5519  	if err := s.CreateNIC(nicID, e); err != nil {
  5520  		t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
  5521  	}
  5522  
  5523  	tests := []struct {
  5524  		name             string
  5525  		proto            tcpip.NetworkProtocolNumber
  5526  		addr             tcpip.Address
  5527  		expectedLinkAddr tcpip.LinkAddress
  5528  	}{
  5529  		{
  5530  			name:             "IPv4",
  5531  			proto:            ipv4.ProtocolNumber,
  5532  			addr:             header.IPv4Broadcast,
  5533  			expectedLinkAddr: header.EthernetBroadcastAddress,
  5534  		},
  5535  		{
  5536  			name:             "IPv6",
  5537  			proto:            ipv6.ProtocolNumber,
  5538  			addr:             header.IPv6AllNodesMulticastAddress,
  5539  			expectedLinkAddr: header.EthernetAddressFromMulticastIPv6Address(header.IPv6AllNodesMulticastAddress),
  5540  		},
  5541  	}
  5542  
  5543  	for _, test := range tests {
  5544  		t.Run(test.name, func(t *testing.T) {
  5545  			ch := make(chan stack.LinkResolutionResult, 1)
  5546  			if err := s.GetLinkAddress(nicID, test.addr, tcpip.Address{}, test.proto, func(r stack.LinkResolutionResult) {
  5547  				ch <- r
  5548  			}); err != nil {
  5549  				t.Fatalf("s.GetLinkAddress(%d, %s, '', %d, _): %s", nicID, test.addr, test.proto, err)
  5550  			}
  5551  
  5552  			if diff := cmp.Diff(stack.LinkResolutionResult{LinkAddress: test.expectedLinkAddr, Err: nil}, <-ch); diff != "" {
  5553  				t.Fatalf("link resolution result mismatch (-want +got):\n%s", diff)
  5554  			}
  5555  		})
  5556  	}
  5557  }
  5558  
  5559  // TODO(b/221146133): Test with:
  5560  //   - Multiple NICs
  5561  //   - Gateway first route tables
  5562  //   - IPv6
  5563  //   - Set local address
  5564  //   - Set NIC
  5565  func TestFindRoute(t *testing.T) {
  5566  	// Just use a consistent prefix length throughout tests for simplicity.
  5567  	const prefixLen = 24
  5568  
  5569  	type nic struct {
  5570  		id        tcpip.NICID
  5571  		addresses []string
  5572  	}
  5573  	type route struct {
  5574  		gateway string
  5575  		subnet  string
  5576  		nic     tcpip.NICID
  5577  		srcHint string
  5578  	}
  5579  	type query struct {
  5580  		name        string
  5581  		remote      string
  5582  		wantID      tcpip.NICID
  5583  		wantLocal   string
  5584  		wantNextHop string
  5585  		wantErr     bool
  5586  	}
  5587  	stacks := []struct {
  5588  		name    string
  5589  		nics    []nic
  5590  		routes  []route
  5591  		queries []query
  5592  	}{
  5593  		{
  5594  			name: "one NIC, multiple addresses, partially overlapping addresses",
  5595  			nics: []nic{{id: 1, addresses: []string{"169.254.9.1", "169.254.169.1"}}},
  5596  			routes: []route{
  5597  				{gateway: "1.1.1.1", subnet: "0.0.0.0/0", nic: 1},
  5598  				{gateway: "1.1.1.1", subnet: "169.254.169.0/25", nic: 1},
  5599  			},
  5600  			queries: []query{
  5601  				{
  5602  					name:        "match default only",
  5603  					remote:      "2.2.2.2",
  5604  					wantID:      1,
  5605  					wantLocal:   "169.254.9.1",
  5606  					wantNextHop: "1.1.1.1",
  5607  				},
  5608  				{
  5609  					name:        "match both, but prefer non-default",
  5610  					remote:      "169.254.169.2",
  5611  					wantID:      1,
  5612  					wantLocal:   "169.254.169.1",
  5613  					wantNextHop: "1.1.1.1",
  5614  				},
  5615  			},
  5616  		},
  5617  		{
  5618  			name: "one NIC, multiple addresses, addresses swapped",
  5619  			nics: []nic{{id: 1, addresses: []string{"192.168.2.1", "192.168.1.1"}}},
  5620  			routes: []route{
  5621  				{gateway: "192.168.2.22", subnet: "192.168.2.0/24", nic: 1},
  5622  				{gateway: "192.168.1.11", subnet: "0.0.0.0/0", nic: 1},
  5623  			},
  5624  			queries: []query{
  5625  				{
  5626  					name:        "match default only",
  5627  					remote:      "1.1.1.1",
  5628  					wantID:      1,
  5629  					wantLocal:   "192.168.2.1",
  5630  					wantNextHop: "192.168.1.11",
  5631  				},
  5632  				{
  5633  					name:        "match both, but prefer non-default",
  5634  					remote:      "192.168.2.2",
  5635  					wantID:      1,
  5636  					wantLocal:   "192.168.2.1",
  5637  					wantNextHop: "192.168.2.22",
  5638  				},
  5639  			},
  5640  		},
  5641  		{
  5642  			name: "one NIC, multiple addresses, gateway last",
  5643  			nics: []nic{{id: 1, addresses: []string{"192.168.1.1", "192.168.2.1"}}},
  5644  			routes: []route{
  5645  				{gateway: "192.168.2.22", subnet: "192.168.2.0/24", nic: 1},
  5646  				{gateway: "192.168.1.11", subnet: "0.0.0.0/0", nic: 1},
  5647  			},
  5648  			queries: []query{
  5649  				{
  5650  					name:        "match default only",
  5651  					remote:      "1.1.1.1",
  5652  					wantID:      1,
  5653  					wantLocal:   "192.168.1.1",
  5654  					wantNextHop: "192.168.1.11",
  5655  				},
  5656  				{
  5657  					name:        "match both, but prefer non-default",
  5658  					remote:      "192.168.2.2",
  5659  					wantID:      1,
  5660  					wantLocal:   "192.168.2.1",
  5661  					wantNextHop: "192.168.2.22",
  5662  				},
  5663  			},
  5664  		},
  5665  		{
  5666  			name: "one NIC, multiple addresses, no default gateway",
  5667  			nics: []nic{{id: 1, addresses: []string{"192.168.1.1", "192.168.2.1"}}},
  5668  			routes: []route{
  5669  				{gateway: "192.168.2.22", subnet: "192.168.2.0/24", nic: 1},
  5670  				{gateway: "192.168.1.11", subnet: "192.168.1.0/24", nic: 1},
  5671  			},
  5672  			queries: []query{
  5673  				{
  5674  					name:        "match single A",
  5675  					remote:      "192.168.1.2",
  5676  					wantID:      1,
  5677  					wantLocal:   "192.168.1.1",
  5678  					wantNextHop: "192.168.1.11",
  5679  				},
  5680  				{
  5681  					name:        "match single B",
  5682  					remote:      "192.168.2.2",
  5683  					wantID:      1,
  5684  					wantLocal:   "192.168.2.1",
  5685  					wantNextHop: "192.168.2.22",
  5686  				},
  5687  				{
  5688  					name:    "match none",
  5689  					remote:  "3.3.3.3",
  5690  					wantErr: true,
  5691  				},
  5692  			},
  5693  		},
  5694  		{
  5695  			name: "one NIC, multiple addresses, no gateways",
  5696  			nics: []nic{{id: 1, addresses: []string{"169.254.169.1", "169.254.9.1"}}},
  5697  			routes: []route{
  5698  				{subnet: "10.0.0.0/8", nic: 1},
  5699  			},
  5700  			queries: []query{
  5701  				{
  5702  					name:        "match first",
  5703  					remote:      "10.132.0.4",
  5704  					wantID:      1,
  5705  					wantLocal:   "169.254.169.1",
  5706  					wantNextHop: "", // No gateway, so no next hop.
  5707  				},
  5708  			},
  5709  		},
  5710  		{
  5711  			name: "one NIC, multiple addresses, source hints, no gateways",
  5712  			nics: []nic{{id: 1, addresses: []string{"169.254.169.1", "169.254.9.1", "10.132.1.1"}}},
  5713  			routes: []route{
  5714  				{subnet: "10.0.0.0/8", nic: 1, srcHint: "169.254.9.1"},
  5715  			},
  5716  			queries: []query{
  5717  				{
  5718  					name:        "match hint",
  5719  					remote:      "10.132.0.4",
  5720  					wantID:      1,
  5721  					wantLocal:   "169.254.9.1",
  5722  					wantNextHop: "", // No gateway, so no next hop.
  5723  				},
  5724  			},
  5725  		},
  5726  	}
  5727  
  5728  	for _, stackConfig := range stacks {
  5729  		t.Run(stackConfig.name, func(t *testing.T) {
  5730  			// Create the stack. The channel endpoint is unused, but necessary for creation.
  5731  			ep := channel.New(1, defaultMTU, "")
  5732  			stk := stack.New(stack.Options{
  5733  				NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol /*, arp.NewProtocol*/},
  5734  			})
  5735  
  5736  			// Create NICs and assign addresses to them.
  5737  			for _, nic := range stackConfig.nics {
  5738  				if err := stk.CreateNIC(nic.id, ep); err != nil {
  5739  					t.Fatal("NewNIC failed:", err)
  5740  				}
  5741  				for _, addr := range nic.addresses {
  5742  					protocolAddr := tcpip.ProtocolAddress{
  5743  						Protocol: header.IPv4ProtocolNumber,
  5744  						AddressWithPrefix: tcpip.AddressWithPrefix{
  5745  							Address:   testutil.MustParse4(addr),
  5746  							PrefixLen: prefixLen,
  5747  						},
  5748  					}
  5749  					if err := stk.AddProtocolAddress(nic.id, protocolAddr, stack.AddressProperties{}); err != nil {
  5750  						t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", 1, protocolAddr, err)
  5751  					}
  5752  				}
  5753  			}
  5754  
  5755  			// Setup the route table.
  5756  			var routeTable []tcpip.Route
  5757  			for _, route := range stackConfig.routes {
  5758  				rt := tcpip.Route{
  5759  					Destination: testutil.MustParseSubnet4(route.subnet),
  5760  					NIC:         route.nic,
  5761  				}
  5762  				if len(route.gateway) > 0 {
  5763  					rt.Gateway = testutil.MustParse4(route.gateway)
  5764  				}
  5765  				if len(route.srcHint) > 0 {
  5766  					rt.SourceHint = testutil.MustParse4(route.srcHint)
  5767  				}
  5768  				routeTable = append(routeTable, rt)
  5769  			}
  5770  			stk.SetRouteTable(routeTable)
  5771  
  5772  			for _, query := range stackConfig.queries {
  5773  				t.Run(query.name, func(t *testing.T) {
  5774  					route, err := stk.FindRoute(
  5775  						0,
  5776  						tcpip.Address{},
  5777  						testutil.MustParse4(query.remote),
  5778  						header.IPv4ProtocolNumber,
  5779  						false, /* multicastLoop */
  5780  					)
  5781  					if err != nil {
  5782  						if _, ok := err.(*tcpip.ErrHostUnreachable); query.wantErr && ok {
  5783  							return
  5784  						}
  5785  						t.Fatalf("FoundRoute failed: %v", err)
  5786  					}
  5787  					if got, want := route.OutgoingNIC(), query.wantID; got != want {
  5788  						t.Errorf("got outgoing NIC %d, but wanted %d", got, want)
  5789  					}
  5790  					if got, want := route.LocalAddress(), testutil.MustParse4(query.wantLocal); got != want {
  5791  						t.Errorf("got local address %s, but wanted %s", got, want)
  5792  					}
  5793  					var nextHop tcpip.Address
  5794  					if len(query.wantNextHop) > 0 {
  5795  						nextHop = testutil.MustParse4(query.wantNextHop)
  5796  					}
  5797  					if got, want := route.NextHop(), nextHop; got != want {
  5798  						t.Errorf("got next hop %s, but wanted %s", got, want)
  5799  					}
  5800  				})
  5801  			}
  5802  		})
  5803  	}
  5804  }