gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/pkg/tcpip/stack/ndp_test.go (about) 1 // Copyright 2019 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 16 17 import ( 18 "encoding/binary" 19 "fmt" 20 "math" 21 "math/rand" 22 "testing" 23 "time" 24 25 "github.com/google/go-cmp/cmp" 26 "gvisor.dev/gvisor/pkg/buffer" 27 cryptorand "gvisor.dev/gvisor/pkg/rand" 28 "gvisor.dev/gvisor/pkg/tcpip" 29 "gvisor.dev/gvisor/pkg/tcpip/checker" 30 "gvisor.dev/gvisor/pkg/tcpip/faketime" 31 "gvisor.dev/gvisor/pkg/tcpip/header" 32 "gvisor.dev/gvisor/pkg/tcpip/link/channel" 33 "gvisor.dev/gvisor/pkg/tcpip/link/loopback" 34 "gvisor.dev/gvisor/pkg/tcpip/network/ipv6" 35 "gvisor.dev/gvisor/pkg/tcpip/prependable" 36 "gvisor.dev/gvisor/pkg/tcpip/stack" 37 "gvisor.dev/gvisor/pkg/tcpip/testutil" 38 "gvisor.dev/gvisor/pkg/tcpip/transport/icmp" 39 "gvisor.dev/gvisor/pkg/tcpip/transport/udp" 40 "gvisor.dev/gvisor/pkg/waiter" 41 ) 42 43 var ( 44 addr1 = testutil.MustParse6("a00::1") 45 addr2 = testutil.MustParse6("a00::2") 46 addr3 = testutil.MustParse6("a00::3") 47 ) 48 49 const ( 50 linkAddr1 = tcpip.LinkAddress("\x02\x02\x03\x04\x05\x06") 51 linkAddr2 = tcpip.LinkAddress("\x02\x02\x03\x04\x05\x07") 52 linkAddr3 = tcpip.LinkAddress("\x02\x02\x03\x04\x05\x08") 53 linkAddr4 = tcpip.LinkAddress("\x02\x02\x03\x04\x05\x09") 54 55 defaultPrefixLen = 128 56 infiniteVLSeconds = math.MaxUint32 57 ) 58 59 var ( 60 llAddr1 = header.LinkLocalAddr(linkAddr1) 61 llAddr2 = header.LinkLocalAddr(linkAddr2) 62 llAddr3 = header.LinkLocalAddr(linkAddr3) 63 llAddr4 = header.LinkLocalAddr(linkAddr4) 64 dstAddr = tcpip.FullAddress{ 65 Addr: tcpip.AddrFromSlice([]byte("\x0a\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01")), 66 Port: 25, 67 } 68 ) 69 70 func addrForSubnet(subnet tcpip.Subnet, linkAddr tcpip.LinkAddress) tcpip.AddressWithPrefix { 71 if !header.IsValidUnicastEthernetAddress(linkAddr) { 72 return tcpip.AddressWithPrefix{} 73 } 74 75 subnetID := subnet.ID() 76 addrBytes := subnetID.AsSlice() 77 header.EthernetAdddressToModifiedEUI64IntoBuf(linkAddr, addrBytes[header.IIDOffsetInIPv6Address:]) 78 return tcpip.AddressWithPrefix{ 79 Address: tcpip.AddrFromSlice(addrBytes), 80 PrefixLen: 64, 81 } 82 } 83 84 // prefixSubnetAddr returns a prefix (Address + Length), the prefix's equivalent 85 // tcpip.Subnet, and an address where the lower half of the address is composed 86 // of the EUI-64 of linkAddr if it is a valid unicast ethernet address. 87 func prefixSubnetAddr(offset uint8, linkAddr tcpip.LinkAddress) (tcpip.AddressWithPrefix, tcpip.Subnet, tcpip.AddressWithPrefix) { 88 prefixBytes := []byte{1, 2, 3, 4, 5, 6, 7, 8 + offset, 0, 0, 0, 0, 0, 0, 0, 0} 89 prefix := tcpip.AddressWithPrefix{ 90 Address: tcpip.AddrFrom16Slice(prefixBytes), 91 PrefixLen: 64, 92 } 93 94 subnet := prefix.Subnet() 95 96 return prefix, subnet, addrForSubnet(subnet, linkAddr) 97 } 98 99 // ndpDADEvent is a set of parameters that was passed to 100 // ndpDispatcher.OnDuplicateAddressDetectionResult. 101 type ndpDADEvent struct { 102 nicID tcpip.NICID 103 addr tcpip.Address 104 res stack.DADResult 105 } 106 107 type ndpOffLinkRouteEvent struct { 108 nicID tcpip.NICID 109 subnet tcpip.Subnet 110 router tcpip.Address 111 prf header.NDPRoutePreference 112 // true if route was updated, false if invalidated. 113 updated bool 114 } 115 116 type ndpPrefixEvent struct { 117 nicID tcpip.NICID 118 prefix tcpip.Subnet 119 // true if prefix was discovered, false if invalidated. 120 discovered bool 121 } 122 123 type ndpAutoGenAddrNewEvent struct { 124 nicID tcpip.NICID 125 addr tcpip.AddressWithPrefix 126 addrDisp *addressDispatcher 127 } 128 129 type ndpAutoGenAddrEventType int 130 131 const ( 132 deprecatedAddr ndpAutoGenAddrEventType = iota 133 invalidatedAddr 134 ) 135 136 type ndpAutoGenAddrEvent struct { 137 nicID tcpip.NICID 138 addr tcpip.AddressWithPrefix 139 eventType ndpAutoGenAddrEventType 140 } 141 142 func (e ndpAutoGenAddrEvent) String() string { 143 return fmt.Sprintf("%T{nicID=%d addr=%s eventType=%d}", e, e.nicID, e.addr, e.eventType) 144 } 145 146 type ndpRDNSS struct { 147 addrs []tcpip.Address 148 lifetime time.Duration 149 } 150 151 type ndpRDNSSEvent struct { 152 nicID tcpip.NICID 153 rdnss ndpRDNSS 154 } 155 156 type ndpDNSSLEvent struct { 157 nicID tcpip.NICID 158 domainNames []string 159 lifetime time.Duration 160 } 161 162 type ndpDHCPv6Event struct { 163 nicID tcpip.NICID 164 configuration ipv6.DHCPv6ConfigurationFromNDPRA 165 } 166 167 var _ ipv6.NDPDispatcher = (*ndpDispatcher)(nil) 168 169 // ndpDispatcher implements NDPDispatcher so tests can know when various NDP 170 // related events happen for test purposes. 171 type ndpDispatcher struct { 172 dadC chan ndpDADEvent 173 offLinkRouteC chan ndpOffLinkRouteEvent 174 prefixC chan ndpPrefixEvent 175 autoGenAddrC chan ndpAutoGenAddrEvent 176 autoGenAddrNewC chan ndpAutoGenAddrNewEvent 177 // autoGenInstallDisp controls whether address dispatchers are installed for 178 // new auto-generated addresses. 179 autoGenInstallDisp bool 180 rdnssC chan ndpRDNSSEvent 181 dnsslC chan ndpDNSSLEvent 182 routeTable []tcpip.Route 183 dhcpv6ConfigurationC chan ndpDHCPv6Event 184 } 185 186 // Implements ipv6.NDPDispatcher.OnDuplicateAddressDetectionResult. 187 func (n *ndpDispatcher) OnDuplicateAddressDetectionResult(nicID tcpip.NICID, addr tcpip.Address, res stack.DADResult) { 188 if n.dadC != nil { 189 n.dadC <- ndpDADEvent{ 190 nicID, 191 addr, 192 res, 193 } 194 } 195 } 196 197 // Implements ipv6.NDPDispatcher.OnOffLinkRouteUpdated. 198 func (n *ndpDispatcher) OnOffLinkRouteUpdated(nicID tcpip.NICID, subnet tcpip.Subnet, router tcpip.Address, prf header.NDPRoutePreference) { 199 if c := n.offLinkRouteC; c != nil { 200 c <- ndpOffLinkRouteEvent{ 201 nicID, 202 subnet, 203 router, 204 prf, 205 true, 206 } 207 } 208 } 209 210 // Implements ipv6.NDPDispatcher.OnOffLinkRouteInvalidated. 211 func (n *ndpDispatcher) OnOffLinkRouteInvalidated(nicID tcpip.NICID, subnet tcpip.Subnet, router tcpip.Address) { 212 if c := n.offLinkRouteC; c != nil { 213 var prf header.NDPRoutePreference 214 c <- ndpOffLinkRouteEvent{ 215 nicID, 216 subnet, 217 router, 218 prf, 219 false, 220 } 221 } 222 } 223 224 // Implements ipv6.NDPDispatcher.OnOnLinkPrefixDiscovered. 225 func (n *ndpDispatcher) OnOnLinkPrefixDiscovered(nicID tcpip.NICID, prefix tcpip.Subnet) { 226 if c := n.prefixC; c != nil { 227 c <- ndpPrefixEvent{ 228 nicID, 229 prefix, 230 true, 231 } 232 } 233 } 234 235 // Implements ipv6.NDPDispatcher.OnOnLinkPrefixInvalidated. 236 func (n *ndpDispatcher) OnOnLinkPrefixInvalidated(nicID tcpip.NICID, prefix tcpip.Subnet) { 237 if c := n.prefixC; c != nil { 238 c <- ndpPrefixEvent{ 239 nicID, 240 prefix, 241 false, 242 } 243 } 244 } 245 246 func (n *ndpDispatcher) OnAutoGenAddress(nicID tcpip.NICID, addr tcpip.AddressWithPrefix) stack.AddressDispatcher { 247 if c := n.autoGenAddrNewC; c != nil { 248 e := ndpAutoGenAddrNewEvent{ 249 nicID, 250 addr, 251 nil, 252 } 253 if n.autoGenInstallDisp { 254 e.addrDisp = &addressDispatcher{ 255 changedCh: make(chan addressChangedEvent, 1), 256 removedCh: make(chan stack.AddressRemovalReason, 1), 257 nicid: nicID, 258 addr: addr, 259 } 260 } 261 c <- e 262 if n.autoGenInstallDisp { 263 return e.addrDisp 264 } 265 } 266 return nil 267 } 268 269 func (n *ndpDispatcher) OnAutoGenAddressDeprecated(nicID tcpip.NICID, addr tcpip.AddressWithPrefix) { 270 if c := n.autoGenAddrC; c != nil { 271 c <- ndpAutoGenAddrEvent{ 272 nicID, 273 addr, 274 deprecatedAddr, 275 } 276 } 277 } 278 279 func (n *ndpDispatcher) OnAutoGenAddressInvalidated(nicID tcpip.NICID, addr tcpip.AddressWithPrefix) { 280 if c := n.autoGenAddrC; c != nil { 281 c <- ndpAutoGenAddrEvent{ 282 nicID, 283 addr, 284 invalidatedAddr, 285 } 286 } 287 } 288 289 // Implements ipv6.NDPDispatcher.OnRecursiveDNSServerOption. 290 func (n *ndpDispatcher) OnRecursiveDNSServerOption(nicID tcpip.NICID, addrs []tcpip.Address, lifetime time.Duration) { 291 if c := n.rdnssC; c != nil { 292 c <- ndpRDNSSEvent{ 293 nicID, 294 ndpRDNSS{ 295 addrs, 296 lifetime, 297 }, 298 } 299 } 300 } 301 302 // Implements ipv6.NDPDispatcher.OnDNSSearchListOption. 303 func (n *ndpDispatcher) OnDNSSearchListOption(nicID tcpip.NICID, domainNames []string, lifetime time.Duration) { 304 if n.dnsslC != nil { 305 n.dnsslC <- ndpDNSSLEvent{ 306 nicID, 307 domainNames, 308 lifetime, 309 } 310 } 311 } 312 313 // Implements ipv6.NDPDispatcher.OnDHCPv6Configuration. 314 func (n *ndpDispatcher) OnDHCPv6Configuration(nicID tcpip.NICID, configuration ipv6.DHCPv6ConfigurationFromNDPRA) { 315 if c := n.dhcpv6ConfigurationC; c != nil { 316 c <- ndpDHCPv6Event{ 317 nicID, 318 configuration, 319 } 320 } 321 } 322 323 // channelLinkWithHeaderLength is a channel.Endpoint with a configurable 324 // header length. 325 type channelLinkWithHeaderLength struct { 326 *channel.Endpoint 327 headerLength uint16 328 } 329 330 func (l *channelLinkWithHeaderLength) MaxHeaderLength() uint16 { 331 return l.headerLength 332 } 333 334 // Check e to make sure that the event is for addr on nic with ID 1, and the 335 // resolved flag set to resolved with the specified err. 336 func checkDADEvent(e ndpDADEvent, nicID tcpip.NICID, addr tcpip.Address, res stack.DADResult) string { 337 return cmp.Diff(ndpDADEvent{nicID: nicID, addr: addr, res: res}, e, cmp.AllowUnexported(e)) 338 } 339 340 // addressLifetimes returns address lifetimes computed by adding pl and vl 341 // from the reference time. 342 // 343 // If pl is 0, the returned lifetimes will be deprecated and have a zero value 344 // for the PreferredUntil field. 345 // 346 // If vl is infinite, the returned lifetimes will contain a maximal ValidUntil 347 // value. 348 func addressLifetimes(received tcpip.MonotonicTime, pl, vl uint32) stack.AddressLifetimes { 349 var preferredUntil, validUntil tcpip.MonotonicTime 350 if pl > 0 { 351 preferredUntil = received.Add(time.Duration(pl) * time.Second) 352 } 353 if vl == math.MaxUint32 { 354 validUntil = tcpip.MonotonicTimeInfinite() 355 } else { 356 validUntil = received.Add(time.Duration(vl) * time.Second) 357 } 358 return stack.AddressLifetimes{ 359 Deprecated: pl == 0, 360 PreferredUntil: preferredUntil, 361 ValidUntil: validUntil, 362 } 363 } 364 365 // TestDADDisabled tests that an address successfully resolves immediately 366 // when DAD is not enabled (the default for an empty stack.Options). 367 func TestDADDisabled(t *testing.T) { 368 const nicID = 1 369 ndpDisp := ndpDispatcher{ 370 dadC: make(chan ndpDADEvent, 1), 371 } 372 e := channel.New(0, 1280, linkAddr1) 373 s := stack.New(stack.Options{ 374 NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{ 375 NDPDisp: &ndpDisp, 376 })}, 377 }) 378 if err := s.CreateNIC(nicID, e); err != nil { 379 t.Fatalf("CreateNIC(%d, _) = %s", nicID, err) 380 } 381 382 addrWithPrefix := tcpip.AddressWithPrefix{ 383 Address: addr1, 384 PrefixLen: defaultPrefixLen, 385 } 386 protocolAddr := tcpip.ProtocolAddress{ 387 Protocol: header.IPv6ProtocolNumber, 388 AddressWithPrefix: addrWithPrefix, 389 } 390 addrDisp := &addressDispatcher{ 391 changedCh: make(chan addressChangedEvent, 1), 392 nicid: nicID, 393 addr: addrWithPrefix, 394 } 395 properties := stack.AddressProperties{ 396 Disp: addrDisp, 397 } 398 if err := s.AddProtocolAddress(nicID, protocolAddr, properties); err != nil { 399 t.Fatalf("AddProtocolAddress(%d, %+v, %#v) = %s", nicID, protocolAddr, properties, err) 400 } 401 402 // Should get the address immediately since we should not have performed 403 // DAD on it. 404 select { 405 case e := <-ndpDisp.dadC: 406 if diff := checkDADEvent(e, nicID, addr1, &stack.DADSucceeded{}); diff != "" { 407 t.Errorf("DAD event mismatch (-want +got):\n%s", diff) 408 } 409 default: 410 t.Fatal("expected DAD event") 411 } 412 if err := addrDisp.expectChanged(stack.AddressLifetimes{}, stack.AddressAssigned); err != nil { 413 t.Error(err) 414 } 415 if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, addrWithPrefix); err != nil { 416 t.Fatal(err) 417 } 418 419 // We should not have sent any NDP NS messages. 420 if got := s.Stats().ICMP.V6.PacketsSent.NeighborSolicit.Value(); got != 0 { 421 t.Fatalf("got NeighborSolicit = %d, want = 0", got) 422 } 423 } 424 425 func TestDADResolveLoopback(t *testing.T) { 426 const nicID = 1 427 ndpDisp := ndpDispatcher{ 428 dadC: make(chan ndpDADEvent, 1), 429 } 430 431 dadConfigs := stack.DADConfigurations{ 432 RetransmitTimer: time.Second, 433 DupAddrDetectTransmits: 1, 434 } 435 clock := faketime.NewManualClock() 436 s := stack.New(stack.Options{ 437 Clock: clock, 438 NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{ 439 NDPDisp: &ndpDisp, 440 DADConfigs: dadConfigs, 441 })}, 442 }) 443 if err := s.CreateNIC(nicID, loopback.New()); err != nil { 444 t.Fatalf("CreateNIC(%d, _) = %s", nicID, err) 445 } 446 447 addrWithPrefix := tcpip.AddressWithPrefix{ 448 Address: addr1, 449 PrefixLen: defaultPrefixLen, 450 } 451 addrDisp := &addressDispatcher{ 452 nicid: nicID, 453 addr: addrWithPrefix, 454 changedCh: make(chan addressChangedEvent, 1), 455 } 456 properties := stack.AddressProperties{ 457 Disp: addrDisp, 458 } 459 protocolAddr := tcpip.ProtocolAddress{ 460 Protocol: header.IPv6ProtocolNumber, 461 AddressWithPrefix: addrWithPrefix, 462 } 463 if err := s.AddProtocolAddress(nicID, protocolAddr, properties); err != nil { 464 t.Fatalf("AddProtocolAddress(%d, %+v, %#v) = %s", nicID, protocolAddr, properties, err) 465 } 466 467 // Address should not be considered bound to the NIC yet (DAD ongoing). 468 if err := addrDisp.expectChanged(stack.AddressLifetimes{}, stack.AddressTentative); err != nil { 469 t.Error(err) 470 } 471 if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil { 472 t.Fatal(err) 473 } 474 475 // DAD should not resolve after the normal resolution time since our DAD 476 // message was looped back - we should extend our DAD process. 477 dadResolutionTime := time.Duration(dadConfigs.DupAddrDetectTransmits) * dadConfigs.RetransmitTimer 478 clock.Advance(dadResolutionTime) 479 if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil { 480 t.Error(err) 481 } 482 483 // Make sure the address does not resolve before the extended resolution time 484 // has passed. 485 const delta = time.Nanosecond 486 // DAD will send extra NS probes if an NS message is looped back. 487 const extraTransmits = 3 488 clock.Advance(dadResolutionTime*extraTransmits - delta) 489 if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil { 490 t.Error(err) 491 } 492 493 // DAD should now resolve. 494 clock.Advance(delta) 495 if diff := checkDADEvent(<-ndpDisp.dadC, nicID, addr1, &stack.DADSucceeded{}); diff != "" { 496 t.Errorf("DAD event mismatch (-want +got):\n%s", diff) 497 } 498 if err := addrDisp.expectStateChanged(stack.AddressAssigned); err != nil { 499 t.Error(err) 500 } 501 } 502 503 // TestDADResolve tests that an address successfully resolves after performing 504 // DAD for various values of DupAddrDetectTransmits and RetransmitTimer. 505 // Included in the subtests is a test to make sure that an invalid 506 // RetransmitTimer (<1ms) values get fixed to the default RetransmitTimer of 1s. 507 // This tests also validates the NDP NS packet that is transmitted. 508 func TestDADResolve(t *testing.T) { 509 const nicID = 1 510 511 tests := []struct { 512 name string 513 linkHeaderLen uint16 514 dupAddrDetectTransmits uint8 515 retransTimer time.Duration 516 expectedRetransmitTimer time.Duration 517 }{ 518 { 519 name: "1:1s:1s", 520 dupAddrDetectTransmits: 1, 521 retransTimer: time.Second, 522 expectedRetransmitTimer: time.Second, 523 }, 524 { 525 name: "2:1s:1s", 526 linkHeaderLen: 1, 527 dupAddrDetectTransmits: 2, 528 retransTimer: time.Second, 529 expectedRetransmitTimer: time.Second, 530 }, 531 { 532 name: "1:2s:2s", 533 linkHeaderLen: 2, 534 dupAddrDetectTransmits: 1, 535 retransTimer: 2 * time.Second, 536 expectedRetransmitTimer: 2 * time.Second, 537 }, 538 // 0s is an invalid RetransmitTimer timer and will be fixed to 539 // the default RetransmitTimer value of 1s. 540 { 541 name: "1:0s:1s", 542 linkHeaderLen: 3, 543 dupAddrDetectTransmits: 1, 544 retransTimer: 0, 545 expectedRetransmitTimer: time.Second, 546 }, 547 } 548 549 for _, test := range tests { 550 t.Run(test.name, func(t *testing.T) { 551 ndpDisp := ndpDispatcher{ 552 dadC: make(chan ndpDADEvent, 1), 553 } 554 e := channelLinkWithHeaderLength{ 555 Endpoint: channel.New(int(test.dupAddrDetectTransmits), 1280, linkAddr1), 556 headerLength: test.linkHeaderLen, 557 } 558 e.Endpoint.LinkEPCapabilities |= stack.CapabilityResolutionRequired 559 560 clock := faketime.NewManualClock() 561 s := stack.New(stack.Options{ 562 Clock: clock, 563 RandSource: rand.NewSource(time.Now().UnixNano()), 564 NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{ 565 NDPDisp: &ndpDisp, 566 DADConfigs: stack.DADConfigurations{ 567 RetransmitTimer: test.retransTimer, 568 DupAddrDetectTransmits: test.dupAddrDetectTransmits, 569 }, 570 })}, 571 }) 572 if err := s.CreateNIC(nicID, &e); err != nil { 573 t.Fatalf("CreateNIC(%d, _) = %s", nicID, err) 574 } 575 576 // We add a default route so the call to FindRoute below will succeed 577 // once we have an assigned address. 578 s.SetRouteTable([]tcpip.Route{{ 579 Destination: header.IPv6EmptySubnet, 580 Gateway: addr3, 581 NIC: nicID, 582 }}) 583 584 addrWithPrefix := tcpip.AddressWithPrefix{ 585 Address: addr1, 586 PrefixLen: defaultPrefixLen, 587 } 588 addrDisp := &addressDispatcher{ 589 nicid: nicID, 590 addr: addrWithPrefix, 591 changedCh: make(chan addressChangedEvent, 1), 592 } 593 protocolAddr := tcpip.ProtocolAddress{ 594 Protocol: header.IPv6ProtocolNumber, 595 AddressWithPrefix: addrWithPrefix, 596 } 597 if err := s.AddProtocolAddress(nicID, protocolAddr, stack.AddressProperties{Disp: addrDisp}); err != nil { 598 t.Fatalf("AddProtocolAddress(%d, %+v, {}) = %s", nicID, protocolAddr, err) 599 } 600 if err := addrDisp.expectChanged(stack.AddressLifetimes{}, stack.AddressTentative); err != nil { 601 t.Error(err) 602 } 603 604 // Make sure the address does not resolve before the resolution time has 605 // passed. 606 const delta = time.Nanosecond 607 clock.Advance(test.expectedRetransmitTimer*time.Duration(test.dupAddrDetectTransmits) - delta) 608 if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil { 609 t.Error(err) 610 } 611 // Should not get a route even if we specify the local address as the 612 // tentative address. 613 { 614 r, err := s.FindRoute(nicID, tcpip.Address{}, addr2, header.IPv6ProtocolNumber, false) 615 if _, ok := err.(*tcpip.ErrHostUnreachable); !ok { 616 t.Errorf("got FindRoute(%d, '', %s, %d, false) = (%+v, %v), want = (_, %s)", nicID, addr2, header.IPv6ProtocolNumber, r, err, &tcpip.ErrHostUnreachable{}) 617 } 618 if r != nil { 619 r.Release() 620 } 621 } 622 { 623 r, err := s.FindRoute(nicID, addr1, addr2, header.IPv6ProtocolNumber, false) 624 if _, ok := err.(*tcpip.ErrHostUnreachable); !ok { 625 t.Errorf("got FindRoute(%d, %s, %s, %d, false) = (%+v, %v), want = (_, %s)", nicID, addr1, addr2, header.IPv6ProtocolNumber, r, err, &tcpip.ErrHostUnreachable{}) 626 } 627 if r != nil { 628 r.Release() 629 } 630 } 631 632 if t.Failed() { 633 t.FailNow() 634 } 635 636 // Wait for DAD to resolve. 637 clock.Advance(delta) 638 select { 639 case e := <-ndpDisp.dadC: 640 if diff := checkDADEvent(e, nicID, addr1, &stack.DADSucceeded{}); diff != "" { 641 t.Errorf("DAD event mismatch (-want +got):\n%s", diff) 642 } 643 default: 644 t.Fatalf("expected DAD event for %s on NIC(%d)", addr1, nicID) 645 } 646 if err := addrDisp.expectStateChanged(stack.AddressAssigned); err != nil { 647 t.Error(err) 648 } 649 if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, addrWithPrefix); err != nil { 650 t.Error(err) 651 } 652 // Should get a route using the address now that it is resolved. 653 { 654 r, err := s.FindRoute(nicID, tcpip.Address{}, addr2, header.IPv6ProtocolNumber, false) 655 if err != nil { 656 t.Errorf("got FindRoute(%d, '', %s, %d, false): %s", nicID, addr2, header.IPv6ProtocolNumber, err) 657 } else if r.LocalAddress() != addr1 { 658 t.Errorf("got r.LocalAddress() = %s, want = %s", r.LocalAddress(), addr1) 659 } 660 r.Release() 661 } 662 { 663 r, err := s.FindRoute(nicID, addr1, addr2, header.IPv6ProtocolNumber, false) 664 if err != nil { 665 t.Errorf("got FindRoute(%d, %s, %s, %d, false): %s", nicID, addr1, addr2, header.IPv6ProtocolNumber, err) 666 } else if r.LocalAddress() != addr1 { 667 t.Errorf("got r.LocalAddress() = %s, want = %s", r.LocalAddress(), addr1) 668 } 669 if r != nil { 670 r.Release() 671 } 672 } 673 674 if t.Failed() { 675 t.FailNow() 676 } 677 678 // Should not have sent any more NS messages. 679 if got := s.Stats().ICMP.V6.PacketsSent.NeighborSolicit.Value(); got != uint64(test.dupAddrDetectTransmits) { 680 t.Fatalf("got NeighborSolicit = %d, want = %d", got, test.dupAddrDetectTransmits) 681 } 682 683 // Validate the sent Neighbor Solicitation messages. 684 for i := uint8(0); i < test.dupAddrDetectTransmits; i++ { 685 p := e.Read() 686 if p == nil { 687 t.Fatal("packet didn't arrive") 688 } 689 690 // Make sure its an IPv6 packet. 691 if p.NetworkProtocolNumber != header.IPv6ProtocolNumber { 692 t.Fatalf("got Proto = %d, want = %d", p.NetworkProtocolNumber, header.IPv6ProtocolNumber) 693 } 694 695 // Make sure the right remote link address is used. 696 snmc := header.SolicitedNodeAddr(addr1) 697 if want := header.EthernetAddressFromMulticastIPv6Address(snmc); p.EgressRoute.RemoteLinkAddress != want { 698 t.Errorf("got remote link address = %s, want = %s", p.EgressRoute.RemoteLinkAddress, want) 699 } 700 701 // Check NDP NS packet. 702 // 703 // As per RFC 4861 section 4.3, a possible option is the Source Link 704 // Layer option, but this option MUST NOT be included when the source 705 // address of the packet is the unspecified address. 706 payload := stack.PayloadSince(p.NetworkHeader()) 707 defer payload.Release() 708 checker.IPv6(t, payload, 709 checker.SrcAddr(header.IPv6Any), 710 checker.DstAddr(snmc), 711 checker.TTL(header.NDPHopLimit), 712 checker.NDPNS( 713 checker.NDPNSTargetAddress(addr1), 714 )) 715 716 if l, want := p.AvailableHeaderBytes(), int(test.linkHeaderLen); l != want { 717 t.Errorf("got p.AvailableHeaderBytes() = %d; want = %d", l, want) 718 } 719 p.DecRef() 720 } 721 }) 722 } 723 } 724 725 func rxNDPSolicit(e *channel.Endpoint, tgt tcpip.Address) { 726 hdr := prependable.New(header.IPv6MinimumSize + header.ICMPv6NeighborSolicitMinimumSize) 727 pkt := header.ICMPv6(hdr.Prepend(header.ICMPv6NeighborSolicitMinimumSize)) 728 pkt.SetType(header.ICMPv6NeighborSolicit) 729 ns := header.NDPNeighborSolicit(pkt.MessageBody()) 730 ns.SetTargetAddress(tgt) 731 snmc := header.SolicitedNodeAddr(tgt) 732 pkt.SetChecksum(header.ICMPv6Checksum(header.ICMPv6ChecksumParams{ 733 Header: pkt, 734 Src: header.IPv6Any, 735 Dst: snmc, 736 })) 737 payloadLength := hdr.UsedLength() 738 ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize)) 739 ip.Encode(&header.IPv6Fields{ 740 PayloadLength: uint16(payloadLength), 741 TransportProtocol: icmp.ProtocolNumber6, 742 HopLimit: 255, 743 SrcAddr: header.IPv6Any, 744 DstAddr: snmc, 745 }) 746 e.InjectInbound(header.IPv6ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{Payload: buffer.MakeWithData(hdr.View())})) 747 } 748 749 // TestDADFail tests to make sure that the DAD process fails if another node is 750 // detected to be performing DAD on the same address (receive an NS message from 751 // a node doing DAD for the same address), or if another node is detected to own 752 // the address already (receive an NA message for the tentative address). 753 func TestDADFail(t *testing.T) { 754 const nicID = 1 755 756 tests := []struct { 757 name string 758 rxPkt func(e *channel.Endpoint, tgt tcpip.Address) 759 getStat func(s tcpip.ICMPv6ReceivedPacketStats) *tcpip.StatCounter 760 expectedHolderLinkAddress tcpip.LinkAddress 761 }{ 762 { 763 name: "RxSolicit", 764 rxPkt: rxNDPSolicit, 765 getStat: func(s tcpip.ICMPv6ReceivedPacketStats) *tcpip.StatCounter { 766 return s.NeighborSolicit 767 }, 768 expectedHolderLinkAddress: "", 769 }, 770 { 771 name: "RxAdvert", 772 rxPkt: func(e *channel.Endpoint, tgt tcpip.Address) { 773 naSize := header.ICMPv6NeighborAdvertMinimumSize + header.NDPLinkLayerAddressSize 774 hdr := prependable.New(header.IPv6MinimumSize + naSize) 775 pkt := header.ICMPv6(hdr.Prepend(naSize)) 776 pkt.SetType(header.ICMPv6NeighborAdvert) 777 na := header.NDPNeighborAdvert(pkt.MessageBody()) 778 na.SetSolicitedFlag(true) 779 na.SetOverrideFlag(true) 780 na.SetTargetAddress(tgt) 781 na.Options().Serialize(header.NDPOptionsSerializer{ 782 header.NDPTargetLinkLayerAddressOption(linkAddr1), 783 }) 784 pkt.SetChecksum(header.ICMPv6Checksum(header.ICMPv6ChecksumParams{ 785 Header: pkt, 786 Src: tgt, 787 Dst: header.IPv6AllNodesMulticastAddress, 788 })) 789 payloadLength := hdr.UsedLength() 790 ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize)) 791 ip.Encode(&header.IPv6Fields{ 792 PayloadLength: uint16(payloadLength), 793 TransportProtocol: icmp.ProtocolNumber6, 794 HopLimit: 255, 795 SrcAddr: tgt, 796 DstAddr: header.IPv6AllNodesMulticastAddress, 797 }) 798 e.InjectInbound(header.IPv6ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{Payload: buffer.MakeWithData(hdr.View())})) 799 }, 800 getStat: func(s tcpip.ICMPv6ReceivedPacketStats) *tcpip.StatCounter { 801 return s.NeighborAdvert 802 }, 803 expectedHolderLinkAddress: linkAddr1, 804 }, 805 } 806 807 for _, test := range tests { 808 t.Run(test.name, func(t *testing.T) { 809 ndpDisp := ndpDispatcher{ 810 dadC: make(chan ndpDADEvent, 1), 811 } 812 dadConfigs := stack.DefaultDADConfigurations() 813 dadConfigs.RetransmitTimer = time.Second * 2 814 815 e := channel.New(0, 1280, linkAddr1) 816 clock := faketime.NewManualClock() 817 s := stack.New(stack.Options{ 818 NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{ 819 NDPDisp: &ndpDisp, 820 DADConfigs: dadConfigs, 821 })}, 822 Clock: clock, 823 }) 824 if err := s.CreateNIC(nicID, e); err != nil { 825 t.Fatalf("CreateNIC(%d, _) = %s", nicID, err) 826 } 827 828 addrDisp := &addressDispatcher{ 829 changedCh: make(chan addressChangedEvent, 1), 830 removedCh: make(chan stack.AddressRemovalReason, 1), 831 nicid: nicID, 832 addr: addr1.WithPrefix(), 833 } 834 properties := stack.AddressProperties{ 835 Disp: addrDisp, 836 } 837 protocolAddr := tcpip.ProtocolAddress{ 838 Protocol: header.IPv6ProtocolNumber, 839 AddressWithPrefix: addr1.WithPrefix(), 840 } 841 if err := s.AddProtocolAddress(nicID, protocolAddr, properties); err != nil { 842 t.Fatalf("AddProtocolAddress(%d, %+v, %#v): %s", nicID, protocolAddr, properties, err) 843 } 844 if err := addrDisp.expectChanged(stack.AddressLifetimes{}, stack.AddressTentative); err != nil { 845 t.Fatal(err) 846 } 847 848 // Address should not be considered bound to the NIC yet 849 // (DAD ongoing). 850 if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil { 851 t.Fatal(err) 852 } 853 854 // Receive a packet to simulate an address conflict. 855 test.rxPkt(e, addr1) 856 857 stat := test.getStat(s.Stats().ICMP.V6.PacketsReceived) 858 if got := stat.Value(); got != 1 { 859 t.Fatalf("got stat = %d, want = 1", got) 860 } 861 862 // Wait for DAD to fail and make sure the address did 863 // not get resolved. 864 clock.Advance(time.Duration(dadConfigs.DupAddrDetectTransmits) * dadConfigs.RetransmitTimer) 865 select { 866 case e := <-ndpDisp.dadC: 867 if diff := checkDADEvent(e, nicID, addr1, &stack.DADDupAddrDetected{HolderLinkAddress: test.expectedHolderLinkAddress}); diff != "" { 868 t.Errorf("DAD event mismatch (-want +got):\n%s", diff) 869 } 870 default: 871 // If we don't get a failure event after the 872 // expected resolution time + extra 1s buffer, 873 // something is wrong. 874 t.Fatal("timed out waiting for DAD failure") 875 } 876 if err := addrDisp.expectRemoved(stack.AddressRemovalDADFailed); err != nil { 877 t.Fatal(err) 878 } 879 if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil { 880 t.Fatal(err) 881 } 882 883 // Attempting to add the address again should not fail if the address's 884 // state was cleaned up when DAD failed. 885 if err := s.AddProtocolAddress(nicID, protocolAddr, stack.AddressProperties{}); err != nil { 886 t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", nicID, protocolAddr, err) 887 } 888 }) 889 } 890 } 891 892 func TestDADStop(t *testing.T) { 893 const nicID = 1 894 895 tests := []struct { 896 name string 897 stopFn func(t *testing.T, s *stack.Stack) 898 verifyFn func(t *testing.T, ad *addressDispatcher) 899 skipFinalAddrCheck bool 900 }{ 901 // Tests to make sure that DAD stops when an address is removed. 902 { 903 name: "Remove address", 904 stopFn: func(t *testing.T, s *stack.Stack) { 905 if err := s.RemoveAddress(nicID, addr1); err != nil { 906 t.Fatalf("RemoveAddress(%d, %s): %s", nicID, addr1, err) 907 } 908 }, 909 verifyFn: func(t *testing.T, ad *addressDispatcher) { 910 if err := ad.expectRemoved(stack.AddressRemovalManualAction); err != nil { 911 t.Error(err) 912 } 913 }, 914 }, 915 916 // Tests to make sure that DAD stops when the NIC is disabled. 917 { 918 name: "Disable NIC", 919 stopFn: func(t *testing.T, s *stack.Stack) { 920 if err := s.DisableNIC(nicID); err != nil { 921 t.Fatalf("DisableNIC(%d): %s", nicID, err) 922 } 923 }, 924 verifyFn: func(t *testing.T, ad *addressDispatcher) { 925 if err := ad.expectStateChanged(stack.AddressDisabled); err != nil { 926 t.Error(err) 927 } 928 }, 929 }, 930 931 // Tests to make sure that DAD stops when the NIC is removed. 932 { 933 name: "Remove NIC", 934 stopFn: func(t *testing.T, s *stack.Stack) { 935 if err := s.RemoveNIC(nicID); err != nil { 936 t.Fatalf("RemoveNIC(%d): %s", nicID, err) 937 } 938 }, 939 verifyFn: func(t *testing.T, ad *addressDispatcher) { 940 if err := ad.expectRemoved(stack.AddressRemovalInterfaceRemoved); err != nil { 941 t.Error(err) 942 } 943 }, 944 // The NIC is removed so we can't check its addresses after calling 945 // stopFn. 946 skipFinalAddrCheck: true, 947 }, 948 } 949 950 for _, test := range tests { 951 t.Run(test.name, func(t *testing.T) { 952 ndpDisp := ndpDispatcher{ 953 dadC: make(chan ndpDADEvent, 1), 954 } 955 956 dadConfigs := stack.DADConfigurations{ 957 RetransmitTimer: time.Second, 958 DupAddrDetectTransmits: 2, 959 } 960 961 e := channel.New(0, 1280, linkAddr1) 962 clock := faketime.NewManualClock() 963 s := stack.New(stack.Options{ 964 NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{ 965 NDPDisp: &ndpDisp, 966 DADConfigs: dadConfigs, 967 })}, 968 Clock: clock, 969 }) 970 if err := s.CreateNIC(nicID, e); err != nil { 971 t.Fatalf("CreateNIC(%d, _): %s", nicID, err) 972 } 973 974 addrDisp := &addressDispatcher{ 975 nicid: nicID, 976 addr: addr1.WithPrefix(), 977 changedCh: make(chan addressChangedEvent, 1), 978 removedCh: make(chan stack.AddressRemovalReason, 1), 979 } 980 properties := stack.AddressProperties{ 981 Disp: addrDisp, 982 } 983 protocolAddr := tcpip.ProtocolAddress{ 984 Protocol: header.IPv6ProtocolNumber, 985 AddressWithPrefix: addr1.WithPrefix(), 986 } 987 if err := s.AddProtocolAddress(nicID, protocolAddr, properties); err != nil { 988 t.Fatalf("AddProtocolAddress(%d, %+v, %#v): %s", nicID, protocolAddr, properties, err) 989 } 990 if err := addrDisp.expectChanged(stack.AddressLifetimes{}, stack.AddressTentative); err != nil { 991 t.Fatal(err) 992 } 993 994 // Address should not be considered bound to the NIC yet (DAD ongoing). 995 if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil { 996 t.Fatal(err) 997 } 998 999 test.stopFn(t, s) 1000 1001 // Wait for DAD to fail (since the address was removed during DAD). 1002 clock.Advance(time.Duration(dadConfigs.DupAddrDetectTransmits) * dadConfigs.RetransmitTimer) 1003 select { 1004 case e := <-ndpDisp.dadC: 1005 if diff := checkDADEvent(e, nicID, addr1, &stack.DADAborted{}); diff != "" { 1006 t.Errorf("DAD event mismatch (-want +got):\n%s", diff) 1007 } 1008 default: 1009 // If we don't get a failure event after the expected resolution 1010 // time + extra 1s buffer, something is wrong. 1011 t.Fatal("timed out waiting for DAD failure") 1012 } 1013 test.verifyFn(t, addrDisp) 1014 1015 if !test.skipFinalAddrCheck { 1016 if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil { 1017 t.Fatal(err) 1018 } 1019 } 1020 1021 // Should not have sent more than 1 NS message. 1022 if got := s.Stats().ICMP.V6.PacketsSent.NeighborSolicit.Value(); got > 1 { 1023 t.Errorf("got NeighborSolicit = %d, want <= 1", got) 1024 } 1025 }) 1026 } 1027 } 1028 1029 // TestSetNDPConfigurations tests that we can update and use per-interface NDP 1030 // configurations without affecting the default NDP configurations or other 1031 // interfaces' configurations. 1032 func TestSetNDPConfigurations(t *testing.T) { 1033 const nicID1 = 1 1034 const nicID2 = 2 1035 const nicID3 = 3 1036 1037 tests := []struct { 1038 name string 1039 dupAddrDetectTransmits uint8 1040 retransmitTimer time.Duration 1041 expectedRetransmitTimer time.Duration 1042 }{ 1043 { 1044 "OK", 1045 1, 1046 time.Second, 1047 time.Second, 1048 }, 1049 { 1050 "Invalid Retransmit Timer", 1051 1, 1052 0, 1053 time.Second, 1054 }, 1055 } 1056 1057 for _, test := range tests { 1058 t.Run(test.name, func(t *testing.T) { 1059 ndpDisp := ndpDispatcher{ 1060 dadC: make(chan ndpDADEvent, 1), 1061 } 1062 e := channel.New(0, 1280, linkAddr1) 1063 clock := faketime.NewManualClock() 1064 s := stack.New(stack.Options{ 1065 NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{ 1066 NDPDisp: &ndpDisp, 1067 })}, 1068 Clock: clock, 1069 }) 1070 1071 expectDADSucceeded := func(nicID tcpip.NICID, addr tcpip.Address) { 1072 select { 1073 case e := <-ndpDisp.dadC: 1074 if diff := checkDADEvent(e, nicID, addr, &stack.DADSucceeded{}); diff != "" { 1075 t.Errorf("DAD event mismatch (-want +got):\n%s", diff) 1076 } 1077 default: 1078 t.Fatalf("expected DAD event for %s", addr) 1079 } 1080 } 1081 1082 // This NIC(1)'s NDP configurations will be updated to 1083 // be different from the default. 1084 if err := s.CreateNIC(nicID1, e); err != nil { 1085 t.Fatalf("CreateNIC(%d, _) = %s", nicID1, err) 1086 } 1087 1088 // Created before updating NIC(1)'s NDP configurations 1089 // but updating NIC(1)'s NDP configurations should not 1090 // affect other existing NICs. 1091 if err := s.CreateNIC(nicID2, e); err != nil { 1092 t.Fatalf("CreateNIC(%d, _) = %s", nicID2, err) 1093 } 1094 1095 // Update the configurations on NIC(1) to use DAD. 1096 if ipv6Ep, err := s.GetNetworkEndpoint(nicID1, header.IPv6ProtocolNumber); err != nil { 1097 t.Fatalf("s.GetNetworkEndpoint(%d, %d): %s", nicID1, header.IPv6ProtocolNumber, err) 1098 } else { 1099 dad := ipv6Ep.(stack.DuplicateAddressDetector) 1100 dad.SetDADConfigurations(stack.DADConfigurations{ 1101 DupAddrDetectTransmits: test.dupAddrDetectTransmits, 1102 RetransmitTimer: test.retransmitTimer, 1103 }) 1104 } 1105 1106 // Created after updating NIC(1)'s NDP configurations 1107 // but the stack's default NDP configurations should not 1108 // have been updated. 1109 if err := s.CreateNIC(nicID3, e); err != nil { 1110 t.Fatalf("CreateNIC(%d, _) = %s", nicID3, err) 1111 } 1112 1113 // Add addresses for each NIC. 1114 addrWithPrefix1 := tcpip.AddressWithPrefix{Address: addr1, PrefixLen: defaultPrefixLen} 1115 protocolAddr1 := tcpip.ProtocolAddress{ 1116 Protocol: header.IPv6ProtocolNumber, 1117 AddressWithPrefix: addrWithPrefix1, 1118 } 1119 addr1Disp := addressDispatcher{ 1120 nicid: nicID1, 1121 addr: addrWithPrefix1, 1122 changedCh: make(chan addressChangedEvent, 1), 1123 removedCh: make(chan stack.AddressRemovalReason, 1), 1124 } 1125 properties1 := stack.AddressProperties{ 1126 Disp: &addr1Disp, 1127 } 1128 if err := s.AddProtocolAddress(nicID1, protocolAddr1, properties1); err != nil { 1129 t.Fatalf("AddProtocolAddress(%d, %+v, %#v) = %s", nicID1, protocolAddr1, properties1, err) 1130 } 1131 if err := addr1Disp.expectChanged(stack.AddressLifetimes{}, stack.AddressTentative); err != nil { 1132 t.Error(err) 1133 } 1134 addrWithPrefix2 := tcpip.AddressWithPrefix{Address: addr2, PrefixLen: defaultPrefixLen} 1135 protocolAddr2 := tcpip.ProtocolAddress{ 1136 Protocol: header.IPv6ProtocolNumber, 1137 AddressWithPrefix: addrWithPrefix2, 1138 } 1139 addr2Disp := addressDispatcher{ 1140 nicid: nicID2, 1141 addr: addrWithPrefix2, 1142 changedCh: make(chan addressChangedEvent, 1), 1143 removedCh: make(chan stack.AddressRemovalReason, 1), 1144 } 1145 properties2 := stack.AddressProperties{ 1146 Disp: &addr2Disp, 1147 } 1148 if err := s.AddProtocolAddress(nicID2, protocolAddr2, properties2); err != nil { 1149 t.Fatalf("AddProtocolAddress(%d, %+v, %#v) = %s", nicID2, protocolAddr2, properties2, err) 1150 } 1151 expectDADSucceeded(nicID2, addr2) 1152 if err := addr2Disp.expectChanged(stack.AddressLifetimes{}, stack.AddressAssigned); err != nil { 1153 t.Error(err) 1154 } 1155 addrWithPrefix3 := tcpip.AddressWithPrefix{Address: addr3, PrefixLen: defaultPrefixLen} 1156 protocolAddr3 := tcpip.ProtocolAddress{ 1157 Protocol: header.IPv6ProtocolNumber, 1158 AddressWithPrefix: addrWithPrefix3, 1159 } 1160 addr3Disp := addressDispatcher{ 1161 nicid: nicID3, 1162 addr: addrWithPrefix3, 1163 changedCh: make(chan addressChangedEvent, 1), 1164 removedCh: make(chan stack.AddressRemovalReason, 1), 1165 } 1166 properties3 := stack.AddressProperties{ 1167 Disp: &addr3Disp, 1168 } 1169 if err := s.AddProtocolAddress(nicID3, protocolAddr3, properties3); err != nil { 1170 t.Fatalf("AddProtocolAddress(%d, %+v, %#v) = %s", nicID3, protocolAddr3, properties3, err) 1171 } 1172 expectDADSucceeded(nicID3, addr3) 1173 if err := addr3Disp.expectChanged(stack.AddressLifetimes{}, stack.AddressAssigned); err != nil { 1174 t.Error(err) 1175 } 1176 1177 // Address should not be considered bound to NIC(1) yet 1178 // (DAD ongoing). 1179 if err := checkGetMainNICAddress(s, nicID1, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil { 1180 t.Fatal(err) 1181 } 1182 1183 // Should get the address on NIC(2) and NIC(3) 1184 // immediately since we should not have performed DAD on 1185 // it as the stack was configured to not do DAD by 1186 // default and we only updated the NDP configurations on 1187 // NIC(1). 1188 if err := checkGetMainNICAddress(s, nicID2, header.IPv6ProtocolNumber, addrWithPrefix2); err != nil { 1189 t.Fatal(err) 1190 } 1191 if err := checkGetMainNICAddress(s, nicID3, header.IPv6ProtocolNumber, addrWithPrefix3); err != nil { 1192 t.Fatal(err) 1193 } 1194 1195 // Sleep until right before resolution to make sure the address didn't 1196 // resolve on NIC(1) yet. 1197 const delta = 1 1198 clock.Advance(time.Duration(test.dupAddrDetectTransmits)*test.expectedRetransmitTimer - delta) 1199 if err := checkGetMainNICAddress(s, nicID1, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil { 1200 t.Fatal(err) 1201 } 1202 1203 // Wait for DAD to resolve. 1204 clock.Advance(delta) 1205 expectDADSucceeded(nicID1, addr1) 1206 if err := addr1Disp.expectStateChanged(stack.AddressAssigned); err != nil { 1207 t.Error(err) 1208 } 1209 if err := checkGetMainNICAddress(s, nicID1, header.IPv6ProtocolNumber, addrWithPrefix1); err != nil { 1210 t.Fatal(err) 1211 } 1212 }) 1213 } 1214 } 1215 1216 // raBuf returns a valid NDP Router Advertisement with options, router 1217 // preference and DHCPv6 configurations specified. 1218 func raBuf(ip tcpip.Address, rl uint16, managedAddress, otherConfigurations bool, prf header.NDPRoutePreference, optSer header.NDPOptionsSerializer) *stack.PacketBuffer { 1219 const flagsByte = 1 1220 const routerLifetimeOffset = 2 1221 1222 icmpSize := header.ICMPv6HeaderSize + header.NDPRAMinimumSize + optSer.Length() 1223 hdr := prependable.New(header.IPv6MinimumSize + icmpSize) 1224 pkt := header.ICMPv6(hdr.Prepend(icmpSize)) 1225 pkt.SetType(header.ICMPv6RouterAdvert) 1226 pkt.SetCode(0) 1227 raPayload := pkt.MessageBody() 1228 ra := header.NDPRouterAdvert(raPayload) 1229 // Populate the Router Lifetime. 1230 binary.BigEndian.PutUint16(raPayload[routerLifetimeOffset:], rl) 1231 // Populate the Managed Address flag field. 1232 if managedAddress { 1233 // The Managed Addresses flag field is the 7th bit of the flags byte. 1234 raPayload[flagsByte] |= 1 << 7 1235 } 1236 // Populate the Other Configurations flag field. 1237 if otherConfigurations { 1238 // The Other Configurations flag field is the 6th bit of the flags byte. 1239 raPayload[flagsByte] |= 1 << 6 1240 } 1241 // The Prf field is held in the flags byte. 1242 raPayload[flagsByte] |= byte(prf) << 3 1243 opts := ra.Options() 1244 opts.Serialize(optSer) 1245 pkt.SetChecksum(header.ICMPv6Checksum(header.ICMPv6ChecksumParams{ 1246 Header: pkt, 1247 Src: ip, 1248 Dst: header.IPv6AllNodesMulticastAddress, 1249 })) 1250 payloadLength := hdr.UsedLength() 1251 iph := header.IPv6(hdr.Prepend(header.IPv6MinimumSize)) 1252 iph.Encode(&header.IPv6Fields{ 1253 PayloadLength: uint16(payloadLength), 1254 TransportProtocol: icmp.ProtocolNumber6, 1255 HopLimit: header.NDPHopLimit, 1256 SrcAddr: ip, 1257 DstAddr: header.IPv6AllNodesMulticastAddress, 1258 }) 1259 1260 return stack.NewPacketBuffer(stack.PacketBufferOptions{ 1261 Payload: buffer.MakeWithData(hdr.View()), 1262 }) 1263 } 1264 1265 // raBufWithOpts returns a valid NDP Router Advertisement with options. 1266 // 1267 // Note, raBufWithOpts does not populate any of the RA fields other than the 1268 // Router Lifetime. 1269 func raBufWithOpts(ip tcpip.Address, rl uint16, optSer header.NDPOptionsSerializer) *stack.PacketBuffer { 1270 return raBuf(ip, rl, false /* managedAddress */, false /* otherConfigurations */, 0 /* prf */, optSer) 1271 } 1272 1273 // raBufWithDHCPv6 returns a valid NDP Router Advertisement with DHCPv6 related 1274 // fields set. 1275 // 1276 // Note, raBufWithDHCPv6 does not populate any of the RA fields other than the 1277 // DHCPv6 related ones. 1278 func raBufWithDHCPv6(ip tcpip.Address, managedAddresses, otherConfigurations bool) *stack.PacketBuffer { 1279 return raBuf(ip, 0, managedAddresses, otherConfigurations, 0 /* prf */, header.NDPOptionsSerializer{}) 1280 } 1281 1282 // raBuf returns a valid NDP Router Advertisement. 1283 // 1284 // Note, raBuf does not populate any of the RA fields other than the 1285 // Router Lifetime. 1286 func raBufSimple(ip tcpip.Address, rl uint16) *stack.PacketBuffer { 1287 return raBufWithOpts(ip, rl, header.NDPOptionsSerializer{}) 1288 } 1289 1290 // raBufWithPrf returns a valid NDP Router Advertisement with a preference. 1291 // 1292 // Note, raBufWithPrf does not populate any of the RA fields other than the 1293 // Router Lifetime and Default Router Preference fields. 1294 func raBufWithPrf(ip tcpip.Address, rl uint16, prf header.NDPRoutePreference) *stack.PacketBuffer { 1295 return raBuf(ip, rl, false /* managedAddress */, false /* otherConfigurations */, prf, header.NDPOptionsSerializer{}) 1296 } 1297 1298 // raBufWithPI returns a valid NDP Router Advertisement with a single Prefix 1299 // Information option. 1300 // 1301 // Note, raBufWithPI does not populate any of the RA fields other than the 1302 // Router Lifetime. 1303 func raBufWithPI(ip tcpip.Address, rl uint16, prefix tcpip.AddressWithPrefix, onLink, auto bool, vl, pl uint32) *stack.PacketBuffer { 1304 flags := uint8(0) 1305 if onLink { 1306 // The OnLink flag is the 7th bit in the flags byte. 1307 flags |= 1 << 7 1308 } 1309 if auto { 1310 // The Address Auto-Configuration flag is the 6th bit in the 1311 // flags byte. 1312 flags |= 1 << 6 1313 } 1314 1315 // A valid header.NDPPrefixInformation must be 30 bytes. 1316 buf := [30]byte{} 1317 // The first byte in a header.NDPPrefixInformation is the Prefix Length 1318 // field. 1319 buf[0] = uint8(prefix.PrefixLen) 1320 // The 2nd byte within a header.NDPPrefixInformation is the Flags field. 1321 buf[1] = flags 1322 // The Valid Lifetime field starts after the 2nd byte within a 1323 // header.NDPPrefixInformation. 1324 binary.BigEndian.PutUint32(buf[2:], vl) 1325 // The Preferred Lifetime field starts after the 6th byte within a 1326 // header.NDPPrefixInformation. 1327 binary.BigEndian.PutUint32(buf[6:], pl) 1328 // The Prefix Address field starts after the 14th byte within a 1329 // header.NDPPrefixInformation. 1330 copy(buf[14:], prefix.Address.AsSlice()) 1331 return raBufWithOpts(ip, rl, header.NDPOptionsSerializer{ 1332 header.NDPPrefixInformation(buf[:]), 1333 }) 1334 } 1335 1336 // raBufWithRIO returns a valid NDP Router Advertisement with a single Route 1337 // Information option. 1338 // 1339 // All fields in the RA will be zero except the RIO option. 1340 func raBufWithRIO(t *testing.T, ip tcpip.Address, prefix tcpip.AddressWithPrefix, lifetimeSeconds uint32, prf header.NDPRoutePreference) *stack.PacketBuffer { 1341 // buf will hold the route information option after the Type and Length 1342 // fields. 1343 // 1344 // 2.3. Route Information Option 1345 // 1346 // 0 1 2 3 1347 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 1348 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1349 // | Type | Length | Prefix Length |Resvd|Prf|Resvd| 1350 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1351 // | Route Lifetime | 1352 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1353 // | Prefix (Variable Length) | 1354 // . . 1355 // . . 1356 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1357 var buf [22]byte 1358 buf[0] = uint8(prefix.PrefixLen) 1359 buf[1] = byte(prf) << 3 1360 binary.BigEndian.PutUint32(buf[2:], lifetimeSeconds) 1361 if n := copy(buf[6:], prefix.Address.AsSlice()); n != prefix.Address.Len() { 1362 t.Fatalf("got copy(...) = %d, want = %d", n, prefix.Address.Len()) 1363 } 1364 return raBufWithOpts(ip, 0 /* router lifetime */, header.NDPOptionsSerializer{ 1365 header.NDPRouteInformation(buf[:]), 1366 }) 1367 } 1368 1369 func TestDynamicConfigurationsDisabled(t *testing.T) { 1370 const ( 1371 nicID = 1 1372 maxRtrSolicitDelay = time.Second 1373 ) 1374 1375 prefix := tcpip.AddressWithPrefix{ 1376 Address: testutil.MustParse6("102:304:506:708::"), 1377 PrefixLen: 64, 1378 } 1379 1380 tests := []struct { 1381 name string 1382 config func(bool) ipv6.NDPConfigurations 1383 ra *stack.PacketBuffer 1384 }{ 1385 { 1386 name: "No Router Discovery", 1387 config: func(enable bool) ipv6.NDPConfigurations { 1388 return ipv6.NDPConfigurations{DiscoverDefaultRouters: enable} 1389 }, 1390 ra: raBufSimple(llAddr2, 1000), 1391 }, 1392 { 1393 name: "No Prefix Discovery", 1394 config: func(enable bool) ipv6.NDPConfigurations { 1395 return ipv6.NDPConfigurations{DiscoverOnLinkPrefixes: enable} 1396 }, 1397 ra: raBufWithPI(llAddr2, 0, prefix, true, false, 10, 0), 1398 }, 1399 { 1400 name: "No Autogenerate Addresses", 1401 config: func(enable bool) ipv6.NDPConfigurations { 1402 return ipv6.NDPConfigurations{AutoGenGlobalAddresses: enable} 1403 }, 1404 ra: raBufWithPI(llAddr2, 0, prefix, false, true, 10, 0), 1405 }, 1406 } 1407 1408 for _, test := range tests { 1409 t.Run(test.name, func(t *testing.T) { 1410 // Being configured to discover routers/prefixes or auto-generate 1411 // addresses means RAs must be handled, and router/prefix discovery or 1412 // SLAAC must be enabled. 1413 // 1414 // This tests all possible combinations of the configurations where 1415 // router/prefix discovery or SLAAC are disabled. 1416 for i := 0; i < 7; i++ { 1417 handle := ipv6.HandlingRAsDisabled 1418 if i&1 != 0 { 1419 handle = ipv6.HandlingRAsEnabledWhenForwardingDisabled 1420 } 1421 enable := i&2 != 0 1422 forwarding := i&4 == 0 1423 1424 t.Run(fmt.Sprintf("HandleRAs(%s), Forwarding(%t), Enabled(%t)", handle, forwarding, enable), func(t *testing.T) { 1425 ndpDisp := ndpDispatcher{ 1426 offLinkRouteC: make(chan ndpOffLinkRouteEvent, 1), 1427 prefixC: make(chan ndpPrefixEvent, 1), 1428 autoGenAddrC: make(chan ndpAutoGenAddrEvent, 1), 1429 } 1430 ndpConfigs := test.config(enable) 1431 ndpConfigs.HandleRAs = handle 1432 ndpConfigs.MaxRtrSolicitations = 1 1433 ndpConfigs.RtrSolicitationInterval = maxRtrSolicitDelay 1434 ndpConfigs.MaxRtrSolicitationDelay = maxRtrSolicitDelay 1435 clock := faketime.NewManualClock() 1436 s := stack.New(stack.Options{ 1437 Clock: clock, 1438 NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{ 1439 NDPConfigs: ndpConfigs, 1440 NDPDisp: &ndpDisp, 1441 })}, 1442 }) 1443 if err := s.SetForwardingDefaultAndAllNICs(ipv6.ProtocolNumber, forwarding); err != nil { 1444 t.Fatalf("SetForwardingDefaultAndAllNICs(%d, %t): %s", ipv6.ProtocolNumber, forwarding, err) 1445 } 1446 1447 e := channel.New(1, 1280, linkAddr1) 1448 if err := s.CreateNIC(nicID, e); err != nil { 1449 t.Fatalf("CreateNIC(%d, _): %s", nicID, err) 1450 } 1451 1452 handleRAsDisabled := handle == ipv6.HandlingRAsDisabled || forwarding 1453 ep, err := s.GetNetworkEndpoint(nicID, ipv6.ProtocolNumber) 1454 if err != nil { 1455 t.Fatalf("s.GetNetworkEndpoint(%d, %d): %s", nicID, ipv6.ProtocolNumber, err) 1456 } 1457 stats := ep.Stats() 1458 v6Stats, ok := stats.(*ipv6.Stats) 1459 if !ok { 1460 t.Fatalf("got v6Stats = %T, expected = %T", stats, v6Stats) 1461 } 1462 1463 // Make sure that when handling RAs are enabled, we solicit routers. 1464 clock.Advance(maxRtrSolicitDelay) 1465 if got, want := v6Stats.ICMP.PacketsSent.RouterSolicit.Value(), boolToUint64(!handleRAsDisabled); got != want { 1466 t.Errorf("got v6Stats.ICMP.PacketsSent.RouterSolicit.Value() = %d, want = %d", got, want) 1467 } 1468 if handleRAsDisabled { 1469 if p := e.Read(); p != nil { 1470 t.Errorf("unexpectedly got a packet = %#v", p) 1471 } 1472 } else if p := e.Read(); p == nil { 1473 t.Error("expected router solicitation packet") 1474 } else if p.NetworkProtocolNumber != header.IPv6ProtocolNumber { 1475 t.Errorf("got Proto = %d, want = %d", p.NetworkProtocolNumber, header.IPv6ProtocolNumber) 1476 p.DecRef() 1477 } else { 1478 if want := header.EthernetAddressFromMulticastIPv6Address(header.IPv6AllRoutersLinkLocalMulticastAddress); p.EgressRoute.RemoteLinkAddress != want { 1479 t.Errorf("got remote link address = %s, want = %s", p.EgressRoute.RemoteLinkAddress, want) 1480 } 1481 1482 checker.IPv6(t, stack.PayloadSince(p.NetworkHeader()), 1483 checker.SrcAddr(header.IPv6Any), 1484 checker.DstAddr(header.IPv6AllRoutersLinkLocalMulticastAddress), 1485 checker.TTL(header.NDPHopLimit), 1486 checker.NDPRS(checker.NDPRSOptions(nil)), 1487 ) 1488 p.DecRef() 1489 } 1490 1491 // Make sure we do not discover any routers or prefixes, or perform 1492 // SLAAC on reception of an RA. 1493 e.InjectInbound(header.IPv6ProtocolNumber, test.ra.Clone()) 1494 // Make sure that the unhandled RA stat is only incremented when 1495 // handling RAs is disabled. 1496 if got, want := v6Stats.UnhandledRouterAdvertisements.Value(), boolToUint64(handleRAsDisabled); got != want { 1497 t.Errorf("got v6Stats.UnhandledRouterAdvertisements.Value() = %d, want = %d", got, want) 1498 } 1499 select { 1500 case e := <-ndpDisp.offLinkRouteC: 1501 t.Errorf("unexpectedly updated an off-link route when configured not to: %#v", e) 1502 default: 1503 } 1504 select { 1505 case e := <-ndpDisp.prefixC: 1506 t.Errorf("unexpectedly discovered a prefix when configured not to: %#v", e) 1507 default: 1508 } 1509 select { 1510 case e := <-ndpDisp.autoGenAddrC: 1511 t.Errorf("unexpectedly auto-generated an address when configured not to: %#v", e) 1512 default: 1513 } 1514 }) 1515 } 1516 }) 1517 } 1518 } 1519 1520 func boolToUint64(v bool) uint64 { 1521 if v { 1522 return 1 1523 } 1524 return 0 1525 } 1526 1527 func checkOffLinkRouteEvent(e ndpOffLinkRouteEvent, nicID tcpip.NICID, subnet tcpip.Subnet, router tcpip.Address, prf header.NDPRoutePreference, updated bool) string { 1528 return cmp.Diff(ndpOffLinkRouteEvent{nicID: nicID, subnet: subnet, router: router, prf: prf, updated: updated}, e, cmp.AllowUnexported(e)) 1529 } 1530 1531 func testWithRAs(t *testing.T, f func(*testing.T, ipv6.HandleRAsConfiguration, bool)) { 1532 tests := [...]struct { 1533 name string 1534 handleRAs ipv6.HandleRAsConfiguration 1535 forwarding bool 1536 }{ 1537 { 1538 name: "Handle RAs when forwarding disabled", 1539 handleRAs: ipv6.HandlingRAsEnabledWhenForwardingDisabled, 1540 forwarding: false, 1541 }, 1542 { 1543 name: "Always Handle RAs with forwarding disabled", 1544 handleRAs: ipv6.HandlingRAsAlwaysEnabled, 1545 forwarding: false, 1546 }, 1547 { 1548 name: "Always Handle RAs with forwarding enabled", 1549 handleRAs: ipv6.HandlingRAsAlwaysEnabled, 1550 forwarding: true, 1551 }, 1552 } 1553 1554 for _, test := range tests { 1555 t.Run(test.name, func(t *testing.T) { 1556 f(t, test.handleRAs, test.forwarding) 1557 }) 1558 } 1559 } 1560 1561 func TestOffLinkRouteDiscovery(t *testing.T) { 1562 const nicID = 1 1563 1564 moreSpecificPrefix := tcpip.AddressWithPrefix{Address: testutil.MustParse6("a00::"), PrefixLen: 16} 1565 tests := []struct { 1566 name string 1567 1568 discoverDefaultRouters bool 1569 discoverMoreSpecificRoutes bool 1570 1571 dest tcpip.Subnet 1572 ra func(*testing.T, tcpip.Address, uint16, header.NDPRoutePreference) *stack.PacketBuffer 1573 }{ 1574 { 1575 name: "Default router discovery", 1576 discoverDefaultRouters: true, 1577 discoverMoreSpecificRoutes: false, 1578 dest: header.IPv6EmptySubnet, 1579 ra: func(_ *testing.T, router tcpip.Address, lifetimeSeconds uint16, prf header.NDPRoutePreference) *stack.PacketBuffer { 1580 return raBufWithPrf(router, lifetimeSeconds, prf) 1581 }, 1582 }, 1583 { 1584 name: "More-specific route discovery", 1585 discoverDefaultRouters: false, 1586 discoverMoreSpecificRoutes: true, 1587 dest: moreSpecificPrefix.Subnet(), 1588 ra: func(t *testing.T, router tcpip.Address, lifetimeSeconds uint16, prf header.NDPRoutePreference) *stack.PacketBuffer { 1589 return raBufWithRIO(t, router, moreSpecificPrefix, uint32(lifetimeSeconds), prf) 1590 }, 1591 }, 1592 } 1593 1594 for _, test := range tests { 1595 t.Run(test.name, func(t *testing.T) { 1596 testWithRAs(t, func(t *testing.T, handleRAs ipv6.HandleRAsConfiguration, forwarding bool) { 1597 ndpDisp := ndpDispatcher{ 1598 offLinkRouteC: make(chan ndpOffLinkRouteEvent, 1), 1599 } 1600 e := channel.New(0, 1280, linkAddr1) 1601 clock := faketime.NewManualClock() 1602 s := stack.New(stack.Options{ 1603 NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{ 1604 NDPConfigs: ipv6.NDPConfigurations{ 1605 HandleRAs: handleRAs, 1606 DiscoverDefaultRouters: test.discoverDefaultRouters, 1607 DiscoverMoreSpecificRoutes: test.discoverMoreSpecificRoutes, 1608 }, 1609 NDPDisp: &ndpDisp, 1610 })}, 1611 Clock: clock, 1612 }) 1613 1614 expectOffLinkRouteEvent := func(addr tcpip.Address, prf header.NDPRoutePreference, updated bool) { 1615 t.Helper() 1616 1617 select { 1618 case e := <-ndpDisp.offLinkRouteC: 1619 if diff := checkOffLinkRouteEvent(e, nicID, test.dest, addr, prf, updated); diff != "" { 1620 t.Errorf("off-link route event mismatch (-want +got):\n%s", diff) 1621 } 1622 default: 1623 t.Fatal("expected router discovery event") 1624 } 1625 } 1626 1627 expectAsyncOffLinkRouteInvalidationEvent := func(addr tcpip.Address, timeout time.Duration) { 1628 t.Helper() 1629 1630 clock.Advance(timeout) 1631 select { 1632 case e := <-ndpDisp.offLinkRouteC: 1633 var prf header.NDPRoutePreference 1634 if diff := checkOffLinkRouteEvent(e, nicID, test.dest, addr, prf, false); diff != "" { 1635 t.Errorf("off-link route event mismatch (-want +got):\n%s", diff) 1636 } 1637 default: 1638 t.Fatal("timed out waiting for router discovery event") 1639 } 1640 } 1641 1642 if err := s.SetForwardingDefaultAndAllNICs(ipv6.ProtocolNumber, forwarding); err != nil { 1643 t.Fatalf("SetForwardingDefaultAndAllNICs(%d, %t): %s", ipv6.ProtocolNumber, forwarding, err) 1644 } 1645 1646 if err := s.CreateNIC(nicID, e); err != nil { 1647 t.Fatalf("CreateNIC(%d, _): %s", nicID, err) 1648 } 1649 1650 // Rx an RA from lladdr2 with zero lifetime. It should not be 1651 // remembered. 1652 e.InjectInbound(header.IPv6ProtocolNumber, test.ra(t, llAddr2, 0, header.MediumRoutePreference)) 1653 select { 1654 case <-ndpDisp.offLinkRouteC: 1655 t.Fatal("unexpectedly updated an off-link route with 0 lifetime") 1656 default: 1657 } 1658 1659 // Discover an off-link route through llAddr2. 1660 e.InjectInbound(header.IPv6ProtocolNumber, test.ra(t, llAddr2, 1000, header.ReservedRoutePreference)) 1661 if test.discoverMoreSpecificRoutes { 1662 // The reserved value is considered invalid with more-specific route 1663 // discovery so we inject the same packet but with the default 1664 // (medium) preference value. 1665 select { 1666 case <-ndpDisp.offLinkRouteC: 1667 t.Fatal("unexpectedly updated an off-link route with a reserved preference value") 1668 default: 1669 } 1670 e.InjectInbound(header.IPv6ProtocolNumber, test.ra(t, llAddr2, 1000, header.MediumRoutePreference)) 1671 } 1672 expectOffLinkRouteEvent(llAddr2, header.MediumRoutePreference, true) 1673 1674 // Rx an RA from another router (lladdr3) with non-zero lifetime and 1675 // non-default preference value. 1676 const l3LifetimeSeconds = 6 1677 e.InjectInbound(header.IPv6ProtocolNumber, test.ra(t, llAddr3, l3LifetimeSeconds, header.HighRoutePreference)) 1678 expectOffLinkRouteEvent(llAddr3, header.HighRoutePreference, true) 1679 1680 // Rx an RA from lladdr2 with lesser lifetime and default (medium) 1681 // preference value. 1682 const l2LifetimeSeconds = 2 1683 e.InjectInbound(header.IPv6ProtocolNumber, test.ra(t, llAddr2, l2LifetimeSeconds, header.MediumRoutePreference)) 1684 select { 1685 case <-ndpDisp.offLinkRouteC: 1686 t.Fatal("should not receive a off-link route event when updating lifetimes for known routers") 1687 default: 1688 } 1689 1690 // Rx an RA from lladdr2 with a different preference. 1691 e.InjectInbound(header.IPv6ProtocolNumber, test.ra(t, llAddr2, l2LifetimeSeconds, header.LowRoutePreference)) 1692 expectOffLinkRouteEvent(llAddr2, header.LowRoutePreference, true) 1693 1694 // Wait for lladdr2's router invalidation job to execute. The lifetime 1695 // of the router should have been updated to the most recent (smaller) 1696 // lifetime. 1697 // 1698 // Wait for the normal lifetime plus an extra bit for the 1699 // router to get invalidated. If we don't get an invalidation 1700 // event after this time, then something is wrong. 1701 expectAsyncOffLinkRouteInvalidationEvent(llAddr2, l2LifetimeSeconds*time.Second) 1702 1703 // Rx an RA from lladdr2 with huge lifetime. 1704 e.InjectInbound(header.IPv6ProtocolNumber, test.ra(t, llAddr2, 1000, header.MediumRoutePreference)) 1705 expectOffLinkRouteEvent(llAddr2, header.MediumRoutePreference, true) 1706 1707 // Rx an RA from lladdr2 with zero lifetime. It should be invalidated. 1708 e.InjectInbound(header.IPv6ProtocolNumber, test.ra(t, llAddr2, 0, header.MediumRoutePreference)) 1709 expectOffLinkRouteEvent(llAddr2, header.MediumRoutePreference, false) 1710 1711 // Wait for lladdr3's router invalidation job to execute. The lifetime 1712 // of the router should have been updated to the most recent (smaller) 1713 // lifetime. 1714 // 1715 // Wait for the normal lifetime plus an extra bit for the 1716 // router to get invalidated. If we don't get an invalidation 1717 // event after this time, then something is wrong. 1718 expectAsyncOffLinkRouteInvalidationEvent(llAddr3, l3LifetimeSeconds*time.Second) 1719 }) 1720 }) 1721 } 1722 } 1723 1724 // TestRouterDiscoveryMaxRouters tests that only 1725 // ipv6.MaxDiscoveredOffLinkRoutes discovered routers are remembered. 1726 func TestRouterDiscoveryMaxRouters(t *testing.T) { 1727 const nicID = 1 1728 1729 ndpDisp := ndpDispatcher{ 1730 offLinkRouteC: make(chan ndpOffLinkRouteEvent, 1), 1731 } 1732 e := channel.New(0, 1280, linkAddr1) 1733 s := stack.New(stack.Options{ 1734 NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{ 1735 NDPConfigs: ipv6.NDPConfigurations{ 1736 HandleRAs: ipv6.HandlingRAsEnabledWhenForwardingDisabled, 1737 DiscoverDefaultRouters: true, 1738 }, 1739 NDPDisp: &ndpDisp, 1740 })}, 1741 }) 1742 1743 if err := s.CreateNIC(nicID, e); err != nil { 1744 t.Fatalf("CreateNIC(%d, _): %s", nicID, err) 1745 } 1746 1747 // Receive an RA from 2 more than the max number of discovered routers. 1748 for i := 1; i <= ipv6.MaxDiscoveredOffLinkRoutes+2; i++ { 1749 linkAddr := []byte{2, 2, 3, 4, 5, 0} 1750 linkAddr[5] = byte(i) 1751 llAddr := header.LinkLocalAddr(tcpip.LinkAddress(linkAddr)) 1752 1753 e.InjectInbound(header.IPv6ProtocolNumber, raBufSimple(llAddr, 5)) 1754 1755 if i <= ipv6.MaxDiscoveredOffLinkRoutes { 1756 select { 1757 case e := <-ndpDisp.offLinkRouteC: 1758 if diff := checkOffLinkRouteEvent(e, nicID, header.IPv6EmptySubnet, llAddr, header.MediumRoutePreference, true); diff != "" { 1759 t.Errorf("off-link route event mismatch (-want +got):\n%s", diff) 1760 } 1761 default: 1762 t.Fatal("expected router discovery event") 1763 } 1764 1765 } else { 1766 select { 1767 case <-ndpDisp.offLinkRouteC: 1768 t.Fatal("should not have discovered a new router after we already discovered the max number of routers") 1769 default: 1770 } 1771 } 1772 } 1773 } 1774 1775 // Check e to make sure that the event is for prefix on nic with ID 1, and the 1776 // discovered flag set to discovered. 1777 func checkPrefixEvent(e ndpPrefixEvent, prefix tcpip.Subnet, discovered bool) string { 1778 return cmp.Diff(ndpPrefixEvent{nicID: 1, prefix: prefix, discovered: discovered}, e, cmp.AllowUnexported(e)) 1779 } 1780 1781 func TestPrefixDiscovery(t *testing.T) { 1782 prefix1, subnet1, _ := prefixSubnetAddr(0, "") 1783 prefix2, subnet2, _ := prefixSubnetAddr(1, "") 1784 prefix3, subnet3, _ := prefixSubnetAddr(2, "") 1785 1786 testWithRAs(t, func(t *testing.T, handleRAs ipv6.HandleRAsConfiguration, forwarding bool) { 1787 ndpDisp := ndpDispatcher{ 1788 prefixC: make(chan ndpPrefixEvent, 1), 1789 } 1790 e := channel.New(0, 1280, linkAddr1) 1791 clock := faketime.NewManualClock() 1792 s := stack.New(stack.Options{ 1793 NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{ 1794 NDPConfigs: ipv6.NDPConfigurations{ 1795 HandleRAs: handleRAs, 1796 DiscoverOnLinkPrefixes: true, 1797 }, 1798 NDPDisp: &ndpDisp, 1799 })}, 1800 Clock: clock, 1801 }) 1802 1803 if err := s.CreateNIC(1, e); err != nil { 1804 t.Fatalf("CreateNIC(1) = %s", err) 1805 } 1806 1807 expectPrefixEvent := func(prefix tcpip.Subnet, discovered bool) { 1808 t.Helper() 1809 1810 select { 1811 case e := <-ndpDisp.prefixC: 1812 if diff := checkPrefixEvent(e, prefix, discovered); diff != "" { 1813 t.Errorf("prefix event mismatch (-want +got):\n%s", diff) 1814 } 1815 default: 1816 t.Fatal("expected prefix discovery event") 1817 } 1818 } 1819 1820 if err := s.SetForwardingDefaultAndAllNICs(ipv6.ProtocolNumber, forwarding); err != nil { 1821 t.Fatalf("SetForwardingDefaultAndAllNICs(%d, %t): %s", ipv6.ProtocolNumber, forwarding, err) 1822 } 1823 1824 // Receive an RA with prefix1 in an NDP Prefix Information option (PI) 1825 // with zero valid lifetime. 1826 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, false, 0, 0)) 1827 select { 1828 case <-ndpDisp.prefixC: 1829 t.Fatal("unexpectedly discovered a prefix with 0 lifetime") 1830 default: 1831 } 1832 1833 // Receive an RA with prefix1 in an NDP Prefix Information option (PI) 1834 // with non-zero lifetime. 1835 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, false, 100, 0)) 1836 expectPrefixEvent(subnet1, true) 1837 1838 // Receive an RA with prefix2 in a PI. 1839 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix2, true, false, 100, 0)) 1840 expectPrefixEvent(subnet2, true) 1841 1842 // Receive an RA with prefix3 in a PI. 1843 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix3, true, false, 100, 0)) 1844 expectPrefixEvent(subnet3, true) 1845 1846 // Receive an RA with prefix1 in a PI with lifetime = 0. 1847 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, false, 0, 0)) 1848 expectPrefixEvent(subnet1, false) 1849 1850 // Receive an RA with prefix2 in a PI with lesser lifetime. 1851 lifetime := uint32(2) 1852 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix2, true, false, lifetime, 0)) 1853 select { 1854 case <-ndpDisp.prefixC: 1855 t.Fatal("unexpectedly received prefix event when updating lifetime") 1856 default: 1857 } 1858 1859 // Wait for prefix2's most recent invalidation job plus some buffer to 1860 // expire. 1861 clock.Advance(time.Duration(lifetime) * time.Second) 1862 select { 1863 case e := <-ndpDisp.prefixC: 1864 if diff := checkPrefixEvent(e, subnet2, false); diff != "" { 1865 t.Errorf("prefix event mismatch (-want +got):\n%s", diff) 1866 } 1867 default: 1868 t.Fatal("timed out waiting for prefix discovery event") 1869 } 1870 1871 // Receive RA to invalidate prefix3. 1872 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix3, true, false, 0, 0)) 1873 expectPrefixEvent(subnet3, false) 1874 }) 1875 } 1876 1877 func TestPrefixDiscoveryWithInfiniteLifetime(t *testing.T) { 1878 prefix := tcpip.AddressWithPrefix{ 1879 Address: testutil.MustParse6("102:304:506:708::"), 1880 PrefixLen: 64, 1881 } 1882 subnet := prefix.Subnet() 1883 1884 ndpDisp := ndpDispatcher{ 1885 prefixC: make(chan ndpPrefixEvent, 1), 1886 } 1887 e := channel.New(0, 1280, linkAddr1) 1888 clock := faketime.NewManualClock() 1889 s := stack.New(stack.Options{ 1890 NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{ 1891 NDPConfigs: ipv6.NDPConfigurations{ 1892 HandleRAs: ipv6.HandlingRAsEnabledWhenForwardingDisabled, 1893 DiscoverOnLinkPrefixes: true, 1894 }, 1895 NDPDisp: &ndpDisp, 1896 })}, 1897 Clock: clock, 1898 }) 1899 1900 if err := s.CreateNIC(1, e); err != nil { 1901 t.Fatalf("CreateNIC(1) = %s", err) 1902 } 1903 1904 expectPrefixEvent := func(prefix tcpip.Subnet, discovered bool) { 1905 t.Helper() 1906 1907 select { 1908 case e := <-ndpDisp.prefixC: 1909 if diff := checkPrefixEvent(e, prefix, discovered); diff != "" { 1910 t.Errorf("prefix event mismatch (-want +got):\n%s", diff) 1911 } 1912 default: 1913 t.Fatal("expected prefix discovery event") 1914 } 1915 } 1916 1917 // Receive an RA with prefix in an NDP Prefix Information option (PI) 1918 // with infinite valid lifetime which should not get invalidated. 1919 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, false, infiniteLifetimeSeconds, 0)) 1920 expectPrefixEvent(subnet, true) 1921 clock.Advance(header.NDPInfiniteLifetime) 1922 select { 1923 case <-ndpDisp.prefixC: 1924 t.Fatal("unexpectedly invalidated a prefix with infinite lifetime") 1925 default: 1926 } 1927 1928 // Receive an RA with finite lifetime. 1929 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, false, infiniteLifetimeSeconds-1, 0)) 1930 clock.Advance(header.NDPInfiniteLifetime - time.Second) 1931 select { 1932 case e := <-ndpDisp.prefixC: 1933 if diff := checkPrefixEvent(e, subnet, false); diff != "" { 1934 t.Errorf("prefix event mismatch (-want +got):\n%s", diff) 1935 } 1936 default: 1937 t.Fatal("timed out waiting for prefix discovery event") 1938 } 1939 1940 // Receive an RA with finite lifetime. 1941 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, false, infiniteLifetimeSeconds-1, 0)) 1942 expectPrefixEvent(subnet, true) 1943 1944 // Receive an RA with prefix with an infinite lifetime. 1945 // The prefix should not be invalidated. 1946 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, false, infiniteLifetimeSeconds, 0)) 1947 clock.Advance(header.NDPInfiniteLifetime) 1948 select { 1949 case <-ndpDisp.prefixC: 1950 t.Fatal("unexpectedly invalidated a prefix with infinite lifetime") 1951 default: 1952 } 1953 1954 // Receive an RA with 0 lifetime. 1955 // The prefix should get invalidated. 1956 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, false, 0, 0)) 1957 expectPrefixEvent(subnet, false) 1958 } 1959 1960 // TestPrefixDiscoveryMaxRouters tests that only 1961 // ipv6.MaxDiscoveredOnLinkPrefixes discovered on-link prefixes are remembered. 1962 func TestPrefixDiscoveryMaxOnLinkPrefixes(t *testing.T) { 1963 ndpDisp := ndpDispatcher{ 1964 prefixC: make(chan ndpPrefixEvent, ipv6.MaxDiscoveredOnLinkPrefixes+3), 1965 } 1966 e := channel.New(0, 1280, linkAddr1) 1967 s := stack.New(stack.Options{ 1968 NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{ 1969 NDPConfigs: ipv6.NDPConfigurations{ 1970 HandleRAs: ipv6.HandlingRAsEnabledWhenForwardingDisabled, 1971 DiscoverDefaultRouters: false, 1972 DiscoverOnLinkPrefixes: true, 1973 }, 1974 NDPDisp: &ndpDisp, 1975 })}, 1976 }) 1977 1978 if err := s.CreateNIC(1, e); err != nil { 1979 t.Fatalf("CreateNIC(1) = %s", err) 1980 } 1981 1982 optSer := make(header.NDPOptionsSerializer, ipv6.MaxDiscoveredOnLinkPrefixes+2) 1983 prefixes := [ipv6.MaxDiscoveredOnLinkPrefixes + 2]tcpip.Subnet{} 1984 1985 // Receive an RA with 2 more than the max number of discovered on-link 1986 // prefixes. 1987 for i := 0; i < ipv6.MaxDiscoveredOnLinkPrefixes+2; i++ { 1988 prefixAddr := [16]byte{1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0} 1989 prefixAddr[7] = byte(i) 1990 prefix := tcpip.AddressWithPrefix{ 1991 Address: tcpip.AddrFromSlice(prefixAddr[:]), 1992 PrefixLen: 64, 1993 } 1994 prefixes[i] = prefix.Subnet() 1995 buf := [30]byte{} 1996 buf[0] = uint8(prefix.PrefixLen) 1997 buf[1] = 128 1998 binary.BigEndian.PutUint32(buf[2:], 10) 1999 copy(buf[14:], prefix.Address.AsSlice()) 2000 2001 optSer[i] = header.NDPPrefixInformation(buf[:]) 2002 } 2003 2004 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithOpts(llAddr1, 0, optSer)) 2005 for i := 0; i < ipv6.MaxDiscoveredOnLinkPrefixes+2; i++ { 2006 if i < ipv6.MaxDiscoveredOnLinkPrefixes { 2007 select { 2008 case e := <-ndpDisp.prefixC: 2009 if diff := checkPrefixEvent(e, prefixes[i], true); diff != "" { 2010 t.Errorf("prefix event mismatch (-want +got):\n%s", diff) 2011 } 2012 default: 2013 t.Fatal("expected prefix discovery event") 2014 } 2015 } else { 2016 select { 2017 case <-ndpDisp.prefixC: 2018 t.Fatal("should not have discovered a new prefix after we already discovered the max number of prefixes") 2019 default: 2020 } 2021 } 2022 } 2023 } 2024 2025 // Checks to see if list contains an IPv6 address, item. 2026 func containsV6Addr(list []tcpip.ProtocolAddress, item tcpip.AddressWithPrefix) bool { 2027 protocolAddress := tcpip.ProtocolAddress{ 2028 Protocol: header.IPv6ProtocolNumber, 2029 AddressWithPrefix: item, 2030 } 2031 2032 return containsAddr(list, protocolAddress) 2033 } 2034 2035 // Check e to make sure that the event is for addr on nic with ID 1, and the 2036 // event type is set to eventType. 2037 func checkAutoGenAddrEvent(e ndpAutoGenAddrEvent, addr tcpip.AddressWithPrefix, eventType ndpAutoGenAddrEventType) string { 2038 return cmp.Diff( 2039 ndpAutoGenAddrEvent{nicID: 1, addr: addr, eventType: eventType}, 2040 e, 2041 cmp.AllowUnexported(e), 2042 ) 2043 } 2044 2045 const minVLSeconds = uint32(ipv6.MinPrefixInformationValidLifetimeForUpdate / time.Second) 2046 const infiniteLifetimeSeconds = uint32(header.NDPInfiniteLifetime / time.Second) 2047 2048 func expectAutoGenAddrEvent(t *testing.T, ndpDisp *ndpDispatcher, addr tcpip.AddressWithPrefix, eventType ndpAutoGenAddrEventType) { 2049 t.Helper() 2050 2051 select { 2052 case e := <-ndpDisp.autoGenAddrC: 2053 if diff := checkAutoGenAddrEvent(e, addr, eventType); diff != "" { 2054 t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff) 2055 } 2056 default: 2057 t.Fatal("expected addr auto gen event") 2058 } 2059 } 2060 2061 // expectAutoGenAddrNewEvent expects that a new auto-gen addr event is 2062 // immediately available with addr. 2063 // 2064 // The return *addressDispatcher is non-nil iff ndpDisp.autoGenInstallDisp is 2065 // true. 2066 func expectAutoGenAddrNewEvent(ndpDisp *ndpDispatcher, addr tcpip.AddressWithPrefix) (*addressDispatcher, error) { 2067 select { 2068 case e := <-ndpDisp.autoGenAddrNewC: 2069 if diff := cmp.Diff( 2070 ndpAutoGenAddrNewEvent{nicID: 1, addr: addr}, 2071 e, 2072 cmp.AllowUnexported(e), 2073 cmp.FilterValues(func(*addressDispatcher, *addressDispatcher) bool { return true }, cmp.Ignore()), 2074 ); diff != "" { 2075 return nil, fmt.Errorf("new auto-gen addr event mismatch (-want +got):\n%s", diff) 2076 } 2077 if ndpDisp.autoGenInstallDisp != (e.addrDisp != nil) { 2078 return nil, fmt.Errorf("install-disp=%t but addr-disp=%#v", ndpDisp.autoGenInstallDisp, e.addrDisp) 2079 } 2080 return e.addrDisp, nil 2081 default: 2082 return nil, fmt.Errorf("expected new auto-gen addr event") 2083 } 2084 } 2085 2086 func TestMaxSlaacPrefixes(t *testing.T) { 2087 const ( 2088 nicID = 1 2089 // Each SLAAC prefix gets a stable and temporary address. 2090 slaacAddrsPerPrefix = 2 2091 // Send an extra prefix than what we will discover to make sure we do not 2092 // discover the extra prefix. 2093 slaacPrefixesInRA = ipv6.MaxDiscoveredSLAACPrefixes + 1 2094 ) 2095 2096 ndpDisp := ndpDispatcher{ 2097 autoGenAddrNewC: make(chan ndpAutoGenAddrNewEvent, slaacPrefixesInRA*slaacAddrsPerPrefix), 2098 } 2099 e := channel.New(0, 1280, linkAddr1) 2100 s := stack.New(stack.Options{ 2101 NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{ 2102 NDPConfigs: ipv6.NDPConfigurations{ 2103 HandleRAs: ipv6.HandlingRAsEnabledWhenForwardingDisabled, 2104 AutoGenGlobalAddresses: true, 2105 AutoGenTempGlobalAddresses: true, 2106 }, 2107 NDPDisp: &ndpDisp, 2108 })}, 2109 }) 2110 2111 if err := s.CreateNIC(nicID, e); err != nil { 2112 t.Fatalf("CreateNIC(%d) = %s", nicID, err) 2113 } 2114 2115 optSer := make(header.NDPOptionsSerializer, 0, slaacPrefixesInRA) 2116 prefixes := [slaacPrefixesInRA]tcpip.Subnet{} 2117 for i := 0; i < slaacPrefixesInRA; i++ { 2118 prefixAddr := [16]byte{1, 2, 3, 4, 5, 6, 7, byte(i), 0, 0, 0, 0, 0, 0, 0, 0} 2119 prefix := tcpip.AddressWithPrefix{ 2120 Address: tcpip.AddrFromSlice(prefixAddr[:]), 2121 PrefixLen: 64, 2122 } 2123 prefixes[i] = prefix.Subnet() 2124 // Serialize a prefix information option. 2125 buf := [30]byte{} 2126 buf[0] = uint8(prefix.PrefixLen) 2127 // Set the autonomous configuration flag. 2128 buf[1] = 64 2129 // Set the preferred and valid lifetimes to the maximum possible value. 2130 binary.BigEndian.PutUint32(buf[2:], math.MaxUint32) 2131 binary.BigEndian.PutUint32(buf[6:], math.MaxUint32) 2132 if n := copy(buf[14:], prefix.Address.AsSlice()); n != prefix.Address.Len() { 2133 t.Fatalf("got copy(...) = %d, want = %d", n, prefix.Address.Len()) 2134 } 2135 optSer = append(optSer, header.NDPPrefixInformation(buf[:])) 2136 } 2137 2138 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithOpts(llAddr1, 0, optSer)) 2139 for i := 0; i < slaacPrefixesInRA; i++ { 2140 for j := 0; j < slaacAddrsPerPrefix; j++ { 2141 if i < ipv6.MaxDiscoveredSLAACPrefixes { 2142 select { 2143 case e := <-ndpDisp.autoGenAddrNewC: 2144 if e.nicID != nicID { 2145 t.Errorf("got e.nicID = %d, want = %d", e.nicID, nicID) 2146 } 2147 if !prefixes[i].Contains(e.addr.Address) { 2148 t.Errorf("got prefixes[%d].Contains(%s) = false, want = true", i, e.addr) 2149 } 2150 if e.addrDisp != nil { 2151 t.Error("auto-gen new addr event unexpectedly contains address dispatcher") 2152 } 2153 default: 2154 t.Fatalf("expected auto-gen new addr event; i=%d, j=%d", i, j) 2155 } 2156 } else { 2157 select { 2158 case <-ndpDisp.autoGenAddrNewC: 2159 t.Fatal("should not have discovered a new auto-gen addr after we already discovered the max number of prefixes") 2160 default: 2161 } 2162 } 2163 } 2164 } 2165 } 2166 2167 // TestAutoGenAddr tests that an address is properly generated and invalidated 2168 // when configured to do so. 2169 func TestAutoGenAddr(t *testing.T) { 2170 prefix1, _, addr1 := prefixSubnetAddr(0, linkAddr1) 2171 prefix2, _, addr2 := prefixSubnetAddr(1, linkAddr1) 2172 2173 testWithRAs(t, func(t *testing.T, handleRAs ipv6.HandleRAsConfiguration, forwarding bool) { 2174 const autoGenAddrCount = 1 2175 ndpDisp := ndpDispatcher{ 2176 autoGenAddrNewC: make(chan ndpAutoGenAddrNewEvent, autoGenAddrCount), 2177 autoGenAddrC: make(chan ndpAutoGenAddrEvent, autoGenAddrCount), 2178 autoGenInstallDisp: true, 2179 } 2180 e := channel.New(0, 1280, linkAddr1) 2181 clock := faketime.NewManualClock() 2182 s := stack.New(stack.Options{ 2183 NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{ 2184 NDPConfigs: ipv6.NDPConfigurations{ 2185 HandleRAs: handleRAs, 2186 AutoGenGlobalAddresses: true, 2187 }, 2188 NDPDisp: &ndpDisp, 2189 })}, 2190 Clock: clock, 2191 }) 2192 2193 if err := s.SetForwardingDefaultAndAllNICs(ipv6.ProtocolNumber, forwarding); err != nil { 2194 t.Fatalf("SetForwardingDefaultAndAllNICs(%d, %t): %s", ipv6.ProtocolNumber, forwarding, err) 2195 } 2196 2197 if err := s.CreateNIC(1, e); err != nil { 2198 t.Fatalf("CreateNIC(1) = %s", err) 2199 } 2200 2201 // Receive an RA with prefix1 in an NDP Prefix Information option (PI) 2202 // with zero valid lifetime. 2203 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, 0, 0)) 2204 select { 2205 case <-ndpDisp.autoGenAddrC: 2206 t.Fatal("unexpectedly auto-generated an address with 0 lifetime") 2207 default: 2208 } 2209 2210 // Receive an RA with prefix1 in an NDP Prefix Information option (PI) 2211 // with non-zero lifetime. 2212 var preferredLifetime1 uint32 2213 validLifetime1 := uint32(100) 2214 received := clock.NowMonotonic() 2215 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, validLifetime1, preferredLifetime1)) 2216 addr1Disp, err := expectAutoGenAddrNewEvent(&ndpDisp, addr1) 2217 if err != nil { 2218 t.Fatalf("error expecting prefix1 stable address generated event: %s", err) 2219 } 2220 if err := addr1Disp.expectChanged(addressLifetimes(received, preferredLifetime1, validLifetime1), stack.AddressAssigned); err != nil { 2221 t.Error(err) 2222 } 2223 if !containsV6Addr(s.NICInfo()[1].ProtocolAddresses, addr1) { 2224 t.Fatalf("Should have %s in the list of addresses", addr1) 2225 } 2226 2227 // Receive an RA with prefix2 in an NDP Prefix Information option (PI) 2228 // with preferred lifetime > valid lifetime 2229 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, 5, 6)) 2230 select { 2231 case <-ndpDisp.autoGenAddrC: 2232 t.Fatal("unexpectedly auto-generated an address with preferred lifetime > valid lifetime") 2233 default: 2234 } 2235 2236 // Receive an RA with prefix2 in a PI with a valid lifetime that exceeds 2237 // the minimum. 2238 validLifetime2 := uint32(minVLSeconds + 1) 2239 preferredLifetime2 := uint32(minVLSeconds + 1) 2240 received = clock.NowMonotonic() 2241 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix2, true, true, validLifetime2, preferredLifetime2)) 2242 addr2Disp, err := expectAutoGenAddrNewEvent(&ndpDisp, addr2) 2243 if err != nil { 2244 t.Fatalf("error expecting prefix2 stable address generated event: %s", err) 2245 } 2246 if err := addr2Disp.expectChanged(addressLifetimes(received, preferredLifetime2, validLifetime2), stack.AddressAssigned); err != nil { 2247 t.Error(err) 2248 } 2249 if !containsV6Addr(s.NICInfo()[1].ProtocolAddresses, addr1) { 2250 t.Fatalf("Should have %s in the list of addresses", addr1) 2251 } 2252 if !containsV6Addr(s.NICInfo()[1].ProtocolAddresses, addr2) { 2253 t.Fatalf("Should have %s in the list of addresses", addr2) 2254 } 2255 2256 // Refresh valid lifetime for addr of prefix1. 2257 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, validLifetime1, 0)) 2258 select { 2259 case <-ndpDisp.autoGenAddrC: 2260 t.Fatal("unexpectedly auto-generated an address when we already have an address for a prefix") 2261 default: 2262 } 2263 2264 // Wait for addr of prefix1 to be invalidated. 2265 clock.Advance(ipv6.MinPrefixInformationValidLifetimeForUpdate) 2266 expectAutoGenAddrEvent(t, &ndpDisp, addr1, invalidatedAddr) 2267 if err := addr1Disp.expectRemoved(stack.AddressRemovalInvalidated); err != nil { 2268 t.Fatal(err) 2269 } 2270 if containsV6Addr(s.NICInfo()[1].ProtocolAddresses, addr1) { 2271 t.Fatalf("Should not have %s in the list of addresses", addr1) 2272 } 2273 if !containsV6Addr(s.NICInfo()[1].ProtocolAddresses, addr2) { 2274 t.Fatalf("Should have %s in the list of addresses", addr2) 2275 } 2276 }) 2277 } 2278 2279 func addressCheck(addrs []tcpip.ProtocolAddress, containList, notContainList []tcpip.AddressWithPrefix) string { 2280 ret := "" 2281 for _, c := range containList { 2282 if !containsV6Addr(addrs, c) { 2283 ret += fmt.Sprintf("should have %s in the list of addresses\n", c) 2284 } 2285 } 2286 for _, c := range notContainList { 2287 if containsV6Addr(addrs, c) { 2288 ret += fmt.Sprintf("should not have %s in the list of addresses\n", c) 2289 } 2290 } 2291 return ret 2292 } 2293 2294 // TestAutoGenTempAddr tests that temporary SLAAC addresses are generated when 2295 // configured to do so as part of IPv6 Privacy Extensions. 2296 func TestAutoGenTempAddr(t *testing.T) { 2297 const nicID = 1 2298 2299 prefix1, _, addr1 := prefixSubnetAddr(0, linkAddr1) 2300 prefix2, _, addr2 := prefixSubnetAddr(1, linkAddr1) 2301 2302 tests := []struct { 2303 name string 2304 dupAddrTransmits uint8 2305 retransmitTimer time.Duration 2306 }{ 2307 { 2308 name: "DAD disabled", 2309 }, 2310 { 2311 name: "DAD enabled", 2312 dupAddrTransmits: 1, 2313 retransmitTimer: time.Second, 2314 }, 2315 } 2316 2317 for i, test := range tests { 2318 t.Run(test.name, func(t *testing.T) { 2319 seed := []byte{uint8(i)} 2320 var tempIIDHistory [header.IIDSize]byte 2321 header.InitialTempIID(tempIIDHistory[:], seed, nicID) 2322 newTempAddr := func(stableAddr tcpip.Address) tcpip.AddressWithPrefix { 2323 return header.GenerateTempIPv6SLAACAddr(tempIIDHistory[:], stableAddr) 2324 } 2325 2326 const autoGenAddrCount = 2 2327 ndpDisp := ndpDispatcher{ 2328 dadC: make(chan ndpDADEvent, 2), 2329 autoGenAddrNewC: make(chan ndpAutoGenAddrNewEvent, autoGenAddrCount), 2330 autoGenAddrC: make(chan ndpAutoGenAddrEvent, autoGenAddrCount), 2331 autoGenInstallDisp: true, 2332 } 2333 e := channel.New(0, 1280, linkAddr1) 2334 clock := faketime.NewManualClock() 2335 s := stack.New(stack.Options{ 2336 NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{ 2337 DADConfigs: stack.DADConfigurations{ 2338 DupAddrDetectTransmits: test.dupAddrTransmits, 2339 RetransmitTimer: test.retransmitTimer, 2340 }, 2341 NDPConfigs: ipv6.NDPConfigurations{ 2342 HandleRAs: ipv6.HandlingRAsEnabledWhenForwardingDisabled, 2343 AutoGenGlobalAddresses: true, 2344 AutoGenTempGlobalAddresses: true, 2345 MaxTempAddrValidLifetime: 3 * ipv6.MinPrefixInformationValidLifetimeForUpdate, 2346 MaxTempAddrPreferredLifetime: 3 * ipv6.MinPrefixInformationValidLifetimeForUpdate, 2347 }, 2348 NDPDisp: &ndpDisp, 2349 TempIIDSeed: seed, 2350 })}, 2351 Clock: clock, 2352 }) 2353 2354 if err := s.CreateNIC(nicID, e); err != nil { 2355 t.Fatalf("CreateNIC(%d, _) = %s", nicID, err) 2356 } 2357 2358 expectDADEventAsync := func(addr tcpip.Address) { 2359 t.Helper() 2360 2361 clock.Advance(time.Duration(test.dupAddrTransmits) * test.retransmitTimer) 2362 select { 2363 case e := <-ndpDisp.dadC: 2364 if diff := checkDADEvent(e, nicID, addr, &stack.DADSucceeded{}); diff != "" { 2365 t.Errorf("DAD event mismatch (-want +got):\n%s", diff) 2366 } 2367 default: 2368 t.Fatal("timed out waiting for DAD event") 2369 } 2370 } 2371 2372 expectAddrDispatcherTentative := func(addrDisp *addressDispatcher, wantLifetimes stack.AddressLifetimes) { 2373 t.Helper() 2374 2375 if test.dupAddrTransmits != 0 { 2376 if err := addrDisp.expectChanged(wantLifetimes, stack.AddressTentative); err != nil { 2377 t.Error(err) 2378 } 2379 } 2380 } 2381 2382 // Receive an RA with prefix1 in an NDP Prefix Information option (PI) 2383 // with zero valid lifetime. 2384 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, 0, 0)) 2385 select { 2386 case e := <-ndpDisp.autoGenAddrC: 2387 t.Fatalf("unexpectedly auto-generated an address with 0 lifetime; event = %+v", e) 2388 default: 2389 } 2390 2391 // Receive an RA with prefix1 in an NDP Prefix Information option (PI) 2392 // with non-zero valid lifetime. 2393 prefix1VL := uint32(100) 2394 var prefix1PL uint32 2395 received := clock.NowMonotonic() 2396 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, prefix1VL, prefix1PL)) 2397 addr1Disp, err := expectAutoGenAddrNewEvent(&ndpDisp, addr1) 2398 if err != nil { 2399 t.Fatalf("error expecting prefix1 stable address generated event: %s", err) 2400 } 2401 expectAddrDispatcherTentative(addr1Disp, addressLifetimes(received, prefix1PL, prefix1VL)) 2402 expectDADEventAsync(addr1.Address) 2403 if err := addr1Disp.expectChanged(addressLifetimes(received, prefix1PL, prefix1VL), stack.AddressAssigned); err != nil { 2404 t.Error(err) 2405 } 2406 select { 2407 case e := <-ndpDisp.autoGenAddrC: 2408 t.Fatalf("unexpectedly got an auto gen addr event = %+v", e) 2409 default: 2410 } 2411 if mismatch := addressCheck(s.NICInfo()[nicID].ProtocolAddresses, []tcpip.AddressWithPrefix{addr1}, nil); mismatch != "" { 2412 t.Fatal(mismatch) 2413 } 2414 2415 // Receive an RA with prefix1 in an NDP Prefix Information option (PI) 2416 // with non-zero valid & preferred lifetimes. 2417 tempAddr1 := newTempAddr(addr1.Address) 2418 prefix1PL = uint32(100) 2419 received = clock.NowMonotonic() 2420 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, prefix1VL, prefix1PL)) 2421 if err := addr1Disp.expectLifetimesChanged(addressLifetimes(received, prefix1PL, prefix1VL)); err != nil { 2422 t.Error(err) 2423 } 2424 tempAddr1Disp, err := expectAutoGenAddrNewEvent(&ndpDisp, tempAddr1) 2425 if err != nil { 2426 t.Fatalf("error expecting prefix1 temp address generated event: %s", err) 2427 } 2428 expectAddrDispatcherTentative(tempAddr1Disp, addressLifetimes(received, prefix1PL, prefix1VL)) 2429 expectDADEventAsync(tempAddr1.Address) 2430 if err := tempAddr1Disp.expectChanged(addressLifetimes(received, prefix1PL, prefix1VL), stack.AddressAssigned); err != nil { 2431 t.Error(err) 2432 } 2433 if mismatch := addressCheck(s.NICInfo()[1].ProtocolAddresses, []tcpip.AddressWithPrefix{addr1, tempAddr1}, nil); mismatch != "" { 2434 t.Fatal(mismatch) 2435 } 2436 2437 // Receive an RA with prefix2 in an NDP Prefix Information option (PI) 2438 // with preferred lifetime > valid lifetime 2439 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, 5, 6)) 2440 select { 2441 case e := <-ndpDisp.autoGenAddrC: 2442 t.Fatalf("unexpectedly auto-generated an address with preferred lifetime > valid lifetime; event = %+v", e) 2443 default: 2444 } 2445 if mismatch := addressCheck(s.NICInfo()[nicID].ProtocolAddresses, []tcpip.AddressWithPrefix{addr1, tempAddr1}, nil); mismatch != "" { 2446 t.Fatal(mismatch) 2447 } 2448 2449 // Receive an RA with prefix2 in a PI with a valid lifetime that exceeds 2450 // the minimum and won't be reached in this test. 2451 tempAddr2 := newTempAddr(addr2.Address) 2452 lifetime2 := 2 * minVLSeconds 2453 received2 := clock.NowMonotonic() 2454 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix2, true, true, lifetime2, lifetime2)) 2455 addr2Disp, err := expectAutoGenAddrNewEvent(&ndpDisp, addr2) 2456 if err != nil { 2457 t.Fatalf("error expecting prefix2 stable address generated event: %s", err) 2458 } 2459 expectAddrDispatcherTentative(addr2Disp, addressLifetimes(received2, lifetime2, lifetime2)) 2460 expectDADEventAsync(addr2.Address) 2461 if err := addr2Disp.expectChanged(addressLifetimes(received2, lifetime2, lifetime2), stack.AddressAssigned); err != nil { 2462 t.Error(err) 2463 } 2464 2465 clock.RunImmediatelyScheduledJobs() 2466 tempAddr2Disp, err := expectAutoGenAddrNewEvent(&ndpDisp, tempAddr2) 2467 if err != nil { 2468 t.Fatalf("error expecting prefix2 temp address generated event: %s", err) 2469 } 2470 expectAddrDispatcherTentative(tempAddr2Disp, addressLifetimes(received2, lifetime2, lifetime2)) 2471 expectDADEventAsync(tempAddr2.Address) 2472 if err := tempAddr2Disp.expectChanged(addressLifetimes(received2, lifetime2, lifetime2), stack.AddressAssigned); err != nil { 2473 t.Error(err) 2474 } 2475 if mismatch := addressCheck(s.NICInfo()[nicID].ProtocolAddresses, []tcpip.AddressWithPrefix{addr1, tempAddr1, addr2, tempAddr2}, nil); mismatch != "" { 2476 t.Fatal(mismatch) 2477 } 2478 2479 // Deprecate prefix1. 2480 { 2481 prefix1VL := uint32(100) 2482 received = clock.NowMonotonic() 2483 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, prefix1VL, 0)) 2484 expectAutoGenAddrEvent(t, &ndpDisp, addr1, deprecatedAddr) 2485 if err := addr1Disp.expectLifetimesChanged(addressLifetimes(received, 0, prefix1VL)); err != nil { 2486 t.Error(err) 2487 } 2488 expectAutoGenAddrEvent(t, &ndpDisp, tempAddr1, deprecatedAddr) 2489 if err := tempAddr1Disp.expectLifetimesChanged(addressLifetimes(received, 0, prefix1VL)); err != nil { 2490 t.Error(err) 2491 } 2492 if mismatch := addressCheck(s.NICInfo()[nicID].ProtocolAddresses, []tcpip.AddressWithPrefix{addr1, tempAddr1, addr2, tempAddr2}, nil); mismatch != "" { 2493 t.Fatal(mismatch) 2494 } 2495 } 2496 2497 // Refresh lifetimes for prefix1. 2498 { 2499 prefix1VL := uint32(100) 2500 prefix1PL := uint32(100) 2501 received := clock.NowMonotonic() 2502 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, prefix1VL, prefix1PL)) 2503 if mismatch := addressCheck(s.NICInfo()[nicID].ProtocolAddresses, []tcpip.AddressWithPrefix{addr1, tempAddr1, addr2, tempAddr2}, nil); mismatch != "" { 2504 t.Fatal(mismatch) 2505 } 2506 if err := addr1Disp.expectLifetimesChanged(addressLifetimes(received, prefix1PL, prefix1VL)); err != nil { 2507 t.Error(err) 2508 } 2509 if err := tempAddr1Disp.expectLifetimesChanged(addressLifetimes(received, prefix1PL, prefix1VL)); err != nil { 2510 t.Error(err) 2511 } 2512 } 2513 2514 // Reduce valid lifetime and deprecate addresses of prefix1. 2515 received = clock.NowMonotonic() 2516 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, minVLSeconds, 0)) 2517 expectAutoGenAddrEvent(t, &ndpDisp, addr1, deprecatedAddr) 2518 expectAutoGenAddrEvent(t, &ndpDisp, tempAddr1, deprecatedAddr) 2519 if err := addr1Disp.expectLifetimesChanged(addressLifetimes(received, 0, minVLSeconds)); err != nil { 2520 t.Error(err) 2521 } 2522 if err := tempAddr1Disp.expectLifetimesChanged(addressLifetimes(received, 0, minVLSeconds)); err != nil { 2523 t.Error(err) 2524 } 2525 if mismatch := addressCheck(s.NICInfo()[nicID].ProtocolAddresses, []tcpip.AddressWithPrefix{addr1, tempAddr1, addr2, tempAddr2}, nil); mismatch != "" { 2526 t.Fatal(mismatch) 2527 } 2528 2529 // Wait for addrs of prefix1 to be invalidated. They should be 2530 // invalidated at the same time. 2531 clock.Advance(ipv6.MinPrefixInformationValidLifetimeForUpdate) 2532 select { 2533 case e := <-ndpDisp.autoGenAddrC: 2534 var nextAddr tcpip.AddressWithPrefix 2535 if e.addr == addr1 { 2536 if diff := checkAutoGenAddrEvent(e, addr1, invalidatedAddr); diff != "" { 2537 t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff) 2538 } 2539 nextAddr = tempAddr1 2540 } else { 2541 if diff := checkAutoGenAddrEvent(e, tempAddr1, invalidatedAddr); diff != "" { 2542 t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff) 2543 } 2544 nextAddr = addr1 2545 } 2546 2547 expectAutoGenAddrEvent(t, &ndpDisp, nextAddr, invalidatedAddr) 2548 default: 2549 t.Fatal("timed out waiting for addr auto gen event") 2550 } 2551 if err := addr1Disp.expectRemoved(stack.AddressRemovalInvalidated); err != nil { 2552 t.Error(err) 2553 } 2554 if err := tempAddr1Disp.expectRemoved(stack.AddressRemovalInvalidated); err != nil { 2555 t.Error(err) 2556 } 2557 if mismatch := addressCheck(s.NICInfo()[nicID].ProtocolAddresses, []tcpip.AddressWithPrefix{addr2, tempAddr2}, []tcpip.AddressWithPrefix{addr1, tempAddr1}); mismatch != "" { 2558 t.Fatal(mismatch) 2559 } 2560 2561 // Receive an RA with prefix2 in a PI w/ 0 lifetimes. 2562 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix2, true, true, 0, 0)) 2563 expectAutoGenAddrEvent(t, &ndpDisp, addr2, deprecatedAddr) 2564 expectAutoGenAddrEvent(t, &ndpDisp, tempAddr2, deprecatedAddr) 2565 select { 2566 case e := <-ndpDisp.autoGenAddrC: 2567 t.Errorf("got unexpected auto gen addr event = %+v", e) 2568 default: 2569 } 2570 // Addresses should be deprecated, but their valid-until should be untouched 2571 // as their remaining valid lifetime is too low. 2572 if err := addr2Disp.expectDeprecated(); err != nil { 2573 t.Error(err) 2574 } 2575 if err := tempAddr2Disp.expectDeprecated(); err != nil { 2576 t.Error(err) 2577 } 2578 if mismatch := addressCheck(s.NICInfo()[nicID].ProtocolAddresses, []tcpip.AddressWithPrefix{addr2, tempAddr2}, []tcpip.AddressWithPrefix{addr1, tempAddr1}); mismatch != "" { 2579 t.Fatal(mismatch) 2580 } 2581 }) 2582 } 2583 } 2584 2585 // TestNoAutoGenTempAddrForLinkLocal test that temporary SLAAC addresses are not 2586 // generated for auto generated link-local addresses. 2587 func TestNoAutoGenTempAddrForLinkLocal(t *testing.T) { 2588 const nicID = 1 2589 2590 tests := []struct { 2591 name string 2592 dupAddrTransmits uint8 2593 retransmitTimer time.Duration 2594 }{ 2595 { 2596 name: "DAD disabled", 2597 }, 2598 { 2599 name: "DAD enabled", 2600 dupAddrTransmits: 1, 2601 retransmitTimer: time.Second, 2602 }, 2603 } 2604 2605 for _, test := range tests { 2606 t.Run(test.name, func(t *testing.T) { 2607 const autoGenAddrCount = 1 2608 ndpDisp := ndpDispatcher{ 2609 dadC: make(chan ndpDADEvent, 1), 2610 autoGenAddrNewC: make(chan ndpAutoGenAddrNewEvent, autoGenAddrCount), 2611 autoGenAddrC: make(chan ndpAutoGenAddrEvent, autoGenAddrCount), 2612 autoGenInstallDisp: true, 2613 } 2614 e := channel.New(0, 1280, linkAddr1) 2615 clock := faketime.NewManualClock() 2616 s := stack.New(stack.Options{ 2617 NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{ 2618 NDPConfigs: ipv6.NDPConfigurations{ 2619 AutoGenTempGlobalAddresses: true, 2620 }, 2621 DADConfigs: stack.DADConfigurations{ 2622 DupAddrDetectTransmits: test.dupAddrTransmits, 2623 RetransmitTimer: test.retransmitTimer, 2624 }, 2625 NDPDisp: &ndpDisp, 2626 AutoGenLinkLocal: true, 2627 })}, 2628 Clock: clock, 2629 }) 2630 2631 if err := s.CreateNIC(nicID, e); err != nil { 2632 t.Fatalf("CreateNIC(%d, _) = %s", nicID, err) 2633 } 2634 2635 // The stable link-local address should auto-generate and resolve DAD. 2636 addrDisp, err := expectAutoGenAddrNewEvent(&ndpDisp, tcpip.AddressWithPrefix{Address: llAddr1, PrefixLen: header.IIDOffsetInIPv6Address * 8}) 2637 if err != nil { 2638 t.Fatalf("error expecting stable auto-gen address generated event: %s", err) 2639 } 2640 if test.dupAddrTransmits > 0 { 2641 if err := addrDisp.expectChanged(infiniteLifetimes(), stack.AddressTentative); err != nil { 2642 t.Error(err) 2643 } 2644 } 2645 clock.Advance(time.Duration(test.dupAddrTransmits) * test.retransmitTimer) 2646 select { 2647 case e := <-ndpDisp.dadC: 2648 if diff := checkDADEvent(e, nicID, llAddr1, &stack.DADSucceeded{}); diff != "" { 2649 t.Errorf("DAD event mismatch (-want +got):\n%s", diff) 2650 } 2651 default: 2652 t.Fatal("timed out waiting for DAD event") 2653 } 2654 if err := addrDisp.expectChanged(infiniteLifetimes(), stack.AddressAssigned); err != nil { 2655 t.Error(err) 2656 } 2657 2658 // No new addresses should be generated. 2659 select { 2660 case e := <-ndpDisp.autoGenAddrC: 2661 t.Errorf("got unexpected auto gen addr event = %+v", e) 2662 default: 2663 } 2664 }) 2665 } 2666 } 2667 2668 // TestNoAutoGenTempAddrWithoutStableAddr tests that a temporary SLAAC address 2669 // will not be generated until after DAD completes, even if a new Router 2670 // Advertisement is received to refresh lifetimes. 2671 func TestNoAutoGenTempAddrWithoutStableAddr(t *testing.T) { 2672 const ( 2673 nicID = 1 2674 dadTransmits = 1 2675 retransmitTimer = 2 * time.Second 2676 ) 2677 2678 prefix, _, addr := prefixSubnetAddr(0, linkAddr1) 2679 var tempIIDHistory [header.IIDSize]byte 2680 header.InitialTempIID(tempIIDHistory[:], nil, nicID) 2681 tempAddr := header.GenerateTempIPv6SLAACAddr(tempIIDHistory[:], addr.Address) 2682 2683 const autoGenAddrCount = 1 2684 ndpDisp := ndpDispatcher{ 2685 dadC: make(chan ndpDADEvent, 1), 2686 autoGenAddrNewC: make(chan ndpAutoGenAddrNewEvent, autoGenAddrCount), 2687 autoGenAddrC: make(chan ndpAutoGenAddrEvent, autoGenAddrCount), 2688 autoGenInstallDisp: true, 2689 } 2690 e := channel.New(0, 1280, linkAddr1) 2691 clock := faketime.NewManualClock() 2692 s := stack.New(stack.Options{ 2693 NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{ 2694 DADConfigs: stack.DADConfigurations{ 2695 DupAddrDetectTransmits: dadTransmits, 2696 RetransmitTimer: retransmitTimer, 2697 }, 2698 NDPConfigs: ipv6.NDPConfigurations{ 2699 HandleRAs: ipv6.HandlingRAsEnabledWhenForwardingDisabled, 2700 AutoGenGlobalAddresses: true, 2701 AutoGenTempGlobalAddresses: true, 2702 }, 2703 NDPDisp: &ndpDisp, 2704 })}, 2705 Clock: clock, 2706 }) 2707 2708 if err := s.CreateNIC(nicID, e); err != nil { 2709 t.Fatalf("CreateNIC(%d, _) = %s", nicID, err) 2710 } 2711 2712 // Receive an RA to trigger SLAAC for prefix. 2713 received, pl, vl := clock.NowMonotonic(), uint32(100), uint32(100) 2714 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, vl, pl)) 2715 addrDisp, err := expectAutoGenAddrNewEvent(&ndpDisp, addr) 2716 if err != nil { 2717 t.Fatalf("error expecting stable auto-gen address generated event: %s", err) 2718 } 2719 if err := addrDisp.expectChanged(addressLifetimes(received, pl, vl), stack.AddressTentative); err != nil { 2720 t.Error(err) 2721 } 2722 2723 // DAD on the stable address for prefix has not yet completed. Receiving a new 2724 // RA that would refresh lifetimes should not generate a temporary SLAAC 2725 // address for the prefix. 2726 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, vl, pl)) 2727 select { 2728 case e := <-ndpDisp.autoGenAddrC: 2729 t.Fatalf("unexpected auto gen addr event = %+v", e) 2730 default: 2731 } 2732 2733 // Wait for DAD to complete for the stable address then expect the temporary 2734 // address to be generated. 2735 clock.Advance(dadTransmits * retransmitTimer) 2736 select { 2737 case e := <-ndpDisp.dadC: 2738 if diff := checkDADEvent(e, nicID, addr.Address, &stack.DADSucceeded{}); diff != "" { 2739 t.Errorf("DAD event mismatch (-want +got):\n%s", diff) 2740 } 2741 default: 2742 t.Fatal("timed out waiting for DAD event") 2743 } 2744 if err := addrDisp.expectStateChanged(stack.AddressAssigned); err != nil { 2745 t.Error(err) 2746 } 2747 tempAddrDisp, err := expectAutoGenAddrNewEvent(&ndpDisp, tempAddr) 2748 if err != nil { 2749 t.Fatalf("error expecting temp auto-gen address generated event: %s", err) 2750 } 2751 tempAddrDisp.disable() 2752 } 2753 2754 type tempAddrState struct { 2755 addrWithPrefix tcpip.AddressWithPrefix 2756 generated tcpip.MonotonicTime 2757 disp *addressDispatcher 2758 } 2759 2760 // TestAutoGenTempAddrRegen tests that temporary SLAAC addresses are 2761 // regenerated. 2762 func TestAutoGenTempAddrRegen(t *testing.T) { 2763 const ( 2764 nicID = 1 2765 regenAdv = 2 * time.Second 2766 2767 numTempAddrs = 3 2768 maxTempAddrValidLifetime = numTempAddrs * ipv6.MinPrefixInformationValidLifetimeForUpdate 2769 ) 2770 2771 prefix, _, addr := prefixSubnetAddr(0, linkAddr1) 2772 var tempIIDHistory [header.IIDSize]byte 2773 header.InitialTempIID(tempIIDHistory[:], nil, nicID) 2774 var tempAddrs [numTempAddrs]tempAddrState 2775 for i := 0; i < len(tempAddrs); i++ { 2776 tempAddrs[i] = tempAddrState{ 2777 addrWithPrefix: header.GenerateTempIPv6SLAACAddr(tempIIDHistory[:], addr.Address), 2778 } 2779 } 2780 2781 const autoGenAddrCount = 2 2782 ndpDisp := ndpDispatcher{ 2783 autoGenAddrNewC: make(chan ndpAutoGenAddrNewEvent, autoGenAddrCount), 2784 autoGenAddrC: make(chan ndpAutoGenAddrEvent, autoGenAddrCount), 2785 autoGenInstallDisp: true, 2786 } 2787 e := channel.New(0, 1280, linkAddr1) 2788 ndpConfigs := ipv6.NDPConfigurations{ 2789 HandleRAs: ipv6.HandlingRAsEnabledWhenForwardingDisabled, 2790 AutoGenGlobalAddresses: true, 2791 AutoGenTempGlobalAddresses: true, 2792 RegenAdvanceDuration: regenAdv, 2793 MaxTempAddrValidLifetime: maxTempAddrValidLifetime, 2794 MaxTempAddrPreferredLifetime: ipv6.MinPrefixInformationValidLifetimeForUpdate, 2795 } 2796 clock := faketime.NewManualClock() 2797 randSource := savingRandSource{ 2798 s: rand.NewSource(time.Now().UnixNano()), 2799 } 2800 s := stack.New(stack.Options{ 2801 NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{ 2802 NDPConfigs: ndpConfigs, 2803 NDPDisp: &ndpDisp, 2804 })}, 2805 Clock: clock, 2806 RandSource: &randSource, 2807 }) 2808 2809 if err := s.CreateNIC(nicID, e); err != nil { 2810 t.Fatalf("CreateNIC(%d, _) = %s", nicID, err) 2811 } 2812 2813 expectAutoGenAddrEventAsync := func(addr tcpip.AddressWithPrefix, eventType ndpAutoGenAddrEventType, timeout time.Duration) { 2814 t.Helper() 2815 2816 clock.Advance(timeout) 2817 expectAutoGenAddrEvent(t, &ndpDisp, addr, eventType) 2818 } 2819 2820 tempDesyncFactor := time.Duration(randSource.lastInt63) % ipv6.MaxDesyncFactor 2821 effectiveMaxTempAddrPL := ipv6.MinPrefixInformationValidLifetimeForUpdate - tempDesyncFactor 2822 // The time since the last regeneration before a new temporary address is 2823 // generated. 2824 tempAddrRegenerationTime := effectiveMaxTempAddrPL - regenAdv 2825 2826 // Receive an RA with prefix1 in an NDP Prefix Information option (PI) 2827 // with non-zero valid & preferred lifetimes. 2828 received := clock.NowMonotonic() 2829 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, minVLSeconds, minVLSeconds)) 2830 addrDisp, err := expectAutoGenAddrNewEvent(&ndpDisp, addr) 2831 if err != nil { 2832 t.Fatalf("error expecting stable auto-gen address generated event: %s", err) 2833 } 2834 // Disable receiving events on the stable address since it's not of interest 2835 // to this particular test. 2836 addrDisp.disable() 2837 tempAddrs[0].disp, err = expectAutoGenAddrNewEvent(&ndpDisp, tempAddrs[0].addrWithPrefix) 2838 if err != nil { 2839 t.Fatalf("error expecting temp auto-gen address generated event: %s", err) 2840 } 2841 tempAddrs[0].generated = clock.NowMonotonic() 2842 // Since the max temporary address preferred lifetime is equal to the valid 2843 // lifetime of the prefix, the temporary address generated is preferred 2844 // until the max minus the desync factor. 2845 if err := tempAddrs[0].disp.expectChanged(stack.AddressLifetimes{ 2846 ValidUntil: received.Add(time.Duration(minVLSeconds) * time.Second), 2847 PreferredUntil: received.Add(effectiveMaxTempAddrPL), 2848 }, stack.AddressAssigned); err != nil { 2849 t.Error(err) 2850 } 2851 if mismatch := addressCheck(s.NICInfo()[nicID].ProtocolAddresses, []tcpip.AddressWithPrefix{addr, tempAddrs[0].addrWithPrefix}, nil); mismatch != "" { 2852 t.Fatal(mismatch) 2853 } 2854 2855 // Wait for regeneration 2856 clock.Advance(tempAddrRegenerationTime) 2857 tempAddrs[1].disp, err = expectAutoGenAddrNewEvent(&ndpDisp, tempAddrs[1].addrWithPrefix) 2858 if err != nil { 2859 t.Fatalf("error expecting new temp regenerated address event: %s", err) 2860 } 2861 tempAddrs[1].generated = clock.NowMonotonic() 2862 // New temp address generated with lifetimes of the prefix. 2863 if err := tempAddrs[1].disp.expectChanged(addressLifetimes(received, minVLSeconds, minVLSeconds), stack.AddressAssigned); err != nil { 2864 t.Error(err) 2865 } 2866 received = clock.NowMonotonic() 2867 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, minVLSeconds, minVLSeconds)) 2868 // The first temporary address only has valid lifetime refreshed. 2869 if err := tempAddrs[0].disp.expectValidUntilChanged(received.Add(time.Duration(minVLSeconds) * time.Second)); err != nil { 2870 t.Error(err) 2871 } 2872 if err := tempAddrs[1].disp.expectChanged(stack.AddressLifetimes{ 2873 ValidUntil: received.Add(time.Duration(minVLSeconds) * time.Second), 2874 PreferredUntil: received.Add(effectiveMaxTempAddrPL), 2875 }, stack.AddressAssigned); err != nil { 2876 t.Error(err) 2877 } 2878 if mismatch := addressCheck(s.NICInfo()[nicID].ProtocolAddresses, []tcpip.AddressWithPrefix{addr, tempAddrs[0].addrWithPrefix, tempAddrs[1].addrWithPrefix}, nil); mismatch != "" { 2879 t.Fatal(mismatch) 2880 } 2881 expectAutoGenAddrEventAsync(tempAddrs[0].addrWithPrefix, deprecatedAddr, regenAdv) 2882 if err := tempAddrs[0].disp.expectDeprecated(); err != nil { 2883 t.Error(err) 2884 } 2885 2886 // Wait for regeneration 2887 clock.Advance(tempAddrRegenerationTime - regenAdv) 2888 tempAddrs[2].disp, err = expectAutoGenAddrNewEvent(&ndpDisp, tempAddrs[2].addrWithPrefix) 2889 if err != nil { 2890 t.Fatalf("error expecting new temp twice-regenerated address event: %s", err) 2891 } 2892 tempAddrs[2].generated = clock.NowMonotonic() 2893 if err := tempAddrs[2].disp.expectChanged(addressLifetimes(received, minVLSeconds, minVLSeconds), stack.AddressAssigned); err != nil { 2894 t.Error(err) 2895 } 2896 expectAutoGenAddrEventAsync(tempAddrs[1].addrWithPrefix, deprecatedAddr, regenAdv) 2897 if err := tempAddrs[1].disp.expectDeprecated(); err != nil { 2898 t.Error(err) 2899 } 2900 2901 // Stop generating temporary addresses 2902 ndpConfigs.AutoGenTempGlobalAddresses = false 2903 if ipv6Ep, err := s.GetNetworkEndpoint(nicID, header.IPv6ProtocolNumber); err != nil { 2904 t.Fatalf("s.GetNetworkEndpoint(%d, %d): %s", nicID, header.IPv6ProtocolNumber, err) 2905 } else { 2906 ndpEP := ipv6Ep.(ipv6.NDPEndpoint) 2907 ndpEP.SetNDPConfigurations(ndpConfigs) 2908 } 2909 2910 // Refresh lifetimes and wait for the last temporary address to be deprecated. 2911 received = clock.NowMonotonic() 2912 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, minVLSeconds, minVLSeconds)) 2913 for i, tempAddrState := range tempAddrs { 2914 if i == 2 { 2915 if err := tempAddrState.disp.expectLifetimesChanged(stack.AddressLifetimes{ 2916 ValidUntil: received.Add(time.Duration(minVLSeconds) * time.Second), 2917 // The effective max preferred lifetime since address generation is used 2918 // since it is less than the refreshed prefix preferred lifetime. 2919 PreferredUntil: tempAddrState.generated.Add(effectiveMaxTempAddrPL), 2920 }); err != nil { 2921 t.Error(err) 2922 } 2923 } else { 2924 if err := tempAddrState.disp.expectValidUntilChanged(received.Add(time.Duration(minVLSeconds) * time.Second)); err != nil { 2925 t.Errorf("addr %d error: %s", i, err) 2926 } 2927 } 2928 } 2929 expectAutoGenAddrEventAsync(tempAddrs[2].addrWithPrefix, deprecatedAddr, effectiveMaxTempAddrPL-regenAdv) 2930 if err := tempAddrs[2].disp.expectDeprecated(); err != nil { 2931 t.Error(err) 2932 } 2933 2934 // Refresh lifetimes such that the prefix is valid and preferred forever. 2935 // 2936 // This should not affect the lifetimes of temporary addresses because they 2937 // are capped by the maximum valid and preferred lifetimes for temporary 2938 // addresses. 2939 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, infiniteLifetimeSeconds, infiniteLifetimeSeconds)) 2940 for i, tempAddrState := range tempAddrs { 2941 if err := tempAddrState.disp.expectValidUntilChanged(tempAddrState.generated.Add(maxTempAddrValidLifetime)); err != nil { 2942 t.Errorf("addr %d error: %s", i, err) 2943 } 2944 } 2945 2946 // Wait for all the temporary addresses to get invalidated. 2947 invalidateAfter := maxTempAddrValidLifetime - clock.NowMonotonic().Sub(tcpip.MonotonicTime{}) 2948 var tempAddrWithPrefix [numTempAddrs]tcpip.AddressWithPrefix 2949 for i, tempAddrState := range tempAddrs { 2950 tempAddrWithPrefix[i] = tempAddrState.addrWithPrefix 2951 expectAutoGenAddrEventAsync(tempAddrState.addrWithPrefix, invalidatedAddr, invalidateAfter) 2952 invalidateAfter = tempAddrRegenerationTime 2953 if err := tempAddrState.disp.expectRemoved(stack.AddressRemovalInvalidated); err != nil { 2954 t.Errorf("addr %d error: %s", i, err) 2955 } 2956 } 2957 if mismatch := addressCheck(s.NICInfo()[nicID].ProtocolAddresses, []tcpip.AddressWithPrefix{addr}, tempAddrWithPrefix[:]); mismatch != "" { 2958 t.Fatal(mismatch) 2959 } 2960 } 2961 2962 // TestAutoGenTempAddrRegenJobUpdates tests that a temporary address's 2963 // regeneration job gets updated when refreshing the address's lifetimes. 2964 func TestAutoGenTempAddrRegenJobUpdates(t *testing.T) { 2965 const ( 2966 nicID = 1 2967 regenAdv = 2 * time.Second 2968 2969 numTempAddrs = 3 2970 maxTempAddrPreferredLifetime = ipv6.MinPrefixInformationValidLifetimeForUpdate 2971 maxTempAddrPreferredLifetimeSeconds = uint32(maxTempAddrPreferredLifetime / time.Second) 2972 ) 2973 2974 prefix, _, addr := prefixSubnetAddr(0, linkAddr1) 2975 var tempIIDHistory [header.IIDSize]byte 2976 header.InitialTempIID(tempIIDHistory[:], nil, nicID) 2977 var tempAddrs [numTempAddrs]tempAddrState 2978 for i := 0; i < len(tempAddrs); i++ { 2979 tempAddrs[i] = tempAddrState{ 2980 addrWithPrefix: header.GenerateTempIPv6SLAACAddr(tempIIDHistory[:], addr.Address), 2981 } 2982 } 2983 2984 const autoGenAddrCount = 2 2985 ndpDisp := ndpDispatcher{ 2986 autoGenAddrNewC: make(chan ndpAutoGenAddrNewEvent, autoGenAddrCount), 2987 autoGenAddrC: make(chan ndpAutoGenAddrEvent, autoGenAddrCount), 2988 autoGenInstallDisp: true, 2989 } 2990 e := channel.New(0, 1280, linkAddr1) 2991 ndpConfigs := ipv6.NDPConfigurations{ 2992 HandleRAs: ipv6.HandlingRAsEnabledWhenForwardingDisabled, 2993 AutoGenGlobalAddresses: true, 2994 AutoGenTempGlobalAddresses: true, 2995 RegenAdvanceDuration: regenAdv, 2996 MaxTempAddrPreferredLifetime: maxTempAddrPreferredLifetime, 2997 MaxTempAddrValidLifetime: maxTempAddrPreferredLifetime * 2, 2998 } 2999 clock := faketime.NewManualClock() 3000 initialTime := clock.NowMonotonic() 3001 randSource := savingRandSource{ 3002 s: rand.NewSource(time.Now().UnixNano()), 3003 } 3004 s := stack.New(stack.Options{ 3005 NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{ 3006 NDPConfigs: ndpConfigs, 3007 NDPDisp: &ndpDisp, 3008 })}, 3009 Clock: clock, 3010 RandSource: &randSource, 3011 }) 3012 3013 if err := s.CreateNIC(nicID, e); err != nil { 3014 t.Fatalf("CreateNIC(%d, _) = %s", nicID, err) 3015 } 3016 3017 tempDesyncFactor := time.Duration(randSource.lastInt63) % ipv6.MaxDesyncFactor 3018 effectiveMaxTempAddrPL := maxTempAddrPreferredLifetime - tempDesyncFactor 3019 3020 expectAutoGenAddrEventAsync := func(addr tcpip.AddressWithPrefix, eventType ndpAutoGenAddrEventType, timeout time.Duration) { 3021 t.Helper() 3022 3023 clock.Advance(timeout) 3024 expectAutoGenAddrEvent(t, &ndpDisp, addr, eventType) 3025 } 3026 3027 // Receive an RA with prefix1 in an NDP Prefix Information option (PI) 3028 // with non-zero valid & preferred lifetimes. 3029 received := clock.NowMonotonic() 3030 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, maxTempAddrPreferredLifetimeSeconds, maxTempAddrPreferredLifetimeSeconds)) 3031 addrDisp, err := expectAutoGenAddrNewEvent(&ndpDisp, addr) 3032 if err != nil { 3033 t.Fatalf("error expecting stable auto-gen address generated event: %s", err) 3034 } 3035 // Ignore events about the stable address, since that's not relevant to this test. 3036 addrDisp.disable() 3037 tempAddrs[0].disp, err = expectAutoGenAddrNewEvent(&ndpDisp, tempAddrs[0].addrWithPrefix) 3038 if err != nil { 3039 t.Fatalf("error expecting temp auto-gen address generated event: %s", err) 3040 } 3041 tempAddrs[0].generated = clock.NowMonotonic() 3042 if err := tempAddrs[0].disp.expectChanged(stack.AddressLifetimes{ 3043 ValidUntil: received.Add(maxTempAddrPreferredLifetime), 3044 PreferredUntil: received.Add(effectiveMaxTempAddrPL), 3045 }, stack.AddressAssigned); err != nil { 3046 t.Error(err) 3047 } 3048 if mismatch := addressCheck(s.NICInfo()[nicID].ProtocolAddresses, []tcpip.AddressWithPrefix{addr, tempAddrs[0].addrWithPrefix}, nil); mismatch != "" { 3049 t.Fatal(mismatch) 3050 } 3051 3052 // Deprecate the prefix. 3053 // 3054 // A new temporary address should be generated after the regeneration 3055 // time has passed since the prefix is deprecated. 3056 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, maxTempAddrPreferredLifetimeSeconds, 0)) 3057 expectAutoGenAddrEvent(t, &ndpDisp, addr, deprecatedAddr) 3058 expectAutoGenAddrEvent(t, &ndpDisp, tempAddrs[0].addrWithPrefix, deprecatedAddr) 3059 if err := tempAddrs[0].disp.expectDeprecated(); err != nil { 3060 t.Error(err) 3061 } 3062 select { 3063 case e := <-ndpDisp.autoGenAddrC: 3064 t.Fatalf("unexpected auto gen addr event = %#v", e) 3065 default: 3066 } 3067 3068 // The time since the last regeneration before a new temporary address is 3069 // generated. 3070 tempAddrRegenenerationTime := effectiveMaxTempAddrPL - regenAdv 3071 3072 // Advance the clock by the regeneration time but don't expect a new temporary 3073 // address as the prefix is deprecated. 3074 clock.Advance(tempAddrRegenenerationTime) 3075 select { 3076 case e := <-ndpDisp.autoGenAddrC: 3077 t.Fatalf("unexpected auto gen addr event = %#v", e) 3078 default: 3079 } 3080 3081 // Prefer the prefix again. 3082 // 3083 // A new temporary address should immediately be generated since the 3084 // regeneration time has already passed since the last address was generated 3085 // - this regeneration does not depend on a job. 3086 received = clock.NowMonotonic() 3087 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, maxTempAddrPreferredLifetimeSeconds, maxTempAddrPreferredLifetimeSeconds)) 3088 if err := tempAddrs[0].disp.expectLifetimesChanged( 3089 stack.AddressLifetimes{ 3090 ValidUntil: received.Add(maxTempAddrPreferredLifetime), 3091 PreferredUntil: tempAddrs[0].generated.Add(effectiveMaxTempAddrPL), 3092 }); err != nil { 3093 t.Error(err) 3094 } 3095 tempAddrs[1].disp, err = expectAutoGenAddrNewEvent(&ndpDisp, tempAddrs[1].addrWithPrefix) 3096 if err != nil { 3097 t.Fatalf("error expecting temp auto-gen address regenerated event: %s", err) 3098 } 3099 tempAddrs[1].generated = clock.NowMonotonic() 3100 if err := tempAddrs[1].disp.expectChanged(stack.AddressLifetimes{ 3101 ValidUntil: received.Add(maxTempAddrPreferredLifetime), 3102 PreferredUntil: received.Add(effectiveMaxTempAddrPL), 3103 }, stack.AddressAssigned); err != nil { 3104 t.Error(err) 3105 } 3106 // Wait for the first temporary address to be deprecated. 3107 expectAutoGenAddrEventAsync(tempAddrs[0].addrWithPrefix, deprecatedAddr, regenAdv) 3108 if err := tempAddrs[0].disp.expectDeprecated(); err != nil { 3109 t.Error(err) 3110 } 3111 select { 3112 case e := <-ndpDisp.autoGenAddrC: 3113 t.Fatalf("unexpected auto gen addr event = %s", e) 3114 default: 3115 } 3116 3117 // Increase the maximum lifetimes for temporary addresses to large values 3118 // then refresh the lifetimes of the prefix. 3119 // 3120 // A new address should not be generated after the regeneration time that was 3121 // expected for the previous check. This is because the preferred lifetime for 3122 // the temporary addresses has increased, so it will take more time to 3123 // regenerate a new temporary address. Note, new addresses are only 3124 // regenerated after the preferred lifetime - the regenerate advance duration 3125 // has passed. 3126 const largeLifetimeSeconds = minVLSeconds * 2 3127 const largeLifetime = time.Duration(largeLifetimeSeconds) * time.Second 3128 ndpConfigs.MaxTempAddrValidLifetime = 2 * largeLifetime 3129 ndpConfigs.MaxTempAddrPreferredLifetime = largeLifetime 3130 ipv6Ep, tcpipErr := s.GetNetworkEndpoint(nicID, header.IPv6ProtocolNumber) 3131 if tcpipErr != nil { 3132 t.Fatalf("s.GetNetworkEndpoint(%d, %d): %s", nicID, header.IPv6ProtocolNumber, tcpipErr) 3133 } 3134 ndpEP := ipv6Ep.(ipv6.NDPEndpoint) 3135 ndpEP.SetNDPConfigurations(ndpConfigs) 3136 received = clock.NowMonotonic() 3137 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, largeLifetimeSeconds, largeLifetimeSeconds)) 3138 for i := 0; i <= 1; i++ { 3139 if err := tempAddrs[i].disp.expectLifetimesChanged(stack.AddressLifetimes{ 3140 ValidUntil: received.Add(largeLifetime), 3141 PreferredUntil: tempAddrs[i].generated.Add(largeLifetime - tempDesyncFactor), 3142 }); err != nil { 3143 t.Errorf("addr %d dispatcher error: %s", i, err) 3144 } 3145 } 3146 timeSinceInitialTime := clock.NowMonotonic().Sub(initialTime) 3147 clock.Advance(largeLifetime - timeSinceInitialTime) 3148 expectAutoGenAddrEvent(t, &ndpDisp, tempAddrs[0].addrWithPrefix, deprecatedAddr) 3149 if err := tempAddrs[0].disp.expectDeprecated(); err != nil { 3150 t.Error(err) 3151 } 3152 // to offset the advancement of time to test the first temporary address's 3153 // deprecation after the second was generated 3154 advLess := regenAdv 3155 clock.Advance(timeSinceInitialTime - advLess - (tempDesyncFactor + regenAdv)) 3156 tempAddrs[2].disp, err = expectAutoGenAddrNewEvent(&ndpDisp, tempAddrs[2].addrWithPrefix) 3157 if err != nil { 3158 t.Fatalf("error expecting temp auto-gen address twice-regenerated event: %s", err) 3159 } 3160 tempAddrs[2].generated = clock.NowMonotonic() 3161 if err := tempAddrs[2].disp.expectChanged(addressLifetimes(received, largeLifetimeSeconds, largeLifetimeSeconds), stack.AddressAssigned); err != nil { 3162 t.Error(err) 3163 } 3164 expectAutoGenAddrEventAsync(tempAddrs[1].addrWithPrefix, deprecatedAddr, regenAdv) 3165 if err := tempAddrs[1].disp.expectDeprecated(); err != nil { 3166 t.Error(err) 3167 } 3168 select { 3169 case e := <-ndpDisp.autoGenAddrC: 3170 t.Fatalf("unexpected auto gen addr event = %+v", e) 3171 default: 3172 } 3173 } 3174 3175 // TestMixedSLAACAddrConflictRegen tests SLAAC address regeneration in response 3176 // to a mix of DAD conflicts and NIC-local conflicts. 3177 func TestMixedSLAACAddrConflictRegen(t *testing.T) { 3178 const ( 3179 nicID = 1 3180 nicName = "nic" 3181 lifetimeSeconds = 9999 3182 // From stack.maxSLAACAddrLocalRegenAttempts 3183 maxSLAACAddrLocalRegenAttempts = 10 3184 // We use 2 more addresses than the maximum local regeneration attempts 3185 // because we want to also trigger regeneration in response to a DAD 3186 // conflicts for this test. 3187 maxAddrs = maxSLAACAddrLocalRegenAttempts + 2 3188 dupAddrTransmits = 1 3189 retransmitTimer = time.Second 3190 ) 3191 3192 var tempIIDHistoryWithModifiedEUI64 [header.IIDSize]byte 3193 header.InitialTempIID(tempIIDHistoryWithModifiedEUI64[:], nil, nicID) 3194 3195 var tempIIDHistoryWithOpaqueIID [header.IIDSize]byte 3196 header.InitialTempIID(tempIIDHistoryWithOpaqueIID[:], nil, nicID) 3197 3198 prefix, subnet, stableAddrWithModifiedEUI64 := prefixSubnetAddr(0, linkAddr1) 3199 var stableAddrsWithOpaqueIID [maxAddrs]tcpip.AddressWithPrefix 3200 var tempAddrsWithOpaqueIID [maxAddrs]tcpip.AddressWithPrefix 3201 var tempAddrsWithModifiedEUI64 [maxAddrs]tcpip.AddressWithPrefix 3202 subnetID := subnet.ID() 3203 addrBytes := subnetID.AsSlice() 3204 for i := 0; i < maxAddrs; i++ { 3205 stableAddrsWithOpaqueIID[i] = tcpip.AddressWithPrefix{ 3206 Address: tcpip.AddrFromSlice(header.AppendOpaqueInterfaceIdentifier(addrBytes[:header.IIDOffsetInIPv6Address], subnet, nicName, uint8(i), nil)), 3207 PrefixLen: header.IIDOffsetInIPv6Address * 8, 3208 } 3209 // When generating temporary addresses, the resolved stable address for the 3210 // SLAAC prefix will be the first address stable address generated for the 3211 // prefix as we will not simulate address conflicts for the stable addresses 3212 // in tests involving temporary addresses. Address conflicts for stable 3213 // addresses will be done in their own tests. 3214 tempAddrsWithOpaqueIID[i] = header.GenerateTempIPv6SLAACAddr(tempIIDHistoryWithOpaqueIID[:], stableAddrsWithOpaqueIID[0].Address) 3215 tempAddrsWithModifiedEUI64[i] = header.GenerateTempIPv6SLAACAddr(tempIIDHistoryWithModifiedEUI64[:], stableAddrWithModifiedEUI64.Address) 3216 } 3217 3218 tests := []struct { 3219 name string 3220 addrs []tcpip.AddressWithPrefix 3221 tempAddrs bool 3222 initialExpect tcpip.AddressWithPrefix 3223 maxAddrs int 3224 nicNameFromID func(tcpip.NICID, string) string 3225 }{ 3226 { 3227 name: "Stable addresses with opaque IIDs", 3228 addrs: stableAddrsWithOpaqueIID[:], 3229 maxAddrs: 1, 3230 nicNameFromID: func(tcpip.NICID, string) string { 3231 return nicName 3232 }, 3233 }, 3234 { 3235 name: "Temporary addresses with opaque IIDs", 3236 addrs: tempAddrsWithOpaqueIID[:], 3237 tempAddrs: true, 3238 initialExpect: stableAddrsWithOpaqueIID[0], 3239 maxAddrs: 1 /* initial (stable) address */ + maxSLAACAddrLocalRegenAttempts, 3240 nicNameFromID: func(tcpip.NICID, string) string { 3241 return nicName 3242 }, 3243 }, 3244 { 3245 name: "Temporary addresses with modified EUI64", 3246 addrs: tempAddrsWithModifiedEUI64[:], 3247 tempAddrs: true, 3248 maxAddrs: 1 /* initial (stable) address */ + maxSLAACAddrLocalRegenAttempts, 3249 initialExpect: stableAddrWithModifiedEUI64, 3250 }, 3251 } 3252 3253 for _, test := range tests { 3254 t.Run(test.name, func(t *testing.T) { 3255 ndpDisp := ndpDispatcher{ 3256 autoGenAddrNewC: make(chan ndpAutoGenAddrNewEvent, test.maxAddrs), 3257 // We may receive a deprecated and invalidated event for each SLAAC 3258 // address that is assigned. 3259 autoGenAddrC: make(chan ndpAutoGenAddrEvent, test.maxAddrs*2), 3260 } 3261 e := channel.New(0, 1280, linkAddr1) 3262 clock := faketime.NewManualClock() 3263 s := stack.New(stack.Options{ 3264 Clock: clock, 3265 NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{ 3266 NDPConfigs: ipv6.NDPConfigurations{ 3267 HandleRAs: ipv6.HandlingRAsEnabledWhenForwardingDisabled, 3268 AutoGenGlobalAddresses: true, 3269 AutoGenTempGlobalAddresses: test.tempAddrs, 3270 AutoGenAddressConflictRetries: 1, 3271 }, 3272 NDPDisp: &ndpDisp, 3273 OpaqueIIDOpts: ipv6.OpaqueInterfaceIdentifierOptions{ 3274 NICNameFromID: test.nicNameFromID, 3275 }, 3276 })}, 3277 TransportProtocols: []stack.TransportProtocolFactory{udp.NewProtocol}, 3278 }) 3279 3280 s.SetRouteTable([]tcpip.Route{{ 3281 Destination: header.IPv6EmptySubnet, 3282 Gateway: llAddr2, 3283 NIC: nicID, 3284 }}) 3285 3286 if err := s.CreateNIC(nicID, e); err != nil { 3287 t.Fatalf("CreateNIC(%d, _) = %s", nicID, err) 3288 } 3289 3290 manuallyAssignedAddresses := make(map[tcpip.Address]struct{}) 3291 for j := 0; j < len(test.addrs)-1; j++ { 3292 // The NIC will not attempt to generate an address in response to a 3293 // NIC-local conflict after some maximum number of attempts. We skip 3294 // creating a conflict for the address that would be generated as part 3295 // of the last attempt so we can simulate a DAD conflict for this 3296 // address and restart the NIC-local generation process. 3297 if j == maxSLAACAddrLocalRegenAttempts-1 { 3298 continue 3299 } 3300 3301 protocolAddr := tcpip.ProtocolAddress{ 3302 Protocol: ipv6.ProtocolNumber, 3303 AddressWithPrefix: test.addrs[j].Address.WithPrefix(), 3304 } 3305 if err := s.AddProtocolAddress(nicID, protocolAddr, stack.AddressProperties{}); err != nil { 3306 t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", nicID, protocolAddr, err) 3307 } 3308 3309 manuallyAssignedAddresses[test.addrs[j].Address] = struct{}{} 3310 } 3311 3312 expectAutoGenAddrNewEventAsync := func(addr tcpip.AddressWithPrefix) { 3313 t.Helper() 3314 3315 e := <-ndpDisp.autoGenAddrNewC 3316 if diff := cmp.Diff( 3317 ndpAutoGenAddrNewEvent{nicID: 1, addr: addr}, 3318 e, 3319 cmp.AllowUnexported(e), 3320 cmp.FilterValues(func(*addressDispatcher, *addressDispatcher) bool { return true }, cmp.Ignore()), 3321 ); diff != "" { 3322 t.Errorf("auto-gen new addr event mismatch (-want +got):\n%s", diff) 3323 } 3324 if e.addrDisp != nil { 3325 t.Error("auto-gen new addr event unexpectedly contains address dispatcher") 3326 } 3327 } 3328 3329 expectDADEventAsync := func(addr tcpip.Address) { 3330 t.Helper() 3331 3332 clock.Advance(dupAddrTransmits * retransmitTimer) 3333 if diff := checkDADEvent(<-ndpDisp.dadC, nicID, addr, &stack.DADSucceeded{}); diff != "" { 3334 t.Errorf("DAD event mismatch (-want +got):\n%s", diff) 3335 } 3336 } 3337 3338 // Enable DAD. 3339 ndpDisp.dadC = make(chan ndpDADEvent, 2) 3340 if ipv6Ep, err := s.GetNetworkEndpoint(nicID, header.IPv6ProtocolNumber); err != nil { 3341 t.Fatalf("s.GetNetworkEndpoint(%d, %d): %s", nicID, header.IPv6ProtocolNumber, err) 3342 } else { 3343 ndpEP := ipv6Ep.(stack.DuplicateAddressDetector) 3344 ndpEP.SetDADConfigurations(stack.DADConfigurations{ 3345 DupAddrDetectTransmits: dupAddrTransmits, 3346 RetransmitTimer: retransmitTimer, 3347 }) 3348 } 3349 3350 // Do SLAAC for prefix. 3351 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, lifetimeSeconds, lifetimeSeconds)) 3352 if test.initialExpect != (tcpip.AddressWithPrefix{}) { 3353 if _, err := expectAutoGenAddrNewEvent(&ndpDisp, test.initialExpect); err != nil { 3354 t.Fatalf("error expecting auto-gen address generated event: %s", err) 3355 } 3356 expectDADEventAsync(test.initialExpect.Address) 3357 } 3358 3359 // The last local generation attempt should succeed, but we introduce a 3360 // DAD failure to restart the local generation process. 3361 addr := test.addrs[maxSLAACAddrLocalRegenAttempts-1] 3362 expectAutoGenAddrNewEventAsync(addr) 3363 rxNDPSolicit(e, addr.Address) 3364 select { 3365 case e := <-ndpDisp.dadC: 3366 if diff := checkDADEvent(e, nicID, addr.Address, &stack.DADDupAddrDetected{}); diff != "" { 3367 t.Errorf("DAD event mismatch (-want +got):\n%s", diff) 3368 } 3369 default: 3370 t.Fatal("expected DAD event") 3371 } 3372 expectAutoGenAddrEvent(t, &ndpDisp, addr, invalidatedAddr) 3373 3374 // The last address generated should resolve DAD. 3375 addr = test.addrs[len(test.addrs)-1] 3376 expectAutoGenAddrNewEventAsync(addr) 3377 expectDADEventAsync(addr.Address) 3378 3379 select { 3380 case e := <-ndpDisp.autoGenAddrC: 3381 t.Fatalf("unexpected auto gen addr event = %+v", e) 3382 default: 3383 } 3384 3385 // Wait for all the SLAAC addresses to be invalidated. 3386 clock.Advance(lifetimeSeconds * time.Second) 3387 gotAddresses := make(map[tcpip.Address]struct{}) 3388 for _, a := range s.NICInfo()[nicID].ProtocolAddresses { 3389 gotAddresses[a.AddressWithPrefix.Address] = struct{}{} 3390 } 3391 if diff := cmp.Diff(manuallyAssignedAddresses, gotAddresses); diff != "" { 3392 t.Fatalf("assigned addresses mismatch (-want +got):\n%s", diff) 3393 } 3394 }) 3395 } 3396 } 3397 3398 // stackAndNdpDispatcherWithDefaultRoute returns an ndpDispatcher, 3399 // channel.Endpoint and stack.Stack. 3400 // 3401 // stack.Stack will have a default route through the router (llAddr3) installed 3402 // and a static link-address (linkAddr3) added to the link address cache for the 3403 // router. 3404 func stackAndNdpDispatcherWithDefaultRoute(t *testing.T, nicID tcpip.NICID) (*ndpDispatcher, *channel.Endpoint, *stack.Stack, *faketime.ManualClock) { 3405 t.Helper() 3406 const autoGenAddrCount = 1 3407 ndpDisp := &ndpDispatcher{ 3408 autoGenAddrNewC: make(chan ndpAutoGenAddrNewEvent, autoGenAddrCount), 3409 autoGenAddrC: make(chan ndpAutoGenAddrEvent, autoGenAddrCount), 3410 } 3411 e := channel.New(0, 1280, linkAddr1) 3412 e.LinkEPCapabilities |= stack.CapabilityResolutionRequired 3413 clock := faketime.NewManualClock() 3414 s := stack.New(stack.Options{ 3415 NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{ 3416 NDPConfigs: ipv6.NDPConfigurations{ 3417 HandleRAs: ipv6.HandlingRAsEnabledWhenForwardingDisabled, 3418 AutoGenGlobalAddresses: true, 3419 }, 3420 NDPDisp: ndpDisp, 3421 })}, 3422 TransportProtocols: []stack.TransportProtocolFactory{udp.NewProtocol}, 3423 Clock: clock, 3424 }) 3425 if err := s.CreateNIC(nicID, e); err != nil { 3426 t.Fatalf("CreateNIC(%d, _) = %s", nicID, err) 3427 } 3428 s.SetRouteTable([]tcpip.Route{{ 3429 Destination: header.IPv6EmptySubnet, 3430 Gateway: llAddr3, 3431 NIC: nicID, 3432 }}) 3433 3434 if err := s.AddStaticNeighbor(nicID, ipv6.ProtocolNumber, llAddr3, linkAddr3); err != nil { 3435 t.Fatalf("s.AddStaticNeighbor(%d, %d, %s, %s): %s", nicID, ipv6.ProtocolNumber, llAddr3, linkAddr3, err) 3436 } 3437 return ndpDisp, e, s, clock 3438 } 3439 3440 // addrForNewConnectionTo returns the local address used when creating a new 3441 // connection to addr. 3442 func addrForNewConnectionTo(t *testing.T, s *stack.Stack, addr tcpip.FullAddress) tcpip.Address { 3443 t.Helper() 3444 3445 wq := waiter.Queue{} 3446 we, ch := waiter.NewChannelEntry(waiter.ReadableEvents) 3447 wq.EventRegister(&we) 3448 defer wq.EventUnregister(&we) 3449 defer close(ch) 3450 ep, err := s.NewEndpoint(header.UDPProtocolNumber, header.IPv6ProtocolNumber, &wq) 3451 if err != nil { 3452 t.Fatalf("s.NewEndpoint(%d, %d, _): %s", header.UDPProtocolNumber, header.IPv6ProtocolNumber, err) 3453 } 3454 defer ep.Close() 3455 ep.SocketOptions().SetV6Only(true) 3456 if err := ep.Connect(addr); err != nil { 3457 t.Fatalf("ep.Connect(%+v): %s", addr, err) 3458 } 3459 got, err := ep.GetLocalAddress() 3460 if err != nil { 3461 t.Fatalf("ep.GetLocalAddress(): %s", err) 3462 } 3463 return got.Addr 3464 } 3465 3466 // addrForNewConnection returns the local address used when creating a new 3467 // connection. 3468 func addrForNewConnection(t *testing.T, s *stack.Stack) tcpip.Address { 3469 t.Helper() 3470 3471 return addrForNewConnectionTo(t, s, dstAddr) 3472 } 3473 3474 // addrForNewConnectionWithAddr returns the local address used when creating a 3475 // new connection with a specific local address. 3476 func addrForNewConnectionWithAddr(t *testing.T, s *stack.Stack, addr tcpip.FullAddress) tcpip.Address { 3477 t.Helper() 3478 3479 wq := waiter.Queue{} 3480 we, ch := waiter.NewChannelEntry(waiter.ReadableEvents) 3481 wq.EventRegister(&we) 3482 defer wq.EventUnregister(&we) 3483 defer close(ch) 3484 ep, err := s.NewEndpoint(header.UDPProtocolNumber, header.IPv6ProtocolNumber, &wq) 3485 if err != nil { 3486 t.Fatalf("s.NewEndpoint(%d, %d, _): %s", header.UDPProtocolNumber, header.IPv6ProtocolNumber, err) 3487 } 3488 defer ep.Close() 3489 ep.SocketOptions().SetV6Only(true) 3490 if err := ep.Bind(addr); err != nil { 3491 t.Fatalf("ep.Bind(%+v): %s", addr, err) 3492 } 3493 if err := ep.Connect(dstAddr); err != nil { 3494 t.Fatalf("ep.Connect(%+v): %s", dstAddr, err) 3495 } 3496 got, err := ep.GetLocalAddress() 3497 if err != nil { 3498 t.Fatalf("ep.GetLocalAddress(): %s", err) 3499 } 3500 return got.Addr 3501 } 3502 3503 // TestAutoGenAddrDeprecateFromPI tests deprecating a SLAAC address when 3504 // receiving a PI with 0 preferred lifetime. 3505 func TestAutoGenAddrDeprecateFromPI(t *testing.T) { 3506 const nicID = 1 3507 3508 prefix1, _, addr1 := prefixSubnetAddr(0, linkAddr1) 3509 prefix2, _, addr2 := prefixSubnetAddr(1, linkAddr1) 3510 3511 ndpDisp, e, s, _ := stackAndNdpDispatcherWithDefaultRoute(t, nicID) 3512 3513 expectPrimaryAddr := func(addr tcpip.AddressWithPrefix) { 3514 t.Helper() 3515 3516 if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, addr); err != nil { 3517 t.Fatal(err) 3518 } 3519 3520 if got := addrForNewConnection(t, s); got != addr.Address { 3521 t.Errorf("got addrForNewConnection = %s, want = %s", got, addr.Address) 3522 } 3523 } 3524 3525 // Receive PI for prefix1. 3526 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, 100, 100)) 3527 if _, err := expectAutoGenAddrNewEvent(ndpDisp, addr1); err != nil { 3528 t.Fatalf("error expecting prefix1 stable auto-gen address generated event: %s", err) 3529 } 3530 if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr1) { 3531 t.Fatalf("should have %s in the list of addresses", addr1) 3532 } 3533 expectPrimaryAddr(addr1) 3534 3535 // Deprecate addr for prefix1 immediately. 3536 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, 100, 0)) 3537 expectAutoGenAddrEvent(t, ndpDisp, addr1, deprecatedAddr) 3538 if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr1) { 3539 t.Fatalf("should have %s in the list of addresses", addr1) 3540 } 3541 // addr should still be the primary endpoint as there are no other addresses. 3542 expectPrimaryAddr(addr1) 3543 3544 // Refresh lifetimes of addr generated from prefix1. 3545 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, 100, 100)) 3546 select { 3547 case <-ndpDisp.autoGenAddrC: 3548 t.Fatal("unexpectedly got an auto-generated event") 3549 default: 3550 } 3551 expectPrimaryAddr(addr1) 3552 3553 // Receive PI for prefix2. 3554 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix2, true, true, 100, 100)) 3555 if _, err := expectAutoGenAddrNewEvent(ndpDisp, addr2); err != nil { 3556 t.Fatalf("error expecting prefix2 stable auto-gen address generated event: %s", err) 3557 } 3558 if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr2) { 3559 t.Fatalf("should have %s in the list of addresses", addr2) 3560 } 3561 expectPrimaryAddr(addr2) 3562 3563 // Deprecate addr for prefix2 immediately. 3564 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix2, true, true, 100, 0)) 3565 expectAutoGenAddrEvent(t, ndpDisp, addr2, deprecatedAddr) 3566 if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr2) { 3567 t.Fatalf("should have %s in the list of addresses", addr2) 3568 } 3569 // addr1 should be the primary endpoint now since addr2 is deprecated but 3570 // addr1 is not. 3571 expectPrimaryAddr(addr1) 3572 // addr2 is deprecated but if explicitly requested, it should be used. 3573 fullAddr2 := tcpip.FullAddress{Addr: addr2.Address, NIC: nicID} 3574 if got := addrForNewConnectionWithAddr(t, s, fullAddr2); got != addr2.Address { 3575 t.Errorf("got addrForNewConnectionWithAddr(_, _, %+v) = %s, want = %s", fullAddr2, got, addr2.Address) 3576 } 3577 3578 // Another PI w/ 0 preferred lifetime should not result in a deprecation 3579 // event. 3580 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix2, true, true, 100, 0)) 3581 select { 3582 case <-ndpDisp.autoGenAddrC: 3583 t.Fatal("unexpectedly got an auto-generated event") 3584 default: 3585 } 3586 expectPrimaryAddr(addr1) 3587 if got := addrForNewConnectionWithAddr(t, s, fullAddr2); got != addr2.Address { 3588 t.Errorf("got addrForNewConnectionWithAddr(_, _, %+v) = %s, want = %s", fullAddr2, got, addr2.Address) 3589 } 3590 3591 // Refresh lifetimes of addr generated from prefix2. 3592 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix2, true, true, 100, 100)) 3593 select { 3594 case <-ndpDisp.autoGenAddrC: 3595 t.Fatal("unexpectedly got an auto-generated event") 3596 default: 3597 } 3598 expectPrimaryAddr(addr2) 3599 } 3600 3601 // TestAutoGenAddrJobDeprecation tests that an address is properly deprecated 3602 // when its preferred lifetime expires. 3603 func TestAutoGenAddrJobDeprecation(t *testing.T) { 3604 const nicID = 1 3605 3606 prefix1, _, addr1 := prefixSubnetAddr(0, linkAddr1) 3607 prefix2, _, addr2 := prefixSubnetAddr(1, linkAddr1) 3608 3609 ndpDisp, e, s, clock := stackAndNdpDispatcherWithDefaultRoute(t, nicID) 3610 3611 expectAutoGenAddrEventAfter := func(addr tcpip.AddressWithPrefix, eventType ndpAutoGenAddrEventType, timeout time.Duration) { 3612 t.Helper() 3613 3614 clock.Advance(timeout) 3615 expectAutoGenAddrEvent(t, ndpDisp, addr, eventType) 3616 } 3617 3618 expectPrimaryAddr := func(addr tcpip.AddressWithPrefix) { 3619 t.Helper() 3620 3621 if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, addr); err != nil { 3622 t.Fatal(err) 3623 } 3624 3625 if got := addrForNewConnection(t, s); got != addr.Address { 3626 t.Errorf("got addrForNewConnection = %s, want = %s", got, addr.Address) 3627 } 3628 } 3629 3630 // Receive PI for prefix2. 3631 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix2, true, true, infiniteLifetimeSeconds, infiniteLifetimeSeconds)) 3632 if _, err := expectAutoGenAddrNewEvent(ndpDisp, addr2); err != nil { 3633 t.Fatalf("error expecting prefix2 stable auto-gen address generated event: %s", err) 3634 } 3635 if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr2) { 3636 t.Fatalf("should have %s in the list of addresses", addr2) 3637 } 3638 expectPrimaryAddr(addr2) 3639 3640 // Receive a PI for prefix1. 3641 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, 100, 90)) 3642 if _, err := expectAutoGenAddrNewEvent(ndpDisp, addr1); err != nil { 3643 t.Fatalf("error expecting prefix1 stable auto-gen address generated event: %s", err) 3644 } 3645 if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr1) { 3646 t.Fatalf("should have %s in the list of addresses", addr1) 3647 } 3648 if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr2) { 3649 t.Fatalf("should have %s in the list of addresses", addr2) 3650 } 3651 expectPrimaryAddr(addr1) 3652 3653 // Refresh lifetime for addr of prefix1. 3654 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, minVLSeconds, minVLSeconds-1)) 3655 select { 3656 case <-ndpDisp.autoGenAddrC: 3657 t.Fatal("unexpectedly got an auto-generated event") 3658 default: 3659 } 3660 expectPrimaryAddr(addr1) 3661 3662 // Wait for addr of prefix1 to be deprecated. 3663 expectAutoGenAddrEventAfter(addr1, deprecatedAddr, ipv6.MinPrefixInformationValidLifetimeForUpdate-time.Second) 3664 if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr1) { 3665 t.Fatalf("should not have %s in the list of addresses", addr1) 3666 } 3667 if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr2) { 3668 t.Fatalf("should have %s in the list of addresses", addr2) 3669 } 3670 // addr2 should be the primary endpoint now since addr1 is deprecated but 3671 // addr2 is not. 3672 expectPrimaryAddr(addr2) 3673 3674 // addr1 is deprecated but if explicitly requested, it should be used. 3675 fullAddr1 := tcpip.FullAddress{Addr: addr1.Address, NIC: nicID} 3676 if got := addrForNewConnectionWithAddr(t, s, fullAddr1); got != addr1.Address { 3677 t.Errorf("got addrForNewConnectionWithAddr(_, _, %+v) = %s, want = %s", fullAddr1, got, addr1.Address) 3678 } 3679 3680 // Refresh valid lifetime for addr of prefix1, w/ 0 preferred lifetime to make 3681 // sure we do not get a deprecation event again. 3682 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, minVLSeconds, 0)) 3683 select { 3684 case <-ndpDisp.autoGenAddrC: 3685 t.Fatal("unexpectedly got an auto-generated event") 3686 default: 3687 } 3688 expectPrimaryAddr(addr2) 3689 if got := addrForNewConnectionWithAddr(t, s, fullAddr1); got != addr1.Address { 3690 t.Errorf("got addrForNewConnectionWithAddr(_, _, %+v) = %s, want = %s", fullAddr1, got, addr1.Address) 3691 } 3692 3693 // Refresh lifetimes for addr of prefix1. 3694 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, minVLSeconds, minVLSeconds-1)) 3695 select { 3696 case <-ndpDisp.autoGenAddrC: 3697 t.Fatal("unexpectedly got an auto-generated event") 3698 default: 3699 } 3700 // addr1 is the primary endpoint again since it is non-deprecated now. 3701 expectPrimaryAddr(addr1) 3702 3703 // Wait for addr of prefix1 to be deprecated. 3704 expectAutoGenAddrEventAfter(addr1, deprecatedAddr, ipv6.MinPrefixInformationValidLifetimeForUpdate-time.Second) 3705 if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr1) { 3706 t.Fatalf("should not have %s in the list of addresses", addr1) 3707 } 3708 if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr2) { 3709 t.Fatalf("should have %s in the list of addresses", addr2) 3710 } 3711 // addr2 should be the primary endpoint now since it is not deprecated. 3712 expectPrimaryAddr(addr2) 3713 if got := addrForNewConnectionWithAddr(t, s, fullAddr1); got != addr1.Address { 3714 t.Errorf("got addrForNewConnectionWithAddr(_, _, %+v) = %s, want = %s", fullAddr1, got, addr1.Address) 3715 } 3716 3717 // Wait for addr of prefix1 to be invalidated. 3718 expectAutoGenAddrEventAfter(addr1, invalidatedAddr, time.Second) 3719 if containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr1) { 3720 t.Fatalf("should not have %s in the list of addresses", addr1) 3721 } 3722 if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr2) { 3723 t.Fatalf("should have %s in the list of addresses", addr2) 3724 } 3725 expectPrimaryAddr(addr2) 3726 3727 // Refresh both lifetimes for addr of prefix2 to the same value. 3728 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix2, true, true, minVLSeconds, minVLSeconds)) 3729 select { 3730 case <-ndpDisp.autoGenAddrC: 3731 t.Fatal("unexpectedly got an auto-generated event") 3732 default: 3733 } 3734 3735 // Wait for a deprecation then invalidation events, or just an invalidation 3736 // event. We need to cover both cases but cannot deterministically hit both 3737 // cases because the deprecation and invalidation handlers could be handled in 3738 // either deprecation then invalidation, or invalidation then deprecation 3739 // (which should be cancelled by the invalidation handler). 3740 // 3741 // Since we're about to cause both events to fire, we need the dispatcher 3742 // channel to be able to hold both. 3743 if got, want := len(ndpDisp.autoGenAddrC), 0; got != want { 3744 t.Fatalf("got len(ndpDisp.autoGenAddrC) = %d, want %d", got, want) 3745 } 3746 if got, want := cap(ndpDisp.autoGenAddrC), 1; got != want { 3747 t.Fatalf("got cap(ndpDisp.autoGenAddrC) = %d, want %d", got, want) 3748 } 3749 ndpDisp.autoGenAddrC = make(chan ndpAutoGenAddrEvent, 2) 3750 clock.Advance(ipv6.MinPrefixInformationValidLifetimeForUpdate) 3751 select { 3752 case e := <-ndpDisp.autoGenAddrC: 3753 if diff := checkAutoGenAddrEvent(e, addr2, deprecatedAddr); diff == "" { 3754 // If we get a deprecation event first, we should get an invalidation 3755 // event almost immediately after. 3756 select { 3757 case e := <-ndpDisp.autoGenAddrC: 3758 if diff := checkAutoGenAddrEvent(e, addr2, invalidatedAddr); diff != "" { 3759 t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff) 3760 } 3761 default: 3762 t.Fatal("timed out waiting for addr auto gen event") 3763 } 3764 } else if diff := checkAutoGenAddrEvent(e, addr2, invalidatedAddr); diff == "" { 3765 // If we get an invalidation event first, we should not get a deprecation 3766 // event after. 3767 select { 3768 case <-ndpDisp.autoGenAddrC: 3769 t.Fatal("unexpectedly got an auto-generated event") 3770 default: 3771 } 3772 } else { 3773 t.Fatalf("got unexpected auto-generated event") 3774 } 3775 default: 3776 t.Fatal("timed out waiting for addr auto gen event") 3777 } 3778 if containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr1) { 3779 t.Fatalf("should not have %s in the list of addresses", addr1) 3780 } 3781 if containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr2) { 3782 t.Fatalf("should not have %s in the list of addresses", addr2) 3783 } 3784 // Should not have any primary endpoints. 3785 if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil { 3786 t.Fatal(err) 3787 } 3788 wq := waiter.Queue{} 3789 we, ch := waiter.NewChannelEntry(waiter.ReadableEvents) 3790 wq.EventRegister(&we) 3791 defer wq.EventUnregister(&we) 3792 defer close(ch) 3793 ep, err := s.NewEndpoint(header.UDPProtocolNumber, header.IPv6ProtocolNumber, &wq) 3794 if err != nil { 3795 t.Fatalf("s.NewEndpoint(%d, %d, _): %s", header.UDPProtocolNumber, header.IPv6ProtocolNumber, err) 3796 } 3797 defer ep.Close() 3798 ep.SocketOptions().SetV6Only(true) 3799 3800 { 3801 err := ep.Connect(dstAddr) 3802 if _, ok := err.(*tcpip.ErrHostUnreachable); !ok { 3803 t.Errorf("got ep.Connect(%+v) = %s, want = %s", dstAddr, err, &tcpip.ErrHostUnreachable{}) 3804 } 3805 } 3806 } 3807 3808 // Tests transitioning a SLAAC address's valid lifetime between finite and 3809 // infinite values. 3810 func TestAutoGenAddrFiniteToInfiniteToFiniteVL(t *testing.T) { 3811 const infiniteVLSeconds = math.MaxUint32 3812 3813 prefix, _, addr := prefixSubnetAddr(0, linkAddr1) 3814 3815 const autoGenAddrCount = 1 3816 ndpDisp := ndpDispatcher{ 3817 autoGenAddrNewC: make(chan ndpAutoGenAddrNewEvent, autoGenAddrCount), 3818 autoGenAddrC: make(chan ndpAutoGenAddrEvent, autoGenAddrCount), 3819 autoGenInstallDisp: true, 3820 } 3821 e := channel.New(0, 1280, linkAddr1) 3822 clock := faketime.NewManualClock() 3823 s := stack.New(stack.Options{ 3824 NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{ 3825 NDPConfigs: ipv6.NDPConfigurations{ 3826 HandleRAs: ipv6.HandlingRAsEnabledWhenForwardingDisabled, 3827 AutoGenGlobalAddresses: true, 3828 }, 3829 NDPDisp: &ndpDisp, 3830 })}, 3831 Clock: clock, 3832 }) 3833 3834 if err := s.CreateNIC(1, e); err != nil { 3835 t.Fatalf("CreateNIC(1) = %s", err) 3836 } 3837 3838 // Receive an RA with finite prefix. 3839 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, minVLSeconds, 0)) 3840 addrDisp, err := expectAutoGenAddrNewEvent(&ndpDisp, addr) 3841 if err != nil { 3842 t.Fatalf("error expecting stable auto-gen address generated event: %s", err) 3843 } 3844 if err := addrDisp.expectChanged(addressLifetimes(clock.NowMonotonic(), 0, minVLSeconds), stack.AddressAssigned); err != nil { 3845 t.Error(err) 3846 } 3847 3848 // Receive an new RA with prefix with infinite VL. 3849 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, infiniteVLSeconds, 0)) 3850 if err := addrDisp.expectLifetimesChanged(addressLifetimes(clock.NowMonotonic(), 0, infiniteVLSeconds)); err != nil { 3851 t.Error(err) 3852 } 3853 3854 // Receive a new RA with prefix with finite VL. 3855 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, minVLSeconds, 0)) 3856 if err := addrDisp.expectLifetimesChanged(addressLifetimes(clock.NowMonotonic(), 0, minVLSeconds)); err != nil { 3857 t.Error(err) 3858 } 3859 3860 clock.Advance(ipv6.MinPrefixInformationValidLifetimeForUpdate) 3861 expectAutoGenAddrEvent(t, &ndpDisp, addr, invalidatedAddr) 3862 if err := addrDisp.expectRemoved(stack.AddressRemovalInvalidated); err != nil { 3863 t.Error(err) 3864 } 3865 } 3866 3867 // TestAutoGenAddrValidLifetimeUpdates tests that the valid lifetime of an 3868 // auto-generated address only gets updated when required to, as specified in 3869 // RFC 4862 section 5.5.3.e. 3870 func TestAutoGenAddrValidLifetimeUpdates(t *testing.T) { 3871 prefix, _, addr := prefixSubnetAddr(0, linkAddr1) 3872 3873 tests := []struct { 3874 name string 3875 ovl uint32 3876 nvl uint32 3877 evl uint32 3878 }{ 3879 // Should update the VL to the minimum VL for updating if the 3880 // new VL is less than minVLSeconds but was originally greater than 3881 // it. 3882 { 3883 "LargeVLToVLLessThanMinVLForUpdate", 3884 9999, 3885 1, 3886 minVLSeconds, 3887 }, 3888 { 3889 "LargeVLTo0", 3890 9999, 3891 0, 3892 minVLSeconds, 3893 }, 3894 { 3895 "InfiniteVLToVLLessThanMinVLForUpdate", 3896 infiniteVLSeconds, 3897 1, 3898 minVLSeconds, 3899 }, 3900 { 3901 "InfiniteVLTo0", 3902 infiniteVLSeconds, 3903 0, 3904 minVLSeconds, 3905 }, 3906 3907 // Should not update VL if original VL was less than minVLSeconds 3908 // and the new VL is also less than minVLSeconds. 3909 { 3910 "ShouldNotUpdateWhenBothOldAndNewAreLessThanMinVLForUpdate", 3911 minVLSeconds - 1, 3912 minVLSeconds - 3, 3913 minVLSeconds - 1, 3914 }, 3915 3916 // Should take the new VL if the new VL is greater than the 3917 // remaining time or is greater than minVLSeconds. 3918 { 3919 "MorethanMinVLToLesserButStillMoreThanMinVLForUpdate", 3920 minVLSeconds + 5, 3921 minVLSeconds + 3, 3922 minVLSeconds + 3, 3923 }, 3924 { 3925 "SmallVLToGreaterVLButStillLessThanMinVLForUpdate", 3926 minVLSeconds - 3, 3927 minVLSeconds - 1, 3928 minVLSeconds - 1, 3929 }, 3930 { 3931 "SmallVLToGreaterVLThatIsMoreThaMinVLForUpdate", 3932 minVLSeconds - 3, 3933 minVLSeconds + 1, 3934 minVLSeconds + 1, 3935 }, 3936 } 3937 3938 for _, test := range tests { 3939 t.Run(test.name, func(t *testing.T) { 3940 const autoGenAddrCount = 10 3941 ndpDisp := ndpDispatcher{ 3942 autoGenInstallDisp: true, 3943 autoGenAddrNewC: make(chan ndpAutoGenAddrNewEvent, autoGenAddrCount), 3944 autoGenAddrC: make(chan ndpAutoGenAddrEvent, autoGenAddrCount), 3945 } 3946 e := channel.New(10, 1280, linkAddr1) 3947 clock := faketime.NewManualClock() 3948 s := stack.New(stack.Options{ 3949 NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{ 3950 NDPConfigs: ipv6.NDPConfigurations{ 3951 HandleRAs: ipv6.HandlingRAsEnabledWhenForwardingDisabled, 3952 AutoGenGlobalAddresses: true, 3953 }, 3954 NDPDisp: &ndpDisp, 3955 })}, 3956 Clock: clock, 3957 }) 3958 3959 if err := s.CreateNIC(1, e); err != nil { 3960 t.Fatalf("CreateNIC(1) = %s", err) 3961 } 3962 3963 // Receive an RA with prefix with initial VL, 3964 // test.ovl. 3965 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, test.ovl, 0)) 3966 addrDisp, err := expectAutoGenAddrNewEvent(&ndpDisp, addr) 3967 if err != nil { 3968 t.Fatalf("error expecting stable auto-gen address generated event: %s", err) 3969 } 3970 if err := addrDisp.expectChanged(addressLifetimes(clock.NowMonotonic(), 0, test.ovl), stack.AddressAssigned); err != nil { 3971 t.Error(err) 3972 } 3973 3974 // Receive an new RA with prefix with new VL, 3975 // test.nvl. 3976 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, test.nvl, 0)) 3977 if test.evl != test.ovl { 3978 if err := addrDisp.expectValidUntilChanged(clock.NowMonotonic().Add(time.Duration(test.evl) * time.Second)); err != nil { 3979 t.Error(err) 3980 } 3981 } 3982 3983 // 3984 // Validate that the VL for the address got set 3985 // to test.evl. 3986 // 3987 3988 // The address should not be invalidated until the effective valid 3989 // lifetime has passed. 3990 const delta = 1 3991 clock.Advance(time.Duration(test.evl)*time.Second - delta) 3992 select { 3993 case <-ndpDisp.autoGenAddrC: 3994 t.Fatal("unexpectedly received an auto gen addr event") 3995 default: 3996 } 3997 if err := addrDisp.expectNoEvent(); err != nil { 3998 t.Error(err) 3999 } 4000 4001 // Wait for the invalidation event. 4002 clock.Advance(delta) 4003 select { 4004 case e := <-ndpDisp.autoGenAddrC: 4005 if diff := checkAutoGenAddrEvent(e, addr, invalidatedAddr); diff != "" { 4006 t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff) 4007 } 4008 default: 4009 t.Fatal("timeout waiting for addr auto gen event") 4010 } 4011 if err := addrDisp.expectRemoved(stack.AddressRemovalInvalidated); err != nil { 4012 t.Error(err) 4013 } 4014 }) 4015 } 4016 } 4017 4018 // TestAutoGenAddrRemoval tests that when auto-generated addresses are removed 4019 // by the user, its resources will be cleaned up and an invalidation event will 4020 // be sent to the integrator. 4021 func TestAutoGenAddrRemoval(t *testing.T) { 4022 prefix, _, addr := prefixSubnetAddr(0, linkAddr1) 4023 4024 const autoGenAddrCount = 1 4025 ndpDisp := ndpDispatcher{ 4026 autoGenAddrNewC: make(chan ndpAutoGenAddrNewEvent, autoGenAddrCount), 4027 autoGenAddrC: make(chan ndpAutoGenAddrEvent, autoGenAddrCount), 4028 autoGenInstallDisp: true, 4029 } 4030 e := channel.New(0, 1280, linkAddr1) 4031 clock := faketime.NewManualClock() 4032 s := stack.New(stack.Options{ 4033 NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{ 4034 NDPConfigs: ipv6.NDPConfigurations{ 4035 HandleRAs: ipv6.HandlingRAsEnabledWhenForwardingDisabled, 4036 AutoGenGlobalAddresses: true, 4037 }, 4038 NDPDisp: &ndpDisp, 4039 })}, 4040 Clock: clock, 4041 }) 4042 4043 if err := s.CreateNIC(1, e); err != nil { 4044 t.Fatalf("CreateNIC(1) = %s", err) 4045 } 4046 4047 // Receive a PI to auto-generate an address. 4048 const lifetimeSeconds = 1 4049 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, lifetimeSeconds, 0)) 4050 addrDisp, err := expectAutoGenAddrNewEvent(&ndpDisp, addr) 4051 if err != nil { 4052 t.Fatalf("error expecting stable auto-gen address generated event: %s", err) 4053 } 4054 if err := addrDisp.expectChanged(addressLifetimes(clock.NowMonotonic(), 0, lifetimeSeconds), stack.AddressAssigned); err != nil { 4055 t.Error(err) 4056 } 4057 4058 // Removing the address should result in an invalidation event 4059 // immediately. 4060 if err := s.RemoveAddress(1, addr.Address); err != nil { 4061 t.Fatalf("RemoveAddress(_, %s) = %s", addr.Address, err) 4062 } 4063 expectAutoGenAddrEvent(t, &ndpDisp, addr, invalidatedAddr) 4064 if err := addrDisp.expectRemoved(stack.AddressRemovalManualAction); err != nil { 4065 t.Error(err) 4066 } 4067 4068 // Wait for the original valid lifetime to make sure the original job got 4069 // cancelled/cleaned up. 4070 clock.Advance(lifetimeSeconds * time.Second) 4071 select { 4072 case <-ndpDisp.autoGenAddrC: 4073 t.Fatal("unexpectedly received an auto gen addr event") 4074 default: 4075 } 4076 if err := addrDisp.expectNoEvent(); err != nil { 4077 t.Error(err) 4078 } 4079 } 4080 4081 // TestAutoGenAddrAfterRemoval tests adding a SLAAC address that was previously 4082 // assigned to the NIC but is in the permanentExpired state. 4083 func TestAutoGenAddrAfterRemoval(t *testing.T) { 4084 const nicID = 1 4085 4086 prefix1, _, addr1 := prefixSubnetAddr(0, linkAddr1) 4087 prefix2, _, addr2 := prefixSubnetAddr(1, linkAddr1) 4088 ndpDisp, e, s, clock := stackAndNdpDispatcherWithDefaultRoute(t, nicID) 4089 ndpDisp.autoGenInstallDisp = true 4090 4091 expectPrimaryAddr := func(addr tcpip.AddressWithPrefix) { 4092 t.Helper() 4093 4094 if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, addr); err != nil { 4095 t.Fatal(err) 4096 } 4097 4098 if got := addrForNewConnection(t, s); got != addr.Address { 4099 t.Errorf("got addrForNewConnection = %s, want = %s", got, addr.Address) 4100 } 4101 } 4102 4103 // Receive a PI to auto-generate addr1 with a large valid and preferred 4104 // lifetime. 4105 const largeLifetimeSeconds = 999 4106 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr3, 0, prefix1, true, true, largeLifetimeSeconds, largeLifetimeSeconds)) 4107 if addrDisp, err := expectAutoGenAddrNewEvent(ndpDisp, addr1); err != nil { 4108 t.Fatalf("error expecting prefix1 stable auto-gen address generated event: %s", err) 4109 } else { 4110 addrDisp.disable() 4111 } 4112 expectPrimaryAddr(addr1) 4113 4114 // Add addr2 as a static address. 4115 protoAddr2 := tcpip.ProtocolAddress{ 4116 Protocol: header.IPv6ProtocolNumber, 4117 AddressWithPrefix: addr2, 4118 } 4119 properties := stack.AddressProperties{PEB: stack.FirstPrimaryEndpoint} 4120 if err := s.AddProtocolAddress(nicID, protoAddr2, properties); err != nil { 4121 t.Fatalf("AddProtocolAddress(%d, %+v, %+v) = %s", nicID, protoAddr2, properties, err) 4122 } 4123 // addr2 should be more preferred now since it is at the front of the primary 4124 // list. 4125 expectPrimaryAddr(addr2) 4126 4127 // Get a route using addr2 to increment its reference count then remove it 4128 // to leave it in the permanentExpired state. 4129 if r, err := s.FindRoute(nicID, addr2.Address, addr3, header.IPv6ProtocolNumber, false); err != nil { 4130 t.Fatalf("FindRoute(%d, %s, %s, %d, false): %s", nicID, addr2.Address, addr3, header.IPv6ProtocolNumber, err) 4131 } else { 4132 defer r.Release() 4133 } 4134 if err := s.RemoveAddress(nicID, addr2.Address); err != nil { 4135 t.Fatalf("s.RemoveAddress(%d, %s): %s", nicID, addr2.Address, err) 4136 } 4137 // addr1 should be preferred again since addr2 is in the expired state. 4138 expectPrimaryAddr(addr1) 4139 4140 // Receive a PI to auto-generate addr2 as valid and preferred. 4141 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr3, 0, prefix2, true, true, largeLifetimeSeconds, largeLifetimeSeconds)) 4142 addr2Disp, err := expectAutoGenAddrNewEvent(ndpDisp, addr2) 4143 if err != nil { 4144 t.Fatalf("error expecting prefix2 stable auto-gen address generated event: %s", err) 4145 } 4146 if err := addr2Disp.expectChanged(addressLifetimes(clock.NowMonotonic(), largeLifetimeSeconds, largeLifetimeSeconds), stack.AddressAssigned); err != nil { 4147 t.Error(err) 4148 } 4149 // addr2 should be more preferred now that it is closer to the front of the 4150 // primary list and not deprecated. 4151 expectPrimaryAddr(addr2) 4152 4153 // Removing the address should result in an invalidation event immediately. 4154 // It should still be in the permanentExpired state because r is still held. 4155 // 4156 // We remove addr2 here to make sure addr2 was marked as a SLAAC address 4157 // (it was previously marked as a static address). 4158 if err := s.RemoveAddress(1, addr2.Address); err != nil { 4159 t.Fatalf("RemoveAddress(_, %s) = %s", addr2.Address, err) 4160 } 4161 expectAutoGenAddrEvent(t, ndpDisp, addr2, invalidatedAddr) 4162 if err := addr2Disp.expectRemoved(stack.AddressRemovalManualAction); err != nil { 4163 t.Error(err) 4164 } 4165 // addr1 should be more preferred since addr2 is in the expired state. 4166 expectPrimaryAddr(addr1) 4167 4168 // Receive a PI to auto-generate addr2 as valid and deprecated. 4169 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr3, 0, prefix2, true, true, largeLifetimeSeconds, 0)) 4170 addr2Disp, err = expectAutoGenAddrNewEvent(ndpDisp, addr2) 4171 if err != nil { 4172 t.Fatalf("error expecting prefix2 stable auto-gen address generated event after removing address and new PI: %s", err) 4173 } 4174 if err := addr2Disp.expectChanged(addressLifetimes(clock.NowMonotonic(), 0, largeLifetimeSeconds), stack.AddressAssigned); err != nil { 4175 t.Error(err) 4176 } 4177 // addr1 should still be more preferred since addr2 is deprecated, even though 4178 // it is closer to the front of the primary list. 4179 expectPrimaryAddr(addr1) 4180 4181 // Receive a PI to refresh addr2's preferred lifetime. 4182 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr3, 0, prefix2, true, true, largeLifetimeSeconds, largeLifetimeSeconds)) 4183 select { 4184 case <-ndpDisp.autoGenAddrC: 4185 t.Fatal("unexpectedly got an auto gen addr event") 4186 default: 4187 } 4188 if err := addr2Disp.expectChanged(addressLifetimes(clock.NowMonotonic(), largeLifetimeSeconds, largeLifetimeSeconds), stack.AddressAssigned); err != nil { 4189 t.Error(err) 4190 } 4191 // addr2 should be more preferred now that it is not deprecated. 4192 expectPrimaryAddr(addr2) 4193 4194 if err := s.RemoveAddress(1, addr2.Address); err != nil { 4195 t.Fatalf("RemoveAddress(_, %s) = %s", addr2.Address, err) 4196 } 4197 expectAutoGenAddrEvent(t, ndpDisp, addr2, invalidatedAddr) 4198 if err := addr2Disp.expectRemoved(stack.AddressRemovalManualAction); err != nil { 4199 t.Error(err) 4200 } 4201 expectPrimaryAddr(addr1) 4202 } 4203 4204 // TestAutoGenAddrStaticConflict tests that if SLAAC generates an address that 4205 // is already assigned to the NIC, the static address remains. 4206 func TestAutoGenAddrStaticConflict(t *testing.T) { 4207 prefix, _, addr := prefixSubnetAddr(0, linkAddr1) 4208 4209 const autoGenAddrCount = 1 4210 ndpDisp := ndpDispatcher{ 4211 autoGenAddrNewC: make(chan ndpAutoGenAddrNewEvent, autoGenAddrCount), 4212 autoGenAddrC: make(chan ndpAutoGenAddrEvent, autoGenAddrCount), 4213 } 4214 e := channel.New(0, 1280, linkAddr1) 4215 clock := faketime.NewManualClock() 4216 s := stack.New(stack.Options{ 4217 NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{ 4218 NDPConfigs: ipv6.NDPConfigurations{ 4219 HandleRAs: ipv6.HandlingRAsEnabledWhenForwardingDisabled, 4220 AutoGenGlobalAddresses: true, 4221 }, 4222 NDPDisp: &ndpDisp, 4223 })}, 4224 Clock: clock, 4225 }) 4226 4227 if err := s.CreateNIC(1, e); err != nil { 4228 t.Fatalf("CreateNIC(1) = %s", err) 4229 } 4230 4231 // Add the address as a static address before SLAAC tries to add it. 4232 protocolAddr := tcpip.ProtocolAddress{Protocol: header.IPv6ProtocolNumber, AddressWithPrefix: addr} 4233 if err := s.AddProtocolAddress(1, protocolAddr, stack.AddressProperties{}); err != nil { 4234 t.Fatalf("AddProtocolAddress(1, %+v, {}) = %s", protocolAddr, err) 4235 } 4236 if !containsV6Addr(s.NICInfo()[1].ProtocolAddresses, addr) { 4237 t.Fatalf("Should have %s in the list of addresses", addr1) 4238 } 4239 4240 // Receive a PI where the generated address will be the same as the one 4241 // that we already have assigned statically. 4242 const lifetimeSeconds = 1 4243 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, lifetimeSeconds, 0)) 4244 select { 4245 case <-ndpDisp.autoGenAddrC: 4246 t.Fatal("unexpectedly received an auto gen addr event for an address we already have statically") 4247 default: 4248 } 4249 if !containsV6Addr(s.NICInfo()[1].ProtocolAddresses, addr) { 4250 t.Fatalf("Should have %s in the list of addresses", addr1) 4251 } 4252 4253 // Should not get an invalidation event after the PI's invalidation 4254 // time. 4255 clock.Advance(lifetimeSeconds * time.Second) 4256 select { 4257 case <-ndpDisp.autoGenAddrC: 4258 t.Fatal("unexpectedly received an auto gen addr event") 4259 default: 4260 } 4261 if !containsV6Addr(s.NICInfo()[1].ProtocolAddresses, addr) { 4262 t.Fatalf("Should have %s in the list of addresses", addr1) 4263 } 4264 } 4265 4266 func makeSecretKey(t *testing.T) []byte { 4267 secretKey := make([]byte, header.OpaqueIIDSecretKeyMinBytes) 4268 n, err := cryptorand.Read(secretKey) 4269 if err != nil { 4270 t.Fatalf("cryptorand.Read(_): %s", err) 4271 } 4272 if l := len(secretKey); n != l { 4273 t.Fatalf("got cryptorand.Read(_) = (%d, nil), want = (%d, nil)", n, l) 4274 } 4275 return secretKey 4276 } 4277 4278 // TestAutoGenAddrWithOpaqueIID tests that SLAAC generated addresses will use 4279 // opaque interface identifiers when configured to do so. 4280 func TestAutoGenAddrWithOpaqueIID(t *testing.T) { 4281 const nicID = 1 4282 const nicName = "nic1" 4283 4284 secretKey := makeSecretKey(t) 4285 4286 prefix1, subnet1, _ := prefixSubnetAddr(0, linkAddr1) 4287 prefix2, subnet2, _ := prefixSubnetAddr(1, linkAddr1) 4288 // addr1 and addr2 are the addresses that are expected to be generated when 4289 // stack.Stack is configured to generate opaque interface identifiers as 4290 // defined by RFC 7217. 4291 subnetID := subnet1.ID() 4292 addrBytes := subnetID.AsSlice() 4293 addr1 := tcpip.AddressWithPrefix{ 4294 Address: tcpip.AddrFromSlice(header.AppendOpaqueInterfaceIdentifier(addrBytes[:header.IIDOffsetInIPv6Address], subnet1, nicName, 0, secretKey)), 4295 PrefixLen: 64, 4296 } 4297 subnetID = subnet2.ID() 4298 addrBytes = subnetID.AsSlice() 4299 addr2 := tcpip.AddressWithPrefix{ 4300 Address: tcpip.AddrFromSlice(header.AppendOpaqueInterfaceIdentifier(addrBytes[:header.IIDOffsetInIPv6Address], subnet2, nicName, 0, secretKey)), 4301 PrefixLen: 64, 4302 } 4303 4304 const autoGenAddrCount = 1 4305 ndpDisp := ndpDispatcher{ 4306 autoGenAddrNewC: make(chan ndpAutoGenAddrNewEvent, autoGenAddrCount), 4307 autoGenAddrC: make(chan ndpAutoGenAddrEvent, autoGenAddrCount), 4308 } 4309 e := channel.New(0, 1280, linkAddr1) 4310 clock := faketime.NewManualClock() 4311 s := stack.New(stack.Options{ 4312 NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{ 4313 NDPConfigs: ipv6.NDPConfigurations{ 4314 HandleRAs: ipv6.HandlingRAsEnabledWhenForwardingDisabled, 4315 AutoGenGlobalAddresses: true, 4316 }, 4317 NDPDisp: &ndpDisp, 4318 OpaqueIIDOpts: ipv6.OpaqueInterfaceIdentifierOptions{ 4319 NICNameFromID: func(_ tcpip.NICID, nicName string) string { 4320 return nicName 4321 }, 4322 SecretKey: secretKey, 4323 }, 4324 })}, 4325 Clock: clock, 4326 }) 4327 opts := stack.NICOptions{Name: nicName} 4328 if err := s.CreateNICWithOptions(nicID, e, opts); err != nil { 4329 t.Fatalf("CreateNICWithOptions(%d, _, %+v, _) = %s", nicID, opts, err) 4330 } 4331 4332 // Receive an RA with prefix1 in a PI. 4333 const validLifetimeSecondPrefix1 = 1 4334 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, validLifetimeSecondPrefix1, 0)) 4335 if _, err := expectAutoGenAddrNewEvent(&ndpDisp, addr1); err != nil { 4336 t.Fatalf("error expecting prefix1 stable auto-gen address generated event: %s", err) 4337 } 4338 if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr1) { 4339 t.Fatalf("should have %s in the list of addresses", addr1) 4340 } 4341 4342 // Receive an RA with prefix2 in a PI with a large valid lifetime. 4343 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix2, true, true, 100, 0)) 4344 if _, err := expectAutoGenAddrNewEvent(&ndpDisp, addr2); err != nil { 4345 t.Fatalf("error expecting prefix2 stable auto-gen address generated event: %s", err) 4346 } 4347 if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr1) { 4348 t.Fatalf("should have %s in the list of addresses", addr1) 4349 } 4350 if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr2) { 4351 t.Fatalf("should have %s in the list of addresses", addr2) 4352 } 4353 4354 // Wait for addr of prefix1 to be invalidated. 4355 clock.Advance(validLifetimeSecondPrefix1 * time.Second) 4356 select { 4357 case e := <-ndpDisp.autoGenAddrC: 4358 if diff := checkAutoGenAddrEvent(e, addr1, invalidatedAddr); diff != "" { 4359 t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff) 4360 } 4361 default: 4362 t.Fatal("timed out waiting for addr auto gen event") 4363 } 4364 if containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr1) { 4365 t.Fatalf("should not have %s in the list of addresses", addr1) 4366 } 4367 if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr2) { 4368 t.Fatalf("should have %s in the list of addresses", addr2) 4369 } 4370 } 4371 4372 func TestAutoGenAddrInResponseToDADConflicts(t *testing.T) { 4373 const nicID = 1 4374 const nicName = "nic" 4375 const dadTransmits = 1 4376 const retransmitTimer = time.Second 4377 const maxMaxRetries = 3 4378 const lifetimeSeconds = 10 4379 4380 secretKey := makeSecretKey(t) 4381 4382 prefix, subnet, _ := prefixSubnetAddr(0, linkAddr1) 4383 4384 addrForSubnet := func(subnet tcpip.Subnet, dadCounter uint8) tcpip.AddressWithPrefix { 4385 subnetID := subnet.ID() 4386 addrBytes := subnetID.AsSlice() 4387 return tcpip.AddressWithPrefix{ 4388 Address: tcpip.AddrFromSlice(header.AppendOpaqueInterfaceIdentifier(addrBytes[:header.IIDOffsetInIPv6Address], subnet, nicName, dadCounter, secretKey)), 4389 PrefixLen: 64, 4390 } 4391 } 4392 4393 expectDADEvent := func(t *testing.T, clock *faketime.ManualClock, ndpDisp *ndpDispatcher, addr tcpip.Address, res stack.DADResult) { 4394 t.Helper() 4395 4396 clock.RunImmediatelyScheduledJobs() 4397 select { 4398 case e := <-ndpDisp.dadC: 4399 if diff := checkDADEvent(e, nicID, addr, res); diff != "" { 4400 t.Errorf("DAD event mismatch (-want +got):\n%s", diff) 4401 } 4402 default: 4403 t.Fatal("expected DAD event") 4404 } 4405 } 4406 4407 expectDADEventAsync := func(t *testing.T, clock *faketime.ManualClock, ndpDisp *ndpDispatcher, addr tcpip.Address, res stack.DADResult) { 4408 t.Helper() 4409 4410 clock.Advance(dadTransmits * retransmitTimer) 4411 select { 4412 case e := <-ndpDisp.dadC: 4413 if diff := checkDADEvent(e, nicID, addr, res); diff != "" { 4414 t.Errorf("DAD event mismatch (-want +got):\n%s", diff) 4415 } 4416 default: 4417 t.Fatal("timed out waiting for DAD event") 4418 } 4419 } 4420 4421 stableAddrForTempAddrTest := addrForSubnet(subnet, 0) 4422 4423 addrTypes := []struct { 4424 name string 4425 ndpConfigs ipv6.NDPConfigurations 4426 autoGenLinkLocal bool 4427 prepareFn func(t *testing.T, clock *faketime.ManualClock, ndpDisp *ndpDispatcher, e *channel.Endpoint, tempIIDHistory []byte) []tcpip.AddressWithPrefix 4428 addrGenFn func(dadCounter uint8, tempIIDHistory []byte) tcpip.AddressWithPrefix 4429 }{ 4430 { 4431 name: "Global address", 4432 ndpConfigs: ipv6.NDPConfigurations{ 4433 HandleRAs: ipv6.HandlingRAsEnabledWhenForwardingDisabled, 4434 AutoGenGlobalAddresses: true, 4435 }, 4436 prepareFn: func(_ *testing.T, _ *faketime.ManualClock, _ *ndpDispatcher, e *channel.Endpoint, _ []byte) []tcpip.AddressWithPrefix { 4437 // Receive an RA with prefix1 in a PI. 4438 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, lifetimeSeconds, lifetimeSeconds)) 4439 return nil 4440 4441 }, 4442 addrGenFn: func(dadCounter uint8, _ []byte) tcpip.AddressWithPrefix { 4443 return addrForSubnet(subnet, dadCounter) 4444 }, 4445 }, 4446 { 4447 name: "LinkLocal address", 4448 ndpConfigs: ipv6.NDPConfigurations{}, 4449 autoGenLinkLocal: true, 4450 prepareFn: func(*testing.T, *faketime.ManualClock, *ndpDispatcher, *channel.Endpoint, []byte) []tcpip.AddressWithPrefix { 4451 return nil 4452 }, 4453 addrGenFn: func(dadCounter uint8, _ []byte) tcpip.AddressWithPrefix { 4454 return addrForSubnet(header.IPv6LinkLocalPrefix.Subnet(), dadCounter) 4455 }, 4456 }, 4457 { 4458 name: "Temporary address", 4459 ndpConfigs: ipv6.NDPConfigurations{ 4460 HandleRAs: ipv6.HandlingRAsEnabledWhenForwardingDisabled, 4461 AutoGenGlobalAddresses: true, 4462 AutoGenTempGlobalAddresses: true, 4463 }, 4464 prepareFn: func(t *testing.T, clock *faketime.ManualClock, ndpDisp *ndpDispatcher, e *channel.Endpoint, tempIIDHistory []byte) []tcpip.AddressWithPrefix { 4465 header.InitialTempIID(tempIIDHistory, nil, nicID) 4466 4467 // Generate a stable SLAAC address so temporary addresses will be 4468 // generated. 4469 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, 100, 100)) 4470 if _, err := expectAutoGenAddrNewEvent(ndpDisp, stableAddrForTempAddrTest); err != nil { 4471 t.Fatalf("error expecting stable auto-gen address generated event: %s", err) 4472 } 4473 expectDADEventAsync(t, clock, ndpDisp, stableAddrForTempAddrTest.Address, &stack.DADSucceeded{}) 4474 4475 // The stable address will be assigned throughout the test. 4476 return []tcpip.AddressWithPrefix{stableAddrForTempAddrTest} 4477 }, 4478 addrGenFn: func(_ uint8, tempIIDHistory []byte) tcpip.AddressWithPrefix { 4479 return header.GenerateTempIPv6SLAACAddr(tempIIDHistory, stableAddrForTempAddrTest.Address) 4480 }, 4481 }, 4482 } 4483 4484 for _, addrType := range addrTypes { 4485 t.Run(addrType.name, func(t *testing.T) { 4486 for maxRetries := uint8(0); maxRetries <= maxMaxRetries; maxRetries++ { 4487 for numFailures := uint8(0); numFailures <= maxRetries+1; numFailures++ { 4488 maxRetries := maxRetries 4489 numFailures := numFailures 4490 addrType := addrType 4491 4492 t.Run(fmt.Sprintf("%d max retries and %d failures", maxRetries, numFailures), func(t *testing.T) { 4493 const autoGenAddrCount = 2 4494 ndpDisp := ndpDispatcher{ 4495 dadC: make(chan ndpDADEvent, 1), 4496 autoGenAddrNewC: make(chan ndpAutoGenAddrNewEvent, autoGenAddrCount), 4497 autoGenAddrC: make(chan ndpAutoGenAddrEvent, autoGenAddrCount), 4498 } 4499 e := channel.New(0, 1280, linkAddr1) 4500 ndpConfigs := addrType.ndpConfigs 4501 ndpConfigs.AutoGenAddressConflictRetries = maxRetries 4502 clock := faketime.NewManualClock() 4503 s := stack.New(stack.Options{ 4504 NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{ 4505 AutoGenLinkLocal: addrType.autoGenLinkLocal, 4506 DADConfigs: stack.DADConfigurations{ 4507 DupAddrDetectTransmits: dadTransmits, 4508 RetransmitTimer: retransmitTimer, 4509 }, 4510 NDPConfigs: ndpConfigs, 4511 NDPDisp: &ndpDisp, 4512 OpaqueIIDOpts: ipv6.OpaqueInterfaceIdentifierOptions{ 4513 NICNameFromID: func(_ tcpip.NICID, nicName string) string { 4514 return nicName 4515 }, 4516 SecretKey: secretKey, 4517 }, 4518 })}, 4519 Clock: clock, 4520 }) 4521 opts := stack.NICOptions{Name: nicName} 4522 if err := s.CreateNICWithOptions(nicID, e, opts); err != nil { 4523 t.Fatalf("CreateNICWithOptions(%d, _, %+v) = %s", nicID, opts, err) 4524 } 4525 4526 var tempIIDHistory [header.IIDSize]byte 4527 stableAddrs := addrType.prepareFn(t, clock, &ndpDisp, e, tempIIDHistory[:]) 4528 4529 // Simulate DAD conflicts so the address is regenerated. 4530 for i := uint8(0); i < numFailures; i++ { 4531 addr := addrType.addrGenFn(i, tempIIDHistory[:]) 4532 clock.RunImmediatelyScheduledJobs() 4533 if _, err := expectAutoGenAddrNewEvent(&ndpDisp, addr); err != nil { 4534 t.Fatalf("error expecting auto-gen address generated event after %d failure(s): %s", i, err) 4535 } 4536 4537 // Should not have any new addresses assigned to the NIC. 4538 if mismatch := addressCheck(s.NICInfo()[nicID].ProtocolAddresses, stableAddrs, nil); mismatch != "" { 4539 t.Fatal(mismatch) 4540 } 4541 4542 // Simulate a DAD conflict. 4543 rxNDPSolicit(e, addr.Address) 4544 expectAutoGenAddrEvent(t, &ndpDisp, addr, invalidatedAddr) 4545 expectDADEvent(t, clock, &ndpDisp, addr.Address, &stack.DADDupAddrDetected{}) 4546 4547 // Attempting to add the address manually should not fail if the 4548 // address's state was cleaned up when DAD failed. 4549 protocolAddr := tcpip.ProtocolAddress{ 4550 Protocol: header.IPv6ProtocolNumber, 4551 AddressWithPrefix: addr, 4552 } 4553 if err := s.AddProtocolAddress(nicID, protocolAddr, stack.AddressProperties{}); err != nil { 4554 t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", nicID, protocolAddr, err) 4555 } 4556 if err := s.RemoveAddress(nicID, addr.Address); err != nil { 4557 t.Fatalf("RemoveAddress(%d, %s) = %s", nicID, addr.Address, err) 4558 } 4559 expectDADEvent(t, clock, &ndpDisp, addr.Address, &stack.DADAborted{}) 4560 } 4561 4562 // Should not have any new addresses assigned to the NIC. 4563 if mismatch := addressCheck(s.NICInfo()[nicID].ProtocolAddresses, stableAddrs, nil); mismatch != "" { 4564 t.Fatal(mismatch) 4565 } 4566 4567 // If we had less failures than generation attempts, we should have 4568 // an address after DAD resolves. 4569 if maxRetries+1 > numFailures { 4570 addr := addrType.addrGenFn(numFailures, tempIIDHistory[:]) 4571 clock.RunImmediatelyScheduledJobs() 4572 if _, err := expectAutoGenAddrNewEvent(&ndpDisp, addr); err != nil { 4573 t.Fatalf("error expecting final auto-gen address generated event: %s", err) 4574 } 4575 expectDADEventAsync(t, clock, &ndpDisp, addr.Address, &stack.DADSucceeded{}) 4576 if mismatch := addressCheck(s.NICInfo()[nicID].ProtocolAddresses, append(stableAddrs, addr), nil); mismatch != "" { 4577 t.Fatal(mismatch) 4578 } 4579 } 4580 4581 // Should not attempt address generation again. 4582 select { 4583 case e := <-ndpDisp.autoGenAddrC: 4584 t.Fatalf("unexpectedly got an auto-generated address event = %+v", e) 4585 default: 4586 } 4587 }) 4588 } 4589 } 4590 }) 4591 } 4592 } 4593 4594 // TestAutoGenAddrWithEUI64IIDNoDADRetries tests that a regeneration attempt is 4595 // not made for SLAAC addresses generated with an IID based on the NIC's link 4596 // address. 4597 func TestAutoGenAddrWithEUI64IIDNoDADRetries(t *testing.T) { 4598 const nicID = 1 4599 const dadTransmits = 1 4600 const retransmitTimer = time.Second 4601 const maxRetries = 3 4602 const lifetimeSeconds = 10 4603 4604 prefix, subnet, _ := prefixSubnetAddr(0, linkAddr1) 4605 4606 addrTypes := []struct { 4607 name string 4608 ndpConfigs ipv6.NDPConfigurations 4609 autoGenLinkLocal bool 4610 subnet tcpip.Subnet 4611 triggerSLAACFn func(e *channel.Endpoint) 4612 }{ 4613 { 4614 name: "Global address", 4615 ndpConfigs: ipv6.NDPConfigurations{ 4616 HandleRAs: ipv6.HandlingRAsEnabledWhenForwardingDisabled, 4617 AutoGenGlobalAddresses: true, 4618 AutoGenAddressConflictRetries: maxRetries, 4619 }, 4620 subnet: subnet, 4621 triggerSLAACFn: func(e *channel.Endpoint) { 4622 // Receive an RA with prefix1 in a PI. 4623 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, lifetimeSeconds, lifetimeSeconds)) 4624 4625 }, 4626 }, 4627 { 4628 name: "LinkLocal address", 4629 ndpConfigs: ipv6.NDPConfigurations{ 4630 AutoGenAddressConflictRetries: maxRetries, 4631 }, 4632 autoGenLinkLocal: true, 4633 subnet: header.IPv6LinkLocalPrefix.Subnet(), 4634 triggerSLAACFn: func(e *channel.Endpoint) {}, 4635 }, 4636 } 4637 4638 for _, addrType := range addrTypes { 4639 addrType := addrType 4640 4641 t.Run(addrType.name, func(t *testing.T) { 4642 const autoGenAddrCount = 2 4643 ndpDisp := ndpDispatcher{ 4644 dadC: make(chan ndpDADEvent, 1), 4645 autoGenAddrNewC: make(chan ndpAutoGenAddrNewEvent, autoGenAddrCount), 4646 autoGenAddrC: make(chan ndpAutoGenAddrEvent, autoGenAddrCount), 4647 } 4648 e := channel.New(0, 1280, linkAddr1) 4649 clock := faketime.NewManualClock() 4650 s := stack.New(stack.Options{ 4651 NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{ 4652 AutoGenLinkLocal: addrType.autoGenLinkLocal, 4653 NDPConfigs: addrType.ndpConfigs, 4654 NDPDisp: &ndpDisp, 4655 DADConfigs: stack.DADConfigurations{ 4656 DupAddrDetectTransmits: dadTransmits, 4657 RetransmitTimer: retransmitTimer, 4658 }, 4659 })}, 4660 Clock: clock, 4661 }) 4662 if err := s.CreateNIC(nicID, e); err != nil { 4663 t.Fatalf("CreateNIC(%d, _) = %s", nicID, err) 4664 } 4665 4666 addrType.triggerSLAACFn(e) 4667 4668 subnetID := addrType.subnet.ID() 4669 addrBytes := subnetID.AsSlice() 4670 header.EthernetAdddressToModifiedEUI64IntoBuf(linkAddr1, addrBytes[header.IIDOffsetInIPv6Address:]) 4671 addr := tcpip.AddressWithPrefix{ 4672 Address: tcpip.AddrFromSlice(addrBytes), 4673 PrefixLen: 64, 4674 } 4675 if _, err := expectAutoGenAddrNewEvent(&ndpDisp, addr); err != nil { 4676 t.Fatalf("error expecting stable auto-gen address generated event: %s", err) 4677 } 4678 4679 // Simulate a DAD conflict. 4680 rxNDPSolicit(e, addr.Address) 4681 expectAutoGenAddrEvent(t, &ndpDisp, addr, invalidatedAddr) 4682 select { 4683 case e := <-ndpDisp.dadC: 4684 if diff := checkDADEvent(e, nicID, addr.Address, &stack.DADDupAddrDetected{}); diff != "" { 4685 t.Errorf("DAD event mismatch (-want +got):\n%s", diff) 4686 } 4687 default: 4688 t.Fatal("expected DAD event") 4689 } 4690 4691 // Should not attempt address regeneration. 4692 select { 4693 case e := <-ndpDisp.autoGenAddrC: 4694 t.Fatalf("unexpectedly got an auto-generated address event = %+v", e) 4695 default: 4696 } 4697 }) 4698 } 4699 } 4700 4701 // TestAutoGenAddrContinuesLifetimesAfterRetry tests that retrying address 4702 // generation in response to DAD conflicts does not refresh the lifetimes. 4703 func TestAutoGenAddrContinuesLifetimesAfterRetry(t *testing.T) { 4704 const nicID = 1 4705 const nicName = "nic" 4706 const dadTransmits = 1 4707 const retransmitTimer = 2 * time.Second 4708 const failureTimer = time.Second 4709 const maxRetries = 1 4710 const lifetimeSeconds = 5 4711 4712 secretKey := makeSecretKey(t) 4713 4714 prefix, subnet, _ := prefixSubnetAddr(0, linkAddr1) 4715 4716 const autoGenAddrCount = 2 4717 ndpDisp := ndpDispatcher{ 4718 dadC: make(chan ndpDADEvent, 1), 4719 autoGenAddrNewC: make(chan ndpAutoGenAddrNewEvent, autoGenAddrCount), 4720 autoGenAddrC: make(chan ndpAutoGenAddrEvent, autoGenAddrCount), 4721 autoGenInstallDisp: true, 4722 } 4723 e := channel.New(0, 1280, linkAddr1) 4724 clock := faketime.NewManualClock() 4725 s := stack.New(stack.Options{ 4726 NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{ 4727 DADConfigs: stack.DADConfigurations{ 4728 DupAddrDetectTransmits: dadTransmits, 4729 RetransmitTimer: retransmitTimer, 4730 }, 4731 NDPConfigs: ipv6.NDPConfigurations{ 4732 HandleRAs: ipv6.HandlingRAsEnabledWhenForwardingDisabled, 4733 AutoGenGlobalAddresses: true, 4734 AutoGenAddressConflictRetries: maxRetries, 4735 }, 4736 NDPDisp: &ndpDisp, 4737 OpaqueIIDOpts: ipv6.OpaqueInterfaceIdentifierOptions{ 4738 NICNameFromID: func(_ tcpip.NICID, nicName string) string { 4739 return nicName 4740 }, 4741 SecretKey: secretKey, 4742 }, 4743 })}, 4744 Clock: clock, 4745 }) 4746 opts := stack.NICOptions{Name: nicName} 4747 if err := s.CreateNICWithOptions(nicID, e, opts); err != nil { 4748 t.Fatalf("CreateNICWithOptions(%d, _, %+v) = %s", nicID, opts, err) 4749 } 4750 4751 // Receive an RA with prefix in a PI. 4752 received := clock.NowMonotonic() 4753 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, lifetimeSeconds, lifetimeSeconds)) 4754 4755 subnetID := subnet.ID() 4756 addrBytes := subnetID.AsSlice() 4757 addr := tcpip.AddressWithPrefix{ 4758 Address: tcpip.AddrFromSlice(header.AppendOpaqueInterfaceIdentifier(addrBytes[:header.IIDOffsetInIPv6Address], subnet, nicName, 0, secretKey)), 4759 PrefixLen: 64, 4760 } 4761 addrDisp, err := expectAutoGenAddrNewEvent(&ndpDisp, addr) 4762 if err != nil { 4763 t.Fatalf("error expecting stable auto-gen address (DAD will not resolve) generated event: %s", err) 4764 } 4765 if err := addrDisp.expectChanged(addressLifetimes(received, lifetimeSeconds, lifetimeSeconds), stack.AddressTentative); err != nil { 4766 t.Error(err) 4767 } 4768 4769 // Simulate a DAD conflict after some time has passed. 4770 clock.Advance(failureTimer) 4771 rxNDPSolicit(e, addr.Address) 4772 expectAutoGenAddrEvent(t, &ndpDisp, addr, invalidatedAddr) 4773 if err := addrDisp.expectRemoved(stack.AddressRemovalDADFailed); err != nil { 4774 t.Error(err) 4775 } 4776 select { 4777 case e := <-ndpDisp.dadC: 4778 if diff := checkDADEvent(e, nicID, addr.Address, &stack.DADDupAddrDetected{}); diff != "" { 4779 t.Errorf("DAD event mismatch (-want +got):\n%s", diff) 4780 } 4781 default: 4782 t.Fatal("expected DAD event") 4783 } 4784 4785 // Let the next address resolve. 4786 addr.Address = tcpip.AddrFromSlice(header.AppendOpaqueInterfaceIdentifier(addrBytes[:header.IIDOffsetInIPv6Address], subnet, nicName, 1, secretKey)) 4787 addrDisp, err = expectAutoGenAddrNewEvent(&ndpDisp, addr) 4788 if err != nil { 4789 t.Fatalf("error expecting stable auto-gen address generated event: %s", err) 4790 } 4791 if err := addrDisp.expectChanged(addressLifetimes(received, lifetimeSeconds, lifetimeSeconds), stack.AddressTentative); err != nil { 4792 t.Error(err) 4793 } 4794 clock.Advance(dadTransmits * retransmitTimer) 4795 select { 4796 case e := <-ndpDisp.dadC: 4797 if diff := checkDADEvent(e, nicID, addr.Address, &stack.DADSucceeded{}); diff != "" { 4798 t.Errorf("DAD event mismatch (-want +got):\n%s", diff) 4799 } 4800 default: 4801 t.Fatal("timed out waiting for DAD event") 4802 } 4803 if err := addrDisp.expectStateChanged(stack.AddressAssigned); err != nil { 4804 t.Error(err) 4805 } 4806 4807 // Address should be deprecated/invalidated after the lifetime expires. 4808 // 4809 // Note, the remaining lifetime is calculated from when the PI was first 4810 // processed. Since we wait for some time before simulating a DAD conflict 4811 // and more time for the new address to resolve, the new address is only 4812 // expected to be valid for the remaining time. The DAD conflict should 4813 // not have reset the lifetimes. 4814 // 4815 // We expect either just the invalidation event or the deprecation event 4816 // followed by the invalidation event. 4817 clock.Advance(lifetimeSeconds*time.Second - failureTimer - dadTransmits*retransmitTimer) 4818 select { 4819 case e := <-ndpDisp.autoGenAddrC: 4820 if e.eventType == deprecatedAddr { 4821 if diff := checkAutoGenAddrEvent(e, addr, deprecatedAddr); diff != "" { 4822 t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff) 4823 } 4824 4825 select { 4826 case e := <-ndpDisp.autoGenAddrC: 4827 if diff := checkAutoGenAddrEvent(e, addr, invalidatedAddr); diff != "" { 4828 t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff) 4829 } 4830 default: 4831 t.Fatal("timed out waiting for invalidated auto gen addr event after deprecation") 4832 } 4833 } else { 4834 if diff := checkAutoGenAddrEvent(e, addr, invalidatedAddr); diff != "" { 4835 t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff) 4836 } 4837 } 4838 default: 4839 t.Fatal("timed out waiting for auto gen addr event") 4840 } 4841 if err := addrDisp.expectRemoved(stack.AddressRemovalInvalidated); err != nil { 4842 t.Error(err) 4843 } 4844 } 4845 4846 // TestNDPRecursiveDNSServerDispatch tests that we properly dispatch an event 4847 // to the integrator when an RA is received with the NDP Recursive DNS Server 4848 // option with at least one valid address. 4849 func TestNDPRecursiveDNSServerDispatch(t *testing.T) { 4850 tests := []struct { 4851 name string 4852 opt header.NDPRecursiveDNSServer 4853 expected *ndpRDNSS 4854 }{ 4855 { 4856 "Unspecified", 4857 header.NDPRecursiveDNSServer([]byte{ 4858 0, 0, 4859 0, 0, 0, 2, 4860 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4861 }), 4862 nil, 4863 }, 4864 { 4865 "Multicast", 4866 header.NDPRecursiveDNSServer([]byte{ 4867 0, 0, 4868 0, 0, 0, 2, 4869 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4870 }), 4871 nil, 4872 }, 4873 { 4874 "OptionTooSmall", 4875 header.NDPRecursiveDNSServer([]byte{ 4876 0, 0, 4877 0, 0, 0, 2, 4878 1, 2, 3, 4, 5, 6, 7, 8, 4879 }), 4880 nil, 4881 }, 4882 { 4883 "0Addresses", 4884 header.NDPRecursiveDNSServer([]byte{ 4885 0, 0, 4886 0, 0, 0, 2, 4887 }), 4888 nil, 4889 }, 4890 { 4891 "Valid1Address", 4892 header.NDPRecursiveDNSServer([]byte{ 4893 0, 0, 4894 0, 0, 0, 2, 4895 1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 1, 4896 }), 4897 &ndpRDNSS{ 4898 []tcpip.Address{ 4899 tcpip.AddrFromSlice([]byte("\x01\x02\x03\x04\x05\x06\x07\x08\x00\x00\x00\x00\x00\x00\x00\x01")), 4900 }, 4901 2 * time.Second, 4902 }, 4903 }, 4904 { 4905 "Valid2Addresses", 4906 header.NDPRecursiveDNSServer([]byte{ 4907 0, 0, 4908 0, 0, 0, 1, 4909 1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 1, 4910 1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 2, 4911 }), 4912 &ndpRDNSS{ 4913 []tcpip.Address{ 4914 tcpip.AddrFromSlice([]byte("\x01\x02\x03\x04\x05\x06\x07\x08\x00\x00\x00\x00\x00\x00\x00\x01")), 4915 tcpip.AddrFromSlice([]byte("\x01\x02\x03\x04\x05\x06\x07\x08\x00\x00\x00\x00\x00\x00\x00\x02")), 4916 }, 4917 time.Second, 4918 }, 4919 }, 4920 { 4921 "Valid3Addresses", 4922 header.NDPRecursiveDNSServer([]byte{ 4923 0, 0, 4924 0, 0, 0, 0, 4925 1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 1, 4926 1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 2, 4927 1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 3, 4928 }), 4929 &ndpRDNSS{ 4930 []tcpip.Address{ 4931 tcpip.AddrFromSlice([]byte("\x01\x02\x03\x04\x05\x06\x07\x08\x00\x00\x00\x00\x00\x00\x00\x01")), 4932 tcpip.AddrFromSlice([]byte("\x01\x02\x03\x04\x05\x06\x07\x08\x00\x00\x00\x00\x00\x00\x00\x02")), 4933 tcpip.AddrFromSlice([]byte("\x01\x02\x03\x04\x05\x06\x07\x08\x00\x00\x00\x00\x00\x00\x00\x03")), 4934 }, 4935 0, 4936 }, 4937 }, 4938 } 4939 4940 for _, test := range tests { 4941 t.Run(test.name, func(t *testing.T) { 4942 ndpDisp := ndpDispatcher{ 4943 // We do not expect more than a single RDNSS 4944 // event at any time for this test. 4945 rdnssC: make(chan ndpRDNSSEvent, 1), 4946 } 4947 e := channel.New(0, 1280, linkAddr1) 4948 s := stack.New(stack.Options{ 4949 NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{ 4950 NDPConfigs: ipv6.NDPConfigurations{ 4951 HandleRAs: ipv6.HandlingRAsEnabledWhenForwardingDisabled, 4952 }, 4953 NDPDisp: &ndpDisp, 4954 })}, 4955 }) 4956 if err := s.CreateNIC(1, e); err != nil { 4957 t.Fatalf("CreateNIC(1) = %s", err) 4958 } 4959 4960 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithOpts(llAddr1, 0, header.NDPOptionsSerializer{test.opt})) 4961 4962 if test.expected != nil { 4963 select { 4964 case e := <-ndpDisp.rdnssC: 4965 if e.nicID != 1 { 4966 t.Errorf("got rdnss nicID = %d, want = 1", e.nicID) 4967 } 4968 if diff := cmp.Diff(e.rdnss.addrs, test.expected.addrs); diff != "" { 4969 t.Errorf("rdnss addrs mismatch (-want +got):\n%s", diff) 4970 } 4971 if e.rdnss.lifetime != test.expected.lifetime { 4972 t.Errorf("got rdnss lifetime = %s, want = %s", e.rdnss.lifetime, test.expected.lifetime) 4973 } 4974 default: 4975 t.Fatal("expected an RDNSS option event") 4976 } 4977 } 4978 4979 // Should have no more RDNSS options. 4980 select { 4981 case e := <-ndpDisp.rdnssC: 4982 t.Fatalf("unexpectedly got a new RDNSS option event: %+v", e) 4983 default: 4984 } 4985 }) 4986 } 4987 } 4988 4989 // TestNDPDNSSearchListDispatch tests that the integrator is informed when an 4990 // NDP DNS Search List option is received with at least one domain name in the 4991 // search list. 4992 func TestNDPDNSSearchListDispatch(t *testing.T) { 4993 const nicID = 1 4994 4995 ndpDisp := ndpDispatcher{ 4996 dnsslC: make(chan ndpDNSSLEvent, 3), 4997 } 4998 e := channel.New(0, 1280, linkAddr1) 4999 s := stack.New(stack.Options{ 5000 NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{ 5001 NDPConfigs: ipv6.NDPConfigurations{ 5002 HandleRAs: ipv6.HandlingRAsEnabledWhenForwardingDisabled, 5003 }, 5004 NDPDisp: &ndpDisp, 5005 })}, 5006 }) 5007 if err := s.CreateNIC(nicID, e); err != nil { 5008 t.Fatalf("CreateNIC(%d, _) = %s", nicID, err) 5009 } 5010 5011 optSer := header.NDPOptionsSerializer{ 5012 header.NDPDNSSearchList([]byte{ 5013 0, 0, 5014 0, 0, 0, 0, 5015 2, 'h', 'i', 5016 0, 5017 }), 5018 header.NDPDNSSearchList([]byte{ 5019 0, 0, 5020 0, 0, 0, 1, 5021 1, 'i', 5022 0, 5023 2, 'a', 'm', 5024 2, 'm', 'e', 5025 0, 5026 }), 5027 header.NDPDNSSearchList([]byte{ 5028 0, 0, 5029 0, 0, 1, 0, 5030 3, 'x', 'y', 'z', 5031 0, 5032 5, 'h', 'e', 'l', 'l', 'o', 5033 5, 'w', 'o', 'r', 'l', 'd', 5034 0, 5035 4, 't', 'h', 'i', 's', 5036 2, 'i', 's', 5037 1, 'a', 5038 4, 't', 'e', 's', 't', 5039 0, 5040 }), 5041 } 5042 expected := []struct { 5043 domainNames []string 5044 lifetime time.Duration 5045 }{ 5046 { 5047 domainNames: []string{ 5048 "hi", 5049 }, 5050 lifetime: 0, 5051 }, 5052 { 5053 domainNames: []string{ 5054 "i", 5055 "am.me", 5056 }, 5057 lifetime: time.Second, 5058 }, 5059 { 5060 domainNames: []string{ 5061 "xyz", 5062 "hello.world", 5063 "this.is.a.test", 5064 }, 5065 lifetime: 256 * time.Second, 5066 }, 5067 } 5068 5069 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithOpts(llAddr1, 0, optSer)) 5070 5071 for i, expected := range expected { 5072 select { 5073 case dnssl := <-ndpDisp.dnsslC: 5074 if dnssl.nicID != nicID { 5075 t.Errorf("got %d-th dnssl nicID = %d, want = %d", i, dnssl.nicID, nicID) 5076 } 5077 if diff := cmp.Diff(dnssl.domainNames, expected.domainNames); diff != "" { 5078 t.Errorf("%d-th dnssl domain names mismatch (-want +got):\n%s", i, diff) 5079 } 5080 if dnssl.lifetime != expected.lifetime { 5081 t.Errorf("got %d-th dnssl lifetime = %s, want = %s", i, dnssl.lifetime, expected.lifetime) 5082 } 5083 default: 5084 t.Fatal("expected a DNSSL event") 5085 } 5086 } 5087 5088 // Should have no more DNSSL options. 5089 select { 5090 case <-ndpDisp.dnsslC: 5091 t.Fatal("unexpectedly got a DNSSL event") 5092 default: 5093 } 5094 } 5095 5096 func TestNoCleanupNDPStateWhenForwardingEnabled(t *testing.T) { 5097 const ( 5098 lifetimeSeconds = 999 5099 nicID = 1 5100 ) 5101 5102 const autoGenAddrCount = 1 5103 ndpDisp := ndpDispatcher{ 5104 offLinkRouteC: make(chan ndpOffLinkRouteEvent, 1), 5105 prefixC: make(chan ndpPrefixEvent, 1), 5106 autoGenAddrC: make(chan ndpAutoGenAddrEvent, autoGenAddrCount), 5107 autoGenAddrNewC: make(chan ndpAutoGenAddrNewEvent, autoGenAddrCount), 5108 } 5109 s := stack.New(stack.Options{ 5110 NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{ 5111 AutoGenLinkLocal: true, 5112 NDPConfigs: ipv6.NDPConfigurations{ 5113 HandleRAs: ipv6.HandlingRAsEnabledWhenForwardingDisabled, 5114 DiscoverDefaultRouters: true, 5115 DiscoverOnLinkPrefixes: true, 5116 AutoGenGlobalAddresses: true, 5117 }, 5118 NDPDisp: &ndpDisp, 5119 })}, 5120 }) 5121 5122 e1 := channel.New(0, header.IPv6MinimumMTU, linkAddr1) 5123 if err := s.CreateNIC(nicID, e1); err != nil { 5124 t.Fatalf("CreateNIC(%d, _) = %s", nicID, err) 5125 } 5126 llAddr := tcpip.AddressWithPrefix{Address: llAddr1, PrefixLen: header.IPv6LinkLocalPrefix.PrefixLen} 5127 if _, err := expectAutoGenAddrNewEvent(&ndpDisp, llAddr); err != nil { 5128 t.Fatalf("error expecting link-local auto-gen address generated event: %s", err) 5129 } 5130 5131 prefix, subnet, addr := prefixSubnetAddr(0, linkAddr1) 5132 e1.InjectInbound( 5133 header.IPv6ProtocolNumber, 5134 raBufWithPI( 5135 llAddr3, 5136 lifetimeSeconds, 5137 prefix, 5138 true, /* onLink */ 5139 true, /* auto */ 5140 lifetimeSeconds, 5141 lifetimeSeconds, 5142 ), 5143 ) 5144 select { 5145 case e := <-ndpDisp.offLinkRouteC: 5146 if diff := checkOffLinkRouteEvent(e, nicID, header.IPv6EmptySubnet, llAddr3, header.MediumRoutePreference, true /* discovered */); diff != "" { 5147 t.Errorf("off-link route event mismatch (-want +got):\n%s", diff) 5148 } 5149 default: 5150 t.Errorf("expected off-link route event for %s on NIC(%d)", llAddr3, nicID) 5151 } 5152 select { 5153 case e := <-ndpDisp.prefixC: 5154 if diff := checkPrefixEvent(e, subnet, true /* discovered */); diff != "" { 5155 t.Errorf("off-link route event mismatch (-want +got):\n%s", diff) 5156 } 5157 default: 5158 t.Errorf("expected prefix event for %s on NIC(%d)", prefix, nicID) 5159 } 5160 if _, err := expectAutoGenAddrNewEvent(&ndpDisp, addr); err != nil { 5161 t.Fatalf("error expecting stable auto-gen address generated event: %s", err) 5162 } 5163 5164 // Enabling or disabling forwarding should not invalidate discovered prefixes 5165 // or routers, or auto-generated address. 5166 for _, forwarding := range [...]bool{true, false} { 5167 t.Run(fmt.Sprintf("Transition forwarding to %t", forwarding), func(t *testing.T) { 5168 if err := s.SetForwardingDefaultAndAllNICs(ipv6.ProtocolNumber, forwarding); err != nil { 5169 t.Fatalf("SetForwardingDefaultAndAllNICs(%d, %t): %s", ipv6.ProtocolNumber, forwarding, err) 5170 } 5171 select { 5172 case e := <-ndpDisp.offLinkRouteC: 5173 t.Errorf("unexpected off-link route event = %#v", e) 5174 default: 5175 } 5176 select { 5177 case e := <-ndpDisp.prefixC: 5178 t.Errorf("unexpected prefix event = %#v", e) 5179 default: 5180 } 5181 select { 5182 case e := <-ndpDisp.autoGenAddrC: 5183 t.Errorf("unexpected auto-gen addr event = %#v", e) 5184 default: 5185 } 5186 select { 5187 case e := <-ndpDisp.autoGenAddrNewC: 5188 t.Errorf("unexpected new auto-gen addr event = %#v", e) 5189 default: 5190 } 5191 }) 5192 } 5193 } 5194 5195 func TestCleanupNDPState(t *testing.T) { 5196 const ( 5197 lifetimeSeconds = 5 5198 maxRouterAndPrefixEvents = 4 5199 nicID1 = 1 5200 nicID2 = 2 5201 ) 5202 5203 prefix1, subnet1, e1Addr1 := prefixSubnetAddr(0, linkAddr1) 5204 prefix2, subnet2, e1Addr2 := prefixSubnetAddr(1, linkAddr1) 5205 e2Addr1 := addrForSubnet(subnet1, linkAddr2) 5206 e2Addr2 := addrForSubnet(subnet2, linkAddr2) 5207 llAddrWithPrefix1 := tcpip.AddressWithPrefix{ 5208 Address: llAddr1, 5209 PrefixLen: 64, 5210 } 5211 llAddrWithPrefix2 := tcpip.AddressWithPrefix{ 5212 Address: llAddr2, 5213 PrefixLen: 64, 5214 } 5215 5216 tests := []struct { 5217 name string 5218 cleanupFn func(t *testing.T, s *stack.Stack) 5219 keepAutoGenLinkLocal bool 5220 maxAutoGenAddrEvents int 5221 skipFinalAddrCheck bool 5222 }{ 5223 // A NIC should cleanup all NDP state when it is disabled. 5224 { 5225 name: "Disable NIC", 5226 cleanupFn: func(t *testing.T, s *stack.Stack) { 5227 t.Helper() 5228 5229 if err := s.DisableNIC(nicID1); err != nil { 5230 t.Fatalf("s.DisableNIC(%d): %s", nicID1, err) 5231 } 5232 if err := s.DisableNIC(nicID2); err != nil { 5233 t.Fatalf("s.DisableNIC(%d): %s", nicID2, err) 5234 } 5235 }, 5236 keepAutoGenLinkLocal: false, 5237 maxAutoGenAddrEvents: 6, 5238 }, 5239 5240 // A NIC should cleanup all NDP state when it is removed. 5241 { 5242 name: "Remove NIC", 5243 cleanupFn: func(t *testing.T, s *stack.Stack) { 5244 t.Helper() 5245 5246 if err := s.RemoveNIC(nicID1); err != nil { 5247 t.Fatalf("s.RemoveNIC(%d): %s", nicID1, err) 5248 } 5249 if err := s.RemoveNIC(nicID2); err != nil { 5250 t.Fatalf("s.RemoveNIC(%d): %s", nicID2, err) 5251 } 5252 }, 5253 keepAutoGenLinkLocal: false, 5254 maxAutoGenAddrEvents: 6, 5255 // The NICs are removed so we can't check their addresses after calling 5256 // stopFn. 5257 skipFinalAddrCheck: true, 5258 }, 5259 } 5260 5261 for _, test := range tests { 5262 t.Run(test.name, func(t *testing.T) { 5263 ndpDisp := ndpDispatcher{ 5264 offLinkRouteC: make(chan ndpOffLinkRouteEvent, maxRouterAndPrefixEvents), 5265 prefixC: make(chan ndpPrefixEvent, maxRouterAndPrefixEvents), 5266 autoGenAddrNewC: make(chan ndpAutoGenAddrNewEvent, test.maxAutoGenAddrEvents), 5267 autoGenAddrC: make(chan ndpAutoGenAddrEvent, test.maxAutoGenAddrEvents), 5268 } 5269 clock := faketime.NewManualClock() 5270 s := stack.New(stack.Options{ 5271 NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{ 5272 AutoGenLinkLocal: true, 5273 NDPConfigs: ipv6.NDPConfigurations{ 5274 HandleRAs: ipv6.HandlingRAsEnabledWhenForwardingDisabled, 5275 DiscoverDefaultRouters: true, 5276 DiscoverOnLinkPrefixes: true, 5277 AutoGenGlobalAddresses: true, 5278 }, 5279 NDPDisp: &ndpDisp, 5280 })}, 5281 Clock: clock, 5282 }) 5283 5284 expectOffLinkRouteEvent := func() (bool, ndpOffLinkRouteEvent) { 5285 select { 5286 case e := <-ndpDisp.offLinkRouteC: 5287 return true, e 5288 default: 5289 } 5290 5291 return false, ndpOffLinkRouteEvent{} 5292 } 5293 5294 expectPrefixEvent := func() (bool, ndpPrefixEvent) { 5295 select { 5296 case e := <-ndpDisp.prefixC: 5297 return true, e 5298 default: 5299 } 5300 5301 return false, ndpPrefixEvent{} 5302 } 5303 5304 expectAutoGenAddrEvent := func() (bool, ndpAutoGenAddrEvent) { 5305 select { 5306 case e := <-ndpDisp.autoGenAddrC: 5307 return true, e 5308 default: 5309 } 5310 5311 return false, ndpAutoGenAddrEvent{} 5312 } 5313 5314 expectAutoGenAddrNewEvent := func() (bool, ndpAutoGenAddrNewEvent) { 5315 select { 5316 case e := <-ndpDisp.autoGenAddrNewC: 5317 return true, e 5318 default: 5319 } 5320 return false, ndpAutoGenAddrNewEvent{} 5321 } 5322 5323 e1 := channel.New(0, 1280, linkAddr1) 5324 if err := s.CreateNIC(nicID1, e1); err != nil { 5325 t.Fatalf("CreateNIC(%d, _) = %s", nicID1, err) 5326 } 5327 // We have other tests that make sure we receive the *correct* events 5328 // on normal discovery of routers/prefixes, and auto-generated 5329 // addresses. Here we just make sure we get an event and let other tests 5330 // handle the correctness check. 5331 expectAutoGenAddrNewEvent() 5332 5333 e2 := channel.New(0, 1280, linkAddr2) 5334 if err := s.CreateNIC(nicID2, e2); err != nil { 5335 t.Fatalf("CreateNIC(%d, _) = %s", nicID2, err) 5336 } 5337 expectAutoGenAddrNewEvent() 5338 5339 // Receive RAs on NIC(1) and NIC(2) from default routers (llAddr3 and 5340 // llAddr4) w/ PI (for prefix1 in RA from llAddr3 and prefix2 in RA from 5341 // llAddr4) to discover multiple routers and prefixes, and auto-gen 5342 // multiple addresses. 5343 5344 e1.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr3, lifetimeSeconds, prefix1, true, true, lifetimeSeconds, lifetimeSeconds)) 5345 if ok, _ := expectOffLinkRouteEvent(); !ok { 5346 t.Errorf("expected off-link route event for %s on NIC(%d)", llAddr3, nicID1) 5347 } 5348 if ok, _ := expectPrefixEvent(); !ok { 5349 t.Errorf("expected prefix event for %s on NIC(%d)", prefix1, nicID1) 5350 } 5351 if ok, _ := expectAutoGenAddrNewEvent(); !ok { 5352 t.Errorf("expected auto-gen addr event for %s on NIC(%d)", e1Addr1, nicID1) 5353 } 5354 5355 e1.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr4, lifetimeSeconds, prefix2, true, true, lifetimeSeconds, lifetimeSeconds)) 5356 if ok, _ := expectOffLinkRouteEvent(); !ok { 5357 t.Errorf("expected off-link route event for %s on NIC(%d)", llAddr4, nicID1) 5358 } 5359 if ok, _ := expectPrefixEvent(); !ok { 5360 t.Errorf("expected prefix event for %s on NIC(%d)", prefix2, nicID1) 5361 } 5362 if ok, _ := expectAutoGenAddrNewEvent(); !ok { 5363 t.Errorf("expected auto-gen addr event for %s on NIC(%d)", e1Addr2, nicID1) 5364 } 5365 5366 e2.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr3, lifetimeSeconds, prefix1, true, true, lifetimeSeconds, lifetimeSeconds)) 5367 if ok, _ := expectOffLinkRouteEvent(); !ok { 5368 t.Errorf("expected off-link route event for %s on NIC(%d)", llAddr3, nicID2) 5369 } 5370 if ok, _ := expectPrefixEvent(); !ok { 5371 t.Errorf("expected prefix event for %s on NIC(%d)", prefix1, nicID2) 5372 } 5373 if ok, _ := expectAutoGenAddrNewEvent(); !ok { 5374 t.Errorf("expected auto-gen addr event for %s on NIC(%d)", e1Addr2, nicID2) 5375 } 5376 5377 e2.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr4, lifetimeSeconds, prefix2, true, true, lifetimeSeconds, lifetimeSeconds)) 5378 if ok, _ := expectOffLinkRouteEvent(); !ok { 5379 t.Errorf("expected off-link route event for %s on NIC(%d)", llAddr4, nicID2) 5380 } 5381 if ok, _ := expectPrefixEvent(); !ok { 5382 t.Errorf("expected prefix event for %s on NIC(%d)", prefix2, nicID2) 5383 } 5384 if ok, _ := expectAutoGenAddrNewEvent(); !ok { 5385 t.Errorf("expected auto-gen addr event for %s on NIC(%d)", e2Addr2, nicID2) 5386 } 5387 5388 // We should have the auto-generated addresses added. 5389 nicinfo := s.NICInfo() 5390 nic1Addrs := nicinfo[nicID1].ProtocolAddresses 5391 nic2Addrs := nicinfo[nicID2].ProtocolAddresses 5392 if !containsV6Addr(nic1Addrs, llAddrWithPrefix1) { 5393 t.Errorf("missing %s from the list of addresses for NIC(%d): %+v", llAddrWithPrefix1, nicID1, nic1Addrs) 5394 } 5395 if !containsV6Addr(nic1Addrs, e1Addr1) { 5396 t.Errorf("missing %s from the list of addresses for NIC(%d): %+v", e1Addr1, nicID1, nic1Addrs) 5397 } 5398 if !containsV6Addr(nic1Addrs, e1Addr2) { 5399 t.Errorf("missing %s from the list of addresses for NIC(%d): %+v", e1Addr2, nicID1, nic1Addrs) 5400 } 5401 if !containsV6Addr(nic2Addrs, llAddrWithPrefix2) { 5402 t.Errorf("missing %s from the list of addresses for NIC(%d): %+v", llAddrWithPrefix2, nicID2, nic2Addrs) 5403 } 5404 if !containsV6Addr(nic2Addrs, e2Addr1) { 5405 t.Errorf("missing %s from the list of addresses for NIC(%d): %+v", e2Addr1, nicID2, nic2Addrs) 5406 } 5407 if !containsV6Addr(nic2Addrs, e2Addr2) { 5408 t.Errorf("missing %s from the list of addresses for NIC(%d): %+v", e2Addr2, nicID2, nic2Addrs) 5409 } 5410 5411 // We can't proceed any further if we already failed the test (missing 5412 // some discovery/auto-generated address events or addresses). 5413 if t.Failed() { 5414 t.FailNow() 5415 } 5416 5417 test.cleanupFn(t, s) 5418 5419 // Collect invalidation events after having NDP state cleaned up. 5420 gotOffLinkRouteEvents := make(map[ndpOffLinkRouteEvent]int) 5421 for i := 0; i < maxRouterAndPrefixEvents; i++ { 5422 ok, e := expectOffLinkRouteEvent() 5423 if !ok { 5424 t.Errorf("expected %d off-link route events after becoming a router; got = %d", maxRouterAndPrefixEvents, i) 5425 break 5426 } 5427 gotOffLinkRouteEvents[e]++ 5428 } 5429 gotPrefixEvents := make(map[ndpPrefixEvent]int) 5430 for i := 0; i < maxRouterAndPrefixEvents; i++ { 5431 ok, e := expectPrefixEvent() 5432 if !ok { 5433 t.Errorf("expected %d prefix events after becoming a router; got = %d", maxRouterAndPrefixEvents, i) 5434 break 5435 } 5436 gotPrefixEvents[e]++ 5437 } 5438 gotAutoGenAddrEvents := make(map[ndpAutoGenAddrEvent]int) 5439 for i := 0; i < test.maxAutoGenAddrEvents; i++ { 5440 ok, e := expectAutoGenAddrEvent() 5441 if !ok { 5442 t.Errorf("expected %d auto-generated address events after becoming a router; got = %d", test.maxAutoGenAddrEvents, i) 5443 break 5444 } 5445 gotAutoGenAddrEvents[e]++ 5446 } 5447 5448 // No need to proceed any further if we already failed the test (missing 5449 // some invalidation events). 5450 if t.Failed() { 5451 t.FailNow() 5452 } 5453 5454 expectedOffLinkRouteEvents := map[ndpOffLinkRouteEvent]int{ 5455 {nicID: nicID1, subnet: header.IPv6EmptySubnet, router: llAddr3, updated: false}: 1, 5456 {nicID: nicID1, subnet: header.IPv6EmptySubnet, router: llAddr4, updated: false}: 1, 5457 {nicID: nicID2, subnet: header.IPv6EmptySubnet, router: llAddr3, updated: false}: 1, 5458 {nicID: nicID2, subnet: header.IPv6EmptySubnet, router: llAddr4, updated: false}: 1, 5459 } 5460 if diff := cmp.Diff(expectedOffLinkRouteEvents, gotOffLinkRouteEvents); diff != "" { 5461 t.Errorf("off-link route events mismatch (-want +got):\n%s", diff) 5462 } 5463 expectedPrefixEvents := map[ndpPrefixEvent]int{ 5464 {nicID: nicID1, prefix: subnet1, discovered: false}: 1, 5465 {nicID: nicID1, prefix: subnet2, discovered: false}: 1, 5466 {nicID: nicID2, prefix: subnet1, discovered: false}: 1, 5467 {nicID: nicID2, prefix: subnet2, discovered: false}: 1, 5468 } 5469 if diff := cmp.Diff(expectedPrefixEvents, gotPrefixEvents); diff != "" { 5470 t.Errorf("prefix events mismatch (-want +got):\n%s", diff) 5471 } 5472 expectedAutoGenAddrEvents := map[ndpAutoGenAddrEvent]int{ 5473 {nicID: nicID1, addr: e1Addr1, eventType: invalidatedAddr}: 1, 5474 {nicID: nicID1, addr: e1Addr2, eventType: invalidatedAddr}: 1, 5475 {nicID: nicID2, addr: e2Addr1, eventType: invalidatedAddr}: 1, 5476 {nicID: nicID2, addr: e2Addr2, eventType: invalidatedAddr}: 1, 5477 } 5478 5479 if !test.keepAutoGenLinkLocal { 5480 expectedAutoGenAddrEvents[ndpAutoGenAddrEvent{nicID: nicID1, addr: llAddrWithPrefix1, eventType: invalidatedAddr}] = 1 5481 expectedAutoGenAddrEvents[ndpAutoGenAddrEvent{nicID: nicID2, addr: llAddrWithPrefix2, eventType: invalidatedAddr}] = 1 5482 } 5483 5484 if diff := cmp.Diff(expectedAutoGenAddrEvents, gotAutoGenAddrEvents); diff != "" { 5485 t.Errorf("auto-generated address events mismatch (-want +got):\n%s", diff) 5486 } 5487 5488 if !test.skipFinalAddrCheck { 5489 // Make sure the auto-generated addresses got removed. 5490 nicinfo = s.NICInfo() 5491 nic1Addrs = nicinfo[nicID1].ProtocolAddresses 5492 nic2Addrs = nicinfo[nicID2].ProtocolAddresses 5493 if containsV6Addr(nic1Addrs, llAddrWithPrefix1) != test.keepAutoGenLinkLocal { 5494 if test.keepAutoGenLinkLocal { 5495 t.Errorf("missing %s from the list of addresses for NIC(%d): %+v", llAddrWithPrefix1, nicID1, nic1Addrs) 5496 } else { 5497 t.Errorf("still have %s in the list of addresses for NIC(%d): %+v", llAddrWithPrefix1, nicID1, nic1Addrs) 5498 } 5499 } 5500 if containsV6Addr(nic1Addrs, e1Addr1) { 5501 t.Errorf("still have %s in the list of addresses for NIC(%d): %+v", e1Addr1, nicID1, nic1Addrs) 5502 } 5503 if containsV6Addr(nic1Addrs, e1Addr2) { 5504 t.Errorf("still have %s in the list of addresses for NIC(%d): %+v", e1Addr2, nicID1, nic1Addrs) 5505 } 5506 if containsV6Addr(nic2Addrs, llAddrWithPrefix2) != test.keepAutoGenLinkLocal { 5507 if test.keepAutoGenLinkLocal { 5508 t.Errorf("missing %s from the list of addresses for NIC(%d): %+v", llAddrWithPrefix2, nicID2, nic2Addrs) 5509 } else { 5510 t.Errorf("still have %s in the list of addresses for NIC(%d): %+v", llAddrWithPrefix2, nicID2, nic2Addrs) 5511 } 5512 } 5513 if containsV6Addr(nic2Addrs, e2Addr1) { 5514 t.Errorf("still have %s in the list of addresses for NIC(%d): %+v", e2Addr1, nicID2, nic2Addrs) 5515 } 5516 if containsV6Addr(nic2Addrs, e2Addr2) { 5517 t.Errorf("still have %s in the list of addresses for NIC(%d): %+v", e2Addr2, nicID2, nic2Addrs) 5518 } 5519 } 5520 5521 // Should not get any more events (invalidation timers should have been 5522 // cancelled when the NDP state was cleaned up). 5523 clock.Advance(lifetimeSeconds * time.Second) 5524 select { 5525 case <-ndpDisp.offLinkRouteC: 5526 t.Error("unexpected off-link route event") 5527 default: 5528 } 5529 select { 5530 case <-ndpDisp.prefixC: 5531 t.Error("unexpected prefix event") 5532 default: 5533 } 5534 select { 5535 case <-ndpDisp.autoGenAddrC: 5536 t.Error("unexpected auto-generated address event") 5537 default: 5538 } 5539 select { 5540 case <-ndpDisp.autoGenAddrNewC: 5541 t.Error("unexpected auto-generated address event") 5542 default: 5543 } 5544 }) 5545 } 5546 } 5547 5548 // TestDHCPv6ConfigurationFromNDPDA tests that the NDPDispatcher is properly 5549 // informed when new information about what configurations are available via 5550 // DHCPv6 is learned. 5551 func TestDHCPv6ConfigurationFromNDPDA(t *testing.T) { 5552 const nicID = 1 5553 5554 ndpDisp := ndpDispatcher{ 5555 dhcpv6ConfigurationC: make(chan ndpDHCPv6Event, 1), 5556 } 5557 e := channel.New(0, 1280, linkAddr1) 5558 s := stack.New(stack.Options{ 5559 NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{ 5560 NDPConfigs: ipv6.NDPConfigurations{ 5561 HandleRAs: ipv6.HandlingRAsEnabledWhenForwardingDisabled, 5562 }, 5563 NDPDisp: &ndpDisp, 5564 })}, 5565 }) 5566 5567 if err := s.CreateNIC(nicID, e); err != nil { 5568 t.Fatalf("CreateNIC(%d, _) = %s", nicID, err) 5569 } 5570 5571 expectDHCPv6Event := func(configuration ipv6.DHCPv6ConfigurationFromNDPRA) { 5572 t.Helper() 5573 select { 5574 case e := <-ndpDisp.dhcpv6ConfigurationC: 5575 if diff := cmp.Diff(ndpDHCPv6Event{nicID: nicID, configuration: configuration}, e, cmp.AllowUnexported(e)); diff != "" { 5576 t.Errorf("dhcpv6 event mismatch (-want +got):\n%s", diff) 5577 } 5578 default: 5579 t.Fatal("expected DHCPv6 configuration event") 5580 } 5581 } 5582 5583 expectNoDHCPv6Event := func() { 5584 t.Helper() 5585 select { 5586 case <-ndpDisp.dhcpv6ConfigurationC: 5587 t.Fatal("unexpected DHCPv6 configuration event") 5588 default: 5589 } 5590 } 5591 5592 // Even if the first RA reports no DHCPv6 configurations are available, the 5593 // dispatcher should get an event. 5594 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, false, false)) 5595 expectDHCPv6Event(ipv6.DHCPv6NoConfiguration) 5596 // Receiving the same update again should not result in an event to the 5597 // dispatcher. 5598 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, false, false)) 5599 expectNoDHCPv6Event() 5600 5601 // Receive an RA that updates the DHCPv6 configuration to Other 5602 // Configurations. 5603 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, false, true)) 5604 expectDHCPv6Event(ipv6.DHCPv6OtherConfigurations) 5605 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, false, true)) 5606 expectNoDHCPv6Event() 5607 5608 // Receive an RA that updates the DHCPv6 configuration to Managed Address. 5609 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, true, false)) 5610 expectDHCPv6Event(ipv6.DHCPv6ManagedAddress) 5611 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, true, false)) 5612 expectNoDHCPv6Event() 5613 5614 // Receive an RA that updates the DHCPv6 configuration to none. 5615 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, false, false)) 5616 expectDHCPv6Event(ipv6.DHCPv6NoConfiguration) 5617 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, false, false)) 5618 expectNoDHCPv6Event() 5619 5620 // Receive an RA that updates the DHCPv6 configuration to Managed Address. 5621 // 5622 // Note, when the M flag is set, the O flag is redundant. 5623 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, true, true)) 5624 expectDHCPv6Event(ipv6.DHCPv6ManagedAddress) 5625 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, true, true)) 5626 expectNoDHCPv6Event() 5627 // Even though the DHCPv6 flags are different, the effective configuration is 5628 // the same so we should not receive a new event. 5629 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, true, false)) 5630 expectNoDHCPv6Event() 5631 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, true, true)) 5632 expectNoDHCPv6Event() 5633 5634 // Receive an RA that updates the DHCPv6 configuration to Other 5635 // Configurations. 5636 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, false, true)) 5637 expectDHCPv6Event(ipv6.DHCPv6OtherConfigurations) 5638 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, false, true)) 5639 expectNoDHCPv6Event() 5640 5641 // Cycling the NIC should cause the last DHCPv6 configuration to be cleared. 5642 if err := s.DisableNIC(nicID); err != nil { 5643 t.Fatalf("s.DisableNIC(%d): %s", nicID, err) 5644 } 5645 if err := s.EnableNIC(nicID); err != nil { 5646 t.Fatalf("s.EnableNIC(%d): %s", nicID, err) 5647 } 5648 5649 // Receive an RA that updates the DHCPv6 configuration to Other 5650 // Configurations. 5651 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, false, true)) 5652 expectDHCPv6Event(ipv6.DHCPv6OtherConfigurations) 5653 e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, false, true)) 5654 expectNoDHCPv6Event() 5655 } 5656 5657 var _ rand.Source = (*savingRandSource)(nil) 5658 5659 type savingRandSource struct { 5660 s rand.Source 5661 5662 lastInt63 int64 5663 } 5664 5665 func (d *savingRandSource) Int63() int64 { 5666 i := d.s.Int63() 5667 d.lastInt63 = i 5668 return i 5669 } 5670 func (d *savingRandSource) Seed(seed int64) { 5671 d.s.Seed(seed) 5672 } 5673 5674 // TestRouterSolicitation tests the initial Router Solicitations that are sent 5675 // when a NIC newly becomes enabled. 5676 func TestRouterSolicitation(t *testing.T) { 5677 const nicID = 1 5678 5679 tests := []struct { 5680 name string 5681 linkHeaderLen uint16 5682 linkAddr tcpip.LinkAddress 5683 nicAddr tcpip.Address 5684 expectedSrcAddr tcpip.Address 5685 expectedNDPOpts []header.NDPOption 5686 maxRtrSolicit uint8 5687 rtrSolicitInt time.Duration 5688 effectiveRtrSolicitInt time.Duration 5689 maxRtrSolicitDelay time.Duration 5690 effectiveMaxRtrSolicitDelay time.Duration 5691 }{ 5692 { 5693 name: "Single RS with 2s delay and interval", 5694 expectedSrcAddr: header.IPv6Any, 5695 maxRtrSolicit: 1, 5696 rtrSolicitInt: 2 * time.Second, 5697 effectiveRtrSolicitInt: 2 * time.Second, 5698 maxRtrSolicitDelay: 2 * time.Second, 5699 effectiveMaxRtrSolicitDelay: 2 * time.Second, 5700 }, 5701 { 5702 name: "Single RS with 4s delay and interval", 5703 expectedSrcAddr: header.IPv6Any, 5704 maxRtrSolicit: 1, 5705 rtrSolicitInt: 4 * time.Second, 5706 effectiveRtrSolicitInt: 4 * time.Second, 5707 maxRtrSolicitDelay: 4 * time.Second, 5708 effectiveMaxRtrSolicitDelay: 4 * time.Second, 5709 }, 5710 { 5711 name: "Two RS with delay", 5712 linkHeaderLen: 1, 5713 nicAddr: llAddr1, 5714 expectedSrcAddr: llAddr1, 5715 maxRtrSolicit: 2, 5716 rtrSolicitInt: 2 * time.Second, 5717 effectiveRtrSolicitInt: 2 * time.Second, 5718 maxRtrSolicitDelay: 500 * time.Millisecond, 5719 effectiveMaxRtrSolicitDelay: 500 * time.Millisecond, 5720 }, 5721 { 5722 name: "Single RS without delay", 5723 linkHeaderLen: 2, 5724 linkAddr: linkAddr1, 5725 nicAddr: llAddr1, 5726 expectedSrcAddr: llAddr1, 5727 expectedNDPOpts: []header.NDPOption{ 5728 header.NDPSourceLinkLayerAddressOption(linkAddr1), 5729 }, 5730 maxRtrSolicit: 1, 5731 rtrSolicitInt: 2 * time.Second, 5732 effectiveRtrSolicitInt: 2 * time.Second, 5733 maxRtrSolicitDelay: 0, 5734 effectiveMaxRtrSolicitDelay: 0, 5735 }, 5736 { 5737 name: "Two RS without delay and invalid zero interval", 5738 linkHeaderLen: 3, 5739 linkAddr: linkAddr1, 5740 expectedSrcAddr: header.IPv6Any, 5741 maxRtrSolicit: 2, 5742 rtrSolicitInt: 0, 5743 effectiveRtrSolicitInt: 4 * time.Second, 5744 maxRtrSolicitDelay: 0, 5745 effectiveMaxRtrSolicitDelay: 0, 5746 }, 5747 { 5748 name: "Three RS without delay", 5749 linkAddr: linkAddr1, 5750 expectedSrcAddr: header.IPv6Any, 5751 maxRtrSolicit: 3, 5752 rtrSolicitInt: 500 * time.Millisecond, 5753 effectiveRtrSolicitInt: 500 * time.Millisecond, 5754 maxRtrSolicitDelay: 0, 5755 effectiveMaxRtrSolicitDelay: 0, 5756 }, 5757 { 5758 name: "Two RS with invalid negative delay", 5759 linkAddr: linkAddr1, 5760 expectedSrcAddr: header.IPv6Any, 5761 maxRtrSolicit: 2, 5762 rtrSolicitInt: time.Second, 5763 effectiveRtrSolicitInt: time.Second, 5764 maxRtrSolicitDelay: -3 * time.Second, 5765 effectiveMaxRtrSolicitDelay: time.Second, 5766 }, 5767 } 5768 5769 subTests := []struct { 5770 name string 5771 handleRAs ipv6.HandleRAsConfiguration 5772 afterFirstRS func(*testing.T, *stack.Stack) 5773 }{ 5774 { 5775 name: "Handle RAs when forwarding disabled", 5776 handleRAs: ipv6.HandlingRAsEnabledWhenForwardingDisabled, 5777 afterFirstRS: func(*testing.T, *stack.Stack) {}, 5778 }, 5779 5780 // Enabling forwarding when RAs are always configured to be handled 5781 // should not stop router solicitations. 5782 { 5783 name: "Handle RAs always", 5784 handleRAs: ipv6.HandlingRAsAlwaysEnabled, 5785 afterFirstRS: func(t *testing.T, s *stack.Stack) { 5786 if err := s.SetForwardingDefaultAndAllNICs(ipv6.ProtocolNumber, true); err != nil { 5787 t.Fatalf("SetForwardingDefaultAndAllNICs(%d, true): %s", ipv6.ProtocolNumber, err) 5788 } 5789 }, 5790 }, 5791 } 5792 5793 for _, test := range tests { 5794 t.Run(test.name, func(t *testing.T) { 5795 for _, subTest := range subTests { 5796 t.Run(subTest.name, func(t *testing.T) { 5797 clock := faketime.NewManualClock() 5798 e := channelLinkWithHeaderLength{ 5799 Endpoint: channel.New(int(test.maxRtrSolicit), 1280, test.linkAddr), 5800 headerLength: test.linkHeaderLen, 5801 } 5802 e.Endpoint.LinkEPCapabilities |= stack.CapabilityResolutionRequired 5803 waitForPkt := func(timeout time.Duration) { 5804 t.Helper() 5805 5806 clock.Advance(timeout) 5807 p := e.Read() 5808 if p == nil { 5809 t.Fatal("expected router solicitation packet") 5810 } 5811 defer p.DecRef() 5812 5813 if p.NetworkProtocolNumber != header.IPv6ProtocolNumber { 5814 t.Fatalf("got Proto = %d, want = %d", p.NetworkProtocolNumber, header.IPv6ProtocolNumber) 5815 } 5816 5817 // Make sure the right remote link address is used. 5818 if want := header.EthernetAddressFromMulticastIPv6Address(header.IPv6AllRoutersLinkLocalMulticastAddress); p.EgressRoute.RemoteLinkAddress != want { 5819 t.Errorf("got remote link address = %s, want = %s", p.EgressRoute.RemoteLinkAddress, want) 5820 } 5821 5822 checker.IPv6(t, stack.PayloadSince(p.NetworkHeader()), 5823 checker.SrcAddr(test.expectedSrcAddr), 5824 checker.DstAddr(header.IPv6AllRoutersLinkLocalMulticastAddress), 5825 checker.TTL(header.NDPHopLimit), 5826 checker.NDPRS(checker.NDPRSOptions(test.expectedNDPOpts)), 5827 ) 5828 5829 if l, want := p.AvailableHeaderBytes(), int(test.linkHeaderLen); l != want { 5830 t.Errorf("got p.AvailableHeaderBytes() = %d; want = %d", l, want) 5831 } 5832 } 5833 waitForNothing := func(timeout time.Duration) { 5834 t.Helper() 5835 5836 clock.Advance(timeout) 5837 if p := e.Read(); p != nil { 5838 t.Fatalf("unexpectedly got a packet = %#v", p) 5839 } 5840 } 5841 randSource := savingRandSource{ 5842 s: rand.NewSource(time.Now().UnixNano()), 5843 } 5844 s := stack.New(stack.Options{ 5845 NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{ 5846 NDPConfigs: ipv6.NDPConfigurations{ 5847 HandleRAs: subTest.handleRAs, 5848 MaxRtrSolicitations: test.maxRtrSolicit, 5849 RtrSolicitationInterval: test.rtrSolicitInt, 5850 MaxRtrSolicitationDelay: test.maxRtrSolicitDelay, 5851 }, 5852 })}, 5853 Clock: clock, 5854 RandSource: &randSource, 5855 }) 5856 5857 opts := stack.NICOptions{Disabled: true} 5858 if err := s.CreateNICWithOptions(nicID, &e, opts); err != nil { 5859 t.Fatalf("CreateNICWithOptions(%d, _, %#v) = %s", nicID, opts, err) 5860 } 5861 5862 if addr := test.nicAddr; addr != (tcpip.Address{}) { 5863 protocolAddr := tcpip.ProtocolAddress{ 5864 Protocol: header.IPv6ProtocolNumber, 5865 AddressWithPrefix: addr.WithPrefix(), 5866 } 5867 if err := s.AddProtocolAddress(nicID, protocolAddr, stack.AddressProperties{}); err != nil { 5868 t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", nicID, protocolAddr, err) 5869 } 5870 } 5871 5872 if err := s.EnableNIC(nicID); err != nil { 5873 t.Fatalf("EnableNIC(%d): %s", nicID, err) 5874 } 5875 5876 // Make sure each RS is sent at the right time. 5877 remaining := test.maxRtrSolicit 5878 if remaining != 0 { 5879 maxRtrSolicitDelay := test.maxRtrSolicitDelay 5880 if maxRtrSolicitDelay < 0 { 5881 maxRtrSolicitDelay = ipv6.DefaultNDPConfigurations().MaxRtrSolicitationDelay 5882 } 5883 var actualRtrSolicitDelay time.Duration 5884 if maxRtrSolicitDelay != 0 { 5885 actualRtrSolicitDelay = time.Duration(randSource.lastInt63) % maxRtrSolicitDelay 5886 } 5887 waitForPkt(actualRtrSolicitDelay) 5888 remaining-- 5889 } 5890 5891 subTest.afterFirstRS(t, s) 5892 5893 for ; remaining != 0; remaining-- { 5894 if test.effectiveRtrSolicitInt != 0 { 5895 waitForNothing(test.effectiveRtrSolicitInt - time.Nanosecond) 5896 waitForPkt(time.Nanosecond) 5897 } else { 5898 waitForPkt(0) 5899 } 5900 } 5901 5902 // Make sure no more RS. 5903 if test.effectiveRtrSolicitInt > test.effectiveMaxRtrSolicitDelay { 5904 waitForNothing(test.effectiveRtrSolicitInt) 5905 } else { 5906 waitForNothing(test.effectiveMaxRtrSolicitDelay) 5907 } 5908 5909 if got, want := s.Stats().ICMP.V6.PacketsSent.RouterSolicit.Value(), uint64(test.maxRtrSolicit); got != want { 5910 t.Fatalf("got sent RouterSolicit = %d, want = %d", got, want) 5911 } 5912 }) 5913 } 5914 }) 5915 } 5916 } 5917 5918 func TestStopStartSolicitingRouters(t *testing.T) { 5919 const nicID = 1 5920 const delay = 0 5921 const interval = 500 * time.Millisecond 5922 const maxRtrSolicitations = 3 5923 5924 tests := []struct { 5925 name string 5926 startFn func(t *testing.T, s *stack.Stack) 5927 // first is used to tell stopFn that it is being called for the first time 5928 // after router solicitations were last enabled. 5929 stopFn func(t *testing.T, s *stack.Stack, first bool) 5930 }{ 5931 // Tests that when forwarding is enabled or disabled, router solicitations 5932 // are stopped or started, respectively. 5933 { 5934 name: "Enable and disable forwarding", 5935 startFn: func(t *testing.T, s *stack.Stack) { 5936 t.Helper() 5937 5938 if err := s.SetForwardingDefaultAndAllNICs(ipv6.ProtocolNumber, false); err != nil { 5939 t.Fatalf("SetForwardingDefaultAndAllNICs(%d, false): %s", ipv6.ProtocolNumber, err) 5940 } 5941 }, 5942 stopFn: func(t *testing.T, s *stack.Stack, _ bool) { 5943 t.Helper() 5944 5945 if err := s.SetForwardingDefaultAndAllNICs(ipv6.ProtocolNumber, true); err != nil { 5946 t.Fatalf("SetForwardingDefaultAndAllNICs(%d, true): %s", ipv6.ProtocolNumber, err) 5947 } 5948 }, 5949 }, 5950 5951 // Tests that when a NIC is enabled or disabled, router solicitations 5952 // are started or stopped, respectively. 5953 { 5954 name: "Enable and disable NIC", 5955 startFn: func(t *testing.T, s *stack.Stack) { 5956 t.Helper() 5957 5958 if err := s.EnableNIC(nicID); err != nil { 5959 t.Fatalf("s.EnableNIC(%d): %s", nicID, err) 5960 } 5961 }, 5962 stopFn: func(t *testing.T, s *stack.Stack, _ bool) { 5963 t.Helper() 5964 5965 if err := s.DisableNIC(nicID); err != nil { 5966 t.Fatalf("s.DisableNIC(%d): %s", nicID, err) 5967 } 5968 }, 5969 }, 5970 5971 // Tests that when a NIC is removed, router solicitations are stopped. We 5972 // cannot start router solicitations on a removed NIC. 5973 { 5974 name: "Remove NIC", 5975 stopFn: func(t *testing.T, s *stack.Stack, first bool) { 5976 t.Helper() 5977 5978 // Only try to remove the NIC the first time stopFn is called since it's 5979 // impossible to remove an already removed NIC. 5980 if !first { 5981 return 5982 } 5983 5984 if err := s.RemoveNIC(nicID); err != nil { 5985 t.Fatalf("s.RemoveNIC(%d): %s", nicID, err) 5986 } 5987 }, 5988 }, 5989 } 5990 5991 for _, test := range tests { 5992 t.Run(test.name, func(t *testing.T) { 5993 e := channel.New(maxRtrSolicitations, 1280, linkAddr1) 5994 waitForPkt := func(clock *faketime.ManualClock, timeout time.Duration) { 5995 t.Helper() 5996 5997 clock.Advance(timeout) 5998 p := e.Read() 5999 if p == nil { 6000 t.Fatal("timed out waiting for packet") 6001 } 6002 6003 if p.NetworkProtocolNumber != header.IPv6ProtocolNumber { 6004 t.Fatalf("got Proto = %d, want = %d", p.NetworkProtocolNumber, header.IPv6ProtocolNumber) 6005 } 6006 checker.IPv6(t, stack.PayloadSince(p.NetworkHeader()), 6007 checker.SrcAddr(header.IPv6Any), 6008 checker.DstAddr(header.IPv6AllRoutersLinkLocalMulticastAddress), 6009 checker.TTL(header.NDPHopLimit), 6010 checker.NDPRS()) 6011 p.DecRef() 6012 } 6013 clock := faketime.NewManualClock() 6014 s := stack.New(stack.Options{ 6015 NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{ 6016 NDPConfigs: ipv6.NDPConfigurations{ 6017 HandleRAs: ipv6.HandlingRAsEnabledWhenForwardingDisabled, 6018 MaxRtrSolicitations: maxRtrSolicitations, 6019 RtrSolicitationInterval: interval, 6020 MaxRtrSolicitationDelay: delay, 6021 }, 6022 })}, 6023 Clock: clock, 6024 }) 6025 if err := s.CreateNIC(nicID, e); err != nil { 6026 t.Fatalf("CreateNIC(%d, _) = %s", nicID, err) 6027 } 6028 6029 // Stop soliciting routers. 6030 test.stopFn(t, s, true /* first */) 6031 clock.Advance(delay) 6032 if p := e.Read(); p != nil { 6033 p.DecRef() 6034 // A single RS may have been sent before solicitations were stopped. 6035 clock.Advance(interval) 6036 if pb := e.Read(); pb != nil { 6037 t.Fatal("should not have sent more than one RS message") 6038 } 6039 } 6040 6041 // Stopping router solicitations after it has already been stopped should 6042 // do nothing. 6043 test.stopFn(t, s, false /* first */) 6044 clock.Advance(delay) 6045 if pb := e.Read(); pb != nil { 6046 t.Fatal("unexpectedly got a packet after router solicitation has been stopepd") 6047 } 6048 6049 // If test.startFn is nil, there is no way to restart router solicitations. 6050 if test.startFn == nil { 6051 return 6052 } 6053 6054 // Start soliciting routers. 6055 test.startFn(t, s) 6056 waitForPkt(clock, delay) 6057 waitForPkt(clock, interval) 6058 waitForPkt(clock, interval) 6059 clock.Advance(interval) 6060 if pb := e.Read(); pb != nil { 6061 t.Fatal("unexpectedly got an extra packet after sending out the expected RSs") 6062 } 6063 6064 // Starting router solicitations after it has already completed should do 6065 // nothing. 6066 test.startFn(t, s) 6067 clock.Advance(interval) 6068 if pb := e.Read(); pb != nil { 6069 t.Fatal("unexpectedly got a packet after finishing router solicitations") 6070 } 6071 }) 6072 } 6073 }