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 }