gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/pkg/tcpip/tests/integration/link_resolution_test.go (about)

     1  // Copyright 2020 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 link_resolution_test
    16  
    17  import (
    18  	"bytes"
    19  	"fmt"
    20  	"net"
    21  	"runtime"
    22  	"testing"
    23  	"time"
    24  
    25  	"github.com/google/go-cmp/cmp"
    26  	"github.com/google/go-cmp/cmp/cmpopts"
    27  	"gvisor.dev/gvisor/pkg/buffer"
    28  	"gvisor.dev/gvisor/pkg/sync"
    29  	"gvisor.dev/gvisor/pkg/tcpip"
    30  	"gvisor.dev/gvisor/pkg/tcpip/checker"
    31  	"gvisor.dev/gvisor/pkg/tcpip/checksum"
    32  	"gvisor.dev/gvisor/pkg/tcpip/faketime"
    33  	"gvisor.dev/gvisor/pkg/tcpip/header"
    34  	"gvisor.dev/gvisor/pkg/tcpip/link/channel"
    35  	"gvisor.dev/gvisor/pkg/tcpip/link/ethernet"
    36  	"gvisor.dev/gvisor/pkg/tcpip/link/pipe"
    37  	"gvisor.dev/gvisor/pkg/tcpip/network/arp"
    38  	"gvisor.dev/gvisor/pkg/tcpip/network/ipv4"
    39  	"gvisor.dev/gvisor/pkg/tcpip/network/ipv6"
    40  	"gvisor.dev/gvisor/pkg/tcpip/stack"
    41  	"gvisor.dev/gvisor/pkg/tcpip/tests/utils"
    42  	tcptestutil "gvisor.dev/gvisor/pkg/tcpip/testutil"
    43  	"gvisor.dev/gvisor/pkg/tcpip/transport/icmp"
    44  	"gvisor.dev/gvisor/pkg/tcpip/transport/tcp"
    45  	"gvisor.dev/gvisor/pkg/tcpip/transport/udp"
    46  	"gvisor.dev/gvisor/pkg/waiter"
    47  )
    48  
    49  func setupStack(t *testing.T, stackOpts stack.Options, host1NICID, host2NICID tcpip.NICID) (*stack.Stack, *stack.Stack) {
    50  	return setupStackWithSeparateOpts(t, stackOpts, stackOpts, host1NICID, host2NICID)
    51  }
    52  
    53  func setupStackWithSeparateOpts(t *testing.T, stack1Opts stack.Options, stack2Opts stack.Options, host1NICID, host2NICID tcpip.NICID) (*stack.Stack, *stack.Stack) {
    54  	const maxFrameSize = header.IPv6MinimumMTU + header.EthernetMinimumSize
    55  
    56  	host1Stack := stack.New(stack1Opts)
    57  	host2Stack := stack.New(stack2Opts)
    58  
    59  	host1NIC, host2NIC := pipe.New(utils.LinkAddr1, utils.LinkAddr2, maxFrameSize)
    60  
    61  	if err := host1Stack.CreateNIC(host1NICID, utils.NewEthernetEndpoint(host1NIC)); err != nil {
    62  		t.Fatalf("host1Stack.CreateNIC(%d, _): %s", host1NICID, err)
    63  	}
    64  	if err := host2Stack.CreateNIC(host2NICID, utils.NewEthernetEndpoint(host2NIC)); err != nil {
    65  		t.Fatalf("host2Stack.CreateNIC(%d, _): %s", host2NICID, err)
    66  	}
    67  
    68  	if err := host1Stack.AddProtocolAddress(host1NICID, utils.Ipv4Addr1, stack.AddressProperties{}); err != nil {
    69  		t.Fatalf("host1Stack.AddProtocolAddress(%d, %+v, {}): %s", host1NICID, utils.Ipv4Addr1, err)
    70  	}
    71  	if err := host2Stack.AddProtocolAddress(host2NICID, utils.Ipv4Addr2, stack.AddressProperties{}); err != nil {
    72  		t.Fatalf("host2Stack.AddProtocolAddress(%d, %+v, {}): %s", host2NICID, utils.Ipv4Addr2, err)
    73  	}
    74  	if err := host1Stack.AddProtocolAddress(host1NICID, utils.Ipv6Addr1, stack.AddressProperties{}); err != nil {
    75  		t.Fatalf("host1Stack.AddProtocolAddress(%d, %+v, {}): %s", host1NICID, utils.Ipv6Addr1, err)
    76  	}
    77  	if err := host2Stack.AddProtocolAddress(host2NICID, utils.Ipv6Addr2, stack.AddressProperties{}); err != nil {
    78  		t.Fatalf("host2Stack.AddProtocolAddress(%d, %+v, {}): %s", host2NICID, utils.Ipv6Addr2, err)
    79  	}
    80  
    81  	host1Stack.SetRouteTable([]tcpip.Route{
    82  		{
    83  			Destination: utils.Ipv4Addr1.AddressWithPrefix.Subnet(),
    84  			NIC:         host1NICID,
    85  		},
    86  		{
    87  			Destination: utils.Ipv6Addr1.AddressWithPrefix.Subnet(),
    88  			NIC:         host1NICID,
    89  		},
    90  	})
    91  	host2Stack.SetRouteTable([]tcpip.Route{
    92  		{
    93  			Destination: utils.Ipv4Addr2.AddressWithPrefix.Subnet(),
    94  			NIC:         host2NICID,
    95  		},
    96  		{
    97  			Destination: utils.Ipv6Addr2.AddressWithPrefix.Subnet(),
    98  			NIC:         host2NICID,
    99  		},
   100  	})
   101  
   102  	return host1Stack, host2Stack
   103  }
   104  
   105  // TestPing tests that two hosts can ping each other when link resolution is
   106  // enabled.
   107  func TestPing(t *testing.T) {
   108  	const (
   109  		host1NICID = 1
   110  		host2NICID = 4
   111  
   112  		// icmpDataOffset is the offset to the data in both ICMPv4 and ICMPv6 echo
   113  		// request/reply packets.
   114  		icmpDataOffset = 8
   115  	)
   116  
   117  	tests := []struct {
   118  		name       string
   119  		transProto tcpip.TransportProtocolNumber
   120  		netProto   tcpip.NetworkProtocolNumber
   121  		remoteAddr tcpip.Address
   122  		icmpBuf    func(*testing.T) []byte
   123  	}{
   124  		{
   125  			name:       "IPv4 Ping",
   126  			transProto: icmp.ProtocolNumber4,
   127  			netProto:   ipv4.ProtocolNumber,
   128  			remoteAddr: utils.Ipv4Addr2.AddressWithPrefix.Address,
   129  			icmpBuf: func(t *testing.T) []byte {
   130  				data := [8]byte{1, 2, 3, 4, 5, 6, 7, 8}
   131  				hdr := header.ICMPv4(make([]byte, header.ICMPv4MinimumSize+len(data)))
   132  				hdr.SetType(header.ICMPv4Echo)
   133  				if n := copy(hdr.Payload(), data[:]); n != len(data) {
   134  					t.Fatalf("copied %d bytes but expected to copy %d bytes", n, len(data))
   135  				}
   136  				return hdr
   137  			},
   138  		},
   139  		{
   140  			name:       "IPv6 Ping",
   141  			transProto: icmp.ProtocolNumber6,
   142  			netProto:   ipv6.ProtocolNumber,
   143  			remoteAddr: utils.Ipv6Addr2.AddressWithPrefix.Address,
   144  			icmpBuf: func(t *testing.T) []byte {
   145  				data := [8]byte{1, 2, 3, 4, 5, 6, 7, 8}
   146  				hdr := header.ICMPv6(make([]byte, header.ICMPv6MinimumSize+len(data)))
   147  				hdr.SetType(header.ICMPv6EchoRequest)
   148  				if n := copy(hdr.Payload(), data[:]); n != len(data) {
   149  					t.Fatalf("copied %d bytes but expected to copy %d bytes", n, len(data))
   150  				}
   151  				return hdr
   152  			},
   153  		},
   154  	}
   155  
   156  	for _, test := range tests {
   157  		t.Run(test.name, func(t *testing.T) {
   158  			stackOpts := stack.Options{
   159  				NetworkProtocols:   []stack.NetworkProtocolFactory{arp.NewProtocol, ipv4.NewProtocol, ipv6.NewProtocol},
   160  				TransportProtocols: []stack.TransportProtocolFactory{icmp.NewProtocol4, icmp.NewProtocol6},
   161  			}
   162  
   163  			host1Stack, host2Stack := setupStack(t, stackOpts, host1NICID, host2NICID)
   164  			defer host1Stack.Destroy()
   165  			defer host2Stack.Destroy()
   166  
   167  			var wq waiter.Queue
   168  			we, waiterCH := waiter.NewChannelEntry(waiter.ReadableEvents)
   169  			wq.EventRegister(&we)
   170  			ep, err := host1Stack.NewEndpoint(test.transProto, test.netProto, &wq)
   171  			if err != nil {
   172  				t.Fatalf("host1Stack.NewEndpoint(%d, %d, _): %s", test.transProto, test.netProto, err)
   173  			}
   174  			defer ep.Close()
   175  
   176  			icmpBuf := test.icmpBuf(t)
   177  			var r bytes.Reader
   178  			r.Reset(icmpBuf)
   179  			wOpts := tcpip.WriteOptions{To: &tcpip.FullAddress{Addr: test.remoteAddr}}
   180  			if n, err := ep.Write(&r, wOpts); err != nil {
   181  				t.Fatalf("ep.Write(_, _): %s", err)
   182  			} else if want := int64(len(icmpBuf)); n != want {
   183  				t.Fatalf("got ep.Write(_, _) = (%d, _), want = (%d, _)", n, want)
   184  			}
   185  
   186  			// Wait for the endpoint to be readable.
   187  			<-waiterCH
   188  
   189  			var buf bytes.Buffer
   190  			opts := tcpip.ReadOptions{NeedRemoteAddr: true}
   191  			res, err := ep.Read(&buf, opts)
   192  			if err != nil {
   193  				t.Fatalf("ep.Read(_, %d, %#v): %s", len(icmpBuf), opts, err)
   194  			}
   195  			if diff := cmp.Diff(tcpip.ReadResult{
   196  				Count:      buf.Len(),
   197  				Total:      buf.Len(),
   198  				RemoteAddr: tcpip.FullAddress{Addr: test.remoteAddr},
   199  			}, res, checker.IgnoreCmpPath(
   200  				"ControlMessages",
   201  				"RemoteAddr.NIC",
   202  				"RemoteAddr.Port",
   203  			)); diff != "" {
   204  				t.Errorf("ep.Read: unexpected result (-want +got):\n%s", diff)
   205  			}
   206  			if diff := cmp.Diff(buf.Bytes()[icmpDataOffset:], icmpBuf[icmpDataOffset:]); diff != "" {
   207  				t.Errorf("received data mismatch (-want +got):\n%s", diff)
   208  			}
   209  		})
   210  	}
   211  }
   212  
   213  type transportError struct {
   214  	origin tcpip.SockErrOrigin
   215  	typ    uint8
   216  	code   uint8
   217  	info   uint32
   218  	kind   stack.TransportErrorKind
   219  }
   220  
   221  func TestTCPLinkResolutionFailure(t *testing.T) {
   222  	const (
   223  		host1NICID = 1
   224  		host2NICID = 4
   225  	)
   226  
   227  	tests := []struct {
   228  		name             string
   229  		netProto         tcpip.NetworkProtocolNumber
   230  		remoteAddr       tcpip.Address
   231  		expectedWriteErr tcpip.Error
   232  		sockError        tcpip.SockError
   233  		transErr         transportError
   234  	}{
   235  		{
   236  			name:             "IPv4 with resolvable remote",
   237  			netProto:         ipv4.ProtocolNumber,
   238  			remoteAddr:       utils.Ipv4Addr2.AddressWithPrefix.Address,
   239  			expectedWriteErr: nil,
   240  		},
   241  		{
   242  			name:             "IPv6 with resolvable remote",
   243  			netProto:         ipv6.ProtocolNumber,
   244  			remoteAddr:       utils.Ipv6Addr2.AddressWithPrefix.Address,
   245  			expectedWriteErr: nil,
   246  		},
   247  		{
   248  			name:             "IPv4 without resolvable remote",
   249  			netProto:         ipv4.ProtocolNumber,
   250  			remoteAddr:       utils.Ipv4Addr3.AddressWithPrefix.Address,
   251  			expectedWriteErr: &tcpip.ErrHostUnreachable{},
   252  			sockError: tcpip.SockError{
   253  				Err: &tcpip.ErrHostUnreachable{},
   254  				Dst: tcpip.FullAddress{
   255  					NIC:  host1NICID,
   256  					Addr: utils.Ipv4Addr3.AddressWithPrefix.Address,
   257  					Port: 1234,
   258  				},
   259  				Offender: tcpip.FullAddress{
   260  					NIC:  host1NICID,
   261  					Addr: utils.Ipv4Addr1.AddressWithPrefix.Address,
   262  				},
   263  				NetProto: ipv4.ProtocolNumber,
   264  			},
   265  			transErr: transportError{
   266  				origin: tcpip.SockExtErrorOriginICMP,
   267  				typ:    uint8(header.ICMPv4DstUnreachable),
   268  				code:   uint8(header.ICMPv4HostUnreachable),
   269  				kind:   stack.DestinationHostUnreachableTransportError,
   270  			},
   271  		},
   272  		{
   273  			name:             "IPv6 without resolvable remote",
   274  			netProto:         ipv6.ProtocolNumber,
   275  			remoteAddr:       utils.Ipv6Addr3.AddressWithPrefix.Address,
   276  			expectedWriteErr: &tcpip.ErrHostUnreachable{},
   277  			sockError: tcpip.SockError{
   278  				Err: &tcpip.ErrHostUnreachable{},
   279  				Dst: tcpip.FullAddress{
   280  					NIC:  host1NICID,
   281  					Addr: utils.Ipv6Addr3.AddressWithPrefix.Address,
   282  					Port: 1234,
   283  				},
   284  				Offender: tcpip.FullAddress{
   285  					NIC:  host1NICID,
   286  					Addr: utils.Ipv6Addr1.AddressWithPrefix.Address,
   287  				},
   288  				NetProto: ipv6.ProtocolNumber,
   289  			},
   290  			transErr: transportError{
   291  				origin: tcpip.SockExtErrorOriginICMP6,
   292  				typ:    uint8(header.ICMPv6DstUnreachable),
   293  				code:   uint8(header.ICMPv6AddressUnreachable),
   294  				kind:   stack.DestinationHostUnreachableTransportError,
   295  			},
   296  		},
   297  	}
   298  
   299  	for _, test := range tests {
   300  		t.Run(test.name, func(t *testing.T) {
   301  			clock := faketime.NewManualClock()
   302  			stackOpts := stack.Options{
   303  				NetworkProtocols:   []stack.NetworkProtocolFactory{arp.NewProtocol, ipv4.NewProtocol, ipv6.NewProtocol},
   304  				TransportProtocols: []stack.TransportProtocolFactory{tcp.NewProtocol},
   305  				Clock:              clock,
   306  			}
   307  
   308  			host1Stack, host2Stack := setupStack(t, stackOpts, host1NICID, host2NICID)
   309  			defer host1Stack.Destroy()
   310  			defer host2Stack.Destroy()
   311  
   312  			var listenerWQ waiter.Queue
   313  			listenerEP, err := host2Stack.NewEndpoint(tcp.ProtocolNumber, test.netProto, &listenerWQ)
   314  			if err != nil {
   315  				t.Fatalf("host2Stack.NewEndpoint(%d, %d, _): %s", tcp.ProtocolNumber, test.netProto, err)
   316  			}
   317  			defer listenerEP.Close()
   318  
   319  			listenerAddr := tcpip.FullAddress{Port: 1234}
   320  			if err := listenerEP.Bind(listenerAddr); err != nil {
   321  				t.Fatalf("listenerEP.Bind(%#v): %s", listenerAddr, err)
   322  			}
   323  
   324  			if err := listenerEP.Listen(1); err != nil {
   325  				t.Fatalf("listenerEP.Listen(1): %s", err)
   326  			}
   327  
   328  			var clientWQ waiter.Queue
   329  			we, ch := waiter.NewChannelEntry(waiter.WritableEvents | waiter.EventErr)
   330  			clientWQ.EventRegister(&we)
   331  			clientEP, err := host1Stack.NewEndpoint(tcp.ProtocolNumber, test.netProto, &clientWQ)
   332  			if err != nil {
   333  				t.Fatalf("host1Stack.NewEndpoint(%d, %d, _): %s", tcp.ProtocolNumber, test.netProto, err)
   334  			}
   335  			defer clientEP.Close()
   336  
   337  			sockOpts := clientEP.SocketOptions()
   338  			sockOpts.SetIPv4RecvError(true)
   339  			sockOpts.SetIPv6RecvError(true)
   340  
   341  			remoteAddr := listenerAddr
   342  			remoteAddr.Addr = test.remoteAddr
   343  			{
   344  				err := clientEP.Connect(remoteAddr)
   345  				if _, ok := err.(*tcpip.ErrConnectStarted); !ok {
   346  					t.Fatalf("got clientEP.Connect(%#v) = %s, want = %s", remoteAddr, err, &tcpip.ErrConnectStarted{})
   347  				}
   348  			}
   349  
   350  			// Wait for an error due to link resolution failing, or the endpoint to be
   351  			// writable.
   352  			if test.expectedWriteErr != nil {
   353  				nudConfigs, err := host1Stack.NUDConfigurations(host1NICID, test.netProto)
   354  				if err != nil {
   355  					t.Fatalf("host1Stack.NUDConfigurations(%d, %d): %s", host1NICID, test.netProto, err)
   356  				}
   357  				clock.Advance(time.Duration(nudConfigs.MaxMulticastProbes) * nudConfigs.RetransmitTimer)
   358  			} else {
   359  				clock.RunImmediatelyScheduledJobs()
   360  			}
   361  			<-ch
   362  
   363  			{
   364  				var r bytes.Reader
   365  				r.Reset([]byte{0})
   366  				var wOpts tcpip.WriteOptions
   367  				_, err := clientEP.Write(&r, wOpts)
   368  				if diff := cmp.Diff(test.expectedWriteErr, err); diff != "" {
   369  					t.Errorf("unexpected error from clientEP.Write(_, %#v), (-want, +got):\n%s", wOpts, diff)
   370  				}
   371  			}
   372  
   373  			if test.expectedWriteErr == nil {
   374  				return
   375  			}
   376  
   377  			sockErr := sockOpts.DequeueErr()
   378  			if sockErr == nil {
   379  				t.Fatalf("got sockOpts.DequeueErr() = nil, want = non-nil")
   380  			}
   381  			defer sockErr.Payload.Release()
   382  
   383  			sockErrCmpOpts := []cmp.Option{
   384  				cmpopts.IgnoreUnexported(tcpip.SockError{}),
   385  				cmp.Comparer(func(a, b tcpip.Error) bool {
   386  					// tcpip.Error holds an unexported field but the errors netstack uses
   387  					// are pre defined so we can simply compare pointers.
   388  					return a == b
   389  				}),
   390  				checker.IgnoreCmpPath(
   391  					// Ignore the payload since we do not know the TCP seq/ack numbers.
   392  					"Payload",
   393  					// Ignore the cause since we will compare its properties separately
   394  					// since the concrete type of the cause is unknown.
   395  					"Cause",
   396  				),
   397  			}
   398  
   399  			if addr, err := clientEP.GetLocalAddress(); err != nil {
   400  				t.Fatalf("clientEP.GetLocalAddress(): %s", err)
   401  			} else {
   402  				test.sockError.Offender.Port = addr.Port
   403  			}
   404  			if diff := cmp.Diff(&test.sockError, sockErr, sockErrCmpOpts...); diff != "" {
   405  				t.Errorf("socket error mismatch (-want +got):\n%s", diff)
   406  			}
   407  
   408  			transErr, ok := sockErr.Cause.(stack.TransportError)
   409  			if !ok {
   410  				t.Fatalf("socket error cause is not a transport error; cause = %#v", sockErr.Cause)
   411  			}
   412  			if diff := cmp.Diff(
   413  				test.transErr,
   414  				transportError{
   415  					origin: transErr.Origin(),
   416  					typ:    transErr.Type(),
   417  					code:   transErr.Code(),
   418  					info:   transErr.Info(),
   419  					kind:   transErr.Kind(),
   420  				},
   421  				cmp.AllowUnexported(transportError{}),
   422  			); diff != "" {
   423  				t.Errorf("socket error mismatch (-want +got):\n%s", diff)
   424  			}
   425  		})
   426  	}
   427  }
   428  
   429  func TestForwardingWithLinkResolutionFailure(t *testing.T) {
   430  	const (
   431  		incomingNICID                     = 1
   432  		outgoingNICID                     = 2
   433  		ttl                               = 2
   434  		expectedHostUnreachableErrorCount = 1
   435  	)
   436  	outgoingLinkAddr := tcptestutil.MustParseLink("02:03:03:04:05:06")
   437  
   438  	rxICMPv4EchoRequest := func(e *channel.Endpoint, src, dst tcpip.Address) {
   439  		utils.RxICMPv4EchoRequest(e, src, dst, ttl)
   440  	}
   441  
   442  	rxICMPv6EchoRequest := func(e *channel.Endpoint, src, dst tcpip.Address) {
   443  		utils.RxICMPv6EchoRequest(e, src, dst, ttl)
   444  	}
   445  
   446  	arpChecker := func(t *testing.T, request *stack.PacketBuffer, src, dst tcpip.Address) {
   447  		if request.NetworkProtocolNumber != arp.ProtocolNumber {
   448  			t.Errorf("got request.NetworkProtocolNumber = %d, want = %d", request.NetworkProtocolNumber, arp.ProtocolNumber)
   449  		}
   450  		if request.EgressRoute.RemoteLinkAddress != header.EthernetBroadcastAddress {
   451  			t.Errorf("got request.EgressRoute.RemoteLinkAddress = %s, want = %s", request.EgressRoute.RemoteLinkAddress, header.EthernetBroadcastAddress)
   452  		}
   453  		rep := header.ARP(request.NetworkHeader().Slice())
   454  		if got := rep.Op(); got != header.ARPRequest {
   455  			t.Errorf("got Op() = %d, want = %d", got, header.ARPRequest)
   456  		}
   457  		if got := tcpip.LinkAddress(rep.HardwareAddressSender()); got != outgoingLinkAddr {
   458  			t.Errorf("got HardwareAddressSender = %s, want = %s", got, outgoingLinkAddr)
   459  		}
   460  		if got := tcpip.AddrFromSlice(rep.ProtocolAddressSender()); got != src {
   461  			t.Errorf("got ProtocolAddressSender = %s, want = %s", got, src)
   462  		}
   463  		if got := tcpip.AddrFromSlice(rep.ProtocolAddressTarget()); got != dst {
   464  			t.Errorf("got ProtocolAddressTarget = %s, want = %s", got, dst)
   465  		}
   466  	}
   467  
   468  	ndpChecker := func(t *testing.T, request *stack.PacketBuffer, src, dst tcpip.Address) {
   469  		if request.NetworkProtocolNumber != header.IPv6ProtocolNumber {
   470  			t.Fatalf("got Proto = %d, want = %d", request.NetworkProtocolNumber, header.IPv6ProtocolNumber)
   471  		}
   472  
   473  		snmc := header.SolicitedNodeAddr(dst)
   474  		if want := header.EthernetAddressFromMulticastIPv6Address(snmc); request.EgressRoute.RemoteLinkAddress != want {
   475  			t.Errorf("got remote link address = %s, want = %s", request.EgressRoute.RemoteLinkAddress, want)
   476  		}
   477  
   478  		payload := stack.PayloadSince(request.NetworkHeader())
   479  		defer payload.Release()
   480  		checker.IPv6(t, payload,
   481  			checker.SrcAddr(src),
   482  			checker.DstAddr(snmc),
   483  			checker.TTL(header.NDPHopLimit),
   484  			checker.NDPNS(
   485  				checker.NDPNSTargetAddress(dst),
   486  			))
   487  	}
   488  
   489  	icmpv4Checker := func(t *testing.T, v *buffer.View, src, dst tcpip.Address) {
   490  		checker.IPv4(t, v,
   491  			checker.SrcAddr(src),
   492  			checker.DstAddr(dst),
   493  			checker.TTL(ipv4.DefaultTTL),
   494  			checker.ICMPv4(
   495  				checker.ICMPv4Checksum(),
   496  				checker.ICMPv4Type(header.ICMPv4DstUnreachable),
   497  				checker.ICMPv4Code(header.ICMPv4HostUnreachable),
   498  			),
   499  		)
   500  	}
   501  
   502  	icmpv6Checker := func(t *testing.T, v *buffer.View, src, dst tcpip.Address) {
   503  		checker.IPv6(t, v,
   504  			checker.SrcAddr(src),
   505  			checker.DstAddr(dst),
   506  			checker.TTL(ipv6.DefaultTTL),
   507  			checker.ICMPv6(
   508  				checker.ICMPv6Type(header.ICMPv6DstUnreachable),
   509  				checker.ICMPv6Code(header.ICMPv6AddressUnreachable),
   510  			),
   511  		)
   512  	}
   513  
   514  	tests := []struct {
   515  		name                         string
   516  		networkProtocolFactory       []stack.NetworkProtocolFactory
   517  		networkProtocolNumber        tcpip.NetworkProtocolNumber
   518  		sourceAddr                   tcpip.Address
   519  		destAddr                     tcpip.Address
   520  		incomingAddr                 tcpip.AddressWithPrefix
   521  		outgoingAddr                 tcpip.AddressWithPrefix
   522  		transportProtocol            func(*stack.Stack) stack.TransportProtocol
   523  		rx                           func(*channel.Endpoint, tcpip.Address, tcpip.Address)
   524  		linkResolutionRequestChecker func(*testing.T, *stack.PacketBuffer, tcpip.Address, tcpip.Address)
   525  		icmpReplyChecker             func(*testing.T, *buffer.View, tcpip.Address, tcpip.Address)
   526  		mtu                          uint32
   527  	}{
   528  		{
   529  			name:                   "IPv4 Host unreachable",
   530  			networkProtocolFactory: []stack.NetworkProtocolFactory{arp.NewProtocol, ipv4.NewProtocol},
   531  			networkProtocolNumber:  header.IPv4ProtocolNumber,
   532  			sourceAddr:             tcptestutil.MustParse4("10.0.0.2"),
   533  			destAddr:               tcptestutil.MustParse4("11.0.0.2"),
   534  			incomingAddr: tcpip.AddressWithPrefix{
   535  				Address:   tcpip.AddrFromSlice(net.ParseIP("10.0.0.1").To4()),
   536  				PrefixLen: 8,
   537  			},
   538  			outgoingAddr: tcpip.AddressWithPrefix{
   539  				Address:   tcpip.AddrFromSlice(net.ParseIP("11.0.0.1").To4()),
   540  				PrefixLen: 8,
   541  			},
   542  			transportProtocol:            icmp.NewProtocol4,
   543  			linkResolutionRequestChecker: arpChecker,
   544  			icmpReplyChecker:             icmpv4Checker,
   545  			rx:                           rxICMPv4EchoRequest,
   546  			mtu:                          ipv4.MaxTotalSize,
   547  		},
   548  		{
   549  			name:                   "IPv6 Host unreachable",
   550  			networkProtocolFactory: []stack.NetworkProtocolFactory{ipv6.NewProtocol},
   551  			networkProtocolNumber:  header.IPv6ProtocolNumber,
   552  			sourceAddr:             tcptestutil.MustParse6("10::2"),
   553  			destAddr:               tcptestutil.MustParse6("11::2"),
   554  			incomingAddr: tcpip.AddressWithPrefix{
   555  				Address:   tcpip.AddrFromSlice(net.ParseIP("10::1").To16()),
   556  				PrefixLen: 64,
   557  			},
   558  			outgoingAddr: tcpip.AddressWithPrefix{
   559  				Address:   tcpip.AddrFromSlice(net.ParseIP("11::1").To16()),
   560  				PrefixLen: 64,
   561  			},
   562  			transportProtocol:            icmp.NewProtocol6,
   563  			linkResolutionRequestChecker: ndpChecker,
   564  			icmpReplyChecker:             icmpv6Checker,
   565  			rx:                           rxICMPv6EchoRequest,
   566  			mtu:                          header.IPv6MinimumMTU,
   567  		},
   568  	}
   569  	for _, test := range tests {
   570  		t.Run(test.name, func(t *testing.T) {
   571  			clock := faketime.NewManualClock()
   572  
   573  			s := stack.New(stack.Options{
   574  				NetworkProtocols:   test.networkProtocolFactory,
   575  				TransportProtocols: []stack.TransportProtocolFactory{test.transportProtocol},
   576  				Clock:              clock,
   577  			})
   578  			defer s.Destroy()
   579  
   580  			// Set up endpoint through which we will receive packets.
   581  			incomingEndpoint := channel.New(1, test.mtu, "")
   582  			if err := s.CreateNIC(incomingNICID, incomingEndpoint); err != nil {
   583  				t.Fatalf("CreateNIC(%d, _): %s", incomingNICID, err)
   584  			}
   585  			incomingProtoAddr := tcpip.ProtocolAddress{
   586  				Protocol:          test.networkProtocolNumber,
   587  				AddressWithPrefix: test.incomingAddr,
   588  			}
   589  			if err := s.AddProtocolAddress(incomingNICID, incomingProtoAddr, stack.AddressProperties{}); err != nil {
   590  				t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", incomingNICID, incomingProtoAddr, err)
   591  			}
   592  
   593  			// Set up endpoint through which we will attempt to forward packets.
   594  			outgoingEndpoint := channel.New(1, test.mtu, outgoingLinkAddr)
   595  			outgoingEndpoint.LinkEPCapabilities |= stack.CapabilityResolutionRequired
   596  			if err := s.CreateNIC(outgoingNICID, outgoingEndpoint); err != nil {
   597  				t.Fatalf("CreateNIC(%d, _): %s", outgoingNICID, err)
   598  			}
   599  			outgoingProtoAddr := tcpip.ProtocolAddress{
   600  				Protocol:          test.networkProtocolNumber,
   601  				AddressWithPrefix: test.outgoingAddr,
   602  			}
   603  			if err := s.AddProtocolAddress(outgoingNICID, outgoingProtoAddr, stack.AddressProperties{}); err != nil {
   604  				t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", outgoingNICID, outgoingProtoAddr, err)
   605  			}
   606  
   607  			s.SetRouteTable([]tcpip.Route{
   608  				{
   609  					Destination: test.incomingAddr.Subnet(),
   610  					NIC:         incomingNICID,
   611  				},
   612  				{
   613  					Destination: test.outgoingAddr.Subnet(),
   614  					NIC:         outgoingNICID,
   615  				},
   616  			})
   617  
   618  			if err := s.SetForwardingDefaultAndAllNICs(test.networkProtocolNumber, true); err != nil {
   619  				t.Fatalf("SetForwardingDefaultAndAllNICs(%d, true): %s", test.networkProtocolNumber, err)
   620  			}
   621  
   622  			test.rx(incomingEndpoint, test.sourceAddr, test.destAddr)
   623  
   624  			nudConfigs, err := s.NUDConfigurations(outgoingNICID, test.networkProtocolNumber)
   625  			if err != nil {
   626  				t.Fatalf("s.NUDConfigurations(%d, %d): %s", outgoingNICID, test.networkProtocolNumber, err)
   627  			}
   628  			// Trigger the first packet on the endpoint.
   629  			clock.RunImmediatelyScheduledJobs()
   630  
   631  			for i := 0; i < int(nudConfigs.MaxMulticastProbes); i++ {
   632  				request := outgoingEndpoint.Read()
   633  				if request == nil {
   634  					t.Fatal("expected ARP packet through outgoing NIC")
   635  				}
   636  
   637  				test.linkResolutionRequestChecker(t, request, test.outgoingAddr.Address, test.destAddr)
   638  				request.DecRef()
   639  
   640  				// Advance the clock the span of one request timeout.
   641  				clock.Advance(nudConfigs.RetransmitTimer)
   642  			}
   643  
   644  			// Next, we make a blocking read to retrieve the error packet. This is
   645  			// necessary because outgoing packets are dequeued asynchronously when
   646  			// link resolution fails, and this dequeue is what triggers the ICMP
   647  			// error.
   648  			reply := incomingEndpoint.Read()
   649  			if reply == nil {
   650  				t.Fatal("expected ICMP packet through incoming NIC")
   651  			}
   652  
   653  			payload := stack.PayloadSince(reply.NetworkHeader())
   654  			defer payload.Release()
   655  			test.icmpReplyChecker(t, payload, test.incomingAddr.Address, test.sourceAddr)
   656  			reply.DecRef()
   657  
   658  			// Since link resolution failed, we don't expect the packet to be
   659  			// forwarded.
   660  			forwardedPacket := outgoingEndpoint.Read()
   661  			if forwardedPacket != nil {
   662  				t.Fatalf("expected no ICMP Echo packet through outgoing NIC, instead found: %#v", forwardedPacket)
   663  			}
   664  
   665  			if got, want := s.Stats().IP.Forwarding.HostUnreachable.Value(), expectedHostUnreachableErrorCount; int(got) != want {
   666  				t.Errorf("got rt.Stats().IP.Forwarding.HostUnreachable.Value() = %d, want = %d", got, want)
   667  			}
   668  		})
   669  	}
   670  }
   671  
   672  func TestGetLinkAddress(t *testing.T) {
   673  	const (
   674  		host1NICID = 1
   675  		host2NICID = 4
   676  	)
   677  
   678  	tests := []struct {
   679  		name                  string
   680  		netProto              tcpip.NetworkProtocolNumber
   681  		remoteAddr, localAddr tcpip.Address
   682  		expectedErr           tcpip.Error
   683  	}{
   684  		{
   685  			name:        "IPv4 resolvable",
   686  			netProto:    ipv4.ProtocolNumber,
   687  			remoteAddr:  utils.Ipv4Addr2.AddressWithPrefix.Address,
   688  			expectedErr: nil,
   689  		},
   690  		{
   691  			name:        "IPv6 resolvable",
   692  			netProto:    ipv6.ProtocolNumber,
   693  			remoteAddr:  utils.Ipv6Addr2.AddressWithPrefix.Address,
   694  			expectedErr: nil,
   695  		},
   696  		{
   697  			name:        "IPv4 not resolvable",
   698  			netProto:    ipv4.ProtocolNumber,
   699  			remoteAddr:  utils.Ipv4Addr3.AddressWithPrefix.Address,
   700  			expectedErr: &tcpip.ErrTimeout{},
   701  		},
   702  		{
   703  			name:        "IPv6 not resolvable",
   704  			netProto:    ipv6.ProtocolNumber,
   705  			remoteAddr:  utils.Ipv6Addr3.AddressWithPrefix.Address,
   706  			expectedErr: &tcpip.ErrTimeout{},
   707  		},
   708  		{
   709  			name:        "IPv4 bad local address",
   710  			netProto:    ipv4.ProtocolNumber,
   711  			remoteAddr:  utils.Ipv4Addr2.AddressWithPrefix.Address,
   712  			localAddr:   utils.Ipv4Addr2.AddressWithPrefix.Address,
   713  			expectedErr: &tcpip.ErrBadLocalAddress{},
   714  		},
   715  		{
   716  			name:        "IPv6 bad local address",
   717  			netProto:    ipv6.ProtocolNumber,
   718  			remoteAddr:  utils.Ipv6Addr2.AddressWithPrefix.Address,
   719  			localAddr:   utils.Ipv6Addr2.AddressWithPrefix.Address,
   720  			expectedErr: &tcpip.ErrBadLocalAddress{},
   721  		},
   722  	}
   723  
   724  	for _, test := range tests {
   725  		t.Run(test.name, func(t *testing.T) {
   726  			clock := faketime.NewManualClock()
   727  			stackOpts := stack.Options{
   728  				NetworkProtocols: []stack.NetworkProtocolFactory{arp.NewProtocol, ipv4.NewProtocol, ipv6.NewProtocol},
   729  				Clock:            clock,
   730  			}
   731  
   732  			host1Stack, host2Stack := setupStack(t, stackOpts, host1NICID, host2NICID)
   733  			defer host1Stack.Destroy()
   734  			defer host2Stack.Destroy()
   735  
   736  			ch := make(chan stack.LinkResolutionResult, 1)
   737  			err := host1Stack.GetLinkAddress(host1NICID, test.remoteAddr, test.localAddr, test.netProto, func(r stack.LinkResolutionResult) {
   738  				ch <- r
   739  			})
   740  			if _, ok := err.(*tcpip.ErrWouldBlock); !ok {
   741  				t.Fatalf("got host1Stack.GetLinkAddress(%d, %s, '', %d, _) = %s, want = %s", host1NICID, test.remoteAddr, test.netProto, err, &tcpip.ErrWouldBlock{})
   742  			}
   743  			wantRes := stack.LinkResolutionResult{Err: test.expectedErr}
   744  			if test.expectedErr == nil {
   745  				wantRes.LinkAddress = utils.LinkAddr2
   746  			}
   747  
   748  			nudConfigs, err := host1Stack.NUDConfigurations(host1NICID, test.netProto)
   749  			if err != nil {
   750  				t.Fatalf("host1Stack.NUDConfigurations(%d, %d): %s", host1NICID, test.netProto, err)
   751  			}
   752  
   753  			clock.Advance(time.Duration(nudConfigs.MaxMulticastProbes) * nudConfigs.RetransmitTimer)
   754  			select {
   755  			case got := <-ch:
   756  				if diff := cmp.Diff(wantRes, got); diff != "" {
   757  					t.Fatalf("link resolution result mismatch (-want +got):\n%s", diff)
   758  				}
   759  			default:
   760  				t.Fatal("event didn't arrive")
   761  			}
   762  		})
   763  	}
   764  }
   765  
   766  func TestRouteResolvedFields(t *testing.T) {
   767  	const (
   768  		host1NICID = 1
   769  		host2NICID = 4
   770  	)
   771  
   772  	tests := []struct {
   773  		name                  string
   774  		netProto              tcpip.NetworkProtocolNumber
   775  		localAddr             tcpip.Address
   776  		remoteAddr            tcpip.Address
   777  		immediatelyResolvable bool
   778  		expectedErr           tcpip.Error
   779  		expectedLinkAddr      tcpip.LinkAddress
   780  	}{
   781  		{
   782  			name:                  "IPv4 immediately resolvable",
   783  			netProto:              ipv4.ProtocolNumber,
   784  			localAddr:             utils.Ipv4Addr1.AddressWithPrefix.Address,
   785  			remoteAddr:            header.IPv4AllSystems,
   786  			immediatelyResolvable: true,
   787  			expectedErr:           nil,
   788  			expectedLinkAddr:      header.EthernetAddressFromMulticastIPv4Address(header.IPv4AllSystems),
   789  		},
   790  		{
   791  			name:                  "IPv6 immediately resolvable",
   792  			netProto:              ipv6.ProtocolNumber,
   793  			localAddr:             utils.Ipv6Addr1.AddressWithPrefix.Address,
   794  			remoteAddr:            header.IPv6AllNodesMulticastAddress,
   795  			immediatelyResolvable: true,
   796  			expectedErr:           nil,
   797  			expectedLinkAddr:      header.EthernetAddressFromMulticastIPv6Address(header.IPv6AllNodesMulticastAddress),
   798  		},
   799  		{
   800  			name:                  "IPv4 resolvable",
   801  			netProto:              ipv4.ProtocolNumber,
   802  			localAddr:             utils.Ipv4Addr1.AddressWithPrefix.Address,
   803  			remoteAddr:            utils.Ipv4Addr2.AddressWithPrefix.Address,
   804  			immediatelyResolvable: false,
   805  			expectedErr:           nil,
   806  			expectedLinkAddr:      utils.LinkAddr2,
   807  		},
   808  		{
   809  			name:                  "IPv6 resolvable",
   810  			netProto:              ipv6.ProtocolNumber,
   811  			localAddr:             utils.Ipv6Addr1.AddressWithPrefix.Address,
   812  			remoteAddr:            utils.Ipv6Addr2.AddressWithPrefix.Address,
   813  			immediatelyResolvable: false,
   814  			expectedErr:           nil,
   815  			expectedLinkAddr:      utils.LinkAddr2,
   816  		},
   817  		{
   818  			name:                  "IPv4 not resolvable",
   819  			netProto:              ipv4.ProtocolNumber,
   820  			localAddr:             utils.Ipv4Addr1.AddressWithPrefix.Address,
   821  			remoteAddr:            utils.Ipv4Addr3.AddressWithPrefix.Address,
   822  			immediatelyResolvable: false,
   823  			expectedErr:           &tcpip.ErrTimeout{},
   824  		},
   825  		{
   826  			name:                  "IPv6 not resolvable",
   827  			netProto:              ipv6.ProtocolNumber,
   828  			localAddr:             utils.Ipv6Addr1.AddressWithPrefix.Address,
   829  			remoteAddr:            utils.Ipv6Addr3.AddressWithPrefix.Address,
   830  			immediatelyResolvable: false,
   831  			expectedErr:           &tcpip.ErrTimeout{},
   832  		},
   833  	}
   834  
   835  	for _, test := range tests {
   836  		t.Run(test.name, func(t *testing.T) {
   837  			clock := faketime.NewManualClock()
   838  			stackOpts := stack.Options{
   839  				NetworkProtocols: []stack.NetworkProtocolFactory{arp.NewProtocol, ipv4.NewProtocol, ipv6.NewProtocol},
   840  				Clock:            clock,
   841  			}
   842  
   843  			host1Stack, host2Stack := setupStack(t, stackOpts, host1NICID, host2NICID)
   844  			defer host1Stack.Destroy()
   845  			defer host2Stack.Destroy()
   846  			r, err := host1Stack.FindRoute(host1NICID, test.localAddr, test.remoteAddr, test.netProto, false /* multicastLoop */)
   847  			if err != nil {
   848  				t.Fatalf("host1Stack.FindRoute(%d, %s, %s, %d, false): %s", host1NICID, test.localAddr, test.remoteAddr, test.netProto, err)
   849  			}
   850  			defer r.Release()
   851  
   852  			var wantRouteInfo stack.RouteInfo
   853  			wantRouteInfo.LocalLinkAddress = utils.LinkAddr1
   854  			wantRouteInfo.LocalAddress = test.localAddr
   855  			wantRouteInfo.RemoteAddress = test.remoteAddr
   856  			wantRouteInfo.NetProto = test.netProto
   857  			wantRouteInfo.Loop = stack.PacketOut
   858  			wantRouteInfo.RemoteLinkAddress = test.expectedLinkAddr
   859  
   860  			ch := make(chan stack.ResolvedFieldsResult, 1)
   861  
   862  			if !test.immediatelyResolvable {
   863  				wantUnresolvedRouteInfo := wantRouteInfo
   864  				wantUnresolvedRouteInfo.RemoteLinkAddress = ""
   865  
   866  				err := r.ResolvedFields(func(r stack.ResolvedFieldsResult) {
   867  					ch <- r
   868  				})
   869  				if _, ok := err.(*tcpip.ErrWouldBlock); !ok {
   870  					t.Errorf("got r.ResolvedFields(_) = %s, want = %s", err, &tcpip.ErrWouldBlock{})
   871  				}
   872  
   873  				nudConfigs, err := host1Stack.NUDConfigurations(host1NICID, test.netProto)
   874  				if err != nil {
   875  					t.Fatalf("host1Stack.NUDConfigurations(%d, %d): %s", host1NICID, test.netProto, err)
   876  				}
   877  				clock.Advance(time.Duration(nudConfigs.MaxMulticastProbes) * nudConfigs.RetransmitTimer)
   878  
   879  				select {
   880  				case got := <-ch:
   881  					if diff := cmp.Diff(stack.ResolvedFieldsResult{RouteInfo: wantRouteInfo, Err: test.expectedErr}, got, cmp.AllowUnexported(stack.RouteInfo{})); diff != "" {
   882  						t.Errorf("route resolve result mismatch (-want +got):\n%s", diff)
   883  					}
   884  				default:
   885  					t.Fatalf("event didn't arrive")
   886  				}
   887  
   888  				if test.expectedErr != nil {
   889  					return
   890  				}
   891  
   892  				// At this point the neighbor table should be populated so the route
   893  				// should be immediately resolvable.
   894  			}
   895  
   896  			if err := r.ResolvedFields(func(r stack.ResolvedFieldsResult) {
   897  				ch <- r
   898  			}); err != nil {
   899  				t.Errorf("r.ResolvedFields(_): %s", err)
   900  			}
   901  			select {
   902  			case routeResolveRes := <-ch:
   903  				if diff := cmp.Diff(stack.ResolvedFieldsResult{RouteInfo: wantRouteInfo, Err: nil}, routeResolveRes, cmp.AllowUnexported(stack.RouteInfo{})); diff != "" {
   904  					t.Errorf("route resolve result from resolved route mismatch (-want +got):\n%s", diff)
   905  				}
   906  			default:
   907  				t.Fatal("expected route to be immediately resolvable")
   908  			}
   909  		})
   910  	}
   911  }
   912  
   913  func TestWritePacketsLinkResolution(t *testing.T) {
   914  	const (
   915  		host1NICID = 1
   916  		host2NICID = 4
   917  	)
   918  
   919  	tests := []struct {
   920  		name             string
   921  		netProto         tcpip.NetworkProtocolNumber
   922  		remoteAddr       tcpip.Address
   923  		expectedWriteErr tcpip.Error
   924  	}{
   925  		{
   926  			name:             "IPv4",
   927  			netProto:         ipv4.ProtocolNumber,
   928  			remoteAddr:       utils.Ipv4Addr2.AddressWithPrefix.Address,
   929  			expectedWriteErr: nil,
   930  		},
   931  		{
   932  			name:             "IPv6",
   933  			netProto:         ipv6.ProtocolNumber,
   934  			remoteAddr:       utils.Ipv6Addr2.AddressWithPrefix.Address,
   935  			expectedWriteErr: nil,
   936  		},
   937  	}
   938  
   939  	for _, test := range tests {
   940  		t.Run(test.name, func(t *testing.T) {
   941  			stackOpts := stack.Options{
   942  				NetworkProtocols:   []stack.NetworkProtocolFactory{arp.NewProtocol, ipv4.NewProtocol, ipv6.NewProtocol},
   943  				TransportProtocols: []stack.TransportProtocolFactory{udp.NewProtocol},
   944  			}
   945  
   946  			host1Stack, host2Stack := setupStack(t, stackOpts, host1NICID, host2NICID)
   947  			defer host1Stack.Destroy()
   948  			defer host2Stack.Destroy()
   949  
   950  			var serverWQ waiter.Queue
   951  			serverWE, serverCH := waiter.NewChannelEntry(waiter.ReadableEvents)
   952  			serverWQ.EventRegister(&serverWE)
   953  			serverEP, err := host2Stack.NewEndpoint(udp.ProtocolNumber, test.netProto, &serverWQ)
   954  			if err != nil {
   955  				t.Fatalf("host2Stack.NewEndpoint(%d, %d, _): %s", udp.ProtocolNumber, test.netProto, err)
   956  			}
   957  			defer serverEP.Close()
   958  
   959  			serverAddr := tcpip.FullAddress{Port: 1234}
   960  			if err := serverEP.Bind(serverAddr); err != nil {
   961  				t.Fatalf("serverEP.Bind(%#v): %s", serverAddr, err)
   962  			}
   963  
   964  			r, err := host1Stack.FindRoute(host1NICID, tcpip.Address{}, test.remoteAddr, test.netProto, false /* multicastLoop */)
   965  			if err != nil {
   966  				t.Fatalf("host1Stack.FindRoute(%d, '', %s, %d, false): %s", host1NICID, test.remoteAddr, test.netProto, err)
   967  			}
   968  			defer r.Release()
   969  
   970  			params := stack.NetworkHeaderParams{
   971  				Protocol: udp.ProtocolNumber,
   972  				TTL:      64,
   973  				TOS:      stack.DefaultTOS,
   974  			}
   975  			data := []byte{1, 2}
   976  			pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{
   977  				ReserveHeaderBytes: header.UDPMinimumSize + int(r.MaxHeaderLength()),
   978  				Payload:            buffer.MakeWithData(data),
   979  			})
   980  			pkt.TransportProtocolNumber = udp.ProtocolNumber
   981  			length := uint16(pkt.Data().Size() + header.UDPMinimumSize)
   982  			udpHdr := header.UDP(pkt.TransportHeader().Push(header.UDPMinimumSize))
   983  			udpHdr.Encode(&header.UDPFields{
   984  				SrcPort: 5555,
   985  				DstPort: serverAddr.Port,
   986  				Length:  length,
   987  			})
   988  			xsum := r.PseudoHeaderChecksum(udp.ProtocolNumber, length)
   989  			xsum = checksum.Combine(xsum, pkt.Data().Checksum())
   990  			udpHdr.SetChecksum(^udpHdr.CalculateChecksum(xsum))
   991  
   992  			if err := r.WritePacket(params, pkt); err != nil {
   993  				t.Fatalf("WritePacket(...): %s", err)
   994  			}
   995  			pkt.DecRef()
   996  
   997  			var writer bytes.Buffer
   998  			for {
   999  				var rOpts tcpip.ReadOptions
  1000  				res, err := serverEP.Read(&writer, rOpts)
  1001  				if err != nil {
  1002  					if _, ok := err.(*tcpip.ErrWouldBlock); ok {
  1003  						<-serverCH
  1004  						continue
  1005  					}
  1006  
  1007  					t.Fatalf("serverEP.Read(_, %#v): %s", rOpts, err)
  1008  				}
  1009  
  1010  				if res.Count != len(data) {
  1011  					t.Fatalf("got res.Count = %d, want = %d", res.Count, len(data))
  1012  				}
  1013  
  1014  				break
  1015  			}
  1016  
  1017  			if got, want := host2Stack.Stats().UDP.PacketsReceived.Value(), uint64(1); got != want {
  1018  				t.Errorf("got host2Stack.Stats().UDP.PacketsReceived.Value() = %d, want = %d", got, want)
  1019  			}
  1020  			if diff := cmp.Diff(data, writer.Bytes()); diff != "" {
  1021  				t.Errorf("read bytes mismatch (-want +got):\n%s", diff)
  1022  			}
  1023  		})
  1024  	}
  1025  }
  1026  
  1027  type eventType int
  1028  
  1029  const (
  1030  	entryAdded eventType = iota
  1031  	entryChanged
  1032  	entryRemoved
  1033  )
  1034  
  1035  func (t eventType) String() string {
  1036  	switch t {
  1037  	case entryAdded:
  1038  		return "add"
  1039  	case entryChanged:
  1040  		return "change"
  1041  	case entryRemoved:
  1042  		return "remove"
  1043  	default:
  1044  		return fmt.Sprintf("unknown (%d)", t)
  1045  	}
  1046  }
  1047  
  1048  type eventInfo struct {
  1049  	eventType eventType
  1050  	nicID     tcpip.NICID
  1051  	entry     stack.NeighborEntry
  1052  }
  1053  
  1054  func (e eventInfo) String() string {
  1055  	return fmt.Sprintf("%s event for NIC #%d, %#v", e.eventType, e.nicID, e.entry)
  1056  }
  1057  
  1058  var _ stack.NUDDispatcher = (*nudDispatcher)(nil)
  1059  
  1060  type nudDispatcher struct {
  1061  	c chan eventInfo
  1062  }
  1063  
  1064  func (d *nudDispatcher) OnNeighborAdded(nicID tcpip.NICID, entry stack.NeighborEntry) {
  1065  	e := eventInfo{
  1066  		eventType: entryAdded,
  1067  		nicID:     nicID,
  1068  		entry:     entry,
  1069  	}
  1070  	d.c <- e
  1071  }
  1072  
  1073  func (d *nudDispatcher) OnNeighborChanged(nicID tcpip.NICID, entry stack.NeighborEntry) {
  1074  	e := eventInfo{
  1075  		eventType: entryChanged,
  1076  		nicID:     nicID,
  1077  		entry:     entry,
  1078  	}
  1079  	d.c <- e
  1080  }
  1081  
  1082  func (d *nudDispatcher) OnNeighborRemoved(nicID tcpip.NICID, entry stack.NeighborEntry) {
  1083  	e := eventInfo{
  1084  		eventType: entryRemoved,
  1085  		nicID:     nicID,
  1086  		entry:     entry,
  1087  	}
  1088  	d.c <- e
  1089  }
  1090  
  1091  func (d *nudDispatcher) expectEvent(want eventInfo) error {
  1092  	if diff := cmp.Diff(want, <-d.c, cmp.AllowUnexported(eventInfo{}), cmpopts.IgnoreFields(stack.NeighborEntry{}, "UpdatedAt")); diff != "" {
  1093  		return fmt.Errorf("got invalid event (-want +got):\n%s", diff)
  1094  	}
  1095  	return nil
  1096  }
  1097  
  1098  // TestTCPConfirmNeighborReachability tests that TCP informs layers beneath it
  1099  // that the neighbor used for a route is reachable.
  1100  func TestTCPConfirmNeighborReachability(t *testing.T) {
  1101  	tests := []struct {
  1102  		name            string
  1103  		netProto        tcpip.NetworkProtocolNumber
  1104  		remoteAddr      tcpip.Address
  1105  		neighborAddr    tcpip.Address
  1106  		getEndpoints    func(*testing.T, *stack.Stack, *stack.Stack, *stack.Stack) (tcpip.Endpoint, <-chan struct{}, tcpip.Endpoint, <-chan struct{})
  1107  		isHost1Listener bool
  1108  	}{
  1109  		{
  1110  			name:         "IPv4 active connection through neighbor",
  1111  			netProto:     ipv4.ProtocolNumber,
  1112  			remoteAddr:   utils.Host2IPv4Addr.AddressWithPrefix.Address,
  1113  			neighborAddr: utils.RouterNIC1IPv4Addr.AddressWithPrefix.Address,
  1114  			getEndpoints: func(t *testing.T, host1Stack, _, host2Stack *stack.Stack) (tcpip.Endpoint, <-chan struct{}, tcpip.Endpoint, <-chan struct{}) {
  1115  				var listenerWQ waiter.Queue
  1116  				listenerWE, listenerCH := waiter.NewChannelEntry(waiter.EventIn)
  1117  				listenerWQ.EventRegister(&listenerWE)
  1118  				listenerEP, err := host2Stack.NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &listenerWQ)
  1119  				if err != nil {
  1120  					t.Fatalf("host2Stack.NewEndpoint(%d, %d, _): %s", tcp.ProtocolNumber, ipv4.ProtocolNumber, err)
  1121  				}
  1122  
  1123  				var clientWQ waiter.Queue
  1124  				clientWE, clientCH := waiter.NewChannelEntry(waiter.ReadableEvents | waiter.WritableEvents)
  1125  				clientWQ.EventRegister(&clientWE)
  1126  				clientEP, err := host1Stack.NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &clientWQ)
  1127  				if err != nil {
  1128  					t.Fatalf("host1Stack.NewEndpoint(%d, %d, _): %s", tcp.ProtocolNumber, ipv4.ProtocolNumber, err)
  1129  				}
  1130  
  1131  				return listenerEP, listenerCH, clientEP, clientCH
  1132  			},
  1133  		},
  1134  		{
  1135  			name:         "IPv6 active connection through neighbor",
  1136  			netProto:     ipv6.ProtocolNumber,
  1137  			remoteAddr:   utils.Host2IPv6Addr.AddressWithPrefix.Address,
  1138  			neighborAddr: utils.RouterNIC1IPv6Addr.AddressWithPrefix.Address,
  1139  			getEndpoints: func(t *testing.T, host1Stack, _, host2Stack *stack.Stack) (tcpip.Endpoint, <-chan struct{}, tcpip.Endpoint, <-chan struct{}) {
  1140  				var listenerWQ waiter.Queue
  1141  				listenerWE, listenerCH := waiter.NewChannelEntry(waiter.EventIn)
  1142  				listenerWQ.EventRegister(&listenerWE)
  1143  				listenerEP, err := host2Stack.NewEndpoint(tcp.ProtocolNumber, ipv6.ProtocolNumber, &listenerWQ)
  1144  				if err != nil {
  1145  					t.Fatalf("host2Stack.NewEndpoint(%d, %d, _): %s", tcp.ProtocolNumber, ipv6.ProtocolNumber, err)
  1146  				}
  1147  
  1148  				var clientWQ waiter.Queue
  1149  				clientWE, clientCH := waiter.NewChannelEntry(waiter.ReadableEvents | waiter.WritableEvents)
  1150  				clientWQ.EventRegister(&clientWE)
  1151  				clientEP, err := host1Stack.NewEndpoint(tcp.ProtocolNumber, ipv6.ProtocolNumber, &clientWQ)
  1152  				if err != nil {
  1153  					t.Fatalf("host1Stack.NewEndpoint(%d, %d, _): %s", tcp.ProtocolNumber, ipv6.ProtocolNumber, err)
  1154  				}
  1155  
  1156  				return listenerEP, listenerCH, clientEP, clientCH
  1157  			},
  1158  		},
  1159  		{
  1160  			name:         "IPv4 active connection to neighbor",
  1161  			netProto:     ipv4.ProtocolNumber,
  1162  			remoteAddr:   utils.RouterNIC1IPv4Addr.AddressWithPrefix.Address,
  1163  			neighborAddr: utils.RouterNIC1IPv4Addr.AddressWithPrefix.Address,
  1164  			getEndpoints: func(t *testing.T, host1Stack, routerStack, _ *stack.Stack) (tcpip.Endpoint, <-chan struct{}, tcpip.Endpoint, <-chan struct{}) {
  1165  				var listenerWQ waiter.Queue
  1166  				listenerWE, listenerCH := waiter.NewChannelEntry(waiter.EventIn)
  1167  				listenerWQ.EventRegister(&listenerWE)
  1168  				listenerEP, err := routerStack.NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &listenerWQ)
  1169  				if err != nil {
  1170  					t.Fatalf("routerStack.NewEndpoint(%d, %d, _): %s", tcp.ProtocolNumber, ipv4.ProtocolNumber, err)
  1171  				}
  1172  
  1173  				var clientWQ waiter.Queue
  1174  				clientWE, clientCH := waiter.NewChannelEntry(waiter.ReadableEvents | waiter.WritableEvents)
  1175  				clientWQ.EventRegister(&clientWE)
  1176  				clientEP, err := host1Stack.NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &clientWQ)
  1177  				if err != nil {
  1178  					t.Fatalf("host1Stack.NewEndpoint(%d, %d, _): %s", tcp.ProtocolNumber, ipv4.ProtocolNumber, err)
  1179  				}
  1180  
  1181  				return listenerEP, listenerCH, clientEP, clientCH
  1182  			},
  1183  		},
  1184  		{
  1185  			name:         "IPv6 active connection to neighbor",
  1186  			netProto:     ipv6.ProtocolNumber,
  1187  			remoteAddr:   utils.RouterNIC1IPv6Addr.AddressWithPrefix.Address,
  1188  			neighborAddr: utils.RouterNIC1IPv6Addr.AddressWithPrefix.Address,
  1189  			getEndpoints: func(t *testing.T, host1Stack, routerStack, _ *stack.Stack) (tcpip.Endpoint, <-chan struct{}, tcpip.Endpoint, <-chan struct{}) {
  1190  				var listenerWQ waiter.Queue
  1191  				listenerWE, listenerCH := waiter.NewChannelEntry(waiter.EventIn)
  1192  				listenerWQ.EventRegister(&listenerWE)
  1193  				listenerEP, err := routerStack.NewEndpoint(tcp.ProtocolNumber, ipv6.ProtocolNumber, &listenerWQ)
  1194  				if err != nil {
  1195  					t.Fatalf("routerStack.NewEndpoint(%d, %d, _): %s", tcp.ProtocolNumber, ipv6.ProtocolNumber, err)
  1196  				}
  1197  
  1198  				var clientWQ waiter.Queue
  1199  				clientWE, clientCH := waiter.NewChannelEntry(waiter.ReadableEvents | waiter.WritableEvents)
  1200  				clientWQ.EventRegister(&clientWE)
  1201  				clientEP, err := host1Stack.NewEndpoint(tcp.ProtocolNumber, ipv6.ProtocolNumber, &clientWQ)
  1202  				if err != nil {
  1203  					t.Fatalf("host1Stack.NewEndpoint(%d, %d, _): %s", tcp.ProtocolNumber, ipv6.ProtocolNumber, err)
  1204  				}
  1205  
  1206  				return listenerEP, listenerCH, clientEP, clientCH
  1207  			},
  1208  		},
  1209  		{
  1210  			name:         "IPv4 passive connection to neighbor",
  1211  			netProto:     ipv4.ProtocolNumber,
  1212  			remoteAddr:   utils.Host1IPv4Addr.AddressWithPrefix.Address,
  1213  			neighborAddr: utils.RouterNIC1IPv4Addr.AddressWithPrefix.Address,
  1214  			getEndpoints: func(t *testing.T, host1Stack, routerStack, _ *stack.Stack) (tcpip.Endpoint, <-chan struct{}, tcpip.Endpoint, <-chan struct{}) {
  1215  				var listenerWQ waiter.Queue
  1216  				listenerWE, listenerCH := waiter.NewChannelEntry(waiter.EventIn)
  1217  				listenerWQ.EventRegister(&listenerWE)
  1218  				listenerEP, err := host1Stack.NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &listenerWQ)
  1219  				if err != nil {
  1220  					t.Fatalf("host1Stack.NewEndpoint(%d, %d, _): %s", tcp.ProtocolNumber, ipv4.ProtocolNumber, err)
  1221  				}
  1222  
  1223  				var clientWQ waiter.Queue
  1224  				clientWE, clientCH := waiter.NewChannelEntry(waiter.ReadableEvents | waiter.WritableEvents)
  1225  				clientWQ.EventRegister(&clientWE)
  1226  				clientEP, err := routerStack.NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &clientWQ)
  1227  				if err != nil {
  1228  					t.Fatalf("routerStack.NewEndpoint(%d, %d, _): %s", tcp.ProtocolNumber, ipv4.ProtocolNumber, err)
  1229  				}
  1230  
  1231  				return listenerEP, listenerCH, clientEP, clientCH
  1232  			},
  1233  			isHost1Listener: true,
  1234  		},
  1235  		{
  1236  			name:         "IPv6 passive connection to neighbor",
  1237  			netProto:     ipv6.ProtocolNumber,
  1238  			remoteAddr:   utils.Host1IPv6Addr.AddressWithPrefix.Address,
  1239  			neighborAddr: utils.RouterNIC1IPv6Addr.AddressWithPrefix.Address,
  1240  			getEndpoints: func(t *testing.T, host1Stack, routerStack, _ *stack.Stack) (tcpip.Endpoint, <-chan struct{}, tcpip.Endpoint, <-chan struct{}) {
  1241  				var listenerWQ waiter.Queue
  1242  				listenerWE, listenerCH := waiter.NewChannelEntry(waiter.EventIn)
  1243  				listenerWQ.EventRegister(&listenerWE)
  1244  				listenerEP, err := host1Stack.NewEndpoint(tcp.ProtocolNumber, ipv6.ProtocolNumber, &listenerWQ)
  1245  				if err != nil {
  1246  					t.Fatalf("host1Stack.NewEndpoint(%d, %d, _): %s", tcp.ProtocolNumber, ipv6.ProtocolNumber, err)
  1247  				}
  1248  
  1249  				var clientWQ waiter.Queue
  1250  				clientWE, clientCH := waiter.NewChannelEntry(waiter.ReadableEvents | waiter.WritableEvents)
  1251  				clientWQ.EventRegister(&clientWE)
  1252  				clientEP, err := routerStack.NewEndpoint(tcp.ProtocolNumber, ipv6.ProtocolNumber, &clientWQ)
  1253  				if err != nil {
  1254  					t.Fatalf("routerStack.NewEndpoint(%d, %d, _): %s", tcp.ProtocolNumber, ipv6.ProtocolNumber, err)
  1255  				}
  1256  
  1257  				return listenerEP, listenerCH, clientEP, clientCH
  1258  			},
  1259  			isHost1Listener: true,
  1260  		},
  1261  		{
  1262  			name:         "IPv4 passive connection through neighbor",
  1263  			netProto:     ipv4.ProtocolNumber,
  1264  			remoteAddr:   utils.Host1IPv4Addr.AddressWithPrefix.Address,
  1265  			neighborAddr: utils.RouterNIC1IPv4Addr.AddressWithPrefix.Address,
  1266  			getEndpoints: func(t *testing.T, host1Stack, _, host2Stack *stack.Stack) (tcpip.Endpoint, <-chan struct{}, tcpip.Endpoint, <-chan struct{}) {
  1267  				var listenerWQ waiter.Queue
  1268  				listenerWE, listenerCH := waiter.NewChannelEntry(waiter.EventIn)
  1269  				listenerWQ.EventRegister(&listenerWE)
  1270  				listenerEP, err := host1Stack.NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &listenerWQ)
  1271  				if err != nil {
  1272  					t.Fatalf("host1Stack.NewEndpoint(%d, %d, _): %s", tcp.ProtocolNumber, ipv4.ProtocolNumber, err)
  1273  				}
  1274  
  1275  				var clientWQ waiter.Queue
  1276  				clientWE, clientCH := waiter.NewChannelEntry(waiter.ReadableEvents | waiter.WritableEvents)
  1277  				clientWQ.EventRegister(&clientWE)
  1278  				clientEP, err := host2Stack.NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &clientWQ)
  1279  				if err != nil {
  1280  					t.Fatalf("host2Stack.NewEndpoint(%d, %d, _): %s", tcp.ProtocolNumber, ipv4.ProtocolNumber, err)
  1281  				}
  1282  
  1283  				return listenerEP, listenerCH, clientEP, clientCH
  1284  			},
  1285  			isHost1Listener: true,
  1286  		},
  1287  		{
  1288  			name:         "IPv6 passive connection through neighbor",
  1289  			netProto:     ipv6.ProtocolNumber,
  1290  			remoteAddr:   utils.Host1IPv6Addr.AddressWithPrefix.Address,
  1291  			neighborAddr: utils.RouterNIC1IPv6Addr.AddressWithPrefix.Address,
  1292  			getEndpoints: func(t *testing.T, host1Stack, _, host2Stack *stack.Stack) (tcpip.Endpoint, <-chan struct{}, tcpip.Endpoint, <-chan struct{}) {
  1293  				var listenerWQ waiter.Queue
  1294  				listenerWE, listenerCH := waiter.NewChannelEntry(waiter.EventIn)
  1295  				listenerWQ.EventRegister(&listenerWE)
  1296  				listenerEP, err := host1Stack.NewEndpoint(tcp.ProtocolNumber, ipv6.ProtocolNumber, &listenerWQ)
  1297  				if err != nil {
  1298  					t.Fatalf("host1Stack.NewEndpoint(%d, %d, _): %s", tcp.ProtocolNumber, ipv6.ProtocolNumber, err)
  1299  				}
  1300  
  1301  				var clientWQ waiter.Queue
  1302  				clientWE, clientCH := waiter.NewChannelEntry(waiter.ReadableEvents | waiter.WritableEvents)
  1303  				clientWQ.EventRegister(&clientWE)
  1304  				clientEP, err := host2Stack.NewEndpoint(tcp.ProtocolNumber, ipv6.ProtocolNumber, &clientWQ)
  1305  				if err != nil {
  1306  					t.Fatalf("host2Stack.NewEndpoint(%d, %d, _): %s", tcp.ProtocolNumber, ipv6.ProtocolNumber, err)
  1307  				}
  1308  
  1309  				return listenerEP, listenerCH, clientEP, clientCH
  1310  			},
  1311  			isHost1Listener: true,
  1312  		},
  1313  	}
  1314  
  1315  	for _, test := range tests {
  1316  		t.Run(test.name, func(t *testing.T) {
  1317  			clock := faketime.NewManualClock()
  1318  			nudDisp := nudDispatcher{
  1319  				c: make(chan eventInfo, 3),
  1320  			}
  1321  			stackOpts := stack.Options{
  1322  				NetworkProtocols:   []stack.NetworkProtocolFactory{arp.NewProtocol, ipv4.NewProtocol, ipv6.NewProtocol},
  1323  				TransportProtocols: []stack.TransportProtocolFactory{tcp.NewProtocol},
  1324  				Clock:              clock,
  1325  			}
  1326  			host1StackOpts := stackOpts
  1327  			host1StackOpts.NUDDisp = &nudDisp
  1328  
  1329  			host1Stack := stack.New(host1StackOpts)
  1330  			defer host1Stack.Destroy()
  1331  			routerStack := stack.New(stackOpts)
  1332  			defer routerStack.Destroy()
  1333  			host2Stack := stack.New(stackOpts)
  1334  			defer host2Stack.Destroy()
  1335  			utils.SetupRoutedStacks(t, host1Stack, routerStack, host2Stack)
  1336  
  1337  			// Add a reachable dynamic entry to our neighbor table for the remote.
  1338  			{
  1339  				ch := make(chan stack.LinkResolutionResult, 1)
  1340  				err := host1Stack.GetLinkAddress(utils.Host1NICID, test.neighborAddr, tcpip.Address{}, test.netProto, func(r stack.LinkResolutionResult) {
  1341  					ch <- r
  1342  				})
  1343  				if _, ok := err.(*tcpip.ErrWouldBlock); !ok {
  1344  					t.Fatalf("got host1Stack.GetLinkAddress(%d, %s, '', %d, _) = %s, want = %s", utils.Host1NICID, test.neighborAddr, test.netProto, err, &tcpip.ErrWouldBlock{})
  1345  				}
  1346  				if diff := cmp.Diff(stack.LinkResolutionResult{LinkAddress: utils.LinkAddr2, Err: nil}, <-ch); diff != "" {
  1347  					t.Fatalf("link resolution mismatch (-want +got):\n%s", diff)
  1348  				}
  1349  			}
  1350  			if err := nudDisp.expectEvent(eventInfo{
  1351  				eventType: entryAdded,
  1352  				nicID:     utils.Host1NICID,
  1353  				entry:     stack.NeighborEntry{State: stack.Incomplete, Addr: test.neighborAddr},
  1354  			}); err != nil {
  1355  				t.Fatalf("error waiting for initial NUD event: %s", err)
  1356  			}
  1357  			if err := nudDisp.expectEvent(eventInfo{
  1358  				eventType: entryChanged,
  1359  				nicID:     utils.Host1NICID,
  1360  				entry:     stack.NeighborEntry{State: stack.Reachable, Addr: test.neighborAddr, LinkAddr: utils.LinkAddr2},
  1361  			}); err != nil {
  1362  				t.Fatalf("error waiting for reachable NUD event: %s", err)
  1363  			}
  1364  
  1365  			// Wait for the remote's neighbor entry to be stale before creating a
  1366  			// TCP connection from host1 to some remote.
  1367  			nudConfigs, err := host1Stack.NUDConfigurations(utils.Host1NICID, test.netProto)
  1368  			if err != nil {
  1369  				t.Fatalf("host1Stack.NUDConfigurations(%d, %d): %s", utils.Host1NICID, test.netProto, err)
  1370  			}
  1371  			// The maximum reachable time for a neighbor is some maximum random factor
  1372  			// applied to the base reachable time.
  1373  			//
  1374  			// See NUDConfigurations.BaseReachableTime for more information.
  1375  			maxReachableTime := time.Duration(float32(nudConfigs.BaseReachableTime) * nudConfigs.MaxRandomFactor)
  1376  			clock.Advance(maxReachableTime)
  1377  			if err := nudDisp.expectEvent(eventInfo{
  1378  				eventType: entryChanged,
  1379  				nicID:     utils.Host1NICID,
  1380  				entry:     stack.NeighborEntry{State: stack.Stale, Addr: test.neighborAddr, LinkAddr: utils.LinkAddr2},
  1381  			}); err != nil {
  1382  				t.Fatalf("error waiting for stale NUD event: %s", err)
  1383  			}
  1384  
  1385  			listenerEP, listenerCH, clientEP, clientCH := test.getEndpoints(t, host1Stack, routerStack, host2Stack)
  1386  			defer listenerEP.Close()
  1387  			defer clientEP.Close()
  1388  			listenerAddr := tcpip.FullAddress{Addr: test.remoteAddr, Port: 1234}
  1389  			if err := listenerEP.Bind(listenerAddr); err != nil {
  1390  				t.Fatalf("listenerEP.Bind(%#v): %s", listenerAddr, err)
  1391  			}
  1392  			// A backlog of 1 results in SYN cookies being used for all passive
  1393  			// connections to make sure the only spot in the accept queue is not
  1394  			// taken by a connection that never completes the handshake. We use
  1395  			// a backlog of 2 to make sure SYN cookies are not used.
  1396  			//
  1397  			// We avoid SYN cookies to make sure that an accepted endpoint is able
  1398  			// to confirm the neighbor's reachability through the cached neighbor
  1399  			// entry in the endpoint's route. When SYN cookies are used, the
  1400  			// accepted endpoint is constructed when the handshake has already been
  1401  			// established and such an endpoint's route will not have a cached
  1402  			// neighbor entry as it was not used to send any of packets for the
  1403  			// handshake.
  1404  			if err := listenerEP.Listen(2); err != nil {
  1405  				t.Fatalf("listenerEP.Listen(2): %s", err)
  1406  			}
  1407  			{
  1408  				err := clientEP.Connect(listenerAddr)
  1409  				if _, ok := err.(*tcpip.ErrConnectStarted); !ok {
  1410  					t.Fatalf("got clientEP.Connect(%#v) = %s, want = %s", listenerAddr, err, &tcpip.ErrConnectStarted{})
  1411  				}
  1412  			}
  1413  
  1414  			// Wait for the TCP handshake to complete then make sure the neighbor is
  1415  			// reachable without entering the probe state as TCP should provide NUD
  1416  			// with confirmation that the neighbor is reachable (indicated by a
  1417  			// successful 3-way handshake).
  1418  			<-clientCH
  1419  			if err := nudDisp.expectEvent(eventInfo{
  1420  				eventType: entryChanged,
  1421  				nicID:     utils.Host1NICID,
  1422  				entry:     stack.NeighborEntry{State: stack.Delay, Addr: test.neighborAddr, LinkAddr: utils.LinkAddr2},
  1423  			}); err != nil {
  1424  				t.Fatalf("error waiting for delay NUD event: %s", err)
  1425  			}
  1426  			<-listenerCH
  1427  			if err := nudDisp.expectEvent(eventInfo{
  1428  				eventType: entryChanged,
  1429  				nicID:     utils.Host1NICID,
  1430  				entry:     stack.NeighborEntry{State: stack.Reachable, Addr: test.neighborAddr, LinkAddr: utils.LinkAddr2},
  1431  			}); err != nil {
  1432  				t.Fatalf("error waiting for reachable NUD event: %s", err)
  1433  			}
  1434  
  1435  			peerEP, peerWQ, err := listenerEP.Accept(nil)
  1436  			if err != nil {
  1437  				t.Fatalf("listenerEP.Accept(): %s", err)
  1438  			}
  1439  			defer peerEP.Close()
  1440  			peerWE, peerCH := waiter.NewChannelEntry(waiter.ReadableEvents)
  1441  			peerWQ.EventRegister(&peerWE)
  1442  
  1443  			// Wait for the neighbor to be stale again then send data to the remote.
  1444  			//
  1445  			// On successful transmission, the neighbor should become reachable
  1446  			// without probing the neighbor as a TCP ACK would be received which is an
  1447  			// indication of the neighbor being reachable.
  1448  			clock.Advance(maxReachableTime)
  1449  			if err := nudDisp.expectEvent(eventInfo{
  1450  				eventType: entryChanged,
  1451  				nicID:     utils.Host1NICID,
  1452  				entry:     stack.NeighborEntry{State: stack.Stale, Addr: test.neighborAddr, LinkAddr: utils.LinkAddr2},
  1453  			}); err != nil {
  1454  				t.Fatalf("error waiting for stale NUD event: %s", err)
  1455  			}
  1456  			{
  1457  				var r bytes.Reader
  1458  				r.Reset([]byte{0})
  1459  				var wOpts tcpip.WriteOptions
  1460  				if _, err := clientEP.Write(&r, wOpts); err != nil {
  1461  					t.Errorf("clientEP.Write(_, %#v): %s", wOpts, err)
  1462  				}
  1463  			}
  1464  			// Heads up, there is a race here.
  1465  			//
  1466  			// Incoming TCP segments are handled in
  1467  			// tcp.(*endpoint).handleSegmentLocked:
  1468  			//
  1469  			//	- tcp.(*endpoint).rcv.handleRcvdSegment puts the segment on the
  1470  			//		segment queue and notifies waiting readers (such as this channel)
  1471  			//
  1472  			//	- tcp.(*endpoint).snd.handleRcvdSegment sends an ACK for the segment
  1473  			//		and notifies the NUD machinery that the peer is reachable
  1474  			//
  1475  			// Thus we must permit a delay between the readable signal and the
  1476  			// expected NUD event.
  1477  			//
  1478  			// At the time of writing, this race is reliably hit with gotsan.
  1479  			<-peerCH
  1480  			for len(nudDisp.c) == 0 {
  1481  				runtime.Gosched()
  1482  			}
  1483  			if err := nudDisp.expectEvent(eventInfo{
  1484  				eventType: entryChanged,
  1485  				nicID:     utils.Host1NICID,
  1486  				entry:     stack.NeighborEntry{State: stack.Delay, Addr: test.neighborAddr, LinkAddr: utils.LinkAddr2},
  1487  			}); err != nil {
  1488  				t.Fatalf("error waiting for delay NUD event: %s", err)
  1489  			}
  1490  			if test.isHost1Listener {
  1491  				// If host1 is not the client, host1 does not send any data so TCP
  1492  				// has no way to know it is making forward progress. Because of this,
  1493  				// TCP should not mark the route reachable and NUD should go through the
  1494  				// probe state.
  1495  				clock.Advance(nudConfigs.DelayFirstProbeTime)
  1496  				if err := nudDisp.expectEvent(eventInfo{
  1497  					eventType: entryChanged,
  1498  					nicID:     utils.Host1NICID,
  1499  					entry:     stack.NeighborEntry{State: stack.Probe, Addr: test.neighborAddr, LinkAddr: utils.LinkAddr2},
  1500  				}); err != nil {
  1501  					t.Fatalf("error waiting for probe NUD event: %s", err)
  1502  				}
  1503  			}
  1504  			{
  1505  				var r bytes.Reader
  1506  				r.Reset([]byte{0})
  1507  				var wOpts tcpip.WriteOptions
  1508  				if _, err := peerEP.Write(&r, wOpts); err != nil {
  1509  					t.Errorf("peerEP.Write(_, %#v): %s", wOpts, err)
  1510  				}
  1511  			}
  1512  			<-clientCH
  1513  			if err := nudDisp.expectEvent(eventInfo{
  1514  				eventType: entryChanged,
  1515  				nicID:     utils.Host1NICID,
  1516  				entry:     stack.NeighborEntry{State: stack.Reachable, Addr: test.neighborAddr, LinkAddr: utils.LinkAddr2},
  1517  			}); err != nil {
  1518  				t.Fatalf("error waiting for reachable NUD event: %s", err)
  1519  			}
  1520  		})
  1521  	}
  1522  }
  1523  
  1524  func TestDAD(t *testing.T) {
  1525  	dadConfigs := stack.DADConfigurations{
  1526  		DupAddrDetectTransmits: 1,
  1527  		RetransmitTimer:        time.Second,
  1528  	}
  1529  
  1530  	tests := []struct {
  1531  		name           string
  1532  		netProto       tcpip.NetworkProtocolNumber
  1533  		dadNetProto    tcpip.NetworkProtocolNumber
  1534  		remoteAddr     tcpip.Address
  1535  		expectedResult stack.DADResult
  1536  	}{
  1537  		{
  1538  			name:           "IPv4 own address",
  1539  			netProto:       ipv4.ProtocolNumber,
  1540  			dadNetProto:    arp.ProtocolNumber,
  1541  			remoteAddr:     utils.Ipv4Addr1.AddressWithPrefix.Address,
  1542  			expectedResult: &stack.DADSucceeded{},
  1543  		},
  1544  		{
  1545  			name:           "IPv6 own address",
  1546  			netProto:       ipv6.ProtocolNumber,
  1547  			dadNetProto:    ipv6.ProtocolNumber,
  1548  			remoteAddr:     utils.Ipv6Addr1.AddressWithPrefix.Address,
  1549  			expectedResult: &stack.DADSucceeded{},
  1550  		},
  1551  		{
  1552  			name:           "IPv4 duplicate address",
  1553  			netProto:       ipv4.ProtocolNumber,
  1554  			dadNetProto:    arp.ProtocolNumber,
  1555  			remoteAddr:     utils.Ipv4Addr2.AddressWithPrefix.Address,
  1556  			expectedResult: &stack.DADDupAddrDetected{HolderLinkAddress: utils.LinkAddr2},
  1557  		},
  1558  		{
  1559  			name:           "IPv6 duplicate address",
  1560  			netProto:       ipv6.ProtocolNumber,
  1561  			dadNetProto:    ipv6.ProtocolNumber,
  1562  			remoteAddr:     utils.Ipv6Addr2.AddressWithPrefix.Address,
  1563  			expectedResult: &stack.DADDupAddrDetected{HolderLinkAddress: utils.LinkAddr2},
  1564  		},
  1565  		{
  1566  			name:           "IPv4 no duplicate address",
  1567  			netProto:       ipv4.ProtocolNumber,
  1568  			dadNetProto:    arp.ProtocolNumber,
  1569  			remoteAddr:     utils.Ipv4Addr3.AddressWithPrefix.Address,
  1570  			expectedResult: &stack.DADSucceeded{},
  1571  		},
  1572  		{
  1573  			name:           "IPv6 no duplicate address",
  1574  			netProto:       ipv6.ProtocolNumber,
  1575  			dadNetProto:    ipv6.ProtocolNumber,
  1576  			remoteAddr:     utils.Ipv6Addr3.AddressWithPrefix.Address,
  1577  			expectedResult: &stack.DADSucceeded{},
  1578  		},
  1579  	}
  1580  
  1581  	for _, test := range tests {
  1582  		t.Run(test.name, func(t *testing.T) {
  1583  			clock := faketime.NewManualClock()
  1584  			stackOpts := stack.Options{
  1585  				Clock: clock,
  1586  				NetworkProtocols: []stack.NetworkProtocolFactory{
  1587  					arp.NewProtocol,
  1588  					ipv4.NewProtocol,
  1589  					ipv6.NewProtocol,
  1590  				},
  1591  			}
  1592  
  1593  			host1Stack, host2Stack := setupStack(t, stackOpts, utils.Host1NICID, utils.Host2NICID)
  1594  			defer host1Stack.Destroy()
  1595  			defer host2Stack.Destroy()
  1596  
  1597  			// DAD should be disabled by default.
  1598  			if res, err := host1Stack.CheckDuplicateAddress(utils.Host1NICID, test.netProto, test.remoteAddr, func(r stack.DADResult) {
  1599  				t.Errorf("unexpectedly called DAD completion handler when DAD was supposed to be disabled")
  1600  			}); err != nil {
  1601  				t.Fatalf("host1Stack.CheckDuplicateAddress(%d, %d, %s, _): %s", utils.Host1NICID, test.netProto, test.remoteAddr, err)
  1602  			} else if res != stack.DADDisabled {
  1603  				t.Errorf("got host1Stack.CheckDuplicateAddress(%d, %d, %s, _) = %d, want = %d", utils.Host1NICID, test.netProto, test.remoteAddr, res, stack.DADDisabled)
  1604  			}
  1605  
  1606  			// Enable DAD then attempt to check if an address is duplicated.
  1607  			netEP, err := host1Stack.GetNetworkEndpoint(utils.Host1NICID, test.dadNetProto)
  1608  			if err != nil {
  1609  				t.Fatalf("host1Stack.GetNetworkEndpoint(%d, %d): %s", utils.Host1NICID, test.dadNetProto, err)
  1610  			}
  1611  			dad, ok := netEP.(stack.DuplicateAddressDetector)
  1612  			if !ok {
  1613  				t.Fatalf("expected %T to implement stack.DuplicateAddressDetector", netEP)
  1614  			}
  1615  			dad.SetDADConfigurations(dadConfigs)
  1616  			ch := make(chan stack.DADResult, 3)
  1617  			if res, err := host1Stack.CheckDuplicateAddress(utils.Host1NICID, test.netProto, test.remoteAddr, func(r stack.DADResult) {
  1618  				ch <- r
  1619  			}); err != nil {
  1620  				t.Fatalf("host1Stack.CheckDuplicateAddress(%d, %d, %s, _): %s", utils.Host1NICID, test.netProto, test.remoteAddr, err)
  1621  			} else if res != stack.DADStarting {
  1622  				t.Errorf("got host1Stack.CheckDuplicateAddress(%d, %d, %s, _) = %d, want = %d", utils.Host1NICID, test.netProto, test.remoteAddr, res, stack.DADStarting)
  1623  			}
  1624  
  1625  			expectResults := 1
  1626  			if _, ok := test.expectedResult.(*stack.DADSucceeded); ok {
  1627  				const delta = time.Nanosecond
  1628  				clock.Advance(time.Duration(dadConfigs.DupAddrDetectTransmits)*dadConfigs.RetransmitTimer - delta)
  1629  				select {
  1630  				case r := <-ch:
  1631  					t.Fatalf("unexpectedly got DAD result before the DAD timeout; r = %#v", r)
  1632  				default:
  1633  				}
  1634  
  1635  				// If we expect the resolve to succeed try requesting DAD again on the
  1636  				// same address. The handler for the new request should be called once
  1637  				// the original DAD request completes.
  1638  				expectResults = 2
  1639  				if res, err := host1Stack.CheckDuplicateAddress(utils.Host1NICID, test.netProto, test.remoteAddr, func(r stack.DADResult) {
  1640  					ch <- r
  1641  				}); err != nil {
  1642  					t.Fatalf("host1Stack.CheckDuplicateAddress(%d, %d, %s, _): %s", utils.Host1NICID, test.netProto, test.remoteAddr, err)
  1643  				} else if res != stack.DADAlreadyRunning {
  1644  					t.Errorf("got host1Stack.CheckDuplicateAddress(%d, %d, %s, _) = %d, want = %d", utils.Host1NICID, test.netProto, test.remoteAddr, res, stack.DADAlreadyRunning)
  1645  				}
  1646  
  1647  				clock.Advance(delta)
  1648  			}
  1649  
  1650  			for i := 0; i < expectResults; i++ {
  1651  				if diff := cmp.Diff(test.expectedResult, <-ch); diff != "" {
  1652  					t.Errorf("(i=%d) DAD result mismatch (-want +got):\n%s", i, diff)
  1653  				}
  1654  			}
  1655  
  1656  			// Should have no more results.
  1657  			select {
  1658  			case r := <-ch:
  1659  				t.Errorf("unexpectedly got an extra DAD result; r = %#v", r)
  1660  			default:
  1661  			}
  1662  		})
  1663  	}
  1664  }
  1665  
  1666  type settableLinkEndpoint struct {
  1667  	stack.LinkEndpoint
  1668  	mu   sync.Mutex
  1669  	addr tcpip.LinkAddress
  1670  }
  1671  
  1672  func newSettableLinkEndpoint(e stack.LinkEndpoint) *settableLinkEndpoint {
  1673  	return &settableLinkEndpoint{
  1674  		LinkEndpoint: e,
  1675  		addr:         e.LinkAddress(),
  1676  	}
  1677  }
  1678  
  1679  func (e *settableLinkEndpoint) setLinkAddress(addr tcpip.LinkAddress) {
  1680  	e.mu.Lock()
  1681  	defer e.mu.Unlock()
  1682  	e.addr = addr
  1683  }
  1684  
  1685  func (e *settableLinkEndpoint) LinkAddress() tcpip.LinkAddress {
  1686  	e.mu.Lock()
  1687  	defer e.mu.Unlock()
  1688  	return e.addr
  1689  }
  1690  
  1691  type monitorableLinkEndpoint struct {
  1692  	stack.LinkEndpoint
  1693  	ch chan tcpip.LinkAddress
  1694  }
  1695  
  1696  func newMonitorableLinkEndpoint(e stack.LinkEndpoint) *monitorableLinkEndpoint {
  1697  	return &monitorableLinkEndpoint{e, make(chan tcpip.LinkAddress, 1)}
  1698  }
  1699  
  1700  func (e *monitorableLinkEndpoint) WritePackets(pkts stack.PacketBufferList) (int, tcpip.Error) {
  1701  	for _, pkt := range pkts.AsSlice() {
  1702  		dstAddr := header.Ethernet(pkt.LinkHeader().Slice()).DestinationAddress()
  1703  		e.ch <- dstAddr
  1704  	}
  1705  	e.LinkEndpoint.WritePackets(pkts)
  1706  
  1707  	return 0, nil
  1708  }
  1709  
  1710  func (e *monitorableLinkEndpoint) waitForLinkAddress(addr tcpip.LinkAddress, wait time.Duration) error {
  1711  	c := time.After(wait)
  1712  	for {
  1713  		select {
  1714  		case sentAddr := <-e.ch:
  1715  			if addr == sentAddr {
  1716  				return nil
  1717  			}
  1718  		case <-c:
  1719  			return fmt.Errorf("timed out waiting for endpoint to send packet with destination address: %v", addr)
  1720  		}
  1721  	}
  1722  }
  1723  
  1724  func TestUpdateCachedNeighborEntry(t *testing.T) {
  1725  	d := []byte{1, 2}
  1726  	params := stack.NetworkHeaderParams{
  1727  		Protocol: udp.ProtocolNumber,
  1728  		TTL:      64,
  1729  		TOS:      stack.DefaultTOS,
  1730  	}
  1731  
  1732  	writePacket := func(t *testing.T, r *stack.Route) {
  1733  		pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{
  1734  			ReserveHeaderBytes: header.UDPMinimumSize + int(r.MaxHeaderLength()),
  1735  			Payload:            buffer.MakeWithData(d),
  1736  		})
  1737  		if err := r.WritePacket(params, pkt); err != nil {
  1738  			t.Fatalf("WritePacket(...): %s", err)
  1739  		}
  1740  		pkt.DecRef()
  1741  	}
  1742  
  1743  	const (
  1744  		host1NICID = 1
  1745  		host2NICID = 4
  1746  	)
  1747  	stackOpts := stack.Options{
  1748  		NetworkProtocols: []stack.NetworkProtocolFactory{
  1749  			arp.NewProtocol,
  1750  			ipv4.NewProtocolWithOptions(ipv4.Options{
  1751  				IGMP: ipv4.IGMPOptions{
  1752  					Enabled: false,
  1753  				},
  1754  			}),
  1755  			ipv6.NewProtocolWithOptions(ipv6.Options{
  1756  				MLD: ipv6.MLDOptions{
  1757  					Enabled: false,
  1758  				},
  1759  			}),
  1760  		},
  1761  		TransportProtocols: []stack.TransportProtocolFactory{udp.NewProtocol},
  1762  	}
  1763  
  1764  	const maxFrameSize = header.IPv6MinimumMTU + header.EthernetMinimumSize
  1765  
  1766  	host1Stack := stack.New(stackOpts)
  1767  	host2Stack := stack.New(stackOpts)
  1768  	defer host1Stack.Destroy()
  1769  	defer host2Stack.Destroy()
  1770  
  1771  	host1Pipe, host2Pipe := pipe.New(utils.LinkAddr1, utils.LinkAddr2, maxFrameSize)
  1772  
  1773  	host1NICMonitorable := newMonitorableLinkEndpoint(ethernet.New(host1Pipe))
  1774  	host2NICSettable := newSettableLinkEndpoint(host2Pipe)
  1775  
  1776  	if err := host1Stack.CreateNIC(host1NICID, host1NICMonitorable); err != nil {
  1777  		t.Fatalf("host1Stack.CreateNIC(%d, _): %s", host1NICID, err)
  1778  	}
  1779  	if err := host2Stack.CreateNIC(host2NICID, ethernet.New(host2NICSettable)); err != nil {
  1780  		t.Fatalf("host2Stack.CreateNIC(%d, _): %s", host2NICID, err)
  1781  	}
  1782  
  1783  	if err := host1Stack.AddProtocolAddress(host1NICID, utils.Ipv4Addr1, stack.AddressProperties{}); err != nil {
  1784  		t.Fatalf("host1Stack.AddProtocolAddress(%d, %+v, {}): %s", host1NICID, utils.Ipv4Addr1, err)
  1785  	}
  1786  	if err := host2Stack.AddProtocolAddress(host2NICID, utils.Ipv4Addr2, stack.AddressProperties{}); err != nil {
  1787  		t.Fatalf("host2Stack.AddProtocolAddress(%d, %+v, {}): %s", host2NICID, utils.Ipv4Addr2, err)
  1788  	}
  1789  
  1790  	host1Stack.SetRouteTable([]tcpip.Route{
  1791  		{
  1792  			Destination: utils.Ipv4Addr1.AddressWithPrefix.Subnet(),
  1793  			NIC:         host1NICID,
  1794  		},
  1795  	})
  1796  	host2Stack.SetRouteTable([]tcpip.Route{
  1797  		{
  1798  			Destination: utils.Ipv4Addr2.AddressWithPrefix.Subnet(),
  1799  			NIC:         host2NICID,
  1800  		},
  1801  	})
  1802  
  1803  	localAddr := utils.Ipv4Addr1.AddressWithPrefix.Address
  1804  	neighborAddr := utils.Ipv4Addr2.AddressWithPrefix.Address
  1805  
  1806  	// Obtain a route to a neighbor.
  1807  	r, err := host1Stack.FindRoute(host1NICID, localAddr, neighborAddr, header.IPv4ProtocolNumber, false)
  1808  	if err != nil {
  1809  		t.Fatalf("host1Stack.FindRoute(...): %s", err)
  1810  	}
  1811  
  1812  	// Send packet to neighbor (start link resolution & resolve, then send
  1813  	// packet). Send twice to use cached address the second time.
  1814  	for i := 0; i < 2; i++ {
  1815  		go writePacket(t, r)
  1816  		if err := host1NICMonitorable.waitForLinkAddress(utils.LinkAddr2, time.Second); err != nil {
  1817  			t.Fatalf("host1NIC.waitForLinkAddress(%s): %s", utils.LinkAddr2, err)
  1818  		}
  1819  	}
  1820  
  1821  	// Neighbor no longer reachable, deleted from the neighbor cache.
  1822  	host1Stack.RemoveNeighbor(host1NICID, header.IPv4ProtocolNumber, neighborAddr)
  1823  	host2Stack.DisableNIC(host2NICID)
  1824  
  1825  	// Send a packet to the neighbor that's no longer reachable (should fail).
  1826  	go writePacket(t, r)
  1827  	if err := host1NICMonitorable.waitForLinkAddress(utils.LinkAddr2, time.Second); err == nil {
  1828  		t.Fatalf("got host1NIC.waitForLinkAddress(%s) = nil, want err", utils.LinkAddr2)
  1829  	}
  1830  
  1831  	// Neighbor reachable again with new MAC address.
  1832  	host2Stack.EnableNIC(host2NICID)
  1833  	host2NICSettable.setLinkAddress(utils.LinkAddr3)
  1834  
  1835  	// Pending packet should eventually reach the new neighbor.
  1836  	if err := host1NICMonitorable.waitForLinkAddress(utils.LinkAddr3, 5*time.Second); err != nil {
  1837  		t.Fatalf("host1NIC.waitForLinkAddress(%s): %s", utils.LinkAddr3, err)
  1838  	}
  1839  }