github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/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/SagerNet/gvisor/pkg/rand"
    31  	"github.com/SagerNet/gvisor/pkg/sync"
    32  	"github.com/SagerNet/gvisor/pkg/tcpip"
    33  	"github.com/SagerNet/gvisor/pkg/tcpip/buffer"
    34  	"github.com/SagerNet/gvisor/pkg/tcpip/faketime"
    35  	"github.com/SagerNet/gvisor/pkg/tcpip/header"
    36  	"github.com/SagerNet/gvisor/pkg/tcpip/link/channel"
    37  	"github.com/SagerNet/gvisor/pkg/tcpip/link/loopback"
    38  	"github.com/SagerNet/gvisor/pkg/tcpip/network/arp"
    39  	"github.com/SagerNet/gvisor/pkg/tcpip/network/ipv4"
    40  	"github.com/SagerNet/gvisor/pkg/tcpip/network/ipv6"
    41  	"github.com/SagerNet/gvisor/pkg/tcpip/stack"
    42  	"github.com/SagerNet/gvisor/pkg/tcpip/testutil"
    43  	"github.com/SagerNet/gvisor/pkg/tcpip/transport/udp"
    44  )
    45  
    46  const (
    47  	fakeNetNumber        tcpip.NetworkProtocolNumber = math.MaxUint32
    48  	fakeNetHeaderLen                                 = 12
    49  	fakeDefaultPrefixLen                             = 8
    50  
    51  	// fakeControlProtocol is used for control packets that represent
    52  	// destination port unreachable.
    53  	fakeControlProtocol tcpip.TransportProtocolNumber = 2
    54  
    55  	// defaultMTU is the MTU, in bytes, used throughout the tests, except
    56  	// where another value is explicitly used. It is chosen to match the MTU
    57  	// of loopback interfaces on linux systems.
    58  	defaultMTU = 65536
    59  
    60  	dstAddrOffset        = 0
    61  	srcAddrOffset        = 1
    62  	protocolNumberOffset = 2
    63  )
    64  
    65  func checkGetMainNICAddress(s *stack.Stack, nicID tcpip.NICID, proto tcpip.NetworkProtocolNumber, want tcpip.AddressWithPrefix) error {
    66  	if addr, err := s.GetMainNICAddress(nicID, proto); err != nil {
    67  		return fmt.Errorf("stack.GetMainNICAddress(%d, %d): %s", nicID, proto, err)
    68  	} else if addr != want {
    69  		return fmt.Errorf("got stack.GetMainNICAddress(%d, %d) = %s, want = %s", nicID, proto, addr, want)
    70  	}
    71  	return nil
    72  }
    73  
    74  // fakeNetworkEndpoint is a network-layer protocol endpoint. It counts sent and
    75  // received packets; the counts of all endpoints are aggregated in the protocol
    76  // descriptor.
    77  //
    78  // Headers of this protocol are fakeNetHeaderLen bytes, but we currently only
    79  // use the first three: destination address, source address, and transport
    80  // protocol. They're all one byte fields to simplify parsing.
    81  type fakeNetworkEndpoint struct {
    82  	stack.AddressableEndpointState
    83  
    84  	mu struct {
    85  		sync.RWMutex
    86  
    87  		enabled    bool
    88  		forwarding bool
    89  	}
    90  
    91  	nic        stack.NetworkInterface
    92  	proto      *fakeNetworkProtocol
    93  	dispatcher stack.TransportDispatcher
    94  }
    95  
    96  func (f *fakeNetworkEndpoint) Enable() tcpip.Error {
    97  	f.mu.Lock()
    98  	defer f.mu.Unlock()
    99  	f.mu.enabled = true
   100  	return nil
   101  }
   102  
   103  func (f *fakeNetworkEndpoint) Enabled() bool {
   104  	f.mu.RLock()
   105  	defer f.mu.RUnlock()
   106  	return f.mu.enabled
   107  }
   108  
   109  func (f *fakeNetworkEndpoint) Disable() {
   110  	f.mu.Lock()
   111  	defer f.mu.Unlock()
   112  	f.mu.enabled = false
   113  }
   114  
   115  func (f *fakeNetworkEndpoint) MTU() uint32 {
   116  	return f.nic.MTU() - uint32(f.MaxHeaderLength())
   117  }
   118  
   119  func (*fakeNetworkEndpoint) DefaultTTL() uint8 {
   120  	return 123
   121  }
   122  
   123  func (f *fakeNetworkEndpoint) HandlePacket(pkt *stack.PacketBuffer) {
   124  	if _, _, ok := f.proto.Parse(pkt); !ok {
   125  		return
   126  	}
   127  
   128  	// Increment the received packet count in the protocol descriptor.
   129  	netHdr := pkt.NetworkHeader().View()
   130  
   131  	dst := tcpip.Address(netHdr[dstAddrOffset:][:1])
   132  	addressEndpoint := f.AcquireAssignedAddress(dst, f.nic.Promiscuous(), stack.CanBePrimaryEndpoint)
   133  	if addressEndpoint == nil {
   134  		return
   135  	}
   136  	addressEndpoint.DecRef()
   137  
   138  	f.proto.packetCount[int(dst[0])%len(f.proto.packetCount)]++
   139  
   140  	// Handle control packets.
   141  	if netHdr[protocolNumberOffset] == uint8(fakeControlProtocol) {
   142  		hdr, ok := pkt.Data().PullUp(fakeNetHeaderLen)
   143  		if !ok {
   144  			return
   145  		}
   146  		// DeleteFront invalidates slices. Make a copy before trimming.
   147  		nb := append([]byte(nil), hdr...)
   148  		pkt.Data().DeleteFront(fakeNetHeaderLen)
   149  		f.dispatcher.DeliverTransportError(
   150  			tcpip.Address(nb[srcAddrOffset:srcAddrOffset+1]),
   151  			tcpip.Address(nb[dstAddrOffset:dstAddrOffset+1]),
   152  			fakeNetNumber,
   153  			tcpip.TransportProtocolNumber(nb[protocolNumberOffset]),
   154  			// Nothing checks the error.
   155  			nil, /* transport error */
   156  			pkt,
   157  		)
   158  		return
   159  	}
   160  
   161  	// Dispatch the packet to the transport protocol.
   162  	f.dispatcher.DeliverTransportPacket(tcpip.TransportProtocolNumber(pkt.NetworkHeader().View()[protocolNumberOffset]), pkt)
   163  }
   164  
   165  func (f *fakeNetworkEndpoint) MaxHeaderLength() uint16 {
   166  	return f.nic.MaxHeaderLength() + fakeNetHeaderLen
   167  }
   168  
   169  func (f *fakeNetworkEndpoint) NetworkProtocolNumber() tcpip.NetworkProtocolNumber {
   170  	return f.proto.Number()
   171  }
   172  
   173  func (f *fakeNetworkEndpoint) WritePacket(r *stack.Route, params stack.NetworkHeaderParams, pkt *stack.PacketBuffer) tcpip.Error {
   174  	// Increment the sent packet count in the protocol descriptor.
   175  	f.proto.sendPacketCount[int(r.RemoteAddress()[0])%len(f.proto.sendPacketCount)]++
   176  
   177  	// Add the protocol's header to the packet and send it to the link
   178  	// endpoint.
   179  	hdr := pkt.NetworkHeader().Push(fakeNetHeaderLen)
   180  	pkt.NetworkProtocolNumber = fakeNetNumber
   181  	hdr[dstAddrOffset] = r.RemoteAddress()[0]
   182  	hdr[srcAddrOffset] = r.LocalAddress()[0]
   183  	hdr[protocolNumberOffset] = byte(params.Protocol)
   184  
   185  	if r.Loop()&stack.PacketLoop != 0 {
   186  		f.HandlePacket(pkt.Clone())
   187  	}
   188  	if r.Loop()&stack.PacketOut == 0 {
   189  		return nil
   190  	}
   191  
   192  	return f.nic.WritePacket(r, fakeNetNumber, pkt)
   193  }
   194  
   195  // WritePackets implements stack.LinkEndpoint.WritePackets.
   196  func (*fakeNetworkEndpoint) WritePackets(*stack.Route, stack.PacketBufferList, stack.NetworkHeaderParams) (int, tcpip.Error) {
   197  	panic("not implemented")
   198  }
   199  
   200  func (*fakeNetworkEndpoint) WriteHeaderIncludedPacket(*stack.Route, *stack.PacketBuffer) tcpip.Error {
   201  	return &tcpip.ErrNotSupported{}
   202  }
   203  
   204  func (f *fakeNetworkEndpoint) Close() {
   205  	f.AddressableEndpointState.Cleanup()
   206  }
   207  
   208  // Stats implements NetworkEndpoint.
   209  func (*fakeNetworkEndpoint) Stats() stack.NetworkEndpointStats {
   210  	return &fakeNetworkEndpointStats{}
   211  }
   212  
   213  var _ stack.NetworkEndpointStats = (*fakeNetworkEndpointStats)(nil)
   214  
   215  type fakeNetworkEndpointStats struct{}
   216  
   217  // IsNetworkEndpointStats implements stack.NetworkEndpointStats.
   218  func (*fakeNetworkEndpointStats) IsNetworkEndpointStats() {}
   219  
   220  // fakeNetworkProtocol is a network-layer protocol descriptor. It aggregates the
   221  // number of packets sent and received via endpoints of this protocol. The index
   222  // where packets are added is given by the packet's destination address MOD 10.
   223  type fakeNetworkProtocol struct {
   224  	packetCount     [10]int
   225  	sendPacketCount [10]int
   226  	defaultTTL      uint8
   227  }
   228  
   229  func (*fakeNetworkProtocol) Number() tcpip.NetworkProtocolNumber {
   230  	return fakeNetNumber
   231  }
   232  
   233  func (*fakeNetworkProtocol) MinimumPacketSize() int {
   234  	return fakeNetHeaderLen
   235  }
   236  
   237  func (*fakeNetworkProtocol) DefaultPrefixLen() int {
   238  	return fakeDefaultPrefixLen
   239  }
   240  
   241  func (f *fakeNetworkProtocol) PacketCount(intfAddr byte) int {
   242  	return f.packetCount[int(intfAddr)%len(f.packetCount)]
   243  }
   244  
   245  func (*fakeNetworkProtocol) ParseAddresses(v buffer.View) (src, dst tcpip.Address) {
   246  	return tcpip.Address(v[srcAddrOffset : srcAddrOffset+1]), tcpip.Address(v[dstAddrOffset : dstAddrOffset+1])
   247  }
   248  
   249  func (f *fakeNetworkProtocol) NewEndpoint(nic stack.NetworkInterface, dispatcher stack.TransportDispatcher) stack.NetworkEndpoint {
   250  	e := &fakeNetworkEndpoint{
   251  		nic:        nic,
   252  		proto:      f,
   253  		dispatcher: dispatcher,
   254  	}
   255  	e.AddressableEndpointState.Init(e)
   256  	return e
   257  }
   258  
   259  func (f *fakeNetworkProtocol) SetOption(option tcpip.SettableNetworkProtocolOption) tcpip.Error {
   260  	switch v := option.(type) {
   261  	case *tcpip.DefaultTTLOption:
   262  		f.defaultTTL = uint8(*v)
   263  		return nil
   264  	default:
   265  		return &tcpip.ErrUnknownProtocolOption{}
   266  	}
   267  }
   268  
   269  func (f *fakeNetworkProtocol) Option(option tcpip.GettableNetworkProtocolOption) tcpip.Error {
   270  	switch v := option.(type) {
   271  	case *tcpip.DefaultTTLOption:
   272  		*v = tcpip.DefaultTTLOption(f.defaultTTL)
   273  		return nil
   274  	default:
   275  		return &tcpip.ErrUnknownProtocolOption{}
   276  	}
   277  }
   278  
   279  // Close implements NetworkProtocol.Close.
   280  func (*fakeNetworkProtocol) Close() {}
   281  
   282  // Wait implements NetworkProtocol.Wait.
   283  func (*fakeNetworkProtocol) Wait() {}
   284  
   285  // Parse implements NetworkProtocol.Parse.
   286  func (*fakeNetworkProtocol) Parse(pkt *stack.PacketBuffer) (tcpip.TransportProtocolNumber, bool, bool) {
   287  	hdr, ok := pkt.NetworkHeader().Consume(fakeNetHeaderLen)
   288  	if !ok {
   289  		return 0, false, false
   290  	}
   291  	pkt.NetworkProtocolNumber = fakeNetNumber
   292  	return tcpip.TransportProtocolNumber(hdr[protocolNumberOffset]), true, true
   293  }
   294  
   295  // Forwarding implements stack.ForwardingNetworkEndpoint.
   296  func (f *fakeNetworkEndpoint) Forwarding() bool {
   297  	f.mu.RLock()
   298  	defer f.mu.RUnlock()
   299  	return f.mu.forwarding
   300  }
   301  
   302  // SetForwarding implements stack.ForwardingNetworkEndpoint.
   303  func (f *fakeNetworkEndpoint) SetForwarding(v bool) {
   304  	f.mu.Lock()
   305  	defer f.mu.Unlock()
   306  	f.mu.forwarding = v
   307  }
   308  
   309  func fakeNetFactory(*stack.Stack) stack.NetworkProtocol {
   310  	return &fakeNetworkProtocol{}
   311  }
   312  
   313  // linkEPWithMockedAttach is a stack.LinkEndpoint that tests can use to verify
   314  // that LinkEndpoint.Attach was called.
   315  type linkEPWithMockedAttach struct {
   316  	stack.LinkEndpoint
   317  	attached bool
   318  }
   319  
   320  // Attach implements stack.LinkEndpoint.Attach.
   321  func (l *linkEPWithMockedAttach) Attach(d stack.NetworkDispatcher) {
   322  	l.LinkEndpoint.Attach(d)
   323  	l.attached = d != nil
   324  }
   325  
   326  func (l *linkEPWithMockedAttach) isAttached() bool {
   327  	return l.attached
   328  }
   329  
   330  // Checks to see if list contains an address.
   331  func containsAddr(list []tcpip.ProtocolAddress, item tcpip.ProtocolAddress) bool {
   332  	for _, i := range list {
   333  		if i == item {
   334  			return true
   335  		}
   336  	}
   337  
   338  	return false
   339  }
   340  
   341  func TestNetworkReceive(t *testing.T) {
   342  	// Create a stack with the fake network protocol, one nic, and two
   343  	// addresses attached to it: 1 & 2.
   344  	ep := channel.New(10, defaultMTU, "")
   345  	s := stack.New(stack.Options{
   346  		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
   347  	})
   348  	if err := s.CreateNIC(1, ep); err != nil {
   349  		t.Fatal("CreateNIC failed:", err)
   350  	}
   351  
   352  	if err := s.AddAddress(1, fakeNetNumber, "\x01"); err != nil {
   353  		t.Fatal("AddAddress failed:", err)
   354  	}
   355  
   356  	if err := s.AddAddress(1, fakeNetNumber, "\x02"); err != nil {
   357  		t.Fatal("AddAddress failed:", err)
   358  	}
   359  
   360  	fakeNet := s.NetworkProtocolInstance(fakeNetNumber).(*fakeNetworkProtocol)
   361  
   362  	buf := buffer.NewView(30)
   363  
   364  	// Make sure packet with wrong address is not delivered.
   365  	buf[dstAddrOffset] = 3
   366  	ep.InjectInbound(fakeNetNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
   367  		Data: buf.ToVectorisedView(),
   368  	}))
   369  	if fakeNet.packetCount[1] != 0 {
   370  		t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 0)
   371  	}
   372  	if fakeNet.packetCount[2] != 0 {
   373  		t.Errorf("packetCount[2] = %d, want %d", fakeNet.packetCount[2], 0)
   374  	}
   375  
   376  	// Make sure packet is delivered to first endpoint.
   377  	buf[dstAddrOffset] = 1
   378  	ep.InjectInbound(fakeNetNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
   379  		Data: buf.ToVectorisedView(),
   380  	}))
   381  	if fakeNet.packetCount[1] != 1 {
   382  		t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 1)
   383  	}
   384  	if fakeNet.packetCount[2] != 0 {
   385  		t.Errorf("packetCount[2] = %d, want %d", fakeNet.packetCount[2], 0)
   386  	}
   387  
   388  	// Make sure packet is delivered to second endpoint.
   389  	buf[dstAddrOffset] = 2
   390  	ep.InjectInbound(fakeNetNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
   391  		Data: buf.ToVectorisedView(),
   392  	}))
   393  	if fakeNet.packetCount[1] != 1 {
   394  		t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 1)
   395  	}
   396  	if fakeNet.packetCount[2] != 1 {
   397  		t.Errorf("packetCount[2] = %d, want %d", fakeNet.packetCount[2], 1)
   398  	}
   399  
   400  	// Make sure packet is not delivered if protocol number is wrong.
   401  	ep.InjectInbound(fakeNetNumber-1, stack.NewPacketBuffer(stack.PacketBufferOptions{
   402  		Data: buf.ToVectorisedView(),
   403  	}))
   404  	if fakeNet.packetCount[1] != 1 {
   405  		t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 1)
   406  	}
   407  	if fakeNet.packetCount[2] != 1 {
   408  		t.Errorf("packetCount[2] = %d, want %d", fakeNet.packetCount[2], 1)
   409  	}
   410  
   411  	// Make sure packet that is too small is dropped.
   412  	buf.CapLength(2)
   413  	ep.InjectInbound(fakeNetNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
   414  		Data: buf.ToVectorisedView(),
   415  	}))
   416  	if fakeNet.packetCount[1] != 1 {
   417  		t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 1)
   418  	}
   419  	if fakeNet.packetCount[2] != 1 {
   420  		t.Errorf("packetCount[2] = %d, want %d", fakeNet.packetCount[2], 1)
   421  	}
   422  }
   423  
   424  func sendTo(s *stack.Stack, addr tcpip.Address, payload buffer.View) tcpip.Error {
   425  	r, err := s.FindRoute(0, "", addr, fakeNetNumber, false /* multicastLoop */)
   426  	if err != nil {
   427  		return err
   428  	}
   429  	defer r.Release()
   430  	return send(r, payload)
   431  }
   432  
   433  func send(r *stack.Route, payload buffer.View) tcpip.Error {
   434  	return r.WritePacket(stack.NetworkHeaderParams{Protocol: fakeTransNumber, TTL: 123, TOS: stack.DefaultTOS}, stack.NewPacketBuffer(stack.PacketBufferOptions{
   435  		ReserveHeaderBytes: int(r.MaxHeaderLength()),
   436  		Data:               payload.ToVectorisedView(),
   437  	}))
   438  }
   439  
   440  func testSendTo(t *testing.T, s *stack.Stack, addr tcpip.Address, ep *channel.Endpoint, payload buffer.View) {
   441  	t.Helper()
   442  	ep.Drain()
   443  	if err := sendTo(s, addr, payload); err != nil {
   444  		t.Error("sendTo failed:", err)
   445  	}
   446  	if got, want := ep.Drain(), 1; got != want {
   447  		t.Errorf("sendTo packet count: got = %d, want %d", got, want)
   448  	}
   449  }
   450  
   451  func testSend(t *testing.T, r *stack.Route, ep *channel.Endpoint, payload buffer.View) {
   452  	t.Helper()
   453  	ep.Drain()
   454  	if err := send(r, payload); err != nil {
   455  		t.Error("send failed:", err)
   456  	}
   457  	if got, want := ep.Drain(), 1; got != want {
   458  		t.Errorf("send packet count: got = %d, want %d", got, want)
   459  	}
   460  }
   461  
   462  func testFailingSend(t *testing.T, r *stack.Route, payload buffer.View, wantErr tcpip.Error) {
   463  	t.Helper()
   464  	if gotErr := send(r, payload); gotErr != wantErr {
   465  		t.Errorf("send failed: got = %s, want = %s ", gotErr, wantErr)
   466  	}
   467  }
   468  
   469  func testFailingSendTo(t *testing.T, s *stack.Stack, addr tcpip.Address, payload buffer.View, wantErr tcpip.Error) {
   470  	t.Helper()
   471  	if gotErr := sendTo(s, addr, payload); gotErr != wantErr {
   472  		t.Errorf("sendto failed: got = %s, want = %s ", gotErr, wantErr)
   473  	}
   474  }
   475  
   476  func testRecv(t *testing.T, fakeNet *fakeNetworkProtocol, localAddrByte byte, ep *channel.Endpoint, buf buffer.View) {
   477  	t.Helper()
   478  	// testRecvInternal injects one packet, and we expect to receive it.
   479  	want := fakeNet.PacketCount(localAddrByte) + 1
   480  	testRecvInternal(t, fakeNet, localAddrByte, ep, buf, want)
   481  }
   482  
   483  func testFailingRecv(t *testing.T, fakeNet *fakeNetworkProtocol, localAddrByte byte, ep *channel.Endpoint, buf buffer.View) {
   484  	t.Helper()
   485  	// testRecvInternal injects one packet, and we do NOT expect to receive it.
   486  	want := fakeNet.PacketCount(localAddrByte)
   487  	testRecvInternal(t, fakeNet, localAddrByte, ep, buf, want)
   488  }
   489  
   490  func testRecvInternal(t *testing.T, fakeNet *fakeNetworkProtocol, localAddrByte byte, ep *channel.Endpoint, buf buffer.View, want int) {
   491  	t.Helper()
   492  	ep.InjectInbound(fakeNetNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
   493  		Data: buf.ToVectorisedView(),
   494  	}))
   495  	if got := fakeNet.PacketCount(localAddrByte); got != want {
   496  		t.Errorf("receive packet count: got = %d, want %d", got, want)
   497  	}
   498  }
   499  
   500  func TestNetworkSend(t *testing.T) {
   501  	// Create a stack with the fake network protocol, one nic, and one
   502  	// address: 1. The route table sends all packets through the only
   503  	// existing nic.
   504  	ep := channel.New(10, defaultMTU, "")
   505  	s := stack.New(stack.Options{
   506  		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
   507  	})
   508  	if err := s.CreateNIC(1, ep); err != nil {
   509  		t.Fatal("NewNIC failed:", err)
   510  	}
   511  
   512  	{
   513  		subnet, err := tcpip.NewSubnet("\x00", "\x00")
   514  		if err != nil {
   515  			t.Fatal(err)
   516  		}
   517  		s.SetRouteTable([]tcpip.Route{{Destination: subnet, Gateway: "\x00", NIC: 1}})
   518  	}
   519  
   520  	if err := s.AddAddress(1, fakeNetNumber, "\x01"); err != nil {
   521  		t.Fatal("AddAddress failed:", err)
   522  	}
   523  
   524  	// Make sure that the link-layer endpoint received the outbound packet.
   525  	testSendTo(t, s, "\x03", ep, nil)
   526  }
   527  
   528  func TestNetworkSendMultiRoute(t *testing.T) {
   529  	// Create a stack with the fake network protocol, two nics, and two
   530  	// addresses per nic, the first nic has odd address, the second one has
   531  	// even addresses.
   532  	s := stack.New(stack.Options{
   533  		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
   534  	})
   535  
   536  	ep1 := channel.New(10, defaultMTU, "")
   537  	if err := s.CreateNIC(1, ep1); err != nil {
   538  		t.Fatal("CreateNIC failed:", err)
   539  	}
   540  
   541  	if err := s.AddAddress(1, fakeNetNumber, "\x01"); err != nil {
   542  		t.Fatal("AddAddress failed:", err)
   543  	}
   544  
   545  	if err := s.AddAddress(1, fakeNetNumber, "\x03"); err != nil {
   546  		t.Fatal("AddAddress failed:", err)
   547  	}
   548  
   549  	ep2 := channel.New(10, defaultMTU, "")
   550  	if err := s.CreateNIC(2, ep2); err != nil {
   551  		t.Fatal("CreateNIC failed:", err)
   552  	}
   553  
   554  	if err := s.AddAddress(2, fakeNetNumber, "\x02"); err != nil {
   555  		t.Fatal("AddAddress failed:", err)
   556  	}
   557  
   558  	if err := s.AddAddress(2, fakeNetNumber, "\x04"); err != nil {
   559  		t.Fatal("AddAddress failed:", err)
   560  	}
   561  
   562  	// Set a route table that sends all packets with odd destination
   563  	// addresses through the first NIC, and all even destination address
   564  	// through the second one.
   565  	{
   566  		subnet0, err := tcpip.NewSubnet("\x00", "\x01")
   567  		if err != nil {
   568  			t.Fatal(err)
   569  		}
   570  		subnet1, err := tcpip.NewSubnet("\x01", "\x01")
   571  		if err != nil {
   572  			t.Fatal(err)
   573  		}
   574  		s.SetRouteTable([]tcpip.Route{
   575  			{Destination: subnet1, Gateway: "\x00", NIC: 1},
   576  			{Destination: subnet0, Gateway: "\x00", NIC: 2},
   577  		})
   578  	}
   579  
   580  	// Send a packet to an odd destination.
   581  	testSendTo(t, s, "\x05", ep1, nil)
   582  
   583  	// Send a packet to an even destination.
   584  	testSendTo(t, s, "\x06", ep2, nil)
   585  }
   586  
   587  func testRoute(t *testing.T, s *stack.Stack, nic tcpip.NICID, srcAddr, dstAddr, expectedSrcAddr tcpip.Address) {
   588  	r, err := s.FindRoute(nic, srcAddr, dstAddr, fakeNetNumber, false /* multicastLoop */)
   589  	if err != nil {
   590  		t.Fatal("FindRoute failed:", err)
   591  	}
   592  
   593  	defer r.Release()
   594  
   595  	if r.LocalAddress() != expectedSrcAddr {
   596  		t.Fatalf("got Route.LocalAddress() = %s, want = %s", expectedSrcAddr, r.LocalAddress())
   597  	}
   598  
   599  	if r.RemoteAddress() != dstAddr {
   600  		t.Fatalf("got Route.RemoteAddress() = %s, want = %s", dstAddr, r.RemoteAddress())
   601  	}
   602  }
   603  
   604  func testNoRoute(t *testing.T, s *stack.Stack, nic tcpip.NICID, srcAddr, dstAddr tcpip.Address) {
   605  	_, err := s.FindRoute(nic, srcAddr, dstAddr, fakeNetNumber, false /* multicastLoop */)
   606  	if _, ok := err.(*tcpip.ErrNoRoute); !ok {
   607  		t.Fatalf("FindRoute returned unexpected error, got = %v, want = %s", err, &tcpip.ErrNoRoute{})
   608  	}
   609  }
   610  
   611  // TestAttachToLinkEndpointImmediately tests that a LinkEndpoint is attached to
   612  // a NetworkDispatcher when the NIC is created.
   613  func TestAttachToLinkEndpointImmediately(t *testing.T) {
   614  	const nicID = 1
   615  
   616  	tests := []struct {
   617  		name    string
   618  		nicOpts stack.NICOptions
   619  	}{
   620  		{
   621  			name:    "Create enabled NIC",
   622  			nicOpts: stack.NICOptions{Disabled: false},
   623  		},
   624  		{
   625  			name:    "Create disabled NIC",
   626  			nicOpts: stack.NICOptions{Disabled: true},
   627  		},
   628  	}
   629  
   630  	for _, test := range tests {
   631  		t.Run(test.name, func(t *testing.T) {
   632  			s := stack.New(stack.Options{
   633  				NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
   634  			})
   635  
   636  			e := linkEPWithMockedAttach{
   637  				LinkEndpoint: loopback.New(),
   638  			}
   639  
   640  			if err := s.CreateNICWithOptions(nicID, &e, test.nicOpts); err != nil {
   641  				t.Fatalf("CreateNICWithOptions(%d, _, %+v) = %s", nicID, test.nicOpts, err)
   642  			}
   643  			if !e.isAttached() {
   644  				t.Fatal("link endpoint not attached to a network dispatcher")
   645  			}
   646  		})
   647  	}
   648  }
   649  
   650  func TestDisableUnknownNIC(t *testing.T) {
   651  	s := stack.New(stack.Options{
   652  		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
   653  	})
   654  
   655  	err := s.DisableNIC(1)
   656  	if _, ok := err.(*tcpip.ErrUnknownNICID); !ok {
   657  		t.Fatalf("got s.DisableNIC(1) = %v, want = %s", err, &tcpip.ErrUnknownNICID{})
   658  	}
   659  }
   660  
   661  func TestDisabledNICsNICInfoAndCheckNIC(t *testing.T) {
   662  	const nicID = 1
   663  
   664  	s := stack.New(stack.Options{
   665  		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
   666  	})
   667  
   668  	e := loopback.New()
   669  	nicOpts := stack.NICOptions{Disabled: true}
   670  	if err := s.CreateNICWithOptions(nicID, e, nicOpts); err != nil {
   671  		t.Fatalf("CreateNICWithOptions(%d, _, %+v) = %s", nicID, nicOpts, err)
   672  	}
   673  
   674  	checkNIC := func(enabled bool) {
   675  		t.Helper()
   676  
   677  		allNICInfo := s.NICInfo()
   678  		nicInfo, ok := allNICInfo[nicID]
   679  		if !ok {
   680  			t.Errorf("entry for %d missing from allNICInfo = %+v", nicID, allNICInfo)
   681  		} else if nicInfo.Flags.Running != enabled {
   682  			t.Errorf("got nicInfo.Flags.Running = %t, want = %t", nicInfo.Flags.Running, enabled)
   683  		}
   684  
   685  		if got := s.CheckNIC(nicID); got != enabled {
   686  			t.Errorf("got s.CheckNIC(%d) = %t, want = %t", nicID, got, enabled)
   687  		}
   688  	}
   689  
   690  	// NIC should initially report itself as disabled.
   691  	checkNIC(false)
   692  
   693  	if err := s.EnableNIC(nicID); err != nil {
   694  		t.Fatalf("s.EnableNIC(%d): %s", nicID, err)
   695  	}
   696  	checkNIC(true)
   697  
   698  	// If the NIC is not reporting a correct enabled status, we cannot trust the
   699  	// next check so end the test here.
   700  	if t.Failed() {
   701  		t.FailNow()
   702  	}
   703  
   704  	if err := s.DisableNIC(nicID); err != nil {
   705  		t.Fatalf("s.DisableNIC(%d): %s", nicID, err)
   706  	}
   707  	checkNIC(false)
   708  }
   709  
   710  func TestRemoveUnknownNIC(t *testing.T) {
   711  	s := stack.New(stack.Options{
   712  		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
   713  	})
   714  
   715  	err := s.RemoveNIC(1)
   716  	if _, ok := err.(*tcpip.ErrUnknownNICID); !ok {
   717  		t.Fatalf("got s.RemoveNIC(1) = %v, want = %s", err, &tcpip.ErrUnknownNICID{})
   718  	}
   719  }
   720  
   721  func TestRemoveNIC(t *testing.T) {
   722  	const nicID = 1
   723  
   724  	s := stack.New(stack.Options{
   725  		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
   726  	})
   727  
   728  	e := linkEPWithMockedAttach{
   729  		LinkEndpoint: loopback.New(),
   730  	}
   731  	if err := s.CreateNIC(nicID, &e); err != nil {
   732  		t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
   733  	}
   734  
   735  	// NIC should be present in NICInfo and attached to a NetworkDispatcher.
   736  	allNICInfo := s.NICInfo()
   737  	if _, ok := allNICInfo[nicID]; !ok {
   738  		t.Errorf("entry for %d missing from allNICInfo = %+v", nicID, allNICInfo)
   739  	}
   740  	if !e.isAttached() {
   741  		t.Fatal("link endpoint not attached to a network dispatcher")
   742  	}
   743  
   744  	// Removing a NIC should remove it from NICInfo and e should be detached from
   745  	// the NetworkDispatcher.
   746  	if err := s.RemoveNIC(nicID); err != nil {
   747  		t.Fatalf("s.RemoveNIC(%d): %s", nicID, err)
   748  	}
   749  	if nicInfo, ok := s.NICInfo()[nicID]; ok {
   750  		t.Errorf("got unexpected NICInfo entry for deleted NIC %d = %+v", nicID, nicInfo)
   751  	}
   752  	if e.isAttached() {
   753  		t.Error("link endpoint for removed NIC still attached to a network dispatcher")
   754  	}
   755  }
   756  
   757  func TestRouteWithDownNIC(t *testing.T) {
   758  	tests := []struct {
   759  		name   string
   760  		downFn func(s *stack.Stack, nicID tcpip.NICID) tcpip.Error
   761  		upFn   func(s *stack.Stack, nicID tcpip.NICID) tcpip.Error
   762  	}{
   763  		{
   764  			name:   "Disabled NIC",
   765  			downFn: (*stack.Stack).DisableNIC,
   766  			upFn:   (*stack.Stack).EnableNIC,
   767  		},
   768  
   769  		// Once a NIC is removed, it cannot be brought up.
   770  		{
   771  			name:   "Removed NIC",
   772  			downFn: (*stack.Stack).RemoveNIC,
   773  		},
   774  	}
   775  
   776  	const unspecifiedNIC = 0
   777  	const nicID1 = 1
   778  	const nicID2 = 2
   779  	const addr1 = tcpip.Address("\x01")
   780  	const addr2 = tcpip.Address("\x02")
   781  	const nic1Dst = tcpip.Address("\x05")
   782  	const nic2Dst = tcpip.Address("\x06")
   783  
   784  	setup := func(t *testing.T) (*stack.Stack, *channel.Endpoint, *channel.Endpoint) {
   785  		s := stack.New(stack.Options{
   786  			NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
   787  		})
   788  
   789  		ep1 := channel.New(1, defaultMTU, "")
   790  		if err := s.CreateNIC(nicID1, ep1); err != nil {
   791  			t.Fatalf("CreateNIC(%d, _): %s", nicID1, err)
   792  		}
   793  
   794  		if err := s.AddAddress(nicID1, fakeNetNumber, addr1); err != nil {
   795  			t.Fatalf("AddAddress(%d, %d, %s): %s", nicID1, fakeNetNumber, addr1, err)
   796  		}
   797  
   798  		ep2 := channel.New(1, defaultMTU, "")
   799  		if err := s.CreateNIC(nicID2, ep2); err != nil {
   800  			t.Fatalf("CreateNIC(%d, _): %s", nicID2, err)
   801  		}
   802  
   803  		if err := s.AddAddress(nicID2, fakeNetNumber, addr2); err != nil {
   804  			t.Fatalf("AddAddress(%d, %d, %s): %s", nicID2, fakeNetNumber, addr2, err)
   805  		}
   806  
   807  		// Set a route table that sends all packets with odd destination
   808  		// addresses through the first NIC, and all even destination address
   809  		// through the second one.
   810  		{
   811  			subnet0, err := tcpip.NewSubnet("\x00", "\x01")
   812  			if err != nil {
   813  				t.Fatal(err)
   814  			}
   815  			subnet1, err := tcpip.NewSubnet("\x01", "\x01")
   816  			if err != nil {
   817  				t.Fatal(err)
   818  			}
   819  			s.SetRouteTable([]tcpip.Route{
   820  				{Destination: subnet1, Gateway: "\x00", NIC: nicID1},
   821  				{Destination: subnet0, Gateway: "\x00", NIC: nicID2},
   822  			})
   823  		}
   824  
   825  		return s, ep1, ep2
   826  	}
   827  
   828  	// Tests that routes through a down NIC are not used when looking up a route
   829  	// for a destination.
   830  	t.Run("Find", func(t *testing.T) {
   831  		for _, test := range tests {
   832  			t.Run(test.name, func(t *testing.T) {
   833  				s, _, _ := setup(t)
   834  
   835  				// Test routes to odd address.
   836  				testRoute(t, s, unspecifiedNIC, "", "\x05", addr1)
   837  				testRoute(t, s, unspecifiedNIC, addr1, "\x05", addr1)
   838  				testRoute(t, s, nicID1, addr1, "\x05", addr1)
   839  
   840  				// Test routes to even address.
   841  				testRoute(t, s, unspecifiedNIC, "", "\x06", addr2)
   842  				testRoute(t, s, unspecifiedNIC, addr2, "\x06", addr2)
   843  				testRoute(t, s, nicID2, addr2, "\x06", addr2)
   844  
   845  				// Bringing NIC1 down should result in no routes to odd addresses. Routes to
   846  				// even addresses should continue to be available as NIC2 is still up.
   847  				if err := test.downFn(s, nicID1); err != nil {
   848  					t.Fatalf("test.downFn(_, %d): %s", nicID1, err)
   849  				}
   850  				testNoRoute(t, s, unspecifiedNIC, "", nic1Dst)
   851  				testNoRoute(t, s, unspecifiedNIC, addr1, nic1Dst)
   852  				testNoRoute(t, s, nicID1, addr1, nic1Dst)
   853  				testRoute(t, s, unspecifiedNIC, "", nic2Dst, addr2)
   854  				testRoute(t, s, unspecifiedNIC, addr2, nic2Dst, addr2)
   855  				testRoute(t, s, nicID2, addr2, nic2Dst, addr2)
   856  
   857  				// Bringing NIC2 down should result in no routes to even addresses. No
   858  				// route should be available to any address as routes to odd addresses
   859  				// were made unavailable by bringing NIC1 down above.
   860  				if err := test.downFn(s, nicID2); err != nil {
   861  					t.Fatalf("test.downFn(_, %d): %s", nicID2, err)
   862  				}
   863  				testNoRoute(t, s, unspecifiedNIC, "", nic1Dst)
   864  				testNoRoute(t, s, unspecifiedNIC, addr1, nic1Dst)
   865  				testNoRoute(t, s, nicID1, addr1, nic1Dst)
   866  				testNoRoute(t, s, unspecifiedNIC, "", nic2Dst)
   867  				testNoRoute(t, s, unspecifiedNIC, addr2, nic2Dst)
   868  				testNoRoute(t, s, nicID2, addr2, nic2Dst)
   869  
   870  				if upFn := test.upFn; upFn != nil {
   871  					// Bringing NIC1 up should make routes to odd addresses available
   872  					// again. Routes to even addresses should continue to be unavailable
   873  					// as NIC2 is still down.
   874  					if err := upFn(s, nicID1); err != nil {
   875  						t.Fatalf("test.upFn(_, %d): %s", nicID1, err)
   876  					}
   877  					testRoute(t, s, unspecifiedNIC, "", nic1Dst, addr1)
   878  					testRoute(t, s, unspecifiedNIC, addr1, nic1Dst, addr1)
   879  					testRoute(t, s, nicID1, addr1, nic1Dst, addr1)
   880  					testNoRoute(t, s, unspecifiedNIC, "", nic2Dst)
   881  					testNoRoute(t, s, unspecifiedNIC, addr2, nic2Dst)
   882  					testNoRoute(t, s, nicID2, addr2, nic2Dst)
   883  				}
   884  			})
   885  		}
   886  	})
   887  
   888  	// Tests that writing a packet using a Route through a down NIC fails.
   889  	t.Run("WritePacket", func(t *testing.T) {
   890  		for _, test := range tests {
   891  			t.Run(test.name, func(t *testing.T) {
   892  				s, ep1, ep2 := setup(t)
   893  
   894  				r1, err := s.FindRoute(nicID1, addr1, nic1Dst, fakeNetNumber, false /* multicastLoop */)
   895  				if err != nil {
   896  					t.Errorf("FindRoute(%d, %s, %s, %d, false): %s", nicID1, addr1, nic1Dst, fakeNetNumber, err)
   897  				}
   898  				defer r1.Release()
   899  
   900  				r2, err := s.FindRoute(nicID2, addr2, nic2Dst, fakeNetNumber, false /* multicastLoop */)
   901  				if err != nil {
   902  					t.Errorf("FindRoute(%d, %s, %s, %d, false): %s", nicID2, addr2, nic2Dst, fakeNetNumber, err)
   903  				}
   904  				defer r2.Release()
   905  
   906  				// If we failed to get routes r1 or r2, we cannot proceed with the test.
   907  				if t.Failed() {
   908  					t.FailNow()
   909  				}
   910  
   911  				buf := buffer.View([]byte{1})
   912  				testSend(t, r1, ep1, buf)
   913  				testSend(t, r2, ep2, buf)
   914  
   915  				// Writes with Routes that use NIC1 after being brought down should fail.
   916  				if err := test.downFn(s, nicID1); err != nil {
   917  					t.Fatalf("test.downFn(_, %d): %s", nicID1, err)
   918  				}
   919  				testFailingSend(t, r1, buf, &tcpip.ErrInvalidEndpointState{})
   920  				testSend(t, r2, ep2, buf)
   921  
   922  				// Writes with Routes that use NIC2 after being brought down should fail.
   923  				if err := test.downFn(s, nicID2); err != nil {
   924  					t.Fatalf("test.downFn(_, %d): %s", nicID2, err)
   925  				}
   926  				testFailingSend(t, r1, buf, &tcpip.ErrInvalidEndpointState{})
   927  				testFailingSend(t, r2, buf, &tcpip.ErrInvalidEndpointState{})
   928  
   929  				if upFn := test.upFn; upFn != nil {
   930  					// Writes with Routes that use NIC1 after being brought up should
   931  					// succeed.
   932  					//
   933  					// TODO(github.com/SagerNet/issue/1491): Should we instead completely
   934  					// invalidate all Routes that were bound to a NIC that was brought
   935  					// down at some point?
   936  					if err := upFn(s, nicID1); err != nil {
   937  						t.Fatalf("test.upFn(_, %d): %s", nicID1, err)
   938  					}
   939  					testSend(t, r1, ep1, buf)
   940  					testFailingSend(t, r2, buf, &tcpip.ErrInvalidEndpointState{})
   941  				}
   942  			})
   943  		}
   944  	})
   945  }
   946  
   947  func TestRoutes(t *testing.T) {
   948  	// Create a stack with the fake network protocol, two nics, and two
   949  	// addresses per nic, the first nic has odd address, the second one has
   950  	// even addresses.
   951  	s := stack.New(stack.Options{
   952  		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
   953  	})
   954  
   955  	ep1 := channel.New(10, defaultMTU, "")
   956  	if err := s.CreateNIC(1, ep1); err != nil {
   957  		t.Fatal("CreateNIC failed:", err)
   958  	}
   959  
   960  	if err := s.AddAddress(1, fakeNetNumber, "\x01"); err != nil {
   961  		t.Fatal("AddAddress failed:", err)
   962  	}
   963  
   964  	if err := s.AddAddress(1, fakeNetNumber, "\x03"); err != nil {
   965  		t.Fatal("AddAddress failed:", err)
   966  	}
   967  
   968  	ep2 := channel.New(10, defaultMTU, "")
   969  	if err := s.CreateNIC(2, ep2); err != nil {
   970  		t.Fatal("CreateNIC failed:", err)
   971  	}
   972  
   973  	if err := s.AddAddress(2, fakeNetNumber, "\x02"); err != nil {
   974  		t.Fatal("AddAddress failed:", err)
   975  	}
   976  
   977  	if err := s.AddAddress(2, fakeNetNumber, "\x04"); err != nil {
   978  		t.Fatal("AddAddress failed:", err)
   979  	}
   980  
   981  	// Set a route table that sends all packets with odd destination
   982  	// addresses through the first NIC, and all even destination address
   983  	// through the second one.
   984  	{
   985  		subnet0, err := tcpip.NewSubnet("\x00", "\x01")
   986  		if err != nil {
   987  			t.Fatal(err)
   988  		}
   989  		subnet1, err := tcpip.NewSubnet("\x01", "\x01")
   990  		if err != nil {
   991  			t.Fatal(err)
   992  		}
   993  		s.SetRouteTable([]tcpip.Route{
   994  			{Destination: subnet1, Gateway: "\x00", NIC: 1},
   995  			{Destination: subnet0, Gateway: "\x00", NIC: 2},
   996  		})
   997  	}
   998  
   999  	// Test routes to odd address.
  1000  	testRoute(t, s, 0, "", "\x05", "\x01")
  1001  	testRoute(t, s, 0, "\x01", "\x05", "\x01")
  1002  	testRoute(t, s, 1, "\x01", "\x05", "\x01")
  1003  	testRoute(t, s, 0, "\x03", "\x05", "\x03")
  1004  	testRoute(t, s, 1, "\x03", "\x05", "\x03")
  1005  
  1006  	// Test routes to even address.
  1007  	testRoute(t, s, 0, "", "\x06", "\x02")
  1008  	testRoute(t, s, 0, "\x02", "\x06", "\x02")
  1009  	testRoute(t, s, 2, "\x02", "\x06", "\x02")
  1010  	testRoute(t, s, 0, "\x04", "\x06", "\x04")
  1011  	testRoute(t, s, 2, "\x04", "\x06", "\x04")
  1012  
  1013  	// Try to send to odd numbered address from even numbered ones, then
  1014  	// vice-versa.
  1015  	testNoRoute(t, s, 0, "\x02", "\x05")
  1016  	testNoRoute(t, s, 2, "\x02", "\x05")
  1017  	testNoRoute(t, s, 0, "\x04", "\x05")
  1018  	testNoRoute(t, s, 2, "\x04", "\x05")
  1019  
  1020  	testNoRoute(t, s, 0, "\x01", "\x06")
  1021  	testNoRoute(t, s, 1, "\x01", "\x06")
  1022  	testNoRoute(t, s, 0, "\x03", "\x06")
  1023  	testNoRoute(t, s, 1, "\x03", "\x06")
  1024  }
  1025  
  1026  func TestAddressRemoval(t *testing.T) {
  1027  	const localAddrByte byte = 0x01
  1028  	localAddr := tcpip.Address([]byte{localAddrByte})
  1029  	remoteAddr := tcpip.Address("\x02")
  1030  
  1031  	s := stack.New(stack.Options{
  1032  		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
  1033  	})
  1034  
  1035  	ep := channel.New(10, defaultMTU, "")
  1036  	if err := s.CreateNIC(1, ep); err != nil {
  1037  		t.Fatal("CreateNIC failed:", err)
  1038  	}
  1039  
  1040  	if err := s.AddAddress(1, fakeNetNumber, localAddr); err != nil {
  1041  		t.Fatal("AddAddress failed:", err)
  1042  	}
  1043  	{
  1044  		subnet, err := tcpip.NewSubnet("\x00", "\x00")
  1045  		if err != nil {
  1046  			t.Fatal(err)
  1047  		}
  1048  		s.SetRouteTable([]tcpip.Route{{Destination: subnet, Gateway: "\x00", NIC: 1}})
  1049  	}
  1050  
  1051  	fakeNet := s.NetworkProtocolInstance(fakeNetNumber).(*fakeNetworkProtocol)
  1052  
  1053  	buf := buffer.NewView(30)
  1054  
  1055  	// Send and receive packets, and verify they are received.
  1056  	buf[dstAddrOffset] = localAddrByte
  1057  	testRecv(t, fakeNet, localAddrByte, ep, buf)
  1058  	testSendTo(t, s, remoteAddr, ep, nil)
  1059  
  1060  	// Remove the address, then check that send/receive doesn't work anymore.
  1061  	if err := s.RemoveAddress(1, localAddr); err != nil {
  1062  		t.Fatal("RemoveAddress failed:", err)
  1063  	}
  1064  	testFailingRecv(t, fakeNet, localAddrByte, ep, buf)
  1065  	testFailingSendTo(t, s, remoteAddr, nil, &tcpip.ErrNoRoute{})
  1066  
  1067  	// Check that removing the same address fails.
  1068  	err := s.RemoveAddress(1, localAddr)
  1069  	if _, ok := err.(*tcpip.ErrBadLocalAddress); !ok {
  1070  		t.Fatalf("RemoveAddress returned unexpected error, got = %v, want = %s", err, &tcpip.ErrBadLocalAddress{})
  1071  	}
  1072  }
  1073  
  1074  func TestAddressRemovalWithRouteHeld(t *testing.T) {
  1075  	const localAddrByte byte = 0x01
  1076  	localAddr := tcpip.Address([]byte{localAddrByte})
  1077  	remoteAddr := tcpip.Address("\x02")
  1078  
  1079  	s := stack.New(stack.Options{
  1080  		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
  1081  	})
  1082  
  1083  	ep := channel.New(10, defaultMTU, "")
  1084  	if err := s.CreateNIC(1, ep); err != nil {
  1085  		t.Fatalf("CreateNIC failed: %v", err)
  1086  	}
  1087  	fakeNet := s.NetworkProtocolInstance(fakeNetNumber).(*fakeNetworkProtocol)
  1088  	buf := buffer.NewView(30)
  1089  
  1090  	if err := s.AddAddress(1, fakeNetNumber, localAddr); err != nil {
  1091  		t.Fatal("AddAddress failed:", err)
  1092  	}
  1093  	{
  1094  		subnet, err := tcpip.NewSubnet("\x00", "\x00")
  1095  		if err != nil {
  1096  			t.Fatal(err)
  1097  		}
  1098  		s.SetRouteTable([]tcpip.Route{{Destination: subnet, Gateway: "\x00", NIC: 1}})
  1099  	}
  1100  
  1101  	r, err := s.FindRoute(0, "", remoteAddr, fakeNetNumber, false /* multicastLoop */)
  1102  	if err != nil {
  1103  		t.Fatal("FindRoute failed:", err)
  1104  	}
  1105  
  1106  	// Send and receive packets, and verify they are received.
  1107  	buf[dstAddrOffset] = localAddrByte
  1108  	testRecv(t, fakeNet, localAddrByte, ep, buf)
  1109  	testSend(t, r, ep, nil)
  1110  	testSendTo(t, s, remoteAddr, ep, nil)
  1111  
  1112  	// Remove the address, then check that send/receive doesn't work anymore.
  1113  	if err := s.RemoveAddress(1, localAddr); err != nil {
  1114  		t.Fatal("RemoveAddress failed:", err)
  1115  	}
  1116  	testFailingRecv(t, fakeNet, localAddrByte, ep, buf)
  1117  	testFailingSend(t, r, nil, &tcpip.ErrInvalidEndpointState{})
  1118  	testFailingSendTo(t, s, remoteAddr, nil, &tcpip.ErrNoRoute{})
  1119  
  1120  	// Check that removing the same address fails.
  1121  	{
  1122  		err := s.RemoveAddress(1, localAddr)
  1123  		if _, ok := err.(*tcpip.ErrBadLocalAddress); !ok {
  1124  			t.Fatalf("RemoveAddress returned unexpected error, got = %v, want = %s", err, &tcpip.ErrBadLocalAddress{})
  1125  		}
  1126  	}
  1127  }
  1128  
  1129  func verifyAddress(t *testing.T, s *stack.Stack, nicID tcpip.NICID, addr tcpip.Address) {
  1130  	t.Helper()
  1131  	info, ok := s.NICInfo()[nicID]
  1132  	if !ok {
  1133  		t.Fatalf("NICInfo() failed to find nicID=%d", nicID)
  1134  	}
  1135  	if len(addr) == 0 {
  1136  		// No address given, verify that there is no address assigned to the NIC.
  1137  		for _, a := range info.ProtocolAddresses {
  1138  			if a.Protocol == fakeNetNumber && a.AddressWithPrefix != (tcpip.AddressWithPrefix{}) {
  1139  				t.Errorf("verify no-address: got = %s, want = %s", a.AddressWithPrefix, tcpip.AddressWithPrefix{})
  1140  			}
  1141  		}
  1142  		return
  1143  	}
  1144  	// Address given, verify the address is assigned to the NIC and no other
  1145  	// address is.
  1146  	found := false
  1147  	for _, a := range info.ProtocolAddresses {
  1148  		if a.Protocol == fakeNetNumber {
  1149  			if a.AddressWithPrefix.Address == addr {
  1150  				found = true
  1151  			} else {
  1152  				t.Errorf("verify address: got = %s, want = %s", a.AddressWithPrefix.Address, addr)
  1153  			}
  1154  		}
  1155  	}
  1156  	if !found {
  1157  		t.Errorf("verify address: couldn't find %s on the NIC", addr)
  1158  	}
  1159  }
  1160  
  1161  func TestEndpointExpiration(t *testing.T) {
  1162  	const (
  1163  		localAddrByte byte          = 0x01
  1164  		remoteAddr    tcpip.Address = "\x03"
  1165  		noAddr        tcpip.Address = ""
  1166  		nicID         tcpip.NICID   = 1
  1167  	)
  1168  	localAddr := tcpip.Address([]byte{localAddrByte})
  1169  
  1170  	for _, promiscuous := range []bool{true, false} {
  1171  		for _, spoofing := range []bool{true, false} {
  1172  			t.Run(fmt.Sprintf("promiscuous=%t spoofing=%t", promiscuous, spoofing), func(t *testing.T) {
  1173  				s := stack.New(stack.Options{
  1174  					NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
  1175  				})
  1176  
  1177  				ep := channel.New(10, defaultMTU, "")
  1178  				if err := s.CreateNIC(nicID, ep); err != nil {
  1179  					t.Fatal("CreateNIC failed:", err)
  1180  				}
  1181  
  1182  				{
  1183  					subnet, err := tcpip.NewSubnet("\x00", "\x00")
  1184  					if err != nil {
  1185  						t.Fatal(err)
  1186  					}
  1187  					s.SetRouteTable([]tcpip.Route{{Destination: subnet, Gateway: "\x00", NIC: 1}})
  1188  				}
  1189  
  1190  				fakeNet := s.NetworkProtocolInstance(fakeNetNumber).(*fakeNetworkProtocol)
  1191  				buf := buffer.NewView(30)
  1192  				buf[dstAddrOffset] = localAddrByte
  1193  
  1194  				if promiscuous {
  1195  					if err := s.SetPromiscuousMode(nicID, true); err != nil {
  1196  						t.Fatal("SetPromiscuousMode failed:", err)
  1197  					}
  1198  				}
  1199  
  1200  				if spoofing {
  1201  					if err := s.SetSpoofing(nicID, true); err != nil {
  1202  						t.Fatal("SetSpoofing failed:", err)
  1203  					}
  1204  				}
  1205  
  1206  				// 1. No Address yet, send should only work for spoofing, receive for
  1207  				// promiscuous mode.
  1208  				//-----------------------
  1209  				verifyAddress(t, s, nicID, noAddr)
  1210  				if promiscuous {
  1211  					testRecv(t, fakeNet, localAddrByte, ep, buf)
  1212  				} else {
  1213  					testFailingRecv(t, fakeNet, localAddrByte, ep, buf)
  1214  				}
  1215  				if spoofing {
  1216  					// FIXME(b/139841518):Spoofing doesn't work if there is no primary address.
  1217  					// testSendTo(t, s, remoteAddr, ep, nil)
  1218  				} else {
  1219  					testFailingSendTo(t, s, remoteAddr, nil, &tcpip.ErrNoRoute{})
  1220  				}
  1221  
  1222  				// 2. Add Address, everything should work.
  1223  				//-----------------------
  1224  				if err := s.AddAddress(nicID, fakeNetNumber, localAddr); err != nil {
  1225  					t.Fatal("AddAddress failed:", err)
  1226  				}
  1227  				verifyAddress(t, s, nicID, localAddr)
  1228  				testRecv(t, fakeNet, localAddrByte, ep, buf)
  1229  				testSendTo(t, s, remoteAddr, ep, nil)
  1230  
  1231  				// 3. Remove the address, send should only work for spoofing, receive
  1232  				// for promiscuous mode.
  1233  				//-----------------------
  1234  				if err := s.RemoveAddress(nicID, localAddr); err != nil {
  1235  					t.Fatal("RemoveAddress failed:", err)
  1236  				}
  1237  				verifyAddress(t, s, nicID, noAddr)
  1238  				if promiscuous {
  1239  					testRecv(t, fakeNet, localAddrByte, ep, buf)
  1240  				} else {
  1241  					testFailingRecv(t, fakeNet, localAddrByte, ep, buf)
  1242  				}
  1243  				if spoofing {
  1244  					// FIXME(b/139841518):Spoofing doesn't work if there is no primary address.
  1245  					// testSendTo(t, s, remoteAddr, ep, nil)
  1246  				} else {
  1247  					testFailingSendTo(t, s, remoteAddr, nil, &tcpip.ErrNoRoute{})
  1248  				}
  1249  
  1250  				// 4. Add Address back, everything should work again.
  1251  				//-----------------------
  1252  				if err := s.AddAddress(nicID, fakeNetNumber, localAddr); err != nil {
  1253  					t.Fatal("AddAddress failed:", err)
  1254  				}
  1255  				verifyAddress(t, s, nicID, localAddr)
  1256  				testRecv(t, fakeNet, localAddrByte, ep, buf)
  1257  				testSendTo(t, s, remoteAddr, ep, nil)
  1258  
  1259  				// 5. Take a reference to the endpoint by getting a route. Verify that
  1260  				// we can still send/receive, including sending using the route.
  1261  				//-----------------------
  1262  				r, err := s.FindRoute(0, "", remoteAddr, fakeNetNumber, false /* multicastLoop */)
  1263  				if err != nil {
  1264  					t.Fatal("FindRoute failed:", err)
  1265  				}
  1266  				testRecv(t, fakeNet, localAddrByte, ep, buf)
  1267  				testSendTo(t, s, remoteAddr, ep, nil)
  1268  				testSend(t, r, ep, nil)
  1269  
  1270  				// 6. Remove the address. Send should only work for spoofing, receive
  1271  				// for promiscuous mode.
  1272  				//-----------------------
  1273  				if err := s.RemoveAddress(nicID, localAddr); err != nil {
  1274  					t.Fatal("RemoveAddress failed:", err)
  1275  				}
  1276  				verifyAddress(t, s, nicID, noAddr)
  1277  				if promiscuous {
  1278  					testRecv(t, fakeNet, localAddrByte, ep, buf)
  1279  				} else {
  1280  					testFailingRecv(t, fakeNet, localAddrByte, ep, buf)
  1281  				}
  1282  				if spoofing {
  1283  					testSend(t, r, ep, nil)
  1284  					testSendTo(t, s, remoteAddr, ep, nil)
  1285  				} else {
  1286  					testFailingSend(t, r, nil, &tcpip.ErrInvalidEndpointState{})
  1287  					testFailingSendTo(t, s, remoteAddr, nil, &tcpip.ErrNoRoute{})
  1288  				}
  1289  
  1290  				// 7. Add Address back, everything should work again.
  1291  				//-----------------------
  1292  				if err := s.AddAddress(nicID, fakeNetNumber, localAddr); err != nil {
  1293  					t.Fatal("AddAddress failed:", err)
  1294  				}
  1295  				verifyAddress(t, s, nicID, localAddr)
  1296  				testRecv(t, fakeNet, localAddrByte, ep, buf)
  1297  				testSendTo(t, s, remoteAddr, ep, nil)
  1298  				testSend(t, r, ep, nil)
  1299  
  1300  				// 8. Remove the route, sendTo/recv should still work.
  1301  				//-----------------------
  1302  				r.Release()
  1303  				verifyAddress(t, s, nicID, localAddr)
  1304  				testRecv(t, fakeNet, localAddrByte, ep, buf)
  1305  				testSendTo(t, s, remoteAddr, ep, nil)
  1306  
  1307  				// 9. Remove the address. Send should only work for spoofing, receive
  1308  				// for promiscuous mode.
  1309  				//-----------------------
  1310  				if err := s.RemoveAddress(nicID, localAddr); err != nil {
  1311  					t.Fatal("RemoveAddress failed:", err)
  1312  				}
  1313  				verifyAddress(t, s, nicID, noAddr)
  1314  				if promiscuous {
  1315  					testRecv(t, fakeNet, localAddrByte, ep, buf)
  1316  				} else {
  1317  					testFailingRecv(t, fakeNet, localAddrByte, ep, buf)
  1318  				}
  1319  				if spoofing {
  1320  					// FIXME(b/139841518):Spoofing doesn't work if there is no primary address.
  1321  					// testSendTo(t, s, remoteAddr, ep, nil)
  1322  				} else {
  1323  					testFailingSendTo(t, s, remoteAddr, nil, &tcpip.ErrNoRoute{})
  1324  				}
  1325  			})
  1326  		}
  1327  	}
  1328  }
  1329  
  1330  func TestPromiscuousMode(t *testing.T) {
  1331  	s := stack.New(stack.Options{
  1332  		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
  1333  	})
  1334  
  1335  	ep := channel.New(10, defaultMTU, "")
  1336  	if err := s.CreateNIC(1, ep); err != nil {
  1337  		t.Fatal("CreateNIC failed:", err)
  1338  	}
  1339  
  1340  	{
  1341  		subnet, err := tcpip.NewSubnet("\x00", "\x00")
  1342  		if err != nil {
  1343  			t.Fatal(err)
  1344  		}
  1345  		s.SetRouteTable([]tcpip.Route{{Destination: subnet, Gateway: "\x00", NIC: 1}})
  1346  	}
  1347  
  1348  	fakeNet := s.NetworkProtocolInstance(fakeNetNumber).(*fakeNetworkProtocol)
  1349  
  1350  	buf := buffer.NewView(30)
  1351  
  1352  	// Write a packet, and check that it doesn't get delivered as we don't
  1353  	// have a matching endpoint.
  1354  	const localAddrByte byte = 0x01
  1355  	buf[dstAddrOffset] = localAddrByte
  1356  	testFailingRecv(t, fakeNet, localAddrByte, ep, buf)
  1357  
  1358  	// Set promiscuous mode, then check that packet is delivered.
  1359  	if err := s.SetPromiscuousMode(1, true); err != nil {
  1360  		t.Fatal("SetPromiscuousMode failed:", err)
  1361  	}
  1362  	testRecv(t, fakeNet, localAddrByte, ep, buf)
  1363  
  1364  	// Check that we can't get a route as there is no local address.
  1365  	_, err := s.FindRoute(0, "", "\x02", fakeNetNumber, false /* multicastLoop */)
  1366  	if _, ok := err.(*tcpip.ErrNoRoute); !ok {
  1367  		t.Fatalf("FindRoute returned unexpected error: got = %v, want = %s", err, &tcpip.ErrNoRoute{})
  1368  	}
  1369  
  1370  	// Set promiscuous mode to false, then check that packet can't be
  1371  	// delivered anymore.
  1372  	if err := s.SetPromiscuousMode(1, false); err != nil {
  1373  		t.Fatal("SetPromiscuousMode failed:", err)
  1374  	}
  1375  	testFailingRecv(t, fakeNet, localAddrByte, ep, buf)
  1376  }
  1377  
  1378  // TestExternalSendWithHandleLocal tests that the stack creates a non-local
  1379  // route when spoofing or promiscuous mode are enabled.
  1380  //
  1381  // This test makes sure that packets are transmitted from the stack.
  1382  func TestExternalSendWithHandleLocal(t *testing.T) {
  1383  	const (
  1384  		unspecifiedNICID = 0
  1385  		nicID            = 1
  1386  
  1387  		localAddr = tcpip.Address("\x01")
  1388  		dstAddr   = tcpip.Address("\x03")
  1389  	)
  1390  
  1391  	subnet, err := tcpip.NewSubnet("\x00", "\x00")
  1392  	if err != nil {
  1393  		t.Fatal(err)
  1394  	}
  1395  
  1396  	tests := []struct {
  1397  		name           string
  1398  		configureStack func(*testing.T, *stack.Stack)
  1399  	}{
  1400  		{
  1401  			name:           "Default",
  1402  			configureStack: func(*testing.T, *stack.Stack) {},
  1403  		},
  1404  		{
  1405  			name: "Spoofing",
  1406  			configureStack: func(t *testing.T, s *stack.Stack) {
  1407  				if err := s.SetSpoofing(nicID, true); err != nil {
  1408  					t.Fatalf("s.SetSpoofing(%d, true): %s", nicID, err)
  1409  				}
  1410  			},
  1411  		},
  1412  		{
  1413  			name: "Promiscuous",
  1414  			configureStack: func(t *testing.T, s *stack.Stack) {
  1415  				if err := s.SetPromiscuousMode(nicID, true); err != nil {
  1416  					t.Fatalf("s.SetPromiscuousMode(%d, true): %s", nicID, err)
  1417  				}
  1418  			},
  1419  		},
  1420  	}
  1421  
  1422  	for _, test := range tests {
  1423  		t.Run(test.name, func(t *testing.T) {
  1424  			for _, handleLocal := range []bool{true, false} {
  1425  				t.Run(fmt.Sprintf("HandleLocal=%t", handleLocal), func(t *testing.T) {
  1426  					s := stack.New(stack.Options{
  1427  						NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
  1428  						HandleLocal:      handleLocal,
  1429  					})
  1430  
  1431  					ep := channel.New(1, defaultMTU, "")
  1432  					if err := s.CreateNIC(nicID, ep); err != nil {
  1433  						t.Fatalf("s.CreateNIC(%d, _): %s", nicID, err)
  1434  					}
  1435  					if err := s.AddAddress(nicID, fakeNetNumber, localAddr); err != nil {
  1436  						t.Fatalf("s.AddAddress(%d, %d, %s): %s", nicID, fakeNetNumber, localAddr, err)
  1437  					}
  1438  
  1439  					s.SetRouteTable([]tcpip.Route{{Destination: subnet, NIC: nicID}})
  1440  
  1441  					test.configureStack(t, s)
  1442  
  1443  					r, err := s.FindRoute(unspecifiedNICID, localAddr, dstAddr, fakeNetNumber, false /* multicastLoop */)
  1444  					if err != nil {
  1445  						t.Fatalf("s.FindRoute(%d, %s, %s, %d, false): %s", unspecifiedNICID, localAddr, dstAddr, fakeNetNumber, err)
  1446  					}
  1447  					defer r.Release()
  1448  
  1449  					if r.LocalAddress() != localAddr {
  1450  						t.Errorf("got r.LocalAddress() = %s, want = %s", r.LocalAddress(), localAddr)
  1451  					}
  1452  					if r.RemoteAddress() != dstAddr {
  1453  						t.Errorf("got r.RemoteAddress() = %s, want = %s", r.RemoteAddress(), dstAddr)
  1454  					}
  1455  
  1456  					if n := ep.Drain(); n != 0 {
  1457  						t.Fatalf("got ep.Drain() = %d, want = 0", n)
  1458  					}
  1459  					if err := r.WritePacket(stack.NetworkHeaderParams{
  1460  						Protocol: fakeTransNumber,
  1461  						TTL:      123,
  1462  						TOS:      stack.DefaultTOS,
  1463  					}, stack.NewPacketBuffer(stack.PacketBufferOptions{
  1464  						ReserveHeaderBytes: int(r.MaxHeaderLength()),
  1465  						Data:               buffer.NewView(10).ToVectorisedView(),
  1466  					})); err != nil {
  1467  						t.Fatalf("r.WritePacket(nil, _, _): %s", err)
  1468  					}
  1469  					if n := ep.Drain(); n != 1 {
  1470  						t.Fatalf("got ep.Drain() = %d, want = 1", n)
  1471  					}
  1472  				})
  1473  			}
  1474  		})
  1475  	}
  1476  }
  1477  
  1478  func TestSpoofingWithAddress(t *testing.T) {
  1479  	localAddr := tcpip.Address("\x01")
  1480  	nonExistentLocalAddr := tcpip.Address("\x02")
  1481  	dstAddr := tcpip.Address("\x03")
  1482  
  1483  	s := stack.New(stack.Options{
  1484  		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
  1485  	})
  1486  
  1487  	ep := channel.New(10, defaultMTU, "")
  1488  	if err := s.CreateNIC(1, ep); err != nil {
  1489  		t.Fatal("CreateNIC failed:", err)
  1490  	}
  1491  
  1492  	if err := s.AddAddress(1, fakeNetNumber, localAddr); err != nil {
  1493  		t.Fatal("AddAddress failed:", err)
  1494  	}
  1495  
  1496  	{
  1497  		subnet, err := tcpip.NewSubnet("\x00", "\x00")
  1498  		if err != nil {
  1499  			t.Fatal(err)
  1500  		}
  1501  		s.SetRouteTable([]tcpip.Route{{Destination: subnet, Gateway: "\x00", NIC: 1}})
  1502  	}
  1503  
  1504  	// With address spoofing disabled, FindRoute does not permit an address
  1505  	// that was not added to the NIC to be used as the source.
  1506  	r, err := s.FindRoute(0, nonExistentLocalAddr, dstAddr, fakeNetNumber, false /* multicastLoop */)
  1507  	if err == nil {
  1508  		t.Errorf("FindRoute succeeded with route %+v when it should have failed", r)
  1509  	}
  1510  
  1511  	// With address spoofing enabled, FindRoute permits any address to be used
  1512  	// as the source.
  1513  	if err := s.SetSpoofing(1, true); err != nil {
  1514  		t.Fatal("SetSpoofing failed:", err)
  1515  	}
  1516  	r, err = s.FindRoute(0, nonExistentLocalAddr, dstAddr, fakeNetNumber, false /* multicastLoop */)
  1517  	if err != nil {
  1518  		t.Fatal("FindRoute failed:", err)
  1519  	}
  1520  	if r.LocalAddress() != nonExistentLocalAddr {
  1521  		t.Errorf("got Route.LocalAddress() = %s, want = %s", r.LocalAddress(), nonExistentLocalAddr)
  1522  	}
  1523  	if r.RemoteAddress() != dstAddr {
  1524  		t.Errorf("got Route.RemoteAddress() = %s, want = %s", r.RemoteAddress(), dstAddr)
  1525  	}
  1526  	// Sending a packet works.
  1527  	testSendTo(t, s, dstAddr, ep, nil)
  1528  	testSend(t, r, ep, nil)
  1529  
  1530  	// FindRoute should also work with a local address that exists on the NIC.
  1531  	r, err = s.FindRoute(0, localAddr, dstAddr, fakeNetNumber, false /* multicastLoop */)
  1532  	if err != nil {
  1533  		t.Fatal("FindRoute failed:", err)
  1534  	}
  1535  	if r.LocalAddress() != localAddr {
  1536  		t.Errorf("got Route.LocalAddress() = %s, want = %s", r.LocalAddress(), nonExistentLocalAddr)
  1537  	}
  1538  	if r.RemoteAddress() != dstAddr {
  1539  		t.Errorf("got Route.RemoteAddress() = %s, want = %s", r.RemoteAddress(), dstAddr)
  1540  	}
  1541  	// Sending a packet using the route works.
  1542  	testSend(t, r, ep, nil)
  1543  }
  1544  
  1545  func TestSpoofingNoAddress(t *testing.T) {
  1546  	nonExistentLocalAddr := tcpip.Address("\x01")
  1547  	dstAddr := tcpip.Address("\x02")
  1548  
  1549  	s := stack.New(stack.Options{
  1550  		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
  1551  	})
  1552  
  1553  	ep := channel.New(10, defaultMTU, "")
  1554  	if err := s.CreateNIC(1, ep); err != nil {
  1555  		t.Fatal("CreateNIC failed:", err)
  1556  	}
  1557  
  1558  	{
  1559  		subnet, err := tcpip.NewSubnet("\x00", "\x00")
  1560  		if err != nil {
  1561  			t.Fatal(err)
  1562  		}
  1563  		s.SetRouteTable([]tcpip.Route{{Destination: subnet, Gateway: "\x00", NIC: 1}})
  1564  	}
  1565  
  1566  	// With address spoofing disabled, FindRoute does not permit an address
  1567  	// that was not added to the NIC to be used as the source.
  1568  	r, err := s.FindRoute(0, nonExistentLocalAddr, dstAddr, fakeNetNumber, false /* multicastLoop */)
  1569  	if err == nil {
  1570  		t.Errorf("FindRoute succeeded with route %+v when it should have failed", r)
  1571  	}
  1572  	// Sending a packet fails.
  1573  	testFailingSendTo(t, s, dstAddr, nil, &tcpip.ErrNoRoute{})
  1574  
  1575  	// With address spoofing enabled, FindRoute permits any address to be used
  1576  	// as the source.
  1577  	if err := s.SetSpoofing(1, true); err != nil {
  1578  		t.Fatal("SetSpoofing failed:", err)
  1579  	}
  1580  	r, err = s.FindRoute(0, nonExistentLocalAddr, dstAddr, fakeNetNumber, false /* multicastLoop */)
  1581  	if err != nil {
  1582  		t.Fatal("FindRoute failed:", err)
  1583  	}
  1584  	if r.LocalAddress() != nonExistentLocalAddr {
  1585  		t.Errorf("got Route.LocalAddress() = %s, want = %s", r.LocalAddress(), nonExistentLocalAddr)
  1586  	}
  1587  	if r.RemoteAddress() != dstAddr {
  1588  		t.Errorf("got Route.RemoteAddress() = %s, want = %s", r.RemoteAddress(), dstAddr)
  1589  	}
  1590  	// Sending a packet works.
  1591  	// FIXME(b/139841518):Spoofing doesn't work if there is no primary address.
  1592  	// testSendTo(t, s, remoteAddr, ep, nil)
  1593  }
  1594  
  1595  func TestOutgoingBroadcastWithEmptyRouteTable(t *testing.T) {
  1596  	s := stack.New(stack.Options{
  1597  		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
  1598  	})
  1599  
  1600  	ep := channel.New(10, defaultMTU, "")
  1601  	if err := s.CreateNIC(1, ep); err != nil {
  1602  		t.Fatal("CreateNIC failed:", err)
  1603  	}
  1604  	s.SetRouteTable([]tcpip.Route{})
  1605  
  1606  	// If there is no endpoint, it won't work.
  1607  	{
  1608  		_, err := s.FindRoute(1, header.IPv4Any, header.IPv4Broadcast, fakeNetNumber, false /* multicastLoop */)
  1609  		if _, ok := err.(*tcpip.ErrNetworkUnreachable); !ok {
  1610  			t.Fatalf("got FindRoute(1, %s, %s, %d) = %s, want = %s", header.IPv4Any, header.IPv4Broadcast, fakeNetNumber, err, &tcpip.ErrNetworkUnreachable{})
  1611  		}
  1612  	}
  1613  
  1614  	protoAddr := tcpip.ProtocolAddress{Protocol: fakeNetNumber, AddressWithPrefix: tcpip.AddressWithPrefix{Address: header.IPv4Any}}
  1615  	if err := s.AddProtocolAddress(1, protoAddr); err != nil {
  1616  		t.Fatalf("AddProtocolAddress(1, %v) failed: %v", protoAddr, err)
  1617  	}
  1618  	r, err := s.FindRoute(1, header.IPv4Any, header.IPv4Broadcast, fakeNetNumber, false /* multicastLoop */)
  1619  	if err != nil {
  1620  		t.Fatalf("FindRoute(1, %v, %v, %d) failed: %v", header.IPv4Any, header.IPv4Broadcast, fakeNetNumber, err)
  1621  	}
  1622  	if r.LocalAddress() != header.IPv4Any {
  1623  		t.Errorf("got Route.LocalAddress() = %s, want = %s", r.LocalAddress(), header.IPv4Any)
  1624  	}
  1625  
  1626  	if r.RemoteAddress() != header.IPv4Broadcast {
  1627  		t.Errorf("got Route.RemoteAddress() = %s, want = %s", r.RemoteAddress(), header.IPv4Broadcast)
  1628  	}
  1629  
  1630  	// If the NIC doesn't exist, it won't work.
  1631  	{
  1632  		_, err := s.FindRoute(2, header.IPv4Any, header.IPv4Broadcast, fakeNetNumber, false /* multicastLoop */)
  1633  		if _, ok := err.(*tcpip.ErrNetworkUnreachable); !ok {
  1634  			t.Fatalf("got FindRoute(2, %v, %v, %d) = %v want = %v", header.IPv4Any, header.IPv4Broadcast, fakeNetNumber, err, &tcpip.ErrNetworkUnreachable{})
  1635  		}
  1636  	}
  1637  }
  1638  
  1639  func TestOutgoingBroadcastWithRouteTable(t *testing.T) {
  1640  	defaultAddr := tcpip.AddressWithPrefix{Address: header.IPv4Any}
  1641  	// Local subnet on NIC1: 192.168.1.58/24, gateway 192.168.1.1.
  1642  	nic1Addr := tcpip.AddressWithPrefix{Address: "\xc0\xa8\x01\x3a", PrefixLen: 24}
  1643  	nic1Gateway := testutil.MustParse4("192.168.1.1")
  1644  	// Local subnet on NIC2: 10.10.10.5/24, gateway 10.10.10.1.
  1645  	nic2Addr := tcpip.AddressWithPrefix{Address: "\x0a\x0a\x0a\x05", PrefixLen: 24}
  1646  	nic2Gateway := testutil.MustParse4("10.10.10.1")
  1647  
  1648  	// Create a new stack with two NICs.
  1649  	s := stack.New(stack.Options{
  1650  		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
  1651  	})
  1652  	ep := channel.New(10, defaultMTU, "")
  1653  	if err := s.CreateNIC(1, ep); err != nil {
  1654  		t.Fatalf("CreateNIC failed: %s", err)
  1655  	}
  1656  	if err := s.CreateNIC(2, ep); err != nil {
  1657  		t.Fatalf("CreateNIC failed: %s", err)
  1658  	}
  1659  	nic1ProtoAddr := tcpip.ProtocolAddress{Protocol: fakeNetNumber, AddressWithPrefix: nic1Addr}
  1660  	if err := s.AddProtocolAddress(1, nic1ProtoAddr); err != nil {
  1661  		t.Fatalf("AddProtocolAddress(1, %v) failed: %v", nic1ProtoAddr, err)
  1662  	}
  1663  
  1664  	nic2ProtoAddr := tcpip.ProtocolAddress{Protocol: fakeNetNumber, AddressWithPrefix: nic2Addr}
  1665  	if err := s.AddProtocolAddress(2, nic2ProtoAddr); err != nil {
  1666  		t.Fatalf("AddAddress(2, %v) failed: %v", nic2ProtoAddr, err)
  1667  	}
  1668  
  1669  	// Set the initial route table.
  1670  	rt := []tcpip.Route{
  1671  		{Destination: nic1Addr.Subnet(), NIC: 1},
  1672  		{Destination: nic2Addr.Subnet(), NIC: 2},
  1673  		{Destination: defaultAddr.Subnet(), Gateway: nic2Gateway, NIC: 2},
  1674  		{Destination: defaultAddr.Subnet(), Gateway: nic1Gateway, NIC: 1},
  1675  	}
  1676  	s.SetRouteTable(rt)
  1677  
  1678  	// When an interface is given, the route for a broadcast goes through it.
  1679  	r, err := s.FindRoute(1, nic1Addr.Address, header.IPv4Broadcast, fakeNetNumber, false /* multicastLoop */)
  1680  	if err != nil {
  1681  		t.Fatalf("FindRoute(1, %v, %v, %d) failed: %v", nic1Addr.Address, header.IPv4Broadcast, fakeNetNumber, err)
  1682  	}
  1683  	if r.LocalAddress() != nic1Addr.Address {
  1684  		t.Errorf("got Route.LocalAddress() = %s, want = %s", r.LocalAddress(), nic1Addr.Address)
  1685  	}
  1686  
  1687  	if r.RemoteAddress() != header.IPv4Broadcast {
  1688  		t.Errorf("got Route.RemoteAddress() = %s, want = %s", r.RemoteAddress(), header.IPv4Broadcast)
  1689  	}
  1690  
  1691  	// When an interface is not given, it consults the route table.
  1692  	// 1. Case: Using the default route.
  1693  	r, err = s.FindRoute(0, "", header.IPv4Broadcast, fakeNetNumber, false /* multicastLoop */)
  1694  	if err != nil {
  1695  		t.Fatalf("FindRoute(0, \"\", %s, %d) failed: %s", header.IPv4Broadcast, fakeNetNumber, err)
  1696  	}
  1697  	if r.LocalAddress() != nic2Addr.Address {
  1698  		t.Errorf("got Route.LocalAddress() = %s, want = %s", r.LocalAddress(), nic2Addr.Address)
  1699  	}
  1700  
  1701  	if r.RemoteAddress() != header.IPv4Broadcast {
  1702  		t.Errorf("got Route.RemoteAddress() = %s, want = %s", r.RemoteAddress(), header.IPv4Broadcast)
  1703  	}
  1704  
  1705  	// 2. Case: Having an explicit route for broadcast will select that one.
  1706  	rt = append(
  1707  		[]tcpip.Route{
  1708  			{Destination: tcpip.AddressWithPrefix{Address: header.IPv4Broadcast, PrefixLen: 8 * header.IPv4AddressSize}.Subnet(), NIC: 1},
  1709  		},
  1710  		rt...,
  1711  	)
  1712  	s.SetRouteTable(rt)
  1713  	r, err = s.FindRoute(0, "", header.IPv4Broadcast, fakeNetNumber, false /* multicastLoop */)
  1714  	if err != nil {
  1715  		t.Fatalf("FindRoute(0, \"\", %s, %d) failed: %s", header.IPv4Broadcast, fakeNetNumber, err)
  1716  	}
  1717  	if r.LocalAddress() != nic1Addr.Address {
  1718  		t.Errorf("got Route.LocalAddress() = %s, want = %s", r.LocalAddress(), nic1Addr.Address)
  1719  	}
  1720  
  1721  	if r.RemoteAddress() != header.IPv4Broadcast {
  1722  		t.Errorf("got Route.RemoteAddress() = %s, want = %s", r.RemoteAddress(), header.IPv4Broadcast)
  1723  	}
  1724  }
  1725  
  1726  func TestMulticastOrIPv6LinkLocalNeedsNoRoute(t *testing.T) {
  1727  	for _, tc := range []struct {
  1728  		name        string
  1729  		routeNeeded bool
  1730  		address     tcpip.Address
  1731  	}{
  1732  		// IPv4 multicast address range: 224.0.0.0 - 239.255.255.255
  1733  		//                <=>  0xe0.0x00.0x00.0x00 - 0xef.0xff.0xff.0xff
  1734  		{"IPv4 Multicast 1", false, "\xe0\x00\x00\x00"},
  1735  		{"IPv4 Multicast 2", false, "\xef\xff\xff\xff"},
  1736  		{"IPv4 Unicast 1", true, "\xdf\xff\xff\xff"},
  1737  		{"IPv4 Unicast 2", true, "\xf0\x00\x00\x00"},
  1738  		{"IPv4 Unicast 3", true, "\x00\x00\x00\x00"},
  1739  
  1740  		// IPv6 multicast address is 0xff[8] + flags[4] + scope[4] + groupId[112]
  1741  		{"IPv6 Multicast 1", false, "\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
  1742  		{"IPv6 Multicast 2", false, "\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
  1743  		{"IPv6 Multicast 3", false, "\xff\x0f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"},
  1744  
  1745  		// IPv6 link-local address starts with fe80::/10.
  1746  		{"IPv6 Unicast Link-Local 1", false, "\xfe\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
  1747  		{"IPv6 Unicast Link-Local 2", false, "\xfe\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"},
  1748  		{"IPv6 Unicast Link-Local 3", false, "\xfe\x80\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff"},
  1749  		{"IPv6 Unicast Link-Local 4", false, "\xfe\xbf\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
  1750  		{"IPv6 Unicast Link-Local 5", false, "\xfe\xbf\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"},
  1751  
  1752  		// IPv6 addresses that are neither multicast nor link-local.
  1753  		{"IPv6 Unicast Not Link-Local 1", true, "\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
  1754  		{"IPv6 Unicast Not Link-Local 2", true, "\xf0\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"},
  1755  		{"IPv6 Unicast Not Link-local 3", true, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
  1756  		{"IPv6 Unicast Not Link-Local 4", true, "\xfe\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
  1757  		{"IPv6 Unicast Not Link-Local 5", true, "\xfe\xdf\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
  1758  		{"IPv6 Unicast Not Link-Local 6", true, "\xfd\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
  1759  		{"IPv6 Unicast Not Link-Local 7", true, "\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
  1760  	} {
  1761  		t.Run(tc.name, func(t *testing.T) {
  1762  			s := stack.New(stack.Options{
  1763  				NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
  1764  			})
  1765  
  1766  			ep := channel.New(10, defaultMTU, "")
  1767  			if err := s.CreateNIC(1, ep); err != nil {
  1768  				t.Fatal("CreateNIC failed:", err)
  1769  			}
  1770  
  1771  			s.SetRouteTable([]tcpip.Route{})
  1772  
  1773  			var anyAddr tcpip.Address
  1774  			if len(tc.address) == header.IPv4AddressSize {
  1775  				anyAddr = header.IPv4Any
  1776  			} else {
  1777  				anyAddr = header.IPv6Any
  1778  			}
  1779  
  1780  			var want tcpip.Error = &tcpip.ErrNetworkUnreachable{}
  1781  			if tc.routeNeeded {
  1782  				want = &tcpip.ErrNoRoute{}
  1783  			}
  1784  
  1785  			// If there is no endpoint, it won't work.
  1786  			if _, err := s.FindRoute(1, anyAddr, tc.address, fakeNetNumber, false /* multicastLoop */); err != want {
  1787  				t.Fatalf("got FindRoute(1, %v, %v, %v) = %v, want = %v", anyAddr, tc.address, fakeNetNumber, err, want)
  1788  			}
  1789  
  1790  			if err := s.AddAddress(1, fakeNetNumber, anyAddr); err != nil {
  1791  				t.Fatalf("AddAddress(%v, %v) failed: %v", fakeNetNumber, anyAddr, err)
  1792  			}
  1793  
  1794  			if r, err := s.FindRoute(1, anyAddr, tc.address, fakeNetNumber, false /* multicastLoop */); tc.routeNeeded {
  1795  				// Route table is empty but we need a route, this should cause an error.
  1796  				if _, ok := err.(*tcpip.ErrNoRoute); !ok {
  1797  					t.Fatalf("got FindRoute(1, %v, %v, %v) = %v, want = %v", anyAddr, tc.address, fakeNetNumber, err, &tcpip.ErrNoRoute{})
  1798  				}
  1799  			} else {
  1800  				if err != nil {
  1801  					t.Fatalf("FindRoute(1, %v, %v, %v) failed: %v", anyAddr, tc.address, fakeNetNumber, err)
  1802  				}
  1803  				if r.LocalAddress() != anyAddr {
  1804  					t.Errorf("Bad local address: got %v, want = %v", r.LocalAddress(), anyAddr)
  1805  				}
  1806  				if r.RemoteAddress() != tc.address {
  1807  					t.Errorf("Bad remote address: got %v, want = %v", r.RemoteAddress(), tc.address)
  1808  				}
  1809  			}
  1810  			// If the NIC doesn't exist, it won't work.
  1811  			if _, err := s.FindRoute(2, anyAddr, tc.address, fakeNetNumber, false /* multicastLoop */); err != want {
  1812  				t.Fatalf("got FindRoute(2, %v, %v, %v) = %v want = %v", anyAddr, tc.address, fakeNetNumber, err, want)
  1813  			}
  1814  		})
  1815  	}
  1816  }
  1817  
  1818  func TestNetworkOption(t *testing.T) {
  1819  	s := stack.New(stack.Options{
  1820  		NetworkProtocols:   []stack.NetworkProtocolFactory{fakeNetFactory},
  1821  		TransportProtocols: []stack.TransportProtocolFactory{},
  1822  	})
  1823  
  1824  	opt := tcpip.DefaultTTLOption(5)
  1825  	if err := s.SetNetworkProtocolOption(fakeNetNumber, &opt); err != nil {
  1826  		t.Fatalf("s.SetNetworkProtocolOption(%d, &%T(%d)): %s", fakeNetNumber, opt, opt, err)
  1827  	}
  1828  
  1829  	var optGot tcpip.DefaultTTLOption
  1830  	if err := s.NetworkProtocolOption(fakeNetNumber, &optGot); err != nil {
  1831  		t.Fatalf("s.NetworkProtocolOption(%d, &%T): %s", fakeNetNumber, optGot, err)
  1832  	}
  1833  
  1834  	if opt != optGot {
  1835  		t.Errorf("got optGot = %d, want = %d", optGot, opt)
  1836  	}
  1837  }
  1838  
  1839  func TestGetMainNICAddressAddPrimaryNonPrimary(t *testing.T) {
  1840  	const nicID = 1
  1841  
  1842  	for _, addrLen := range []int{4, 16} {
  1843  		t.Run(fmt.Sprintf("addrLen=%d", addrLen), func(t *testing.T) {
  1844  			for canBe := 0; canBe < 3; canBe++ {
  1845  				t.Run(fmt.Sprintf("canBe=%d", canBe), func(t *testing.T) {
  1846  					for never := 0; never < 3; never++ {
  1847  						t.Run(fmt.Sprintf("never=%d", never), func(t *testing.T) {
  1848  							s := stack.New(stack.Options{
  1849  								NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
  1850  							})
  1851  							ep := channel.New(10, defaultMTU, "")
  1852  							if err := s.CreateNIC(nicID, ep); err != nil {
  1853  								t.Fatalf("CreateNIC(%d, _): %s", nicID, err)
  1854  							}
  1855  							// Insert <canBe> primary and <never> never-primary addresses.
  1856  							// Each one will add a network endpoint to the NIC.
  1857  							primaryAddrAdded := make(map[tcpip.AddressWithPrefix]struct{})
  1858  							for i := 0; i < canBe+never; i++ {
  1859  								var behavior stack.PrimaryEndpointBehavior
  1860  								if i < canBe {
  1861  									behavior = stack.CanBePrimaryEndpoint
  1862  								} else {
  1863  									behavior = stack.NeverPrimaryEndpoint
  1864  								}
  1865  								// Add an address and in case of a primary one include a
  1866  								// prefixLen.
  1867  								address := tcpip.Address(bytes.Repeat([]byte{byte(i)}, addrLen))
  1868  								if behavior == stack.CanBePrimaryEndpoint {
  1869  									protocolAddress := tcpip.ProtocolAddress{
  1870  										Protocol: fakeNetNumber,
  1871  										AddressWithPrefix: tcpip.AddressWithPrefix{
  1872  											Address:   address,
  1873  											PrefixLen: addrLen * 8,
  1874  										},
  1875  									}
  1876  									if err := s.AddProtocolAddressWithOptions(nicID, protocolAddress, behavior); err != nil {
  1877  										t.Fatalf("AddProtocolAddressWithOptions(%d, %#v, %d): %s", nicID, protocolAddress, behavior, err)
  1878  									}
  1879  									// Remember the address/prefix.
  1880  									primaryAddrAdded[protocolAddress.AddressWithPrefix] = struct{}{}
  1881  								} else {
  1882  									if err := s.AddAddressWithOptions(nicID, fakeNetNumber, address, behavior); err != nil {
  1883  										t.Fatalf("AddAddressWithOptions(%d, %d, %s, %d): %s:", nicID, fakeNetNumber, address, behavior, err)
  1884  									}
  1885  								}
  1886  							}
  1887  							// Check that GetMainNICAddress returns an address if at least
  1888  							// one primary address was added. In that case make sure the
  1889  							// address/prefixLen matches what we added.
  1890  							gotAddr, err := s.GetMainNICAddress(nicID, fakeNetNumber)
  1891  							if err != nil {
  1892  								t.Fatalf("GetMainNICAddress(%d, %d): %s", nicID, fakeNetNumber, err)
  1893  							}
  1894  							if len(primaryAddrAdded) == 0 {
  1895  								// No primary addresses present.
  1896  								if wantAddr := (tcpip.AddressWithPrefix{}); gotAddr != wantAddr {
  1897  									t.Fatalf("got GetMainNICAddress(%d, %d) = %s, want = %s", nicID, fakeNetNumber, gotAddr, wantAddr)
  1898  								}
  1899  							} else {
  1900  								// At least one primary address was added, verify the returned
  1901  								// address is in the list of primary addresses we added.
  1902  								if _, ok := primaryAddrAdded[gotAddr]; !ok {
  1903  									t.Fatalf("got GetMainNICAddress(%d, %d) = %s, want = %s", nicID, fakeNetNumber, gotAddr, primaryAddrAdded)
  1904  								}
  1905  							}
  1906  						})
  1907  					}
  1908  				})
  1909  			}
  1910  		})
  1911  	}
  1912  }
  1913  
  1914  func TestGetMainNICAddressErrors(t *testing.T) {
  1915  	const nicID = 1
  1916  
  1917  	s := stack.New(stack.Options{
  1918  		NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol, arp.NewProtocol},
  1919  	})
  1920  	if err := s.CreateNIC(nicID, loopback.New()); err != nil {
  1921  		t.Fatalf("CreateNIC(%d, _): %s", nicID, err)
  1922  	}
  1923  
  1924  	// Sanity check with a successful call.
  1925  	if addr, err := s.GetMainNICAddress(nicID, ipv4.ProtocolNumber); err != nil {
  1926  		t.Errorf("s.GetMainNICAddress(%d, %d): %s", nicID, ipv4.ProtocolNumber, err)
  1927  	} else if want := (tcpip.AddressWithPrefix{}); addr != want {
  1928  		t.Errorf("got s.GetMainNICAddress(%d, %d) = %s, want = %s", nicID, ipv4.ProtocolNumber, addr, want)
  1929  	}
  1930  
  1931  	const unknownNICID = nicID + 1
  1932  	switch addr, err := s.GetMainNICAddress(unknownNICID, ipv4.ProtocolNumber); err.(type) {
  1933  	case *tcpip.ErrUnknownNICID:
  1934  	default:
  1935  		t.Errorf("got s.GetMainNICAddress(%d, %d) = (%s, %T), want = (_, tcpip.ErrUnknownNICID)", unknownNICID, ipv4.ProtocolNumber, addr, err)
  1936  	}
  1937  
  1938  	// ARP is not an addressable network endpoint.
  1939  	switch addr, err := s.GetMainNICAddress(nicID, arp.ProtocolNumber); err.(type) {
  1940  	case *tcpip.ErrNotSupported:
  1941  	default:
  1942  		t.Errorf("got s.GetMainNICAddress(%d, %d) = (%s, %T), want = (_, tcpip.ErrNotSupported)", nicID, arp.ProtocolNumber, addr, err)
  1943  	}
  1944  
  1945  	const unknownProtocolNumber = 1234
  1946  	switch addr, err := s.GetMainNICAddress(nicID, unknownProtocolNumber); err.(type) {
  1947  	case *tcpip.ErrUnknownProtocol:
  1948  	default:
  1949  		t.Errorf("got s.GetMainNICAddress(%d, %d) = (%s, %T), want = (_, tcpip.ErrUnknownProtocol)", nicID, unknownProtocolNumber, addr, err)
  1950  	}
  1951  }
  1952  
  1953  func TestGetMainNICAddressAddRemove(t *testing.T) {
  1954  	s := stack.New(stack.Options{
  1955  		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
  1956  	})
  1957  	ep := channel.New(10, defaultMTU, "")
  1958  	if err := s.CreateNIC(1, ep); err != nil {
  1959  		t.Fatal("CreateNIC failed:", err)
  1960  	}
  1961  
  1962  	for _, tc := range []struct {
  1963  		name      string
  1964  		address   tcpip.Address
  1965  		prefixLen int
  1966  	}{
  1967  		{"IPv4", "\x01\x01\x01\x01", 24},
  1968  		{"IPv6", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", 116},
  1969  	} {
  1970  		t.Run(tc.name, func(t *testing.T) {
  1971  			protocolAddress := tcpip.ProtocolAddress{
  1972  				Protocol: fakeNetNumber,
  1973  				AddressWithPrefix: tcpip.AddressWithPrefix{
  1974  					Address:   tc.address,
  1975  					PrefixLen: tc.prefixLen,
  1976  				},
  1977  			}
  1978  			if err := s.AddProtocolAddress(1, protocolAddress); err != nil {
  1979  				t.Fatal("AddProtocolAddress failed:", err)
  1980  			}
  1981  
  1982  			// Check that we get the right initial address and prefix length.
  1983  			if err := checkGetMainNICAddress(s, 1, fakeNetNumber, protocolAddress.AddressWithPrefix); err != nil {
  1984  				t.Fatal(err)
  1985  			}
  1986  
  1987  			if err := s.RemoveAddress(1, protocolAddress.AddressWithPrefix.Address); err != nil {
  1988  				t.Fatal("RemoveAddress failed:", err)
  1989  			}
  1990  
  1991  			// Check that we get no address after removal.
  1992  			if err := checkGetMainNICAddress(s, 1, fakeNetNumber, tcpip.AddressWithPrefix{}); err != nil {
  1993  				t.Fatal(err)
  1994  			}
  1995  		})
  1996  	}
  1997  }
  1998  
  1999  // Simple network address generator. Good for 255 addresses.
  2000  type addressGenerator struct{ cnt byte }
  2001  
  2002  func (g *addressGenerator) next(addrLen int) tcpip.Address {
  2003  	g.cnt++
  2004  	return tcpip.Address(bytes.Repeat([]byte{g.cnt}, addrLen))
  2005  }
  2006  
  2007  func verifyAddresses(t *testing.T, expectedAddresses, gotAddresses []tcpip.ProtocolAddress) {
  2008  	t.Helper()
  2009  
  2010  	if len(gotAddresses) != len(expectedAddresses) {
  2011  		t.Fatalf("got len(addresses) = %d, want = %d", len(gotAddresses), len(expectedAddresses))
  2012  	}
  2013  
  2014  	sort.Slice(gotAddresses, func(i, j int) bool {
  2015  		return gotAddresses[i].AddressWithPrefix.Address < gotAddresses[j].AddressWithPrefix.Address
  2016  	})
  2017  	sort.Slice(expectedAddresses, func(i, j int) bool {
  2018  		return expectedAddresses[i].AddressWithPrefix.Address < expectedAddresses[j].AddressWithPrefix.Address
  2019  	})
  2020  
  2021  	for i, gotAddr := range gotAddresses {
  2022  		expectedAddr := expectedAddresses[i]
  2023  		if gotAddr != expectedAddr {
  2024  			t.Errorf("got address = %+v, wanted = %+v", gotAddr, expectedAddr)
  2025  		}
  2026  	}
  2027  }
  2028  
  2029  func TestAddAddress(t *testing.T) {
  2030  	const nicID = 1
  2031  	s := stack.New(stack.Options{
  2032  		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
  2033  	})
  2034  	ep := channel.New(10, defaultMTU, "")
  2035  	if err := s.CreateNIC(nicID, ep); err != nil {
  2036  		t.Fatal("CreateNIC failed:", err)
  2037  	}
  2038  
  2039  	var addrGen addressGenerator
  2040  	expectedAddresses := make([]tcpip.ProtocolAddress, 0, 2)
  2041  	for _, addrLen := range []int{4, 16} {
  2042  		address := addrGen.next(addrLen)
  2043  		if err := s.AddAddress(nicID, fakeNetNumber, address); err != nil {
  2044  			t.Fatalf("AddAddress(address=%s) failed: %s", address, err)
  2045  		}
  2046  		expectedAddresses = append(expectedAddresses, tcpip.ProtocolAddress{
  2047  			Protocol:          fakeNetNumber,
  2048  			AddressWithPrefix: tcpip.AddressWithPrefix{Address: address, PrefixLen: fakeDefaultPrefixLen},
  2049  		})
  2050  	}
  2051  
  2052  	gotAddresses := s.AllAddresses()[nicID]
  2053  	verifyAddresses(t, expectedAddresses, gotAddresses)
  2054  }
  2055  
  2056  func TestAddProtocolAddress(t *testing.T) {
  2057  	const nicID = 1
  2058  	s := stack.New(stack.Options{
  2059  		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
  2060  	})
  2061  	ep := channel.New(10, defaultMTU, "")
  2062  	if err := s.CreateNIC(nicID, ep); err != nil {
  2063  		t.Fatal("CreateNIC failed:", err)
  2064  	}
  2065  
  2066  	var addrGen addressGenerator
  2067  	addrLenRange := []int{4, 16}
  2068  	prefixLenRange := []int{8, 13, 20, 32}
  2069  	expectedAddresses := make([]tcpip.ProtocolAddress, 0, len(addrLenRange)*len(prefixLenRange))
  2070  	for _, addrLen := range addrLenRange {
  2071  		for _, prefixLen := range prefixLenRange {
  2072  			protocolAddress := tcpip.ProtocolAddress{
  2073  				Protocol: fakeNetNumber,
  2074  				AddressWithPrefix: tcpip.AddressWithPrefix{
  2075  					Address:   addrGen.next(addrLen),
  2076  					PrefixLen: prefixLen,
  2077  				},
  2078  			}
  2079  			if err := s.AddProtocolAddress(nicID, protocolAddress); err != nil {
  2080  				t.Errorf("AddProtocolAddress(%+v) failed: %s", protocolAddress, err)
  2081  			}
  2082  			expectedAddresses = append(expectedAddresses, protocolAddress)
  2083  		}
  2084  	}
  2085  
  2086  	gotAddresses := s.AllAddresses()[nicID]
  2087  	verifyAddresses(t, expectedAddresses, gotAddresses)
  2088  }
  2089  
  2090  func TestAddAddressWithOptions(t *testing.T) {
  2091  	const nicID = 1
  2092  	s := stack.New(stack.Options{
  2093  		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
  2094  	})
  2095  	ep := channel.New(10, defaultMTU, "")
  2096  	if err := s.CreateNIC(nicID, ep); err != nil {
  2097  		t.Fatal("CreateNIC failed:", err)
  2098  	}
  2099  
  2100  	addrLenRange := []int{4, 16}
  2101  	behaviorRange := []stack.PrimaryEndpointBehavior{stack.CanBePrimaryEndpoint, stack.FirstPrimaryEndpoint, stack.NeverPrimaryEndpoint}
  2102  	expectedAddresses := make([]tcpip.ProtocolAddress, 0, len(addrLenRange)*len(behaviorRange))
  2103  	var addrGen addressGenerator
  2104  	for _, addrLen := range addrLenRange {
  2105  		for _, behavior := range behaviorRange {
  2106  			address := addrGen.next(addrLen)
  2107  			if err := s.AddAddressWithOptions(nicID, fakeNetNumber, address, behavior); err != nil {
  2108  				t.Fatalf("AddAddressWithOptions(address=%s, behavior=%d) failed: %s", address, behavior, err)
  2109  			}
  2110  			expectedAddresses = append(expectedAddresses, tcpip.ProtocolAddress{
  2111  				Protocol:          fakeNetNumber,
  2112  				AddressWithPrefix: tcpip.AddressWithPrefix{Address: address, PrefixLen: fakeDefaultPrefixLen},
  2113  			})
  2114  		}
  2115  	}
  2116  
  2117  	gotAddresses := s.AllAddresses()[nicID]
  2118  	verifyAddresses(t, expectedAddresses, gotAddresses)
  2119  }
  2120  
  2121  func TestAddProtocolAddressWithOptions(t *testing.T) {
  2122  	const nicID = 1
  2123  	s := stack.New(stack.Options{
  2124  		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
  2125  	})
  2126  	ep := channel.New(10, defaultMTU, "")
  2127  	if err := s.CreateNIC(nicID, ep); err != nil {
  2128  		t.Fatal("CreateNIC failed:", err)
  2129  	}
  2130  
  2131  	addrLenRange := []int{4, 16}
  2132  	prefixLenRange := []int{8, 13, 20, 32}
  2133  	behaviorRange := []stack.PrimaryEndpointBehavior{stack.CanBePrimaryEndpoint, stack.FirstPrimaryEndpoint, stack.NeverPrimaryEndpoint}
  2134  	expectedAddresses := make([]tcpip.ProtocolAddress, 0, len(addrLenRange)*len(prefixLenRange)*len(behaviorRange))
  2135  	var addrGen addressGenerator
  2136  	for _, addrLen := range addrLenRange {
  2137  		for _, prefixLen := range prefixLenRange {
  2138  			for _, behavior := range behaviorRange {
  2139  				protocolAddress := tcpip.ProtocolAddress{
  2140  					Protocol: fakeNetNumber,
  2141  					AddressWithPrefix: tcpip.AddressWithPrefix{
  2142  						Address:   addrGen.next(addrLen),
  2143  						PrefixLen: prefixLen,
  2144  					},
  2145  				}
  2146  				if err := s.AddProtocolAddressWithOptions(nicID, protocolAddress, behavior); err != nil {
  2147  					t.Fatalf("AddProtocolAddressWithOptions(%+v, %d) failed: %s", protocolAddress, behavior, err)
  2148  				}
  2149  				expectedAddresses = append(expectedAddresses, protocolAddress)
  2150  			}
  2151  		}
  2152  	}
  2153  
  2154  	gotAddresses := s.AllAddresses()[nicID]
  2155  	verifyAddresses(t, expectedAddresses, gotAddresses)
  2156  }
  2157  
  2158  func TestCreateNICWithOptions(t *testing.T) {
  2159  	type callArgsAndExpect struct {
  2160  		nicID tcpip.NICID
  2161  		opts  stack.NICOptions
  2162  		err   tcpip.Error
  2163  	}
  2164  
  2165  	tests := []struct {
  2166  		desc  string
  2167  		calls []callArgsAndExpect
  2168  	}{
  2169  		{
  2170  			desc: "DuplicateNICID",
  2171  			calls: []callArgsAndExpect{
  2172  				{
  2173  					nicID: tcpip.NICID(1),
  2174  					opts:  stack.NICOptions{Name: "eth1"},
  2175  					err:   nil,
  2176  				},
  2177  				{
  2178  					nicID: tcpip.NICID(1),
  2179  					opts:  stack.NICOptions{Name: "eth2"},
  2180  					err:   &tcpip.ErrDuplicateNICID{},
  2181  				},
  2182  			},
  2183  		},
  2184  		{
  2185  			desc: "DuplicateName",
  2186  			calls: []callArgsAndExpect{
  2187  				{
  2188  					nicID: tcpip.NICID(1),
  2189  					opts:  stack.NICOptions{Name: "lo"},
  2190  					err:   nil,
  2191  				},
  2192  				{
  2193  					nicID: tcpip.NICID(2),
  2194  					opts:  stack.NICOptions{Name: "lo"},
  2195  					err:   &tcpip.ErrDuplicateNICID{},
  2196  				},
  2197  			},
  2198  		},
  2199  		{
  2200  			desc: "Unnamed",
  2201  			calls: []callArgsAndExpect{
  2202  				{
  2203  					nicID: tcpip.NICID(1),
  2204  					opts:  stack.NICOptions{},
  2205  					err:   nil,
  2206  				},
  2207  				{
  2208  					nicID: tcpip.NICID(2),
  2209  					opts:  stack.NICOptions{},
  2210  					err:   nil,
  2211  				},
  2212  			},
  2213  		},
  2214  		{
  2215  			desc: "UnnamedDuplicateNICID",
  2216  			calls: []callArgsAndExpect{
  2217  				{
  2218  					nicID: tcpip.NICID(1),
  2219  					opts:  stack.NICOptions{},
  2220  					err:   nil,
  2221  				},
  2222  				{
  2223  					nicID: tcpip.NICID(1),
  2224  					opts:  stack.NICOptions{},
  2225  					err:   &tcpip.ErrDuplicateNICID{},
  2226  				},
  2227  			},
  2228  		},
  2229  	}
  2230  	for _, test := range tests {
  2231  		t.Run(test.desc, func(t *testing.T) {
  2232  			s := stack.New(stack.Options{})
  2233  			ep := channel.New(0, 0, "\x00\x00\x00\x00\x00\x00")
  2234  			for _, call := range test.calls {
  2235  				if got, want := s.CreateNICWithOptions(call.nicID, ep, call.opts), call.err; got != want {
  2236  					t.Fatalf("CreateNICWithOptions(%v, _, %+v) = %v, want %v", call.nicID, call.opts, got, want)
  2237  				}
  2238  			}
  2239  		})
  2240  	}
  2241  }
  2242  
  2243  func TestNICStats(t *testing.T) {
  2244  	s := stack.New(stack.Options{
  2245  		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
  2246  	})
  2247  
  2248  	nics := []struct {
  2249  		addr        tcpip.Address
  2250  		txByteCount int
  2251  		rxByteCount int
  2252  	}{
  2253  		{
  2254  			addr:        "\x01",
  2255  			txByteCount: 30,
  2256  			rxByteCount: 10,
  2257  		},
  2258  		{
  2259  			addr:        "\x02",
  2260  			txByteCount: 50,
  2261  			rxByteCount: 20,
  2262  		},
  2263  	}
  2264  
  2265  	var txBytesTotal, rxBytesTotal, txPacketsTotal, rxPacketsTotal int
  2266  	for i, nic := range nics {
  2267  		nicid := tcpip.NICID(i)
  2268  		ep := channel.New(1, defaultMTU, "")
  2269  		if err := s.CreateNIC(nicid, ep); err != nil {
  2270  			t.Fatal("CreateNIC failed: ", err)
  2271  		}
  2272  		if err := s.AddAddress(nicid, fakeNetNumber, nic.addr); err != nil {
  2273  			t.Fatal("AddAddress failed:", err)
  2274  		}
  2275  
  2276  		{
  2277  			subnet, err := tcpip.NewSubnet(nic.addr, "\xff")
  2278  			if err != nil {
  2279  				t.Fatal(err)
  2280  			}
  2281  			s.SetRouteTable([]tcpip.Route{{Destination: subnet, Gateway: "\x00", NIC: nicid}})
  2282  		}
  2283  
  2284  		nicStats := s.NICInfo()[nicid].Stats
  2285  
  2286  		// Inbound packet.
  2287  		rxBuffer := buffer.NewView(nic.rxByteCount)
  2288  		ep.InjectInbound(fakeNetNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
  2289  			Data: rxBuffer.ToVectorisedView(),
  2290  		}))
  2291  		if got, want := nicStats.Rx.Packets.Value(), uint64(1); got != want {
  2292  			t.Errorf("got Rx.Packets.Value() = %d, want = %d", got, want)
  2293  		}
  2294  		if got, want := nicStats.Rx.Bytes.Value(), uint64(nic.rxByteCount); got != want {
  2295  			t.Errorf("got Rx.Bytes.Value() = %d, want = %d", got, want)
  2296  		}
  2297  		rxPacketsTotal++
  2298  		rxBytesTotal += nic.rxByteCount
  2299  
  2300  		// Outbound packet.
  2301  		txBuffer := buffer.NewView(nic.txByteCount)
  2302  		actualTxLength := nic.txByteCount + fakeNetHeaderLen
  2303  		if err := sendTo(s, nic.addr, txBuffer); err != nil {
  2304  			t.Fatal("sendTo failed: ", err)
  2305  		}
  2306  		want := ep.Drain()
  2307  		if got := nicStats.Tx.Packets.Value(); got != uint64(want) {
  2308  			t.Errorf("got Tx.Packets.Value() = %d, ep.Drain() = %d", got, want)
  2309  		}
  2310  		if got, want := nicStats.Tx.Bytes.Value(), uint64(actualTxLength); got != want {
  2311  			t.Errorf("got Tx.Bytes.Value() = %d, want = %d", got, want)
  2312  		}
  2313  		txPacketsTotal += want
  2314  		txBytesTotal += actualTxLength
  2315  	}
  2316  
  2317  	// Now verify that each NIC stats was correctly aggregated at the stack level.
  2318  	if got, want := s.Stats().NICs.Rx.Packets.Value(), uint64(rxPacketsTotal); got != want {
  2319  		t.Errorf("got s.Stats().NIC.Rx.Packets.Value() = %d, want = %d", got, want)
  2320  	}
  2321  	if got, want := s.Stats().NICs.Rx.Bytes.Value(), uint64(rxBytesTotal); got != want {
  2322  		t.Errorf("got s.Stats().Rx.Bytes.Value() = %d, want = %d", got, want)
  2323  	}
  2324  	if got, want := s.Stats().NICs.Tx.Packets.Value(), uint64(txPacketsTotal); got != want {
  2325  		t.Errorf("got Tx.Packets.Value() = %d, ep.Drain() = %d", got, want)
  2326  	}
  2327  	if got, want := s.Stats().NICs.Tx.Bytes.Value(), uint64(txBytesTotal); got != want {
  2328  		t.Errorf("got Tx.Bytes.Value() = %d, want = %d", got, want)
  2329  	}
  2330  }
  2331  
  2332  // TestNICContextPreservation tests that you can read out via stack.NICInfo the
  2333  // Context data you pass via NICContext.Context in stack.CreateNICWithOptions.
  2334  func TestNICContextPreservation(t *testing.T) {
  2335  	var ctx *int
  2336  	tests := []struct {
  2337  		name string
  2338  		opts stack.NICOptions
  2339  		want stack.NICContext
  2340  	}{
  2341  		{
  2342  			"context_set",
  2343  			stack.NICOptions{Context: ctx},
  2344  			ctx,
  2345  		},
  2346  		{
  2347  			"context_not_set",
  2348  			stack.NICOptions{},
  2349  			nil,
  2350  		},
  2351  	}
  2352  	for _, test := range tests {
  2353  		t.Run(test.name, func(t *testing.T) {
  2354  			s := stack.New(stack.Options{})
  2355  			id := tcpip.NICID(1)
  2356  			ep := channel.New(0, 0, "\x00\x00\x00\x00\x00\x00")
  2357  			if err := s.CreateNICWithOptions(id, ep, test.opts); err != nil {
  2358  				t.Fatalf("got stack.CreateNICWithOptions(%d, %+v, %+v) = %s, want nil", id, ep, test.opts, err)
  2359  			}
  2360  			nicinfos := s.NICInfo()
  2361  			nicinfo, ok := nicinfos[id]
  2362  			if !ok {
  2363  				t.Fatalf("got nicinfos[%d] = _, %t, want _, true; nicinfos = %+v", id, ok, nicinfos)
  2364  			}
  2365  			if got, want := nicinfo.Context == test.want, true; got != want {
  2366  				t.Fatalf("got nicinfo.Context == ctx = %t, want %t; nicinfo.Context = %p, ctx = %p", got, want, nicinfo.Context, test.want)
  2367  			}
  2368  		})
  2369  	}
  2370  }
  2371  
  2372  // TestNICAutoGenLinkLocalAddr tests the auto-generation of IPv6 link-local
  2373  // addresses.
  2374  func TestNICAutoGenLinkLocalAddr(t *testing.T) {
  2375  	const nicID = 1
  2376  
  2377  	var secretKey [header.OpaqueIIDSecretKeyMinBytes]byte
  2378  	n, err := rand.Read(secretKey[:])
  2379  	if err != nil {
  2380  		t.Fatalf("rand.Read(_): %s", err)
  2381  	}
  2382  	if n != header.OpaqueIIDSecretKeyMinBytes {
  2383  		t.Fatalf("expected rand.Read to read %d bytes, read %d bytes", header.OpaqueIIDSecretKeyMinBytes, n)
  2384  	}
  2385  
  2386  	nicNameFunc := func(_ tcpip.NICID, name string) string {
  2387  		return name
  2388  	}
  2389  
  2390  	tests := []struct {
  2391  		name         string
  2392  		nicName      string
  2393  		autoGen      bool
  2394  		linkAddr     tcpip.LinkAddress
  2395  		iidOpts      ipv6.OpaqueInterfaceIdentifierOptions
  2396  		shouldGen    bool
  2397  		expectedAddr tcpip.Address
  2398  	}{
  2399  		{
  2400  			name:      "Disabled",
  2401  			nicName:   "nic1",
  2402  			autoGen:   false,
  2403  			linkAddr:  linkAddr1,
  2404  			shouldGen: false,
  2405  		},
  2406  		{
  2407  			name:     "Disabled without OIID options",
  2408  			nicName:  "nic1",
  2409  			autoGen:  false,
  2410  			linkAddr: linkAddr1,
  2411  			iidOpts: ipv6.OpaqueInterfaceIdentifierOptions{
  2412  				NICNameFromID: nicNameFunc,
  2413  				SecretKey:     secretKey[:],
  2414  			},
  2415  			shouldGen: false,
  2416  		},
  2417  
  2418  		// Tests for EUI64 based addresses.
  2419  		{
  2420  			name:         "EUI64 Enabled",
  2421  			autoGen:      true,
  2422  			linkAddr:     linkAddr1,
  2423  			shouldGen:    true,
  2424  			expectedAddr: header.LinkLocalAddr(linkAddr1),
  2425  		},
  2426  		{
  2427  			name:      "EUI64 Empty MAC",
  2428  			autoGen:   true,
  2429  			shouldGen: false,
  2430  		},
  2431  		{
  2432  			name:      "EUI64 Invalid MAC",
  2433  			autoGen:   true,
  2434  			linkAddr:  "\x01\x02\x03",
  2435  			shouldGen: false,
  2436  		},
  2437  		{
  2438  			name:      "EUI64 Multicast MAC",
  2439  			autoGen:   true,
  2440  			linkAddr:  "\x01\x02\x03\x04\x05\x06",
  2441  			shouldGen: false,
  2442  		},
  2443  		{
  2444  			name:      "EUI64 Unspecified MAC",
  2445  			autoGen:   true,
  2446  			linkAddr:  "\x00\x00\x00\x00\x00\x00",
  2447  			shouldGen: false,
  2448  		},
  2449  
  2450  		// Tests for Opaque IID based addresses.
  2451  		{
  2452  			name:     "OIID Enabled",
  2453  			nicName:  "nic1",
  2454  			autoGen:  true,
  2455  			linkAddr: linkAddr1,
  2456  			iidOpts: ipv6.OpaqueInterfaceIdentifierOptions{
  2457  				NICNameFromID: nicNameFunc,
  2458  				SecretKey:     secretKey[:],
  2459  			},
  2460  			shouldGen:    true,
  2461  			expectedAddr: header.LinkLocalAddrWithOpaqueIID("nic1", 0, secretKey[:]),
  2462  		},
  2463  		// These are all cases where we would not have generated a
  2464  		// link-local address if opaque IIDs were disabled.
  2465  		{
  2466  			name:    "OIID Empty MAC and empty nicName",
  2467  			autoGen: true,
  2468  			iidOpts: ipv6.OpaqueInterfaceIdentifierOptions{
  2469  				NICNameFromID: nicNameFunc,
  2470  				SecretKey:     secretKey[:1],
  2471  			},
  2472  			shouldGen:    true,
  2473  			expectedAddr: header.LinkLocalAddrWithOpaqueIID("", 0, secretKey[:1]),
  2474  		},
  2475  		{
  2476  			name:     "OIID Invalid MAC",
  2477  			nicName:  "test",
  2478  			autoGen:  true,
  2479  			linkAddr: "\x01\x02\x03",
  2480  			iidOpts: ipv6.OpaqueInterfaceIdentifierOptions{
  2481  				NICNameFromID: nicNameFunc,
  2482  				SecretKey:     secretKey[:2],
  2483  			},
  2484  			shouldGen:    true,
  2485  			expectedAddr: header.LinkLocalAddrWithOpaqueIID("test", 0, secretKey[:2]),
  2486  		},
  2487  		{
  2488  			name:     "OIID Multicast MAC",
  2489  			nicName:  "test2",
  2490  			autoGen:  true,
  2491  			linkAddr: "\x01\x02\x03\x04\x05\x06",
  2492  			iidOpts: ipv6.OpaqueInterfaceIdentifierOptions{
  2493  				NICNameFromID: nicNameFunc,
  2494  				SecretKey:     secretKey[:3],
  2495  			},
  2496  			shouldGen:    true,
  2497  			expectedAddr: header.LinkLocalAddrWithOpaqueIID("test2", 0, secretKey[:3]),
  2498  		},
  2499  		{
  2500  			name:     "OIID Unspecified MAC and nil SecretKey",
  2501  			nicName:  "test3",
  2502  			autoGen:  true,
  2503  			linkAddr: "\x00\x00\x00\x00\x00\x00",
  2504  			iidOpts: ipv6.OpaqueInterfaceIdentifierOptions{
  2505  				NICNameFromID: nicNameFunc,
  2506  			},
  2507  			shouldGen:    true,
  2508  			expectedAddr: header.LinkLocalAddrWithOpaqueIID("test3", 0, nil),
  2509  		},
  2510  	}
  2511  
  2512  	for _, test := range tests {
  2513  		t.Run(test.name, func(t *testing.T) {
  2514  			ndpDisp := ndpDispatcher{
  2515  				autoGenAddrC: make(chan ndpAutoGenAddrEvent, 1),
  2516  			}
  2517  			opts := stack.Options{
  2518  				NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
  2519  					AutoGenLinkLocal: test.autoGen,
  2520  					NDPDisp:          &ndpDisp,
  2521  					OpaqueIIDOpts:    test.iidOpts,
  2522  				})},
  2523  			}
  2524  
  2525  			e := channel.New(0, 1280, test.linkAddr)
  2526  			s := stack.New(opts)
  2527  			nicOpts := stack.NICOptions{Name: test.nicName, Disabled: true}
  2528  			if err := s.CreateNICWithOptions(nicID, e, nicOpts); err != nil {
  2529  				t.Fatalf("CreateNICWithOptions(%d, _, %+v) = %s", nicID, opts, err)
  2530  			}
  2531  
  2532  			// A new disabled NIC should not have any address, even if auto generation
  2533  			// was enabled.
  2534  			allStackAddrs := s.AllAddresses()
  2535  			allNICAddrs, ok := allStackAddrs[nicID]
  2536  			if !ok {
  2537  				t.Fatalf("entry for %d missing from allStackAddrs = %+v", nicID, allStackAddrs)
  2538  			}
  2539  			if l := len(allNICAddrs); l != 0 {
  2540  				t.Fatalf("got len(allNICAddrs) = %d, want = 0", l)
  2541  			}
  2542  
  2543  			// Enabling the NIC should attempt auto-generation of a link-local
  2544  			// address.
  2545  			if err := s.EnableNIC(nicID); err != nil {
  2546  				t.Fatalf("s.EnableNIC(%d): %s", nicID, err)
  2547  			}
  2548  
  2549  			var expectedMainAddr tcpip.AddressWithPrefix
  2550  			if test.shouldGen {
  2551  				expectedMainAddr = tcpip.AddressWithPrefix{
  2552  					Address:   test.expectedAddr,
  2553  					PrefixLen: header.IPv6LinkLocalPrefix.PrefixLen,
  2554  				}
  2555  
  2556  				// Should have auto-generated an address and resolved immediately (DAD
  2557  				// is disabled).
  2558  				select {
  2559  				case e := <-ndpDisp.autoGenAddrC:
  2560  					if diff := checkAutoGenAddrEvent(e, expectedMainAddr, newAddr); diff != "" {
  2561  						t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
  2562  					}
  2563  				default:
  2564  					t.Fatal("expected addr auto gen event")
  2565  				}
  2566  			} else {
  2567  				// Should not have auto-generated an address.
  2568  				select {
  2569  				case <-ndpDisp.autoGenAddrC:
  2570  					t.Fatal("unexpectedly auto-generated an address")
  2571  				default:
  2572  				}
  2573  			}
  2574  
  2575  			if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, expectedMainAddr); err != nil {
  2576  				t.Fatal(err)
  2577  			}
  2578  
  2579  			// Disabling the NIC should remove the auto-generated address.
  2580  			if err := s.DisableNIC(nicID); err != nil {
  2581  				t.Fatalf("s.DisableNIC(%d): %s", nicID, err)
  2582  			}
  2583  			if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil {
  2584  				t.Fatal(err)
  2585  			}
  2586  		})
  2587  	}
  2588  }
  2589  
  2590  // TestNoLinkLocalAutoGenForLoopbackNIC tests that IPv6 link-local addresses are
  2591  // not auto-generated for loopback NICs.
  2592  func TestNoLinkLocalAutoGenForLoopbackNIC(t *testing.T) {
  2593  	const nicID = 1
  2594  	const nicName = "nicName"
  2595  
  2596  	tests := []struct {
  2597  		name          string
  2598  		opaqueIIDOpts ipv6.OpaqueInterfaceIdentifierOptions
  2599  	}{
  2600  		{
  2601  			name:          "IID From MAC",
  2602  			opaqueIIDOpts: ipv6.OpaqueInterfaceIdentifierOptions{},
  2603  		},
  2604  		{
  2605  			name: "Opaque IID",
  2606  			opaqueIIDOpts: ipv6.OpaqueInterfaceIdentifierOptions{
  2607  				NICNameFromID: func(_ tcpip.NICID, nicName string) string {
  2608  					return nicName
  2609  				},
  2610  			},
  2611  		},
  2612  	}
  2613  
  2614  	for _, test := range tests {
  2615  		t.Run(test.name, func(t *testing.T) {
  2616  			opts := stack.Options{
  2617  				NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
  2618  					AutoGenLinkLocal: true,
  2619  					OpaqueIIDOpts:    test.opaqueIIDOpts,
  2620  				})},
  2621  			}
  2622  
  2623  			e := loopback.New()
  2624  			s := stack.New(opts)
  2625  			nicOpts := stack.NICOptions{Name: nicName}
  2626  			if err := s.CreateNICWithOptions(nicID, e, nicOpts); err != nil {
  2627  				t.Fatalf("CreateNICWithOptions(%d, _, %+v) = %s", nicID, nicOpts, err)
  2628  			}
  2629  
  2630  			if err := checkGetMainNICAddress(s, 1, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil {
  2631  				t.Fatal(err)
  2632  			}
  2633  		})
  2634  	}
  2635  }
  2636  
  2637  // TestNICAutoGenAddrDoesDAD tests that the successful auto-generation of IPv6
  2638  // link-local addresses will only be assigned after the DAD process resolves.
  2639  func TestNICAutoGenAddrDoesDAD(t *testing.T) {
  2640  	const nicID = 1
  2641  
  2642  	ndpDisp := ndpDispatcher{
  2643  		dadC: make(chan ndpDADEvent, 1),
  2644  	}
  2645  	dadConfigs := stack.DefaultDADConfigurations()
  2646  	clock := faketime.NewManualClock()
  2647  	opts := stack.Options{
  2648  		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
  2649  			AutoGenLinkLocal: true,
  2650  			NDPDisp:          &ndpDisp,
  2651  			DADConfigs:       dadConfigs,
  2652  		})},
  2653  		Clock: clock,
  2654  	}
  2655  
  2656  	e := channel.New(int(dadConfigs.DupAddrDetectTransmits), 1280, linkAddr1)
  2657  	s := stack.New(opts)
  2658  	if err := s.CreateNIC(nicID, e); err != nil {
  2659  		t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
  2660  	}
  2661  
  2662  	// Address should not be considered bound to the
  2663  	// NIC yet (DAD ongoing).
  2664  	if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil {
  2665  		t.Fatal(err)
  2666  	}
  2667  
  2668  	linkLocalAddr := header.LinkLocalAddr(linkAddr1)
  2669  
  2670  	// Wait for DAD to resolve.
  2671  	clock.Advance(time.Duration(dadConfigs.DupAddrDetectTransmits) * dadConfigs.RetransmitTimer)
  2672  	select {
  2673  	case e := <-ndpDisp.dadC:
  2674  		if diff := checkDADEvent(e, nicID, linkLocalAddr, &stack.DADSucceeded{}); diff != "" {
  2675  			t.Errorf("dad event mismatch (-want +got):\n%s", diff)
  2676  		}
  2677  	default:
  2678  		// We should get a resolution event after 1s (default time to
  2679  		// resolve as per default NDP configurations). Waiting for that
  2680  		// resolution time + an extra 1s without a resolution event
  2681  		// means something is wrong.
  2682  		t.Fatal("timed out waiting for DAD resolution")
  2683  	}
  2684  	if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{Address: linkLocalAddr, PrefixLen: header.IPv6LinkLocalPrefix.PrefixLen}); err != nil {
  2685  		t.Fatal(err)
  2686  	}
  2687  }
  2688  
  2689  // TestNewPEB tests that a new PrimaryEndpointBehavior value (peb) is respected
  2690  // when an address's kind gets "promoted" to permanent from permanentExpired.
  2691  func TestNewPEBOnPromotionToPermanent(t *testing.T) {
  2692  	const nicID = 1
  2693  
  2694  	pebs := []stack.PrimaryEndpointBehavior{
  2695  		stack.NeverPrimaryEndpoint,
  2696  		stack.CanBePrimaryEndpoint,
  2697  		stack.FirstPrimaryEndpoint,
  2698  	}
  2699  
  2700  	for _, pi := range pebs {
  2701  		for _, ps := range pebs {
  2702  			t.Run(fmt.Sprintf("%d-to-%d", pi, ps), func(t *testing.T) {
  2703  				s := stack.New(stack.Options{
  2704  					NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
  2705  				})
  2706  				ep1 := channel.New(10, defaultMTU, "")
  2707  				if err := s.CreateNIC(nicID, ep1); err != nil {
  2708  					t.Fatalf("CreateNIC(%d, _): %s", nicID, err)
  2709  				}
  2710  
  2711  				// Add a permanent address with initial
  2712  				// PrimaryEndpointBehavior (peb), pi. If pi is
  2713  				// NeverPrimaryEndpoint, the address should not
  2714  				// be returned by a call to GetMainNICAddress;
  2715  				// else, it should.
  2716  				const address1 = tcpip.Address("\x01")
  2717  				if err := s.AddAddressWithOptions(nicID, fakeNetNumber, address1, pi); err != nil {
  2718  					t.Fatalf("AddAddressWithOptions(%d, %d, %s, %d): %s", nicID, fakeNetNumber, address1, pi, err)
  2719  				}
  2720  				addr, err := s.GetMainNICAddress(nicID, fakeNetNumber)
  2721  				if err != nil {
  2722  					t.Fatalf("GetMainNICAddress(%d, %d): %s", nicID, fakeNetNumber, err)
  2723  				}
  2724  				if pi == stack.NeverPrimaryEndpoint {
  2725  					if want := (tcpip.AddressWithPrefix{}); addr != want {
  2726  						t.Fatalf("got GetMainNICAddress(%d, %d) = %s, want = %s", nicID, fakeNetNumber, addr, want)
  2727  
  2728  					}
  2729  				} else if addr.Address != address1 {
  2730  					t.Fatalf("got GetMainNICAddress(%d, %d) = %s, want = %s", nicID, fakeNetNumber, addr.Address, address1)
  2731  				}
  2732  
  2733  				{
  2734  					subnet, err := tcpip.NewSubnet("\x00", "\x00")
  2735  					if err != nil {
  2736  						t.Fatalf("NewSubnet failed: %v", err)
  2737  					}
  2738  					s.SetRouteTable([]tcpip.Route{{Destination: subnet, Gateway: "\x00", NIC: 1}})
  2739  				}
  2740  
  2741  				// Take a route through the address so its ref
  2742  				// count gets incremented and does not actually
  2743  				// get deleted when RemoveAddress is called
  2744  				// below. This is because we want to test that a
  2745  				// new peb is respected when an address gets
  2746  				// "promoted" to permanent from a
  2747  				// permanentExpired kind.
  2748  				const address2 = tcpip.Address("\x02")
  2749  				r, err := s.FindRoute(nicID, address1, address2, fakeNetNumber, false)
  2750  				if err != nil {
  2751  					t.Fatalf("FindRoute(%d, %s, %s, %d, false): %s", nicID, address1, address2, fakeNetNumber, err)
  2752  				}
  2753  				defer r.Release()
  2754  				if err := s.RemoveAddress(nicID, address1); err != nil {
  2755  					t.Fatalf("RemoveAddress(%d, %s): %s", nicID, address1, err)
  2756  				}
  2757  
  2758  				//
  2759  				// At this point, the address should still be
  2760  				// known by the NIC, but have its
  2761  				// kind = permanentExpired.
  2762  				//
  2763  
  2764  				// Add some other address with peb set to
  2765  				// FirstPrimaryEndpoint.
  2766  				const address3 = tcpip.Address("\x03")
  2767  				if err := s.AddAddressWithOptions(nicID, fakeNetNumber, address3, stack.FirstPrimaryEndpoint); err != nil {
  2768  					t.Fatalf("AddAddressWithOptions(%d, %d, %s, %d): %s", nicID, fakeNetNumber, address3, stack.FirstPrimaryEndpoint, err)
  2769  
  2770  				}
  2771  
  2772  				// Add back the address we removed earlier and
  2773  				// make sure the new peb was respected.
  2774  				// (The address should just be promoted now).
  2775  				if err := s.AddAddressWithOptions(nicID, fakeNetNumber, address1, ps); err != nil {
  2776  					t.Fatalf("AddAddressWithOptions(%d, %d, %s, %d): %s", nicID, fakeNetNumber, address1, pi, err)
  2777  				}
  2778  				var primaryAddrs []tcpip.Address
  2779  				for _, pa := range s.NICInfo()[nicID].ProtocolAddresses {
  2780  					primaryAddrs = append(primaryAddrs, pa.AddressWithPrefix.Address)
  2781  				}
  2782  				var expectedList []tcpip.Address
  2783  				switch ps {
  2784  				case stack.FirstPrimaryEndpoint:
  2785  					expectedList = []tcpip.Address{
  2786  						"\x01",
  2787  						"\x03",
  2788  					}
  2789  				case stack.CanBePrimaryEndpoint:
  2790  					expectedList = []tcpip.Address{
  2791  						"\x03",
  2792  						"\x01",
  2793  					}
  2794  				case stack.NeverPrimaryEndpoint:
  2795  					expectedList = []tcpip.Address{
  2796  						"\x03",
  2797  					}
  2798  				}
  2799  				if !cmp.Equal(primaryAddrs, expectedList) {
  2800  					t.Fatalf("got NIC's primary addresses = %v, want = %v", primaryAddrs, expectedList)
  2801  				}
  2802  
  2803  				// Once we remove the other address, if the new
  2804  				// peb, ps, was NeverPrimaryEndpoint, no address
  2805  				// should be returned by a call to
  2806  				// GetMainNICAddress; else, our original address
  2807  				// should be returned.
  2808  				if err := s.RemoveAddress(nicID, address3); err != nil {
  2809  					t.Fatalf("RemoveAddress(%d, %s): %s", nicID, address3, err)
  2810  				}
  2811  				addr, err = s.GetMainNICAddress(nicID, fakeNetNumber)
  2812  				if err != nil {
  2813  					t.Fatalf("GetMainNICAddress(%d, %d): %s", nicID, fakeNetNumber, err)
  2814  				}
  2815  				if ps == stack.NeverPrimaryEndpoint {
  2816  					if want := (tcpip.AddressWithPrefix{}); addr != want {
  2817  						t.Fatalf("got GetMainNICAddress(%d, %d) = %s, want = %s", nicID, fakeNetNumber, addr, want)
  2818  					}
  2819  				} else {
  2820  					if addr.Address != address1 {
  2821  						t.Fatalf("got GetMainNICAddress(%d, %d) = %s, want = %s", nicID, fakeNetNumber, addr.Address, address1)
  2822  					}
  2823  				}
  2824  			})
  2825  		}
  2826  	}
  2827  }
  2828  
  2829  func TestIPv6SourceAddressSelectionScopeAndSameAddress(t *testing.T) {
  2830  	const (
  2831  		nicID           = 1
  2832  		lifetimeSeconds = 9999
  2833  	)
  2834  
  2835  	var (
  2836  		linkLocalAddr1         = testutil.MustParse6("fe80::1")
  2837  		linkLocalAddr2         = testutil.MustParse6("fe80::2")
  2838  		linkLocalMulticastAddr = testutil.MustParse6("ff02::1")
  2839  		uniqueLocalAddr1       = testutil.MustParse6("fc00::1")
  2840  		uniqueLocalAddr2       = testutil.MustParse6("fd00::2")
  2841  		globalAddr1            = testutil.MustParse6("a000::1")
  2842  		globalAddr2            = testutil.MustParse6("a000::2")
  2843  		globalAddr3            = testutil.MustParse6("a000::3")
  2844  		ipv4MappedIPv6Addr1    = testutil.MustParse6("::ffff:0.0.0.1")
  2845  		ipv4MappedIPv6Addr2    = testutil.MustParse6("::ffff:0.0.0.2")
  2846  		toredoAddr1            = testutil.MustParse6("2001::1")
  2847  		toredoAddr2            = testutil.MustParse6("2001::2")
  2848  		ipv6ToIPv4Addr1        = testutil.MustParse6("2002::1")
  2849  		ipv6ToIPv4Addr2        = testutil.MustParse6("2002::2")
  2850  	)
  2851  
  2852  	prefix1, _, stableGlobalAddr1 := prefixSubnetAddr(0, linkAddr1)
  2853  	prefix2, _, stableGlobalAddr2 := prefixSubnetAddr(1, linkAddr1)
  2854  
  2855  	var tempIIDHistory [header.IIDSize]byte
  2856  	header.InitialTempIID(tempIIDHistory[:], nil, nicID)
  2857  	tempGlobalAddr1 := header.GenerateTempIPv6SLAACAddr(tempIIDHistory[:], stableGlobalAddr1.Address).Address
  2858  	tempGlobalAddr2 := header.GenerateTempIPv6SLAACAddr(tempIIDHistory[:], stableGlobalAddr2.Address).Address
  2859  
  2860  	// Rule 3 is not tested here, and is instead tested by NDP's AutoGenAddr test.
  2861  	tests := []struct {
  2862  		name                                   string
  2863  		slaacPrefixForTempAddrBeforeNICAddrAdd tcpip.AddressWithPrefix
  2864  		nicAddrs                               []tcpip.Address
  2865  		slaacPrefixForTempAddrAfterNICAddrAdd  tcpip.AddressWithPrefix
  2866  		remoteAddr                             tcpip.Address
  2867  		expectedLocalAddr                      tcpip.Address
  2868  	}{
  2869  		// Test Rule 1 of RFC 6724 section 5 (prefer same address).
  2870  		{
  2871  			name:              "Same Global most preferred (last address)",
  2872  			nicAddrs:          []tcpip.Address{linkLocalAddr1, globalAddr1},
  2873  			remoteAddr:        globalAddr1,
  2874  			expectedLocalAddr: globalAddr1,
  2875  		},
  2876  		{
  2877  			name:              "Same Global most preferred (first address)",
  2878  			nicAddrs:          []tcpip.Address{globalAddr1, uniqueLocalAddr1},
  2879  			remoteAddr:        globalAddr1,
  2880  			expectedLocalAddr: globalAddr1,
  2881  		},
  2882  		{
  2883  			name:              "Same Link Local most preferred (last address)",
  2884  			nicAddrs:          []tcpip.Address{globalAddr1, linkLocalAddr1},
  2885  			remoteAddr:        linkLocalAddr1,
  2886  			expectedLocalAddr: linkLocalAddr1,
  2887  		},
  2888  		{
  2889  			name:              "Same Link Local most preferred (first address)",
  2890  			nicAddrs:          []tcpip.Address{linkLocalAddr1, globalAddr1},
  2891  			remoteAddr:        linkLocalAddr1,
  2892  			expectedLocalAddr: linkLocalAddr1,
  2893  		},
  2894  		{
  2895  			name:              "Same Unique Local most preferred (last address)",
  2896  			nicAddrs:          []tcpip.Address{uniqueLocalAddr1, globalAddr1},
  2897  			remoteAddr:        uniqueLocalAddr1,
  2898  			expectedLocalAddr: uniqueLocalAddr1,
  2899  		},
  2900  		{
  2901  			name:              "Same Unique Local most preferred (first address)",
  2902  			nicAddrs:          []tcpip.Address{globalAddr1, uniqueLocalAddr1},
  2903  			remoteAddr:        uniqueLocalAddr1,
  2904  			expectedLocalAddr: uniqueLocalAddr1,
  2905  		},
  2906  
  2907  		// Test Rule 2 of RFC 6724 section 5 (prefer appropriate scope).
  2908  		{
  2909  			name:              "Global most preferred (last address)",
  2910  			nicAddrs:          []tcpip.Address{linkLocalAddr1, globalAddr1},
  2911  			remoteAddr:        globalAddr2,
  2912  			expectedLocalAddr: globalAddr1,
  2913  		},
  2914  		{
  2915  			name:              "Global most preferred (first address)",
  2916  			nicAddrs:          []tcpip.Address{globalAddr1, linkLocalAddr1},
  2917  			remoteAddr:        globalAddr2,
  2918  			expectedLocalAddr: globalAddr1,
  2919  		},
  2920  		{
  2921  			name:              "Link Local most preferred (last address)",
  2922  			nicAddrs:          []tcpip.Address{globalAddr1, linkLocalAddr1},
  2923  			remoteAddr:        linkLocalAddr2,
  2924  			expectedLocalAddr: linkLocalAddr1,
  2925  		},
  2926  		{
  2927  			name:              "Link Local most preferred (first address)",
  2928  			nicAddrs:          []tcpip.Address{linkLocalAddr1, globalAddr1},
  2929  			remoteAddr:        linkLocalAddr2,
  2930  			expectedLocalAddr: linkLocalAddr1,
  2931  		},
  2932  		{
  2933  			name:              "Link Local most preferred for link local multicast (last address)",
  2934  			nicAddrs:          []tcpip.Address{globalAddr1, linkLocalAddr1},
  2935  			remoteAddr:        linkLocalMulticastAddr,
  2936  			expectedLocalAddr: linkLocalAddr1,
  2937  		},
  2938  		{
  2939  			name:              "Link Local most preferred for link local multicast (first address)",
  2940  			nicAddrs:          []tcpip.Address{linkLocalAddr1, globalAddr1},
  2941  			remoteAddr:        linkLocalMulticastAddr,
  2942  			expectedLocalAddr: linkLocalAddr1,
  2943  		},
  2944  
  2945  		// Test Rule 6 of 6724 section 5 (prefer matching label).
  2946  		{
  2947  			name:              "Unique Local most preferred (last address)",
  2948  			nicAddrs:          []tcpip.Address{uniqueLocalAddr1, globalAddr1, ipv4MappedIPv6Addr1, toredoAddr1, ipv6ToIPv4Addr1},
  2949  			remoteAddr:        uniqueLocalAddr2,
  2950  			expectedLocalAddr: uniqueLocalAddr1,
  2951  		},
  2952  		{
  2953  			name:              "Unique Local most preferred (first address)",
  2954  			nicAddrs:          []tcpip.Address{globalAddr1, ipv4MappedIPv6Addr1, toredoAddr1, ipv6ToIPv4Addr1, uniqueLocalAddr1},
  2955  			remoteAddr:        uniqueLocalAddr2,
  2956  			expectedLocalAddr: uniqueLocalAddr1,
  2957  		},
  2958  		{
  2959  			name:              "Toredo most preferred (first address)",
  2960  			nicAddrs:          []tcpip.Address{toredoAddr1, uniqueLocalAddr1, globalAddr1, ipv4MappedIPv6Addr1, ipv6ToIPv4Addr1},
  2961  			remoteAddr:        toredoAddr2,
  2962  			expectedLocalAddr: toredoAddr1,
  2963  		},
  2964  		{
  2965  			name:              "Toredo most preferred (last address)",
  2966  			nicAddrs:          []tcpip.Address{globalAddr1, ipv4MappedIPv6Addr1, ipv6ToIPv4Addr1, uniqueLocalAddr1, toredoAddr1},
  2967  			remoteAddr:        toredoAddr2,
  2968  			expectedLocalAddr: toredoAddr1,
  2969  		},
  2970  		{
  2971  			name:              "6To4 most preferred (first address)",
  2972  			nicAddrs:          []tcpip.Address{ipv6ToIPv4Addr1, toredoAddr1, uniqueLocalAddr1, globalAddr1, ipv4MappedIPv6Addr1},
  2973  			remoteAddr:        ipv6ToIPv4Addr2,
  2974  			expectedLocalAddr: ipv6ToIPv4Addr1,
  2975  		},
  2976  		{
  2977  			name:              "6To4 most preferred (last address)",
  2978  			nicAddrs:          []tcpip.Address{globalAddr1, ipv4MappedIPv6Addr1, uniqueLocalAddr1, toredoAddr1, ipv6ToIPv4Addr1},
  2979  			remoteAddr:        ipv6ToIPv4Addr2,
  2980  			expectedLocalAddr: ipv6ToIPv4Addr1,
  2981  		},
  2982  		{
  2983  			name:              "IPv4 mapped IPv6 most preferred (first address)",
  2984  			nicAddrs:          []tcpip.Address{ipv4MappedIPv6Addr1, ipv6ToIPv4Addr1, toredoAddr1, uniqueLocalAddr1, globalAddr1},
  2985  			remoteAddr:        ipv4MappedIPv6Addr2,
  2986  			expectedLocalAddr: ipv4MappedIPv6Addr1,
  2987  		},
  2988  		{
  2989  			name:              "IPv4 mapped IPv6 most preferred (last address)",
  2990  			nicAddrs:          []tcpip.Address{globalAddr1, ipv6ToIPv4Addr1, uniqueLocalAddr1, toredoAddr1, ipv4MappedIPv6Addr1},
  2991  			remoteAddr:        ipv4MappedIPv6Addr2,
  2992  			expectedLocalAddr: ipv4MappedIPv6Addr1,
  2993  		},
  2994  
  2995  		// Test Rule 7 of RFC 6724 section 5 (prefer temporary addresses).
  2996  		{
  2997  			name:                                   "Temp Global most preferred (last address)",
  2998  			slaacPrefixForTempAddrBeforeNICAddrAdd: prefix1,
  2999  			nicAddrs:                               []tcpip.Address{linkLocalAddr1, uniqueLocalAddr1, globalAddr1},
  3000  			remoteAddr:                             globalAddr2,
  3001  			expectedLocalAddr:                      tempGlobalAddr1,
  3002  		},
  3003  		{
  3004  			name:                                  "Temp Global most preferred (first address)",
  3005  			nicAddrs:                              []tcpip.Address{linkLocalAddr1, uniqueLocalAddr1, globalAddr1},
  3006  			slaacPrefixForTempAddrAfterNICAddrAdd: prefix1,
  3007  			remoteAddr:                            globalAddr2,
  3008  			expectedLocalAddr:                     tempGlobalAddr1,
  3009  		},
  3010  
  3011  		// Test Rule 8 of RFC 6724 section 5 (use longest matching prefix).
  3012  		{
  3013  			name:              "Longest prefix matched most preferred (first address)",
  3014  			nicAddrs:          []tcpip.Address{globalAddr2, globalAddr1},
  3015  			remoteAddr:        globalAddr3,
  3016  			expectedLocalAddr: globalAddr2,
  3017  		},
  3018  		{
  3019  			name:              "Longest prefix matched most preferred (last address)",
  3020  			nicAddrs:          []tcpip.Address{globalAddr1, globalAddr2},
  3021  			remoteAddr:        globalAddr3,
  3022  			expectedLocalAddr: globalAddr2,
  3023  		},
  3024  
  3025  		// Test returning the endpoint that is closest to the front when
  3026  		// candidate addresses are "equal" from the perspective of RFC 6724
  3027  		// section 5.
  3028  		{
  3029  			name:              "Unique Local for Global",
  3030  			nicAddrs:          []tcpip.Address{linkLocalAddr1, uniqueLocalAddr1, uniqueLocalAddr2},
  3031  			remoteAddr:        globalAddr2,
  3032  			expectedLocalAddr: uniqueLocalAddr1,
  3033  		},
  3034  		{
  3035  			name:              "Link Local for Global",
  3036  			nicAddrs:          []tcpip.Address{linkLocalAddr1, linkLocalAddr2},
  3037  			remoteAddr:        globalAddr2,
  3038  			expectedLocalAddr: linkLocalAddr1,
  3039  		},
  3040  		{
  3041  			name:              "Link Local for Unique Local",
  3042  			nicAddrs:          []tcpip.Address{linkLocalAddr1, linkLocalAddr2},
  3043  			remoteAddr:        uniqueLocalAddr2,
  3044  			expectedLocalAddr: linkLocalAddr1,
  3045  		},
  3046  		{
  3047  			name:                                   "Temp Global for Global",
  3048  			slaacPrefixForTempAddrBeforeNICAddrAdd: prefix1,
  3049  			slaacPrefixForTempAddrAfterNICAddrAdd:  prefix2,
  3050  			remoteAddr:                             globalAddr1,
  3051  			expectedLocalAddr:                      tempGlobalAddr2,
  3052  		},
  3053  	}
  3054  
  3055  	for _, test := range tests {
  3056  		t.Run(test.name, func(t *testing.T) {
  3057  			e := channel.New(0, 1280, linkAddr1)
  3058  			s := stack.New(stack.Options{
  3059  				NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
  3060  					NDPConfigs: ipv6.NDPConfigurations{
  3061  						HandleRAs:                  ipv6.HandlingRAsEnabledWhenForwardingDisabled,
  3062  						AutoGenGlobalAddresses:     true,
  3063  						AutoGenTempGlobalAddresses: true,
  3064  					},
  3065  					NDPDisp: &ndpDispatcher{},
  3066  				})},
  3067  				TransportProtocols: []stack.TransportProtocolFactory{udp.NewProtocol},
  3068  			})
  3069  			if err := s.CreateNIC(nicID, e); err != nil {
  3070  				t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
  3071  			}
  3072  
  3073  			if test.slaacPrefixForTempAddrBeforeNICAddrAdd != (tcpip.AddressWithPrefix{}) {
  3074  				e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr3, 0, test.slaacPrefixForTempAddrBeforeNICAddrAdd, true, true, lifetimeSeconds, lifetimeSeconds))
  3075  			}
  3076  
  3077  			for _, a := range test.nicAddrs {
  3078  				if err := s.AddAddress(nicID, ipv6.ProtocolNumber, a); err != nil {
  3079  					t.Errorf("s.AddAddress(%d, %d, %s): %s", nicID, ipv6.ProtocolNumber, a, err)
  3080  				}
  3081  			}
  3082  
  3083  			if test.slaacPrefixForTempAddrAfterNICAddrAdd != (tcpip.AddressWithPrefix{}) {
  3084  				e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr3, 0, test.slaacPrefixForTempAddrAfterNICAddrAdd, true, true, lifetimeSeconds, lifetimeSeconds))
  3085  			}
  3086  
  3087  			if t.Failed() {
  3088  				t.FailNow()
  3089  			}
  3090  
  3091  			netEP, err := s.GetNetworkEndpoint(nicID, header.IPv6ProtocolNumber)
  3092  			if err != nil {
  3093  				t.Fatalf("s.GetNetworkEndpoint(%d, %d): %s", nicID, header.IPv6ProtocolNumber, err)
  3094  			}
  3095  
  3096  			addressableEndpoint, ok := netEP.(stack.AddressableEndpoint)
  3097  			if !ok {
  3098  				t.Fatal("network endpoint is not addressable")
  3099  			}
  3100  
  3101  			addressEP := addressableEndpoint.AcquireOutgoingPrimaryAddress(test.remoteAddr, false /* allowExpired */)
  3102  			if addressEP == nil {
  3103  				t.Fatal("expected a non-nil address endpoint")
  3104  			}
  3105  			defer addressEP.DecRef()
  3106  
  3107  			if got := addressEP.AddressWithPrefix().Address; got != test.expectedLocalAddr {
  3108  				t.Errorf("got local address = %s, want = %s", got, test.expectedLocalAddr)
  3109  			}
  3110  		})
  3111  	}
  3112  }
  3113  
  3114  func TestAddRemoveIPv4BroadcastAddressOnNICEnableDisable(t *testing.T) {
  3115  	const nicID = 1
  3116  	broadcastAddr := tcpip.ProtocolAddress{
  3117  		Protocol: header.IPv4ProtocolNumber,
  3118  		AddressWithPrefix: tcpip.AddressWithPrefix{
  3119  			Address:   header.IPv4Broadcast,
  3120  			PrefixLen: 32,
  3121  		},
  3122  	}
  3123  
  3124  	e := loopback.New()
  3125  	s := stack.New(stack.Options{
  3126  		NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol},
  3127  	})
  3128  	nicOpts := stack.NICOptions{Disabled: true}
  3129  	if err := s.CreateNICWithOptions(nicID, e, nicOpts); err != nil {
  3130  		t.Fatalf("CreateNIC(%d, _, %+v) = %s", nicID, nicOpts, err)
  3131  	}
  3132  
  3133  	{
  3134  		allStackAddrs := s.AllAddresses()
  3135  		if allNICAddrs, ok := allStackAddrs[nicID]; !ok {
  3136  			t.Fatalf("entry for %d missing from allStackAddrs = %+v", nicID, allStackAddrs)
  3137  		} else if containsAddr(allNICAddrs, broadcastAddr) {
  3138  			t.Fatalf("got allNICAddrs = %+v, don't want = %+v", allNICAddrs, broadcastAddr)
  3139  		}
  3140  	}
  3141  
  3142  	// Enabling the NIC should add the IPv4 broadcast address.
  3143  	if err := s.EnableNIC(nicID); err != nil {
  3144  		t.Fatalf("s.EnableNIC(%d): %s", nicID, err)
  3145  	}
  3146  
  3147  	{
  3148  		allStackAddrs := s.AllAddresses()
  3149  		if allNICAddrs, ok := allStackAddrs[nicID]; !ok {
  3150  			t.Fatalf("entry for %d missing from allStackAddrs = %+v", nicID, allStackAddrs)
  3151  		} else if !containsAddr(allNICAddrs, broadcastAddr) {
  3152  			t.Fatalf("got allNICAddrs = %+v, want = %+v", allNICAddrs, broadcastAddr)
  3153  		}
  3154  	}
  3155  
  3156  	// Disabling the NIC should remove the IPv4 broadcast address.
  3157  	if err := s.DisableNIC(nicID); err != nil {
  3158  		t.Fatalf("s.DisableNIC(%d): %s", nicID, err)
  3159  	}
  3160  
  3161  	{
  3162  		allStackAddrs := s.AllAddresses()
  3163  		if allNICAddrs, ok := allStackAddrs[nicID]; !ok {
  3164  			t.Fatalf("entry for %d missing from allStackAddrs = %+v", nicID, allStackAddrs)
  3165  		} else if containsAddr(allNICAddrs, broadcastAddr) {
  3166  			t.Fatalf("got allNICAddrs = %+v, don't want = %+v", allNICAddrs, broadcastAddr)
  3167  		}
  3168  	}
  3169  }
  3170  
  3171  // TestLeaveIPv6SolicitedNodeAddrBeforeAddrRemoval tests that removing an IPv6
  3172  // address after leaving its solicited node multicast address does not result in
  3173  // an error.
  3174  func TestLeaveIPv6SolicitedNodeAddrBeforeAddrRemoval(t *testing.T) {
  3175  	const nicID = 1
  3176  
  3177  	s := stack.New(stack.Options{
  3178  		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocol},
  3179  	})
  3180  	e := channel.New(10, 1280, linkAddr1)
  3181  	if err := s.CreateNIC(1, e); err != nil {
  3182  		t.Fatalf("CreateNIC(%d, _): %s", nicID, err)
  3183  	}
  3184  
  3185  	if err := s.AddAddress(nicID, ipv6.ProtocolNumber, addr1); err != nil {
  3186  		t.Fatalf("AddAddress(%d, %d, %s): %s", nicID, ipv6.ProtocolNumber, addr1, err)
  3187  	}
  3188  
  3189  	// The NIC should have joined addr1's solicited node multicast address.
  3190  	snmc := header.SolicitedNodeAddr(addr1)
  3191  	in, err := s.IsInGroup(nicID, snmc)
  3192  	if err != nil {
  3193  		t.Fatalf("IsInGroup(%d, %s): %s", nicID, snmc, err)
  3194  	}
  3195  	if !in {
  3196  		t.Fatalf("got IsInGroup(%d, %s) = false, want = true", nicID, snmc)
  3197  	}
  3198  
  3199  	if err := s.LeaveGroup(ipv6.ProtocolNumber, nicID, snmc); err != nil {
  3200  		t.Fatalf("LeaveGroup(%d, %d, %s): %s", ipv6.ProtocolNumber, nicID, snmc, err)
  3201  	}
  3202  	in, err = s.IsInGroup(nicID, snmc)
  3203  	if err != nil {
  3204  		t.Fatalf("IsInGroup(%d, %s): %s", nicID, snmc, err)
  3205  	}
  3206  	if in {
  3207  		t.Fatalf("got IsInGroup(%d, %s) = true, want = false", nicID, snmc)
  3208  	}
  3209  
  3210  	if err := s.RemoveAddress(nicID, addr1); err != nil {
  3211  		t.Fatalf("RemoveAddress(%d, %s) = %s", nicID, addr1, err)
  3212  	}
  3213  }
  3214  
  3215  func TestJoinLeaveMulticastOnNICEnableDisable(t *testing.T) {
  3216  	const nicID = 1
  3217  
  3218  	tests := []struct {
  3219  		name  string
  3220  		proto tcpip.NetworkProtocolNumber
  3221  		addr  tcpip.Address
  3222  	}{
  3223  		{
  3224  			name:  "IPv6 All-Nodes",
  3225  			proto: header.IPv6ProtocolNumber,
  3226  			addr:  header.IPv6AllNodesMulticastAddress,
  3227  		},
  3228  		{
  3229  			name:  "IPv4 All-Systems",
  3230  			proto: header.IPv4ProtocolNumber,
  3231  			addr:  header.IPv4AllSystems,
  3232  		},
  3233  	}
  3234  
  3235  	for _, test := range tests {
  3236  		t.Run(test.name, func(t *testing.T) {
  3237  			e := loopback.New()
  3238  			s := stack.New(stack.Options{
  3239  				NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol, ipv6.NewProtocol},
  3240  			})
  3241  			nicOpts := stack.NICOptions{Disabled: true}
  3242  			if err := s.CreateNICWithOptions(nicID, e, nicOpts); err != nil {
  3243  				t.Fatalf("CreateNIC(%d, _, %+v) = %s", nicID, nicOpts, err)
  3244  			}
  3245  
  3246  			// Should not be in the multicast group yet because the NIC has not been
  3247  			// enabled yet.
  3248  			if isInGroup, err := s.IsInGroup(nicID, test.addr); err != nil {
  3249  				t.Fatalf("IsInGroup(%d, %s): %s", nicID, test.addr, err)
  3250  			} else if isInGroup {
  3251  				t.Fatalf("got IsInGroup(%d, %s) = true, want = false", nicID, test.addr)
  3252  			}
  3253  
  3254  			// The all-nodes multicast group should be joined when the NIC is enabled.
  3255  			if err := s.EnableNIC(nicID); err != nil {
  3256  				t.Fatalf("s.EnableNIC(%d): %s", nicID, err)
  3257  			}
  3258  
  3259  			if isInGroup, err := s.IsInGroup(nicID, test.addr); err != nil {
  3260  				t.Fatalf("IsInGroup(%d, %s): %s", nicID, test.addr, err)
  3261  			} else if !isInGroup {
  3262  				t.Fatalf("got IsInGroup(%d, %s) = false, want = true", nicID, test.addr)
  3263  			}
  3264  
  3265  			// The multicast group should be left when the NIC is disabled.
  3266  			if err := s.DisableNIC(nicID); err != nil {
  3267  				t.Fatalf("s.DisableNIC(%d): %s", nicID, err)
  3268  			}
  3269  
  3270  			if isInGroup, err := s.IsInGroup(nicID, test.addr); err != nil {
  3271  				t.Fatalf("IsInGroup(%d, %s): %s", nicID, test.addr, err)
  3272  			} else if isInGroup {
  3273  				t.Fatalf("got IsInGroup(%d, %s) = true, want = false", nicID, test.addr)
  3274  			}
  3275  
  3276  			// The all-nodes multicast group should be joined when the NIC is enabled.
  3277  			if err := s.EnableNIC(nicID); err != nil {
  3278  				t.Fatalf("s.EnableNIC(%d): %s", nicID, err)
  3279  			}
  3280  
  3281  			if isInGroup, err := s.IsInGroup(nicID, test.addr); err != nil {
  3282  				t.Fatalf("IsInGroup(%d, %s): %s", nicID, test.addr, err)
  3283  			} else if !isInGroup {
  3284  				t.Fatalf("got IsInGroup(%d, %s) = false, want = true", nicID, test.addr)
  3285  			}
  3286  
  3287  			// Leaving the group before disabling the NIC should not cause an error.
  3288  			if err := s.LeaveGroup(test.proto, nicID, test.addr); err != nil {
  3289  				t.Fatalf("s.LeaveGroup(%d, %d, %s): %s", test.proto, nicID, test.addr, err)
  3290  			}
  3291  
  3292  			if err := s.DisableNIC(nicID); err != nil {
  3293  				t.Fatalf("s.DisableNIC(%d): %s", nicID, err)
  3294  			}
  3295  
  3296  			if isInGroup, err := s.IsInGroup(nicID, test.addr); err != nil {
  3297  				t.Fatalf("IsInGroup(%d, %s): %s", nicID, test.addr, err)
  3298  			} else if isInGroup {
  3299  				t.Fatalf("got IsInGroup(%d, %s) = true, want = false", nicID, test.addr)
  3300  			}
  3301  		})
  3302  	}
  3303  }
  3304  
  3305  // TestDoDADWhenNICEnabled tests that IPv6 endpoints that were added while a NIC
  3306  // was disabled have DAD performed on them when the NIC is enabled.
  3307  func TestDoDADWhenNICEnabled(t *testing.T) {
  3308  	const dadTransmits = 1
  3309  	const retransmitTimer = time.Second
  3310  	const nicID = 1
  3311  
  3312  	ndpDisp := ndpDispatcher{
  3313  		dadC: make(chan ndpDADEvent, 1),
  3314  	}
  3315  	clock := faketime.NewManualClock()
  3316  	opts := stack.Options{
  3317  		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
  3318  			DADConfigs: stack.DADConfigurations{
  3319  				DupAddrDetectTransmits: dadTransmits,
  3320  				RetransmitTimer:        retransmitTimer,
  3321  			},
  3322  			NDPDisp: &ndpDisp,
  3323  		})},
  3324  		Clock: clock,
  3325  	}
  3326  
  3327  	e := channel.New(dadTransmits, 1280, linkAddr1)
  3328  	s := stack.New(opts)
  3329  	nicOpts := stack.NICOptions{Disabled: true}
  3330  	if err := s.CreateNICWithOptions(nicID, e, nicOpts); err != nil {
  3331  		t.Fatalf("CreateNIC(%d, _, %+v) = %s", nicID, nicOpts, err)
  3332  	}
  3333  
  3334  	addr := tcpip.ProtocolAddress{
  3335  		Protocol: header.IPv6ProtocolNumber,
  3336  		AddressWithPrefix: tcpip.AddressWithPrefix{
  3337  			Address:   llAddr1,
  3338  			PrefixLen: 128,
  3339  		},
  3340  	}
  3341  	if err := s.AddProtocolAddress(nicID, addr); err != nil {
  3342  		t.Fatalf("AddProtocolAddress(%d, %+v): %s", nicID, addr, err)
  3343  	}
  3344  
  3345  	// Address should be in the list of all addresses.
  3346  	if addrs := s.AllAddresses()[nicID]; !containsV6Addr(addrs, addr.AddressWithPrefix) {
  3347  		t.Fatalf("got s.AllAddresses()[%d] = %+v, want = %+v", nicID, addrs, addr)
  3348  	}
  3349  
  3350  	// Address should be tentative so it should not be a main address.
  3351  	if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil {
  3352  		t.Fatal(err)
  3353  	}
  3354  
  3355  	// Enabling the NIC should start DAD for the address.
  3356  	if err := s.EnableNIC(nicID); err != nil {
  3357  		t.Fatalf("s.EnableNIC(%d): %s", nicID, err)
  3358  	}
  3359  	if addrs := s.AllAddresses()[nicID]; !containsV6Addr(addrs, addr.AddressWithPrefix) {
  3360  		t.Fatalf("got s.AllAddresses()[%d] = %+v, want = %+v", nicID, addrs, addr)
  3361  	}
  3362  
  3363  	// Address should not be considered bound to the NIC yet (DAD ongoing).
  3364  	if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil {
  3365  		t.Fatal(err)
  3366  	}
  3367  
  3368  	// Wait for DAD to resolve.
  3369  	clock.Advance(dadTransmits * retransmitTimer)
  3370  	select {
  3371  	case e := <-ndpDisp.dadC:
  3372  		if diff := checkDADEvent(e, nicID, addr.AddressWithPrefix.Address, &stack.DADSucceeded{}); diff != "" {
  3373  			t.Errorf("dad event mismatch (-want +got):\n%s", diff)
  3374  		}
  3375  	default:
  3376  		t.Fatal("timed out waiting for DAD resolution")
  3377  	}
  3378  	if addrs := s.AllAddresses()[nicID]; !containsV6Addr(addrs, addr.AddressWithPrefix) {
  3379  		t.Fatalf("got s.AllAddresses()[%d] = %+v, want = %+v", nicID, addrs, addr)
  3380  	}
  3381  	if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, addr.AddressWithPrefix); err != nil {
  3382  		t.Fatal(err)
  3383  	}
  3384  
  3385  	// Enabling the NIC again should be a no-op.
  3386  	if err := s.EnableNIC(nicID); err != nil {
  3387  		t.Fatalf("s.EnableNIC(%d): %s", nicID, err)
  3388  	}
  3389  	if addrs := s.AllAddresses()[nicID]; !containsV6Addr(addrs, addr.AddressWithPrefix) {
  3390  		t.Fatalf("got s.AllAddresses()[%d] = %+v, want = %+v", nicID, addrs, addr)
  3391  	}
  3392  	if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, addr.AddressWithPrefix); err != nil {
  3393  		t.Fatal(err)
  3394  	}
  3395  }
  3396  
  3397  func TestStackReceiveBufferSizeOption(t *testing.T) {
  3398  	const sMin = stack.MinBufferSize
  3399  	testCases := []struct {
  3400  		name string
  3401  		rs   tcpip.ReceiveBufferSizeOption
  3402  		err  tcpip.Error
  3403  	}{
  3404  		// Invalid configurations.
  3405  		{"min_below_zero", tcpip.ReceiveBufferSizeOption{Min: -1, Default: sMin, Max: sMin}, &tcpip.ErrInvalidOptionValue{}},
  3406  		{"min_zero", tcpip.ReceiveBufferSizeOption{Min: 0, Default: sMin, Max: sMin}, &tcpip.ErrInvalidOptionValue{}},
  3407  		{"default_below_min", tcpip.ReceiveBufferSizeOption{Min: sMin, Default: sMin - 1, Max: sMin - 1}, &tcpip.ErrInvalidOptionValue{}},
  3408  		{"default_above_max", tcpip.ReceiveBufferSizeOption{Min: sMin, Default: sMin + 1, Max: sMin}, &tcpip.ErrInvalidOptionValue{}},
  3409  		{"max_below_min", tcpip.ReceiveBufferSizeOption{Min: sMin, Default: sMin + 1, Max: sMin - 1}, &tcpip.ErrInvalidOptionValue{}},
  3410  
  3411  		// Valid Configurations
  3412  		{"in_ascending_order", tcpip.ReceiveBufferSizeOption{Min: sMin, Default: sMin + 1, Max: sMin + 2}, nil},
  3413  		{"all_equal", tcpip.ReceiveBufferSizeOption{Min: sMin, Default: sMin, Max: sMin}, nil},
  3414  		{"min_default_equal", tcpip.ReceiveBufferSizeOption{Min: sMin, Default: sMin, Max: sMin + 1}, nil},
  3415  		{"default_max_equal", tcpip.ReceiveBufferSizeOption{Min: sMin, Default: sMin + 1, Max: sMin + 1}, nil},
  3416  	}
  3417  	for _, tc := range testCases {
  3418  		t.Run(tc.name, func(t *testing.T) {
  3419  			s := stack.New(stack.Options{})
  3420  			defer s.Close()
  3421  			if err := s.SetOption(tc.rs); err != tc.err {
  3422  				t.Fatalf("s.SetOption(%#v) = %v, want: %v", tc.rs, err, tc.err)
  3423  			}
  3424  			var rs tcpip.ReceiveBufferSizeOption
  3425  			if tc.err == nil {
  3426  				if err := s.Option(&rs); err != nil {
  3427  					t.Fatalf("s.Option(%#v) = %v, want: nil", rs, err)
  3428  				}
  3429  				if got, want := rs, tc.rs; got != want {
  3430  					t.Fatalf("s.Option(..) returned unexpected value got: %#v, want: %#v", got, want)
  3431  				}
  3432  			}
  3433  		})
  3434  	}
  3435  }
  3436  
  3437  func TestStackSendBufferSizeOption(t *testing.T) {
  3438  	const sMin = stack.MinBufferSize
  3439  	testCases := []struct {
  3440  		name string
  3441  		ss   tcpip.SendBufferSizeOption
  3442  		err  tcpip.Error
  3443  	}{
  3444  		// Invalid configurations.
  3445  		{"min_below_zero", tcpip.SendBufferSizeOption{Min: -1, Default: sMin, Max: sMin}, &tcpip.ErrInvalidOptionValue{}},
  3446  		{"min_zero", tcpip.SendBufferSizeOption{Min: 0, Default: sMin, Max: sMin}, &tcpip.ErrInvalidOptionValue{}},
  3447  		{"default_below_min", tcpip.SendBufferSizeOption{Min: 0, Default: sMin - 1, Max: sMin - 1}, &tcpip.ErrInvalidOptionValue{}},
  3448  		{"default_above_max", tcpip.SendBufferSizeOption{Min: 0, Default: sMin + 1, Max: sMin}, &tcpip.ErrInvalidOptionValue{}},
  3449  		{"max_below_min", tcpip.SendBufferSizeOption{Min: sMin, Default: sMin + 1, Max: sMin - 1}, &tcpip.ErrInvalidOptionValue{}},
  3450  
  3451  		// Valid Configurations
  3452  		{"in_ascending_order", tcpip.SendBufferSizeOption{Min: sMin, Default: sMin + 1, Max: sMin + 2}, nil},
  3453  		{"all_equal", tcpip.SendBufferSizeOption{Min: sMin, Default: sMin, Max: sMin}, nil},
  3454  		{"min_default_equal", tcpip.SendBufferSizeOption{Min: sMin, Default: sMin, Max: sMin + 1}, nil},
  3455  		{"default_max_equal", tcpip.SendBufferSizeOption{Min: sMin, Default: sMin + 1, Max: sMin + 1}, nil},
  3456  	}
  3457  	for _, tc := range testCases {
  3458  		t.Run(tc.name, func(t *testing.T) {
  3459  			s := stack.New(stack.Options{})
  3460  			defer s.Close()
  3461  			err := s.SetOption(tc.ss)
  3462  			if diff := cmp.Diff(tc.err, err); diff != "" {
  3463  				t.Fatalf("unexpected error from s.SetOption(%+v), (-want, +got):\n%s", tc.ss, diff)
  3464  			}
  3465  			if tc.err == nil {
  3466  				var ss tcpip.SendBufferSizeOption
  3467  				if err := s.Option(&ss); err != nil {
  3468  					t.Fatalf("s.Option(%+v) = %v, want: nil", ss, err)
  3469  				}
  3470  				if got, want := ss, tc.ss; got != want {
  3471  					t.Fatalf("s.Option(..) returned unexpected value got: %#v, want: %#v", got, want)
  3472  				}
  3473  			}
  3474  		})
  3475  	}
  3476  }
  3477  
  3478  func TestOutgoingSubnetBroadcast(t *testing.T) {
  3479  	const (
  3480  		unspecifiedNICID = 0
  3481  		nicID1           = 1
  3482  	)
  3483  
  3484  	defaultAddr := tcpip.AddressWithPrefix{
  3485  		Address:   header.IPv4Any,
  3486  		PrefixLen: 0,
  3487  	}
  3488  	defaultSubnet := defaultAddr.Subnet()
  3489  	ipv4Addr := tcpip.AddressWithPrefix{
  3490  		Address:   "\xc0\xa8\x01\x3a",
  3491  		PrefixLen: 24,
  3492  	}
  3493  	ipv4Subnet := ipv4Addr.Subnet()
  3494  	ipv4SubnetBcast := ipv4Subnet.Broadcast()
  3495  	ipv4Gateway := testutil.MustParse4("192.168.1.1")
  3496  	ipv4AddrPrefix31 := tcpip.AddressWithPrefix{
  3497  		Address:   "\xc0\xa8\x01\x3a",
  3498  		PrefixLen: 31,
  3499  	}
  3500  	ipv4Subnet31 := ipv4AddrPrefix31.Subnet()
  3501  	ipv4Subnet31Bcast := ipv4Subnet31.Broadcast()
  3502  	ipv4AddrPrefix32 := tcpip.AddressWithPrefix{
  3503  		Address:   "\xc0\xa8\x01\x3a",
  3504  		PrefixLen: 32,
  3505  	}
  3506  	ipv4Subnet32 := ipv4AddrPrefix32.Subnet()
  3507  	ipv4Subnet32Bcast := ipv4Subnet32.Broadcast()
  3508  	ipv6Addr := tcpip.AddressWithPrefix{
  3509  		Address:   "\x20\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01",
  3510  		PrefixLen: 64,
  3511  	}
  3512  	ipv6Subnet := ipv6Addr.Subnet()
  3513  	ipv6SubnetBcast := ipv6Subnet.Broadcast()
  3514  	remNetAddr := tcpip.AddressWithPrefix{
  3515  		Address:   "\x64\x0a\x7b\x18",
  3516  		PrefixLen: 24,
  3517  	}
  3518  	remNetSubnet := remNetAddr.Subnet()
  3519  	remNetSubnetBcast := remNetSubnet.Broadcast()
  3520  
  3521  	tests := []struct {
  3522  		name                      string
  3523  		nicAddr                   tcpip.ProtocolAddress
  3524  		routes                    []tcpip.Route
  3525  		remoteAddr                tcpip.Address
  3526  		expectedLocalAddress      tcpip.Address
  3527  		expectedRemoteAddress     tcpip.Address
  3528  		expectedRemoteLinkAddress tcpip.LinkAddress
  3529  		expectedNextHop           tcpip.Address
  3530  		expectedNetProto          tcpip.NetworkProtocolNumber
  3531  		expectedLoop              stack.PacketLooping
  3532  	}{
  3533  		// Broadcast to a locally attached subnet populates the broadcast MAC.
  3534  		{
  3535  			name: "IPv4 Broadcast to local subnet",
  3536  			nicAddr: tcpip.ProtocolAddress{
  3537  				Protocol:          header.IPv4ProtocolNumber,
  3538  				AddressWithPrefix: ipv4Addr,
  3539  			},
  3540  			routes: []tcpip.Route{
  3541  				{
  3542  					Destination: ipv4Subnet,
  3543  					NIC:         nicID1,
  3544  				},
  3545  			},
  3546  			remoteAddr:                ipv4SubnetBcast,
  3547  			expectedLocalAddress:      ipv4Addr.Address,
  3548  			expectedRemoteAddress:     ipv4SubnetBcast,
  3549  			expectedRemoteLinkAddress: header.EthernetBroadcastAddress,
  3550  			expectedNetProto:          header.IPv4ProtocolNumber,
  3551  			expectedLoop:              stack.PacketOut | stack.PacketLoop,
  3552  		},
  3553  		// Broadcast to a locally attached /31 subnet does not populate the
  3554  		// broadcast MAC.
  3555  		{
  3556  			name: "IPv4 Broadcast to local /31 subnet",
  3557  			nicAddr: tcpip.ProtocolAddress{
  3558  				Protocol:          header.IPv4ProtocolNumber,
  3559  				AddressWithPrefix: ipv4AddrPrefix31,
  3560  			},
  3561  			routes: []tcpip.Route{
  3562  				{
  3563  					Destination: ipv4Subnet31,
  3564  					NIC:         nicID1,
  3565  				},
  3566  			},
  3567  			remoteAddr:            ipv4Subnet31Bcast,
  3568  			expectedLocalAddress:  ipv4AddrPrefix31.Address,
  3569  			expectedRemoteAddress: ipv4Subnet31Bcast,
  3570  			expectedNetProto:      header.IPv4ProtocolNumber,
  3571  			expectedLoop:          stack.PacketOut,
  3572  		},
  3573  		// Broadcast to a locally attached /32 subnet does not populate the
  3574  		// broadcast MAC.
  3575  		{
  3576  			name: "IPv4 Broadcast to local /32 subnet",
  3577  			nicAddr: tcpip.ProtocolAddress{
  3578  				Protocol:          header.IPv4ProtocolNumber,
  3579  				AddressWithPrefix: ipv4AddrPrefix32,
  3580  			},
  3581  			routes: []tcpip.Route{
  3582  				{
  3583  					Destination: ipv4Subnet32,
  3584  					NIC:         nicID1,
  3585  				},
  3586  			},
  3587  			remoteAddr:            ipv4Subnet32Bcast,
  3588  			expectedLocalAddress:  ipv4AddrPrefix32.Address,
  3589  			expectedRemoteAddress: ipv4Subnet32Bcast,
  3590  			expectedNetProto:      header.IPv4ProtocolNumber,
  3591  			expectedLoop:          stack.PacketOut,
  3592  		},
  3593  		// IPv6 has no notion of a broadcast.
  3594  		{
  3595  			name: "IPv6 'Broadcast' to local subnet",
  3596  			nicAddr: tcpip.ProtocolAddress{
  3597  				Protocol:          header.IPv6ProtocolNumber,
  3598  				AddressWithPrefix: ipv6Addr,
  3599  			},
  3600  			routes: []tcpip.Route{
  3601  				{
  3602  					Destination: ipv6Subnet,
  3603  					NIC:         nicID1,
  3604  				},
  3605  			},
  3606  			remoteAddr:            ipv6SubnetBcast,
  3607  			expectedLocalAddress:  ipv6Addr.Address,
  3608  			expectedRemoteAddress: ipv6SubnetBcast,
  3609  			expectedNetProto:      header.IPv6ProtocolNumber,
  3610  			expectedLoop:          stack.PacketOut,
  3611  		},
  3612  		// Broadcast to a remote subnet in the route table is send to the next-hop
  3613  		// gateway.
  3614  		{
  3615  			name: "IPv4 Broadcast to remote subnet",
  3616  			nicAddr: tcpip.ProtocolAddress{
  3617  				Protocol:          header.IPv4ProtocolNumber,
  3618  				AddressWithPrefix: ipv4Addr,
  3619  			},
  3620  			routes: []tcpip.Route{
  3621  				{
  3622  					Destination: remNetSubnet,
  3623  					Gateway:     ipv4Gateway,
  3624  					NIC:         nicID1,
  3625  				},
  3626  			},
  3627  			remoteAddr:            remNetSubnetBcast,
  3628  			expectedLocalAddress:  ipv4Addr.Address,
  3629  			expectedRemoteAddress: remNetSubnetBcast,
  3630  			expectedNextHop:       ipv4Gateway,
  3631  			expectedNetProto:      header.IPv4ProtocolNumber,
  3632  			expectedLoop:          stack.PacketOut,
  3633  		},
  3634  		// Broadcast to an unknown subnet follows the default route. Note that this
  3635  		// is essentially just routing an unknown destination IP, because w/o any
  3636  		// subnet prefix information a subnet broadcast address is just a normal IP.
  3637  		{
  3638  			name: "IPv4 Broadcast to unknown subnet",
  3639  			nicAddr: tcpip.ProtocolAddress{
  3640  				Protocol:          header.IPv4ProtocolNumber,
  3641  				AddressWithPrefix: ipv4Addr,
  3642  			},
  3643  			routes: []tcpip.Route{
  3644  				{
  3645  					Destination: defaultSubnet,
  3646  					Gateway:     ipv4Gateway,
  3647  					NIC:         nicID1,
  3648  				},
  3649  			},
  3650  			remoteAddr:            remNetSubnetBcast,
  3651  			expectedLocalAddress:  ipv4Addr.Address,
  3652  			expectedRemoteAddress: remNetSubnetBcast,
  3653  			expectedNextHop:       ipv4Gateway,
  3654  			expectedNetProto:      header.IPv4ProtocolNumber,
  3655  			expectedLoop:          stack.PacketOut,
  3656  		},
  3657  	}
  3658  
  3659  	for _, test := range tests {
  3660  		t.Run(test.name, func(t *testing.T) {
  3661  			s := stack.New(stack.Options{
  3662  				NetworkProtocols: []stack.NetworkProtocolFactory{arp.NewProtocol, ipv4.NewProtocol, ipv6.NewProtocol},
  3663  			})
  3664  			ep := channel.New(0, defaultMTU, "")
  3665  			ep.LinkEPCapabilities |= stack.CapabilityResolutionRequired
  3666  			if err := s.CreateNIC(nicID1, ep); err != nil {
  3667  				t.Fatalf("CreateNIC(%d, _): %s", nicID1, err)
  3668  			}
  3669  			if err := s.AddProtocolAddress(nicID1, test.nicAddr); err != nil {
  3670  				t.Fatalf("AddProtocolAddress(%d, %+v): %s", nicID1, test.nicAddr, err)
  3671  			}
  3672  
  3673  			s.SetRouteTable(test.routes)
  3674  
  3675  			var netProto tcpip.NetworkProtocolNumber
  3676  			switch l := len(test.remoteAddr); l {
  3677  			case header.IPv4AddressSize:
  3678  				netProto = header.IPv4ProtocolNumber
  3679  			case header.IPv6AddressSize:
  3680  				netProto = header.IPv6ProtocolNumber
  3681  			default:
  3682  				t.Fatalf("got unexpected address length = %d bytes", l)
  3683  			}
  3684  
  3685  			r, err := s.FindRoute(unspecifiedNICID, "" /* localAddr */, test.remoteAddr, netProto, false /* multicastLoop */)
  3686  			if err != nil {
  3687  				t.Fatalf("FindRoute(%d, '', %s, %d): %s", unspecifiedNICID, test.remoteAddr, netProto, err)
  3688  			}
  3689  			if r.LocalAddress() != test.expectedLocalAddress {
  3690  				t.Errorf("got r.LocalAddress() = %s, want = %s", r.LocalAddress(), test.expectedLocalAddress)
  3691  			}
  3692  			if r.RemoteAddress() != test.expectedRemoteAddress {
  3693  				t.Errorf("got r.RemoteAddress = %s, want = %s", r.RemoteAddress(), test.expectedRemoteAddress)
  3694  			}
  3695  			if got := r.RemoteLinkAddress(); got != test.expectedRemoteLinkAddress {
  3696  				t.Errorf("got r.RemoteLinkAddress() = %s, want = %s", got, test.expectedRemoteLinkAddress)
  3697  			}
  3698  			if r.NextHop() != test.expectedNextHop {
  3699  				t.Errorf("got r.NextHop() = %s, want = %s", r.NextHop(), test.expectedNextHop)
  3700  			}
  3701  			if r.NetProto() != test.expectedNetProto {
  3702  				t.Errorf("got r.NetProto() = %d, want = %d", r.NetProto(), test.expectedNetProto)
  3703  			}
  3704  			if r.Loop() != test.expectedLoop {
  3705  				t.Errorf("got r.Loop() = %x, want = %x", r.Loop(), test.expectedLoop)
  3706  			}
  3707  		})
  3708  	}
  3709  }
  3710  
  3711  func TestResolveWith(t *testing.T) {
  3712  	const (
  3713  		unspecifiedNICID = 0
  3714  		nicID            = 1
  3715  	)
  3716  
  3717  	s := stack.New(stack.Options{
  3718  		NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol, arp.NewProtocol},
  3719  	})
  3720  	ep := channel.New(0, defaultMTU, "")
  3721  	ep.LinkEPCapabilities |= stack.CapabilityResolutionRequired
  3722  	if err := s.CreateNIC(nicID, ep); err != nil {
  3723  		t.Fatalf("CreateNIC(%d, _): %s", nicID, err)
  3724  	}
  3725  	addr := tcpip.ProtocolAddress{
  3726  		Protocol: header.IPv4ProtocolNumber,
  3727  		AddressWithPrefix: tcpip.AddressWithPrefix{
  3728  			Address:   tcpip.Address([]byte{192, 168, 1, 58}),
  3729  			PrefixLen: 24,
  3730  		},
  3731  	}
  3732  	if err := s.AddProtocolAddress(nicID, addr); err != nil {
  3733  		t.Fatalf("AddProtocolAddress(%d, %#v): %s", nicID, addr, err)
  3734  	}
  3735  
  3736  	s.SetRouteTable([]tcpip.Route{{Destination: header.IPv4EmptySubnet, NIC: nicID}})
  3737  
  3738  	remoteAddr := tcpip.Address([]byte{192, 168, 1, 59})
  3739  	r, err := s.FindRoute(unspecifiedNICID, "" /* localAddr */, remoteAddr, header.IPv4ProtocolNumber, false /* multicastLoop */)
  3740  	if err != nil {
  3741  		t.Fatalf("FindRoute(%d, '', %s, %d): %s", unspecifiedNICID, remoteAddr, header.IPv4ProtocolNumber, err)
  3742  	}
  3743  	defer r.Release()
  3744  
  3745  	// Should initially require resolution.
  3746  	if !r.IsResolutionRequired() {
  3747  		t.Fatal("got r.IsResolutionRequired() = false, want = true")
  3748  	}
  3749  
  3750  	// Manually resolving the route should no longer require resolution.
  3751  	r.ResolveWith("\x01")
  3752  	if r.IsResolutionRequired() {
  3753  		t.Fatal("got r.IsResolutionRequired() = true, want = false")
  3754  	}
  3755  }
  3756  
  3757  // TestRouteReleaseAfterAddrRemoval tests that releasing a Route after its
  3758  // associated address is removed should not cause a panic.
  3759  func TestRouteReleaseAfterAddrRemoval(t *testing.T) {
  3760  	const (
  3761  		nicID      = 1
  3762  		localAddr  = tcpip.Address("\x01")
  3763  		remoteAddr = tcpip.Address("\x02")
  3764  	)
  3765  
  3766  	s := stack.New(stack.Options{
  3767  		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
  3768  	})
  3769  
  3770  	ep := channel.New(0, defaultMTU, "")
  3771  	if err := s.CreateNIC(nicID, ep); err != nil {
  3772  		t.Fatalf("CreateNIC(%d, _): %s", nicID, err)
  3773  	}
  3774  	if err := s.AddAddress(nicID, fakeNetNumber, localAddr); err != nil {
  3775  		t.Fatalf("s.AddAddress(%d, %d, %s): %s", nicID, fakeNetNumber, localAddr, err)
  3776  	}
  3777  	{
  3778  		subnet, err := tcpip.NewSubnet("\x00", "\x00")
  3779  		if err != nil {
  3780  			t.Fatal(err)
  3781  		}
  3782  		s.SetRouteTable([]tcpip.Route{{Destination: subnet, Gateway: "\x00", NIC: 1}})
  3783  	}
  3784  
  3785  	r, err := s.FindRoute(nicID, localAddr, remoteAddr, fakeNetNumber, false /* multicastLoop */)
  3786  	if err != nil {
  3787  		t.Fatalf("s.FindRoute(%d, %s, %s, %d, false): %s", nicID, localAddr, remoteAddr, fakeNetNumber, err)
  3788  	}
  3789  	// Should not panic.
  3790  	defer r.Release()
  3791  
  3792  	// Check that removing the same address fails.
  3793  	if err := s.RemoveAddress(nicID, localAddr); err != nil {
  3794  		t.Fatalf("s.RemoveAddress(%d, %s): %s", nicID, localAddr, err)
  3795  	}
  3796  }
  3797  
  3798  func TestGetNetworkEndpoint(t *testing.T) {
  3799  	const nicID = 1
  3800  
  3801  	tests := []struct {
  3802  		name         string
  3803  		protoFactory stack.NetworkProtocolFactory
  3804  		protoNum     tcpip.NetworkProtocolNumber
  3805  	}{
  3806  		{
  3807  			name:         "IPv4",
  3808  			protoFactory: ipv4.NewProtocol,
  3809  			protoNum:     ipv4.ProtocolNumber,
  3810  		},
  3811  		{
  3812  			name:         "IPv6",
  3813  			protoFactory: ipv6.NewProtocol,
  3814  			protoNum:     ipv6.ProtocolNumber,
  3815  		},
  3816  	}
  3817  
  3818  	factories := make([]stack.NetworkProtocolFactory, 0, len(tests))
  3819  	for _, test := range tests {
  3820  		factories = append(factories, test.protoFactory)
  3821  	}
  3822  
  3823  	s := stack.New(stack.Options{
  3824  		NetworkProtocols: factories,
  3825  	})
  3826  
  3827  	if err := s.CreateNIC(nicID, channel.New(0, defaultMTU, "")); err != nil {
  3828  		t.Fatalf("CreateNIC(%d, _): %s", nicID, err)
  3829  	}
  3830  
  3831  	for _, test := range tests {
  3832  		t.Run(test.name, func(t *testing.T) {
  3833  			ep, err := s.GetNetworkEndpoint(nicID, test.protoNum)
  3834  			if err != nil {
  3835  				t.Fatalf("s.GetNetworkEndpoint(%d, %d): %s", nicID, test.protoNum, err)
  3836  			}
  3837  
  3838  			if got := ep.NetworkProtocolNumber(); got != test.protoNum {
  3839  				t.Fatalf("got ep.NetworkProtocolNumber() = %d, want = %d", got, test.protoNum)
  3840  			}
  3841  		})
  3842  	}
  3843  }
  3844  
  3845  func TestGetMainNICAddressWhenNICDisabled(t *testing.T) {
  3846  	const nicID = 1
  3847  
  3848  	s := stack.New(stack.Options{
  3849  		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
  3850  	})
  3851  
  3852  	if err := s.CreateNIC(nicID, channel.New(0, defaultMTU, "")); err != nil {
  3853  		t.Fatalf("CreateNIC(%d, _): %s", nicID, err)
  3854  	}
  3855  
  3856  	protocolAddress := tcpip.ProtocolAddress{
  3857  		Protocol: fakeNetNumber,
  3858  		AddressWithPrefix: tcpip.AddressWithPrefix{
  3859  			Address:   "\x01",
  3860  			PrefixLen: 8,
  3861  		},
  3862  	}
  3863  	if err := s.AddProtocolAddress(nicID, protocolAddress); err != nil {
  3864  		t.Fatalf("AddProtocolAddress(%d, %#v): %s", nicID, protocolAddress, err)
  3865  	}
  3866  
  3867  	// Check that we get the right initial address and prefix length.
  3868  	if err := checkGetMainNICAddress(s, nicID, fakeNetNumber, protocolAddress.AddressWithPrefix); err != nil {
  3869  		t.Fatal(err)
  3870  	}
  3871  
  3872  	// Should still get the address when the NIC is diabled.
  3873  	if err := s.DisableNIC(nicID); err != nil {
  3874  		t.Fatalf("DisableNIC(%d): %s", nicID, err)
  3875  	}
  3876  	if err := checkGetMainNICAddress(s, nicID, fakeNetNumber, protocolAddress.AddressWithPrefix); err != nil {
  3877  		t.Fatal(err)
  3878  	}
  3879  }
  3880  
  3881  // TestAddRoute tests Stack.AddRoute
  3882  func TestAddRoute(t *testing.T) {
  3883  	s := stack.New(stack.Options{})
  3884  
  3885  	subnet1, err := tcpip.NewSubnet("\x00", "\x00")
  3886  	if err != nil {
  3887  		t.Fatal(err)
  3888  	}
  3889  
  3890  	subnet2, err := tcpip.NewSubnet("\x01", "\x01")
  3891  	if err != nil {
  3892  		t.Fatal(err)
  3893  	}
  3894  
  3895  	expected := []tcpip.Route{
  3896  		{Destination: subnet1, Gateway: "\x00", NIC: 1},
  3897  		{Destination: subnet2, Gateway: "\x00", NIC: 1},
  3898  	}
  3899  
  3900  	// Initialize the route table with one route.
  3901  	s.SetRouteTable([]tcpip.Route{expected[0]})
  3902  
  3903  	// Add another route.
  3904  	s.AddRoute(expected[1])
  3905  
  3906  	rt := s.GetRouteTable()
  3907  	if got, want := len(rt), len(expected); got != want {
  3908  		t.Fatalf("Unexpected route table length got = %d, want = %d", got, want)
  3909  	}
  3910  	for i, route := range rt {
  3911  		if got, want := route, expected[i]; got != want {
  3912  			t.Fatalf("Unexpected route got = %#v, want = %#v", got, want)
  3913  		}
  3914  	}
  3915  }
  3916  
  3917  // TestRemoveRoutes tests Stack.RemoveRoutes
  3918  func TestRemoveRoutes(t *testing.T) {
  3919  	s := stack.New(stack.Options{})
  3920  
  3921  	addressToRemove := tcpip.Address("\x01")
  3922  	subnet1, err := tcpip.NewSubnet(addressToRemove, "\x01")
  3923  	if err != nil {
  3924  		t.Fatal(err)
  3925  	}
  3926  
  3927  	subnet2, err := tcpip.NewSubnet(addressToRemove, "\x01")
  3928  	if err != nil {
  3929  		t.Fatal(err)
  3930  	}
  3931  
  3932  	subnet3, err := tcpip.NewSubnet("\x02", "\x02")
  3933  	if err != nil {
  3934  		t.Fatal(err)
  3935  	}
  3936  
  3937  	// Initialize the route table with three routes.
  3938  	s.SetRouteTable([]tcpip.Route{
  3939  		{Destination: subnet1, Gateway: "\x00", NIC: 1},
  3940  		{Destination: subnet2, Gateway: "\x00", NIC: 1},
  3941  		{Destination: subnet3, Gateway: "\x00", NIC: 1},
  3942  	})
  3943  
  3944  	// Remove routes with the specific address.
  3945  	s.RemoveRoutes(func(r tcpip.Route) bool {
  3946  		return r.Destination.ID() == addressToRemove
  3947  	})
  3948  
  3949  	expected := []tcpip.Route{{Destination: subnet3, Gateway: "\x00", NIC: 1}}
  3950  	rt := s.GetRouteTable()
  3951  	if got, want := len(rt), len(expected); got != want {
  3952  		t.Fatalf("Unexpected route table length got = %d, want = %d", got, want)
  3953  	}
  3954  	for i, route := range rt {
  3955  		if got, want := route, expected[i]; got != want {
  3956  			t.Fatalf("Unexpected route got = %#v, want = %#v", got, want)
  3957  		}
  3958  	}
  3959  }
  3960  
  3961  func TestFindRouteWithForwarding(t *testing.T) {
  3962  	const (
  3963  		nicID1 = 1
  3964  		nicID2 = 2
  3965  
  3966  		nic1Addr   = tcpip.Address("\x01")
  3967  		nic2Addr   = tcpip.Address("\x02")
  3968  		remoteAddr = tcpip.Address("\x03")
  3969  	)
  3970  
  3971  	type netCfg struct {
  3972  		proto      tcpip.NetworkProtocolNumber
  3973  		factory    stack.NetworkProtocolFactory
  3974  		nic1Addr   tcpip.Address
  3975  		nic2Addr   tcpip.Address
  3976  		remoteAddr tcpip.Address
  3977  	}
  3978  
  3979  	fakeNetCfg := netCfg{
  3980  		proto:      fakeNetNumber,
  3981  		factory:    fakeNetFactory,
  3982  		nic1Addr:   nic1Addr,
  3983  		nic2Addr:   nic2Addr,
  3984  		remoteAddr: remoteAddr,
  3985  	}
  3986  
  3987  	globalIPv6Addr1 := tcpip.Address(net.ParseIP("a::1").To16())
  3988  	globalIPv6Addr2 := tcpip.Address(net.ParseIP("a::2").To16())
  3989  
  3990  	ipv6LinkLocalNIC1WithGlobalRemote := netCfg{
  3991  		proto:      ipv6.ProtocolNumber,
  3992  		factory:    ipv6.NewProtocol,
  3993  		nic1Addr:   llAddr1,
  3994  		nic2Addr:   globalIPv6Addr2,
  3995  		remoteAddr: globalIPv6Addr1,
  3996  	}
  3997  	ipv6GlobalNIC1WithLinkLocalRemote := netCfg{
  3998  		proto:      ipv6.ProtocolNumber,
  3999  		factory:    ipv6.NewProtocol,
  4000  		nic1Addr:   globalIPv6Addr1,
  4001  		nic2Addr:   llAddr1,
  4002  		remoteAddr: llAddr2,
  4003  	}
  4004  	ipv6GlobalNIC1WithLinkLocalMulticastRemote := netCfg{
  4005  		proto:      ipv6.ProtocolNumber,
  4006  		factory:    ipv6.NewProtocol,
  4007  		nic1Addr:   globalIPv6Addr1,
  4008  		nic2Addr:   globalIPv6Addr2,
  4009  		remoteAddr: "\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01",
  4010  	}
  4011  
  4012  	tests := []struct {
  4013  		name string
  4014  
  4015  		netCfg            netCfg
  4016  		forwardingEnabled bool
  4017  
  4018  		addrNIC   tcpip.NICID
  4019  		localAddr tcpip.Address
  4020  
  4021  		findRouteErr          tcpip.Error
  4022  		dependentOnForwarding bool
  4023  	}{
  4024  		{
  4025  			name:                  "forwarding disabled and localAddr not on specified NIC but route from different NIC",
  4026  			netCfg:                fakeNetCfg,
  4027  			forwardingEnabled:     false,
  4028  			addrNIC:               nicID1,
  4029  			localAddr:             fakeNetCfg.nic2Addr,
  4030  			findRouteErr:          &tcpip.ErrNoRoute{},
  4031  			dependentOnForwarding: false,
  4032  		},
  4033  		{
  4034  			name:                  "forwarding enabled and localAddr not on specified NIC but route from different NIC",
  4035  			netCfg:                fakeNetCfg,
  4036  			forwardingEnabled:     true,
  4037  			addrNIC:               nicID1,
  4038  			localAddr:             fakeNetCfg.nic2Addr,
  4039  			findRouteErr:          &tcpip.ErrNoRoute{},
  4040  			dependentOnForwarding: false,
  4041  		},
  4042  		{
  4043  			name:                  "forwarding disabled and localAddr on specified NIC but route from different NIC",
  4044  			netCfg:                fakeNetCfg,
  4045  			forwardingEnabled:     false,
  4046  			addrNIC:               nicID1,
  4047  			localAddr:             fakeNetCfg.nic1Addr,
  4048  			findRouteErr:          &tcpip.ErrNoRoute{},
  4049  			dependentOnForwarding: false,
  4050  		},
  4051  		{
  4052  			name:                  "forwarding enabled and localAddr on specified NIC but route from different NIC",
  4053  			netCfg:                fakeNetCfg,
  4054  			forwardingEnabled:     true,
  4055  			addrNIC:               nicID1,
  4056  			localAddr:             fakeNetCfg.nic1Addr,
  4057  			findRouteErr:          nil,
  4058  			dependentOnForwarding: true,
  4059  		},
  4060  		{
  4061  			name:                  "forwarding disabled and localAddr on specified NIC and route from same NIC",
  4062  			netCfg:                fakeNetCfg,
  4063  			forwardingEnabled:     false,
  4064  			addrNIC:               nicID2,
  4065  			localAddr:             fakeNetCfg.nic2Addr,
  4066  			findRouteErr:          nil,
  4067  			dependentOnForwarding: false,
  4068  		},
  4069  		{
  4070  			name:                  "forwarding enabled and localAddr on specified NIC and route from same NIC",
  4071  			netCfg:                fakeNetCfg,
  4072  			forwardingEnabled:     true,
  4073  			addrNIC:               nicID2,
  4074  			localAddr:             fakeNetCfg.nic2Addr,
  4075  			findRouteErr:          nil,
  4076  			dependentOnForwarding: false,
  4077  		},
  4078  		{
  4079  			name:                  "forwarding disabled and localAddr not on specified NIC but route from same NIC",
  4080  			netCfg:                fakeNetCfg,
  4081  			forwardingEnabled:     false,
  4082  			addrNIC:               nicID2,
  4083  			localAddr:             fakeNetCfg.nic1Addr,
  4084  			findRouteErr:          &tcpip.ErrNoRoute{},
  4085  			dependentOnForwarding: false,
  4086  		},
  4087  		{
  4088  			name:                  "forwarding enabled and localAddr not on specified NIC but route from same NIC",
  4089  			netCfg:                fakeNetCfg,
  4090  			forwardingEnabled:     true,
  4091  			addrNIC:               nicID2,
  4092  			localAddr:             fakeNetCfg.nic1Addr,
  4093  			findRouteErr:          &tcpip.ErrNoRoute{},
  4094  			dependentOnForwarding: false,
  4095  		},
  4096  		{
  4097  			name:                  "forwarding disabled and localAddr on same NIC as route",
  4098  			netCfg:                fakeNetCfg,
  4099  			forwardingEnabled:     false,
  4100  			localAddr:             fakeNetCfg.nic2Addr,
  4101  			findRouteErr:          nil,
  4102  			dependentOnForwarding: false,
  4103  		},
  4104  		{
  4105  			name:                  "forwarding enabled and localAddr on same NIC as route",
  4106  			netCfg:                fakeNetCfg,
  4107  			forwardingEnabled:     false,
  4108  			localAddr:             fakeNetCfg.nic2Addr,
  4109  			findRouteErr:          nil,
  4110  			dependentOnForwarding: false,
  4111  		},
  4112  		{
  4113  			name:                  "forwarding disabled and localAddr on different NIC as route",
  4114  			netCfg:                fakeNetCfg,
  4115  			forwardingEnabled:     false,
  4116  			localAddr:             fakeNetCfg.nic1Addr,
  4117  			findRouteErr:          &tcpip.ErrNoRoute{},
  4118  			dependentOnForwarding: false,
  4119  		},
  4120  		{
  4121  			name:                  "forwarding enabled and localAddr on different NIC as route",
  4122  			netCfg:                fakeNetCfg,
  4123  			forwardingEnabled:     true,
  4124  			localAddr:             fakeNetCfg.nic1Addr,
  4125  			findRouteErr:          nil,
  4126  			dependentOnForwarding: true,
  4127  		},
  4128  		{
  4129  			name:                  "forwarding disabled and specified NIC only has link-local addr with route on different NIC",
  4130  			netCfg:                ipv6LinkLocalNIC1WithGlobalRemote,
  4131  			forwardingEnabled:     false,
  4132  			addrNIC:               nicID1,
  4133  			findRouteErr:          &tcpip.ErrNoRoute{},
  4134  			dependentOnForwarding: false,
  4135  		},
  4136  		{
  4137  			name:                  "forwarding enabled and specified NIC only has link-local addr with route on different NIC",
  4138  			netCfg:                ipv6LinkLocalNIC1WithGlobalRemote,
  4139  			forwardingEnabled:     true,
  4140  			addrNIC:               nicID1,
  4141  			findRouteErr:          &tcpip.ErrNoRoute{},
  4142  			dependentOnForwarding: false,
  4143  		},
  4144  		{
  4145  			name:                  "forwarding disabled and link-local local addr with route on different NIC",
  4146  			netCfg:                ipv6LinkLocalNIC1WithGlobalRemote,
  4147  			forwardingEnabled:     false,
  4148  			localAddr:             ipv6LinkLocalNIC1WithGlobalRemote.nic1Addr,
  4149  			findRouteErr:          &tcpip.ErrNoRoute{},
  4150  			dependentOnForwarding: false,
  4151  		},
  4152  		{
  4153  			name:                  "forwarding enabled and link-local local addr with route on same NIC",
  4154  			netCfg:                ipv6LinkLocalNIC1WithGlobalRemote,
  4155  			forwardingEnabled:     true,
  4156  			localAddr:             ipv6LinkLocalNIC1WithGlobalRemote.nic1Addr,
  4157  			findRouteErr:          &tcpip.ErrNoRoute{},
  4158  			dependentOnForwarding: false,
  4159  		},
  4160  		{
  4161  			name:                  "forwarding disabled and global local addr with route on same NIC",
  4162  			netCfg:                ipv6LinkLocalNIC1WithGlobalRemote,
  4163  			forwardingEnabled:     true,
  4164  			localAddr:             ipv6LinkLocalNIC1WithGlobalRemote.nic2Addr,
  4165  			findRouteErr:          nil,
  4166  			dependentOnForwarding: false,
  4167  		},
  4168  		{
  4169  			name:                  "forwarding disabled and link-local local addr with route on same NIC",
  4170  			netCfg:                ipv6GlobalNIC1WithLinkLocalRemote,
  4171  			forwardingEnabled:     false,
  4172  			localAddr:             ipv6GlobalNIC1WithLinkLocalRemote.nic2Addr,
  4173  			findRouteErr:          nil,
  4174  			dependentOnForwarding: false,
  4175  		},
  4176  		{
  4177  			name:                  "forwarding enabled and link-local local addr with route on same NIC",
  4178  			netCfg:                ipv6GlobalNIC1WithLinkLocalRemote,
  4179  			forwardingEnabled:     true,
  4180  			localAddr:             ipv6GlobalNIC1WithLinkLocalRemote.nic2Addr,
  4181  			findRouteErr:          nil,
  4182  			dependentOnForwarding: false,
  4183  		},
  4184  		{
  4185  			name:                  "forwarding disabled and global local addr with link-local remote on different NIC",
  4186  			netCfg:                ipv6GlobalNIC1WithLinkLocalRemote,
  4187  			forwardingEnabled:     false,
  4188  			localAddr:             ipv6GlobalNIC1WithLinkLocalRemote.nic1Addr,
  4189  			findRouteErr:          &tcpip.ErrNetworkUnreachable{},
  4190  			dependentOnForwarding: false,
  4191  		},
  4192  		{
  4193  			name:                  "forwarding enabled and global local addr with link-local remote on different NIC",
  4194  			netCfg:                ipv6GlobalNIC1WithLinkLocalRemote,
  4195  			forwardingEnabled:     true,
  4196  			localAddr:             ipv6GlobalNIC1WithLinkLocalRemote.nic1Addr,
  4197  			findRouteErr:          &tcpip.ErrNetworkUnreachable{},
  4198  			dependentOnForwarding: false,
  4199  		},
  4200  		{
  4201  			name:                  "forwarding disabled and global local addr with link-local multicast remote on different NIC",
  4202  			netCfg:                ipv6GlobalNIC1WithLinkLocalMulticastRemote,
  4203  			forwardingEnabled:     false,
  4204  			localAddr:             ipv6GlobalNIC1WithLinkLocalMulticastRemote.nic1Addr,
  4205  			findRouteErr:          &tcpip.ErrNetworkUnreachable{},
  4206  			dependentOnForwarding: false,
  4207  		},
  4208  		{
  4209  			name:                  "forwarding enabled and global local addr with link-local multicast remote on different NIC",
  4210  			netCfg:                ipv6GlobalNIC1WithLinkLocalMulticastRemote,
  4211  			forwardingEnabled:     true,
  4212  			localAddr:             ipv6GlobalNIC1WithLinkLocalMulticastRemote.nic1Addr,
  4213  			findRouteErr:          &tcpip.ErrNetworkUnreachable{},
  4214  			dependentOnForwarding: false,
  4215  		},
  4216  		{
  4217  			name:                  "forwarding disabled and global local addr with link-local multicast remote on same NIC",
  4218  			netCfg:                ipv6GlobalNIC1WithLinkLocalMulticastRemote,
  4219  			forwardingEnabled:     false,
  4220  			localAddr:             ipv6GlobalNIC1WithLinkLocalMulticastRemote.nic2Addr,
  4221  			findRouteErr:          nil,
  4222  			dependentOnForwarding: false,
  4223  		},
  4224  		{
  4225  			name:                  "forwarding enabled and global local addr with link-local multicast remote on same NIC",
  4226  			netCfg:                ipv6GlobalNIC1WithLinkLocalMulticastRemote,
  4227  			forwardingEnabled:     true,
  4228  			localAddr:             ipv6GlobalNIC1WithLinkLocalMulticastRemote.nic2Addr,
  4229  			findRouteErr:          nil,
  4230  			dependentOnForwarding: false,
  4231  		},
  4232  	}
  4233  
  4234  	for _, test := range tests {
  4235  		t.Run(test.name, func(t *testing.T) {
  4236  			s := stack.New(stack.Options{
  4237  				NetworkProtocols: []stack.NetworkProtocolFactory{test.netCfg.factory},
  4238  			})
  4239  
  4240  			ep1 := channel.New(1, defaultMTU, "")
  4241  			if err := s.CreateNIC(nicID1, ep1); err != nil {
  4242  				t.Fatalf("CreateNIC(%d, _): %s:", nicID1, err)
  4243  			}
  4244  
  4245  			ep2 := channel.New(1, defaultMTU, "")
  4246  			if err := s.CreateNIC(nicID2, ep2); err != nil {
  4247  				t.Fatalf("CreateNIC(%d, _): %s:", nicID2, err)
  4248  			}
  4249  
  4250  			if err := s.AddAddress(nicID1, test.netCfg.proto, test.netCfg.nic1Addr); err != nil {
  4251  				t.Fatalf("AddAddress(%d, %d, %s): %s", nicID1, test.netCfg.proto, test.netCfg.nic1Addr, err)
  4252  			}
  4253  
  4254  			if err := s.AddAddress(nicID2, test.netCfg.proto, test.netCfg.nic2Addr); err != nil {
  4255  				t.Fatalf("AddAddress(%d, %d, %s): %s", nicID2, test.netCfg.proto, test.netCfg.nic2Addr, err)
  4256  			}
  4257  
  4258  			if err := s.SetForwardingDefaultAndAllNICs(test.netCfg.proto, test.forwardingEnabled); err != nil {
  4259  				t.Fatalf("SetForwardingDefaultAndAllNICs(%d, %t): %s", test.netCfg.proto, test.forwardingEnabled, err)
  4260  			}
  4261  
  4262  			s.SetRouteTable([]tcpip.Route{{Destination: test.netCfg.remoteAddr.WithPrefix().Subnet(), NIC: nicID2}})
  4263  
  4264  			r, err := s.FindRoute(test.addrNIC, test.localAddr, test.netCfg.remoteAddr, test.netCfg.proto, false /* multicastLoop */)
  4265  			if err == nil {
  4266  				defer r.Release()
  4267  			}
  4268  			if diff := cmp.Diff(test.findRouteErr, err); diff != "" {
  4269  				t.Fatalf("unexpected error from FindRoute(%d, %s, %s, %d, false), (-want, +got):\n%s", test.addrNIC, test.localAddr, test.netCfg.remoteAddr, test.netCfg.proto, diff)
  4270  			}
  4271  
  4272  			if test.findRouteErr != nil {
  4273  				return
  4274  			}
  4275  
  4276  			if r.LocalAddress() != test.localAddr {
  4277  				t.Errorf("got r.LocalAddress() = %s, want = %s", r.LocalAddress(), test.localAddr)
  4278  			}
  4279  			if r.RemoteAddress() != test.netCfg.remoteAddr {
  4280  				t.Errorf("got r.RemoteAddress() = %s, want = %s", r.RemoteAddress(), test.netCfg.remoteAddr)
  4281  			}
  4282  
  4283  			if t.Failed() {
  4284  				t.FailNow()
  4285  			}
  4286  
  4287  			// Sending a packet should always go through NIC2 since we only install a
  4288  			// route to test.netCfg.remoteAddr through NIC2.
  4289  			data := buffer.View([]byte{1, 2, 3, 4})
  4290  			if err := send(r, data); err != nil {
  4291  				t.Fatalf("send(_, _): %s", err)
  4292  			}
  4293  			if n := ep1.Drain(); n != 0 {
  4294  				t.Errorf("got %d unexpected packets from ep1", n)
  4295  			}
  4296  			pkt, ok := ep2.Read()
  4297  			if !ok {
  4298  				t.Fatal("packet not sent through ep2")
  4299  			}
  4300  			if pkt.Route.LocalAddress != test.localAddr {
  4301  				t.Errorf("got pkt.Route.LocalAddress = %s, want = %s", pkt.Route.LocalAddress, test.localAddr)
  4302  			}
  4303  			if pkt.Route.RemoteAddress != test.netCfg.remoteAddr {
  4304  				t.Errorf("got pkt.Route.RemoteAddress = %s, want = %s", pkt.Route.RemoteAddress, test.netCfg.remoteAddr)
  4305  			}
  4306  
  4307  			if !test.forwardingEnabled || !test.dependentOnForwarding {
  4308  				return
  4309  			}
  4310  
  4311  			// Disabling forwarding when the route is dependent on forwarding being
  4312  			// enabled should make the route invalid.
  4313  			if err := s.SetForwardingDefaultAndAllNICs(test.netCfg.proto, false); err != nil {
  4314  				t.Fatalf("SetForwardingDefaultAndAllNICs(%d, false): %s", test.netCfg.proto, err)
  4315  			}
  4316  			{
  4317  				err := send(r, data)
  4318  				if _, ok := err.(*tcpip.ErrInvalidEndpointState); !ok {
  4319  					t.Fatalf("got send(_, _) = %s, want = %s", err, &tcpip.ErrInvalidEndpointState{})
  4320  				}
  4321  			}
  4322  			if n := ep1.Drain(); n != 0 {
  4323  				t.Errorf("got %d unexpected packets from ep1", n)
  4324  			}
  4325  			if n := ep2.Drain(); n != 0 {
  4326  				t.Errorf("got %d unexpected packets from ep2", n)
  4327  			}
  4328  		})
  4329  	}
  4330  }
  4331  
  4332  func TestWritePacketToRemote(t *testing.T) {
  4333  	const nicID = 1
  4334  	const MTU = 1280
  4335  	e := channel.New(1, MTU, linkAddr1)
  4336  	s := stack.New(stack.Options{})
  4337  	if err := s.CreateNIC(nicID, e); err != nil {
  4338  		t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
  4339  	}
  4340  	if err := s.EnableNIC(nicID); err != nil {
  4341  		t.Fatalf("CreateNIC(%d) = %s", nicID, err)
  4342  	}
  4343  	tests := []struct {
  4344  		name     string
  4345  		protocol tcpip.NetworkProtocolNumber
  4346  		payload  []byte
  4347  	}{
  4348  		{
  4349  			name:     "SuccessIPv4",
  4350  			protocol: header.IPv4ProtocolNumber,
  4351  			payload:  []byte{1, 2, 3, 4},
  4352  		},
  4353  		{
  4354  			name:     "SuccessIPv6",
  4355  			protocol: header.IPv6ProtocolNumber,
  4356  			payload:  []byte{5, 6, 7, 8},
  4357  		},
  4358  	}
  4359  	for _, test := range tests {
  4360  		t.Run(test.name, func(t *testing.T) {
  4361  			if err := s.WritePacketToRemote(nicID, linkAddr2, test.protocol, buffer.View(test.payload).ToVectorisedView()); err != nil {
  4362  				t.Fatalf("s.WritePacketToRemote(_, _, _, _) = %s", err)
  4363  			}
  4364  
  4365  			pkt, ok := e.Read()
  4366  			if got, want := ok, true; got != want {
  4367  				t.Fatalf("e.Read() = %t, want %t", got, want)
  4368  			}
  4369  			if got, want := pkt.Proto, test.protocol; got != want {
  4370  				t.Fatalf("pkt.Proto = %d, want %d", got, want)
  4371  			}
  4372  			if pkt.Route.RemoteLinkAddress != linkAddr2 {
  4373  				t.Fatalf("pkt.Route.RemoteAddress = %s, want %s", pkt.Route.RemoteLinkAddress, linkAddr2)
  4374  			}
  4375  			if diff := cmp.Diff(pkt.Pkt.Data().AsRange().ToOwnedView(), buffer.View(test.payload)); diff != "" {
  4376  				t.Errorf("pkt.Pkt.Data mismatch (-want +got):\n%s", diff)
  4377  			}
  4378  		})
  4379  	}
  4380  
  4381  	t.Run("InvalidNICID", func(t *testing.T) {
  4382  		err := s.WritePacketToRemote(234, linkAddr2, header.IPv4ProtocolNumber, buffer.View([]byte{1}).ToVectorisedView())
  4383  		if _, ok := err.(*tcpip.ErrUnknownDevice); !ok {
  4384  			t.Fatalf("s.WritePacketToRemote(_, _, _, _) = %s, want = %s", err, &tcpip.ErrUnknownDevice{})
  4385  		}
  4386  		pkt, ok := e.Read()
  4387  		if got, want := ok, false; got != want {
  4388  			t.Fatalf("e.Read() = %t, %v; want %t", got, pkt, want)
  4389  		}
  4390  	})
  4391  }
  4392  
  4393  func TestClearNeighborCacheOnNICDisable(t *testing.T) {
  4394  	const (
  4395  		nicID    = 1
  4396  		linkAddr = tcpip.LinkAddress("\x02\x02\x03\x04\x05\x06")
  4397  	)
  4398  
  4399  	var (
  4400  		ipv4Addr = testutil.MustParse4("1.2.3.4")
  4401  		ipv6Addr = testutil.MustParse6("102:304:102:304:102:304:102:304")
  4402  	)
  4403  
  4404  	clock := faketime.NewManualClock()
  4405  	s := stack.New(stack.Options{
  4406  		NetworkProtocols: []stack.NetworkProtocolFactory{arp.NewProtocol, ipv4.NewProtocol, ipv6.NewProtocol},
  4407  		Clock:            clock,
  4408  	})
  4409  	e := channel.New(0, 0, "")
  4410  	e.LinkEPCapabilities |= stack.CapabilityResolutionRequired
  4411  	if err := s.CreateNIC(nicID, e); err != nil {
  4412  		t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
  4413  	}
  4414  
  4415  	addrs := []struct {
  4416  		proto tcpip.NetworkProtocolNumber
  4417  		addr  tcpip.Address
  4418  	}{
  4419  		{
  4420  			proto: ipv4.ProtocolNumber,
  4421  			addr:  ipv4Addr,
  4422  		},
  4423  		{
  4424  			proto: ipv6.ProtocolNumber,
  4425  			addr:  ipv6Addr,
  4426  		},
  4427  	}
  4428  	for _, addr := range addrs {
  4429  		if err := s.AddStaticNeighbor(nicID, addr.proto, addr.addr, linkAddr); err != nil {
  4430  			t.Fatalf("s.AddStaticNeighbor(%d, %d, %s, %s): %s", nicID, addr.proto, addr.addr, linkAddr, err)
  4431  		}
  4432  
  4433  		if neighbors, err := s.Neighbors(nicID, addr.proto); err != nil {
  4434  			t.Fatalf("s.Neighbors(%d, %d): %s", nicID, addr.proto, err)
  4435  		} else if diff := cmp.Diff(
  4436  			[]stack.NeighborEntry{{Addr: addr.addr, LinkAddr: linkAddr, State: stack.Static, UpdatedAt: clock.Now()}},
  4437  			neighbors,
  4438  		); diff != "" {
  4439  			t.Fatalf("proto=%d neighbors mismatch (-want +got):\n%s", addr.proto, diff)
  4440  		}
  4441  	}
  4442  
  4443  	// Disabling the NIC should clear the neighbor table.
  4444  	if err := s.DisableNIC(nicID); err != nil {
  4445  		t.Fatalf("s.DisableNIC(%d): %s", nicID, err)
  4446  	}
  4447  	for _, addr := range addrs {
  4448  		if neighbors, err := s.Neighbors(nicID, addr.proto); err != nil {
  4449  			t.Fatalf("s.Neighbors(%d, %d): %s", nicID, addr.proto, err)
  4450  		} else if len(neighbors) != 0 {
  4451  			t.Fatalf("got proto=%d len(neighbors) = %d, want = 0; neighbors = %#v", addr.proto, len(neighbors), neighbors)
  4452  		}
  4453  	}
  4454  
  4455  	// Enabling the NIC should have an empty neighbor table.
  4456  	if err := s.EnableNIC(nicID); err != nil {
  4457  		t.Fatalf("s.EnableNIC(%d): %s", nicID, err)
  4458  	}
  4459  	for _, addr := range addrs {
  4460  		if neighbors, err := s.Neighbors(nicID, addr.proto); err != nil {
  4461  			t.Fatalf("s.Neighbors(%d, %d): %s", nicID, addr.proto, err)
  4462  		} else if len(neighbors) != 0 {
  4463  			t.Fatalf("got proto=%d len(neighbors) = %d, want = 0; neighbors = %#v", addr.proto, len(neighbors), neighbors)
  4464  		}
  4465  	}
  4466  }
  4467  
  4468  func TestGetLinkAddressErrors(t *testing.T) {
  4469  	const (
  4470  		nicID        = 1
  4471  		unknownNICID = nicID + 1
  4472  	)
  4473  
  4474  	s := stack.New(stack.Options{
  4475  		NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol},
  4476  	})
  4477  	if err := s.CreateNIC(nicID, channel.New(0, 0, "")); err != nil {
  4478  		t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
  4479  	}
  4480  
  4481  	{
  4482  		err := s.GetLinkAddress(unknownNICID, "", "", ipv4.ProtocolNumber, nil)
  4483  		if _, ok := err.(*tcpip.ErrUnknownNICID); !ok {
  4484  			t.Errorf("got s.GetLinkAddress(%d, '', '', %d, nil) = %s, want = %s", unknownNICID, ipv4.ProtocolNumber, err, &tcpip.ErrUnknownNICID{})
  4485  		}
  4486  	}
  4487  	{
  4488  		err := s.GetLinkAddress(nicID, "", "", ipv4.ProtocolNumber, nil)
  4489  		if _, ok := err.(*tcpip.ErrNotSupported); !ok {
  4490  			t.Errorf("got s.GetLinkAddress(%d, '', '', %d, nil) = %s, want = %s", unknownNICID, ipv4.ProtocolNumber, err, &tcpip.ErrNotSupported{})
  4491  		}
  4492  	}
  4493  }
  4494  
  4495  func TestStaticGetLinkAddress(t *testing.T) {
  4496  	const (
  4497  		nicID = 1
  4498  	)
  4499  
  4500  	s := stack.New(stack.Options{
  4501  		NetworkProtocols: []stack.NetworkProtocolFactory{arp.NewProtocol, ipv4.NewProtocol, ipv6.NewProtocol},
  4502  	})
  4503  	e := channel.New(0, 0, "")
  4504  	e.LinkEPCapabilities |= stack.CapabilityResolutionRequired
  4505  	if err := s.CreateNIC(nicID, e); err != nil {
  4506  		t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
  4507  	}
  4508  
  4509  	tests := []struct {
  4510  		name             string
  4511  		proto            tcpip.NetworkProtocolNumber
  4512  		addr             tcpip.Address
  4513  		expectedLinkAddr tcpip.LinkAddress
  4514  	}{
  4515  		{
  4516  			name:             "IPv4",
  4517  			proto:            ipv4.ProtocolNumber,
  4518  			addr:             header.IPv4Broadcast,
  4519  			expectedLinkAddr: header.EthernetBroadcastAddress,
  4520  		},
  4521  		{
  4522  			name:             "IPv6",
  4523  			proto:            ipv6.ProtocolNumber,
  4524  			addr:             header.IPv6AllNodesMulticastAddress,
  4525  			expectedLinkAddr: header.EthernetAddressFromMulticastIPv6Address(header.IPv6AllNodesMulticastAddress),
  4526  		},
  4527  	}
  4528  
  4529  	for _, test := range tests {
  4530  		t.Run(test.name, func(t *testing.T) {
  4531  			ch := make(chan stack.LinkResolutionResult, 1)
  4532  			if err := s.GetLinkAddress(nicID, test.addr, "", test.proto, func(r stack.LinkResolutionResult) {
  4533  				ch <- r
  4534  			}); err != nil {
  4535  				t.Fatalf("s.GetLinkAddress(%d, %s, '', %d, _): %s", nicID, test.addr, test.proto, err)
  4536  			}
  4537  
  4538  			if diff := cmp.Diff(stack.LinkResolutionResult{LinkAddress: test.expectedLinkAddr, Err: nil}, <-ch); diff != "" {
  4539  				t.Fatalf("link resolution result mismatch (-want +got):\n%s", diff)
  4540  			}
  4541  		})
  4542  	}
  4543  }