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