// Copyright 2019 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package stack_test

import (
	"bytes"
	"context"
	"encoding/binary"
	"fmt"
	"testing"
	"time"

	"github.com/google/go-cmp/cmp"
	"gvisor.dev/gvisor/pkg/rand"
	"gvisor.dev/gvisor/pkg/tcpip"
	"gvisor.dev/gvisor/pkg/tcpip/buffer"
	"gvisor.dev/gvisor/pkg/tcpip/checker"
	"gvisor.dev/gvisor/pkg/tcpip/faketime"
	"gvisor.dev/gvisor/pkg/tcpip/header"
	"gvisor.dev/gvisor/pkg/tcpip/link/channel"
	"gvisor.dev/gvisor/pkg/tcpip/link/loopback"
	"gvisor.dev/gvisor/pkg/tcpip/network/ipv6"
	"gvisor.dev/gvisor/pkg/tcpip/stack"
	"gvisor.dev/gvisor/pkg/tcpip/transport/icmp"
	"gvisor.dev/gvisor/pkg/tcpip/transport/udp"
	"gvisor.dev/gvisor/pkg/waiter"
)

const (
	addr1     = tcpip.Address("\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01")
	addr2     = tcpip.Address("\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02")
	addr3     = tcpip.Address("\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03")
	linkAddr1 = tcpip.LinkAddress("\x02\x02\x03\x04\x05\x06")
	linkAddr2 = tcpip.LinkAddress("\x02\x02\x03\x04\x05\x07")
	linkAddr3 = tcpip.LinkAddress("\x02\x02\x03\x04\x05\x08")
	linkAddr4 = tcpip.LinkAddress("\x02\x02\x03\x04\x05\x09")

	defaultPrefixLen = 128

	// Extra time to use when waiting for an async event to occur.
	defaultAsyncPositiveEventTimeout = 10 * time.Second

	// Extra time to use when waiting for an async event to not occur.
	//
	// Since a negative check is used to make sure an event did not happen, it is
	// okay to use a smaller timeout compared to the positive case since execution
	// stall in regards to the monotonic clock will not affect the expected
	// outcome.
	defaultAsyncNegativeEventTimeout = time.Second
)

var (
	llAddr1 = header.LinkLocalAddr(linkAddr1)
	llAddr2 = header.LinkLocalAddr(linkAddr2)
	llAddr3 = header.LinkLocalAddr(linkAddr3)
	llAddr4 = header.LinkLocalAddr(linkAddr4)
	dstAddr = tcpip.FullAddress{
		Addr: "\x0a\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01",
		Port: 25,
	}
)

func addrForSubnet(subnet tcpip.Subnet, linkAddr tcpip.LinkAddress) tcpip.AddressWithPrefix {
	if !header.IsValidUnicastEthernetAddress(linkAddr) {
		return tcpip.AddressWithPrefix{}
	}

	addrBytes := []byte(subnet.ID())
	header.EthernetAdddressToModifiedEUI64IntoBuf(linkAddr, addrBytes[header.IIDOffsetInIPv6Address:])
	return tcpip.AddressWithPrefix{
		Address:   tcpip.Address(addrBytes),
		PrefixLen: 64,
	}
}

// prefixSubnetAddr returns a prefix (Address + Length), the prefix's equivalent
// tcpip.Subnet, and an address where the lower half of the address is composed
// of the EUI-64 of linkAddr if it is a valid unicast ethernet address.
func prefixSubnetAddr(offset uint8, linkAddr tcpip.LinkAddress) (tcpip.AddressWithPrefix, tcpip.Subnet, tcpip.AddressWithPrefix) {
	prefixBytes := []byte{1, 2, 3, 4, 5, 6, 7, 8 + offset, 0, 0, 0, 0, 0, 0, 0, 0}
	prefix := tcpip.AddressWithPrefix{
		Address:   tcpip.Address(prefixBytes),
		PrefixLen: 64,
	}

	subnet := prefix.Subnet()

	return prefix, subnet, addrForSubnet(subnet, linkAddr)
}

// ndpDADEvent is a set of parameters that was passed to
// ndpDispatcher.OnDuplicateAddressDetectionResult.
type ndpDADEvent struct {
	nicID tcpip.NICID
	addr  tcpip.Address
	res   stack.DADResult
}

type ndpRouterEvent struct {
	nicID tcpip.NICID
	addr  tcpip.Address
	// true if router was discovered, false if invalidated.
	discovered bool
}

type ndpPrefixEvent struct {
	nicID  tcpip.NICID
	prefix tcpip.Subnet
	// true if prefix was discovered, false if invalidated.
	discovered bool
}

type ndpAutoGenAddrEventType int

const (
	newAddr ndpAutoGenAddrEventType = iota
	deprecatedAddr
	invalidatedAddr
)

type ndpAutoGenAddrEvent struct {
	nicID     tcpip.NICID
	addr      tcpip.AddressWithPrefix
	eventType ndpAutoGenAddrEventType
}

type ndpRDNSS struct {
	addrs    []tcpip.Address
	lifetime time.Duration
}

type ndpRDNSSEvent struct {
	nicID tcpip.NICID
	rdnss ndpRDNSS
}

type ndpDNSSLEvent struct {
	nicID       tcpip.NICID
	domainNames []string
	lifetime    time.Duration
}

type ndpDHCPv6Event struct {
	nicID         tcpip.NICID
	configuration ipv6.DHCPv6ConfigurationFromNDPRA
}

var _ ipv6.NDPDispatcher = (*ndpDispatcher)(nil)

// ndpDispatcher implements NDPDispatcher so tests can know when various NDP
// related events happen for test purposes.
type ndpDispatcher struct {
	dadC                 chan ndpDADEvent
	routerC              chan ndpRouterEvent
	rememberRouter       bool
	prefixC              chan ndpPrefixEvent
	rememberPrefix       bool
	autoGenAddrC         chan ndpAutoGenAddrEvent
	rdnssC               chan ndpRDNSSEvent
	dnsslC               chan ndpDNSSLEvent
	routeTable           []tcpip.Route
	dhcpv6ConfigurationC chan ndpDHCPv6Event
}

// Implements ipv6.NDPDispatcher.OnDuplicateAddressDetectionResult.
func (n *ndpDispatcher) OnDuplicateAddressDetectionResult(nicID tcpip.NICID, addr tcpip.Address, res stack.DADResult) {
	if n.dadC != nil {
		n.dadC <- ndpDADEvent{
			nicID,
			addr,
			res,
		}
	}
}

// Implements ipv6.NDPDispatcher.OnDefaultRouterDiscovered.
func (n *ndpDispatcher) OnDefaultRouterDiscovered(nicID tcpip.NICID, addr tcpip.Address) bool {
	if c := n.routerC; c != nil {
		c <- ndpRouterEvent{
			nicID,
			addr,
			true,
		}
	}

	return n.rememberRouter
}

// Implements ipv6.NDPDispatcher.OnDefaultRouterInvalidated.
func (n *ndpDispatcher) OnDefaultRouterInvalidated(nicID tcpip.NICID, addr tcpip.Address) {
	if c := n.routerC; c != nil {
		c <- ndpRouterEvent{
			nicID,
			addr,
			false,
		}
	}
}

// Implements ipv6.NDPDispatcher.OnOnLinkPrefixDiscovered.
func (n *ndpDispatcher) OnOnLinkPrefixDiscovered(nicID tcpip.NICID, prefix tcpip.Subnet) bool {
	if c := n.prefixC; c != nil {
		c <- ndpPrefixEvent{
			nicID,
			prefix,
			true,
		}
	}

	return n.rememberPrefix
}

// Implements ipv6.NDPDispatcher.OnOnLinkPrefixInvalidated.
func (n *ndpDispatcher) OnOnLinkPrefixInvalidated(nicID tcpip.NICID, prefix tcpip.Subnet) {
	if c := n.prefixC; c != nil {
		c <- ndpPrefixEvent{
			nicID,
			prefix,
			false,
		}
	}
}

func (n *ndpDispatcher) OnAutoGenAddress(nicID tcpip.NICID, addr tcpip.AddressWithPrefix) bool {
	if c := n.autoGenAddrC; c != nil {
		c <- ndpAutoGenAddrEvent{
			nicID,
			addr,
			newAddr,
		}
	}
	return true
}

func (n *ndpDispatcher) OnAutoGenAddressDeprecated(nicID tcpip.NICID, addr tcpip.AddressWithPrefix) {
	if c := n.autoGenAddrC; c != nil {
		c <- ndpAutoGenAddrEvent{
			nicID,
			addr,
			deprecatedAddr,
		}
	}
}

func (n *ndpDispatcher) OnAutoGenAddressInvalidated(nicID tcpip.NICID, addr tcpip.AddressWithPrefix) {
	if c := n.autoGenAddrC; c != nil {
		c <- ndpAutoGenAddrEvent{
			nicID,
			addr,
			invalidatedAddr,
		}
	}
}

// Implements ipv6.NDPDispatcher.OnRecursiveDNSServerOption.
func (n *ndpDispatcher) OnRecursiveDNSServerOption(nicID tcpip.NICID, addrs []tcpip.Address, lifetime time.Duration) {
	if c := n.rdnssC; c != nil {
		c <- ndpRDNSSEvent{
			nicID,
			ndpRDNSS{
				addrs,
				lifetime,
			},
		}
	}
}

// Implements ipv6.NDPDispatcher.OnDNSSearchListOption.
func (n *ndpDispatcher) OnDNSSearchListOption(nicID tcpip.NICID, domainNames []string, lifetime time.Duration) {
	if n.dnsslC != nil {
		n.dnsslC <- ndpDNSSLEvent{
			nicID,
			domainNames,
			lifetime,
		}
	}
}

// Implements ipv6.NDPDispatcher.OnDHCPv6Configuration.
func (n *ndpDispatcher) OnDHCPv6Configuration(nicID tcpip.NICID, configuration ipv6.DHCPv6ConfigurationFromNDPRA) {
	if c := n.dhcpv6ConfigurationC; c != nil {
		c <- ndpDHCPv6Event{
			nicID,
			configuration,
		}
	}
}

// channelLinkWithHeaderLength is a channel.Endpoint with a configurable
// header length.
type channelLinkWithHeaderLength struct {
	*channel.Endpoint
	headerLength uint16
}

func (l *channelLinkWithHeaderLength) MaxHeaderLength() uint16 {
	return l.headerLength
}

// Check e to make sure that the event is for addr on nic with ID 1, and the
// resolved flag set to resolved with the specified err.
func checkDADEvent(e ndpDADEvent, nicID tcpip.NICID, addr tcpip.Address, res stack.DADResult) string {
	return cmp.Diff(ndpDADEvent{nicID: nicID, addr: addr, res: res}, e, cmp.AllowUnexported(e))
}

// TestDADDisabled tests that an address successfully resolves immediately
// when DAD is not enabled (the default for an empty stack.Options).
func TestDADDisabled(t *testing.T) {
	const nicID = 1
	ndpDisp := ndpDispatcher{
		dadC: make(chan ndpDADEvent, 1),
	}
	e := channel.New(0, 1280, linkAddr1)
	s := stack.New(stack.Options{
		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
			NDPDisp: &ndpDisp,
		})},
	})
	if err := s.CreateNIC(nicID, e); err != nil {
		t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
	}

	addrWithPrefix := tcpip.AddressWithPrefix{
		Address:   addr1,
		PrefixLen: defaultPrefixLen,
	}
	if err := s.AddAddressWithPrefix(nicID, header.IPv6ProtocolNumber, addrWithPrefix); err != nil {
		t.Fatalf("AddAddressWithPrefix(%d, %d, %s) = %s", nicID, header.IPv6ProtocolNumber, addrWithPrefix, err)
	}

	// Should get the address immediately since we should not have performed
	// DAD on it.
	select {
	case e := <-ndpDisp.dadC:
		if diff := checkDADEvent(e, nicID, addr1, &stack.DADSucceeded{}); diff != "" {
			t.Errorf("DAD event mismatch (-want +got):\n%s", diff)
		}
	default:
		t.Fatal("expected DAD event")
	}
	if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, addrWithPrefix); err != nil {
		t.Fatal(err)
	}

	// We should not have sent any NDP NS messages.
	if got := s.Stats().ICMP.V6.PacketsSent.NeighborSolicit.Value(); got != 0 {
		t.Fatalf("got NeighborSolicit = %d, want = 0", got)
	}
}

func TestDADResolveLoopback(t *testing.T) {
	const nicID = 1
	ndpDisp := ndpDispatcher{
		dadC: make(chan ndpDADEvent, 1),
	}

	dadConfigs := stack.DADConfigurations{
		RetransmitTimer:        time.Second,
		DupAddrDetectTransmits: 1,
	}
	clock := faketime.NewManualClock()
	s := stack.New(stack.Options{
		Clock: clock,
		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
			NDPDisp:    &ndpDisp,
			DADConfigs: dadConfigs,
		})},
	})
	if err := s.CreateNIC(nicID, loopback.New()); err != nil {
		t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
	}

	addrWithPrefix := tcpip.AddressWithPrefix{
		Address:   addr1,
		PrefixLen: defaultPrefixLen,
	}
	if err := s.AddAddressWithPrefix(nicID, header.IPv6ProtocolNumber, addrWithPrefix); err != nil {
		t.Fatalf("AddAddressWithPrefix(%d, %d, %s) = %s", nicID, header.IPv6ProtocolNumber, addrWithPrefix, err)
	}

	// Address should not be considered bound to the NIC yet (DAD ongoing).
	if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil {
		t.Fatal(err)
	}

	// DAD should not resolve after the normal resolution time since our DAD
	// message was looped back - we should extend our DAD process.
	dadResolutionTime := time.Duration(dadConfigs.DupAddrDetectTransmits) * dadConfigs.RetransmitTimer
	clock.Advance(dadResolutionTime)
	if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil {
		t.Error(err)
	}

	// Make sure the address does not resolve before the extended resolution time
	// has passed.
	const delta = time.Nanosecond
	// DAD will send extra NS probes if an NS message is looped back.
	const extraTransmits = 3
	clock.Advance(dadResolutionTime*extraTransmits - delta)
	if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil {
		t.Error(err)
	}

	// DAD should now resolve.
	clock.Advance(delta)
	if diff := checkDADEvent(<-ndpDisp.dadC, nicID, addr1, &stack.DADSucceeded{}); diff != "" {
		t.Errorf("DAD event mismatch (-want +got):\n%s", diff)
	}
}

// TestDADResolve tests that an address successfully resolves after performing
// DAD for various values of DupAddrDetectTransmits and RetransmitTimer.
// Included in the subtests is a test to make sure that an invalid
// RetransmitTimer (<1ms) values get fixed to the default RetransmitTimer of 1s.
// This tests also validates the NDP NS packet that is transmitted.
func TestDADResolve(t *testing.T) {
	const nicID = 1

	tests := []struct {
		name                    string
		linkHeaderLen           uint16
		dupAddrDetectTransmits  uint8
		retransTimer            time.Duration
		expectedRetransmitTimer time.Duration
	}{
		{
			name:                    "1:1s:1s",
			dupAddrDetectTransmits:  1,
			retransTimer:            time.Second,
			expectedRetransmitTimer: time.Second,
		},
		{
			name:                    "2:1s:1s",
			linkHeaderLen:           1,
			dupAddrDetectTransmits:  2,
			retransTimer:            time.Second,
			expectedRetransmitTimer: time.Second,
		},
		{
			name:                    "1:2s:2s",
			linkHeaderLen:           2,
			dupAddrDetectTransmits:  1,
			retransTimer:            2 * time.Second,
			expectedRetransmitTimer: 2 * time.Second,
		},
		// 0s is an invalid RetransmitTimer timer and will be fixed to
		// the default RetransmitTimer value of 1s.
		{
			name:                    "1:0s:1s",
			linkHeaderLen:           3,
			dupAddrDetectTransmits:  1,
			retransTimer:            0,
			expectedRetransmitTimer: time.Second,
		},
	}

	nonces := [][]byte{
		{1, 2, 3, 4, 5, 6},
		{7, 8, 9, 10, 11, 12},
	}

	var secureRNGBytes []byte
	for _, n := range nonces {
		secureRNGBytes = append(secureRNGBytes, n...)
	}

	for _, test := range tests {
		test := test

		t.Run(test.name, func(t *testing.T) {
			t.Parallel()

			ndpDisp := ndpDispatcher{
				dadC: make(chan ndpDADEvent),
			}

			e := channelLinkWithHeaderLength{
				Endpoint:     channel.New(int(test.dupAddrDetectTransmits), 1280, linkAddr1),
				headerLength: test.linkHeaderLen,
			}
			e.Endpoint.LinkEPCapabilities |= stack.CapabilityResolutionRequired

			var secureRNG bytes.Reader
			secureRNG.Reset(secureRNGBytes)

			s := stack.New(stack.Options{
				SecureRNG: &secureRNG,
				NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
					NDPDisp: &ndpDisp,
					DADConfigs: stack.DADConfigurations{
						RetransmitTimer:        test.retransTimer,
						DupAddrDetectTransmits: test.dupAddrDetectTransmits,
					},
				})},
			})
			if err := s.CreateNIC(nicID, &e); err != nil {
				t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
			}

			// We add a default route so the call to FindRoute below will succeed
			// once we have an assigned address.
			s.SetRouteTable([]tcpip.Route{{
				Destination: header.IPv6EmptySubnet,
				Gateway:     addr3,
				NIC:         nicID,
			}})

			addrWithPrefix := tcpip.AddressWithPrefix{
				Address:   addr1,
				PrefixLen: defaultPrefixLen,
			}
			if err := s.AddAddressWithPrefix(nicID, header.IPv6ProtocolNumber, addrWithPrefix); err != nil {
				t.Fatalf("AddAddressWithPrefix(%d, %d, %s) = %s", nicID, header.IPv6ProtocolNumber, addrWithPrefix, err)
			}

			// Address should not be considered bound to the NIC yet (DAD ongoing).
			if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil {
				t.Fatal(err)
			}

			// Make sure the address does not resolve before the resolution time has
			// passed.
			time.Sleep(test.expectedRetransmitTimer*time.Duration(test.dupAddrDetectTransmits) - defaultAsyncNegativeEventTimeout)
			if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil {
				t.Error(err)
			}
			// Should not get a route even if we specify the local address as the
			// tentative address.
			{
				r, err := s.FindRoute(nicID, "", addr2, header.IPv6ProtocolNumber, false)
				if _, ok := err.(*tcpip.ErrNoRoute); !ok {
					t.Errorf("got FindRoute(%d, '', %s, %d, false) = (%+v, %v), want = (_, %s)", nicID, addr2, header.IPv6ProtocolNumber, r, err, &tcpip.ErrNoRoute{})
				}
				if r != nil {
					r.Release()
				}
			}
			{
				r, err := s.FindRoute(nicID, addr1, addr2, header.IPv6ProtocolNumber, false)
				if _, ok := err.(*tcpip.ErrNoRoute); !ok {
					t.Errorf("got FindRoute(%d, %s, %s, %d, false) = (%+v, %v), want = (_, %s)", nicID, addr1, addr2, header.IPv6ProtocolNumber, r, err, &tcpip.ErrNoRoute{})
				}
				if r != nil {
					r.Release()
				}
			}

			if t.Failed() {
				t.FailNow()
			}

			// Wait for DAD to resolve.
			select {
			case <-time.After(defaultAsyncPositiveEventTimeout):
				t.Fatal("timed out waiting for DAD resolution")
			case e := <-ndpDisp.dadC:
				if diff := checkDADEvent(e, nicID, addr1, &stack.DADSucceeded{}); diff != "" {
					t.Errorf("DAD event mismatch (-want +got):\n%s", diff)
				}
			}
			if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, addrWithPrefix); err != nil {
				t.Error(err)
			}
			// Should get a route using the address now that it is resolved.
			{
				r, err := s.FindRoute(nicID, "", addr2, header.IPv6ProtocolNumber, false)
				if err != nil {
					t.Errorf("got FindRoute(%d, '', %s, %d, false): %s", nicID, addr2, header.IPv6ProtocolNumber, err)
				} else if r.LocalAddress != addr1 {
					t.Errorf("got r.LocalAddress = %s, want = %s", r.LocalAddress, addr1)
				}
				r.Release()
			}
			{
				r, err := s.FindRoute(nicID, addr1, addr2, header.IPv6ProtocolNumber, false)
				if err != nil {
					t.Errorf("got FindRoute(%d, %s, %s, %d, false): %s", nicID, addr1, addr2, header.IPv6ProtocolNumber, err)
				} else if r.LocalAddress != addr1 {
					t.Errorf("got r.LocalAddress = %s, want = %s", r.LocalAddress, addr1)
				}
				if r != nil {
					r.Release()
				}
			}

			if t.Failed() {
				t.FailNow()
			}

			// Should not have sent any more NS messages.
			if got := s.Stats().ICMP.V6.PacketsSent.NeighborSolicit.Value(); got != uint64(test.dupAddrDetectTransmits) {
				t.Fatalf("got NeighborSolicit = %d, want = %d", got, test.dupAddrDetectTransmits)
			}

			// Validate the sent Neighbor Solicitation messages.
			for i := uint8(0); i < test.dupAddrDetectTransmits; i++ {
				p, _ := e.ReadContext(context.Background())

				// Make sure its an IPv6 packet.
				if p.Proto != header.IPv6ProtocolNumber {
					t.Fatalf("got Proto = %d, want = %d", p.Proto, header.IPv6ProtocolNumber)
				}

				// Make sure the right remote link address is used.
				snmc := header.SolicitedNodeAddr(addr1)
				if want := header.EthernetAddressFromMulticastIPv6Address(snmc); p.Route.RemoteLinkAddress != want {
					t.Errorf("got remote link address = %s, want = %s", p.Route.RemoteLinkAddress, want)
				}

				// Check NDP NS packet.
				//
				// As per RFC 4861 section 4.3, a possible option is the Source Link
				// Layer option, but this option MUST NOT be included when the source
				// address of the packet is the unspecified address.
				checker.IPv6(t, stack.PayloadSince(p.Pkt.NetworkHeader()),
					checker.SrcAddr(header.IPv6Any),
					checker.DstAddr(snmc),
					checker.TTL(header.NDPHopLimit),
					checker.NDPNS(
						checker.NDPNSTargetAddress(addr1),
						checker.NDPNSOptions([]header.NDPOption{header.NDPNonceOption(nonces[i])}),
					))

				if l, want := p.Pkt.AvailableHeaderBytes(), int(test.linkHeaderLen); l != want {
					t.Errorf("got p.Pkt.AvailableHeaderBytes() = %d; want = %d", l, want)
				}
			}
		})
	}
}

func rxNDPSolicit(e *channel.Endpoint, tgt tcpip.Address) {
	hdr := buffer.NewPrependable(header.IPv6MinimumSize + header.ICMPv6NeighborSolicitMinimumSize)
	pkt := header.ICMPv6(hdr.Prepend(header.ICMPv6NeighborSolicitMinimumSize))
	pkt.SetType(header.ICMPv6NeighborSolicit)
	ns := header.NDPNeighborSolicit(pkt.MessageBody())
	ns.SetTargetAddress(tgt)
	snmc := header.SolicitedNodeAddr(tgt)
	pkt.SetChecksum(header.ICMPv6Checksum(header.ICMPv6ChecksumParams{
		Header: pkt,
		Src:    header.IPv6Any,
		Dst:    snmc,
	}))
	payloadLength := hdr.UsedLength()
	ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize))
	ip.Encode(&header.IPv6Fields{
		PayloadLength:     uint16(payloadLength),
		TransportProtocol: icmp.ProtocolNumber6,
		HopLimit:          255,
		SrcAddr:           header.IPv6Any,
		DstAddr:           snmc,
	})
	e.InjectInbound(header.IPv6ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{Data: hdr.View().ToVectorisedView()}))
}

// TestDADFail tests to make sure that the DAD process fails if another node is
// detected to be performing DAD on the same address (receive an NS message from
// a node doing DAD for the same address), or if another node is detected to own
// the address already (receive an NA message for the tentative address).
func TestDADFail(t *testing.T) {
	const nicID = 1

	tests := []struct {
		name                      string
		rxPkt                     func(e *channel.Endpoint, tgt tcpip.Address)
		getStat                   func(s tcpip.ICMPv6ReceivedPacketStats) *tcpip.StatCounter
		expectedHolderLinkAddress tcpip.LinkAddress
	}{
		{
			name:  "RxSolicit",
			rxPkt: rxNDPSolicit,
			getStat: func(s tcpip.ICMPv6ReceivedPacketStats) *tcpip.StatCounter {
				return s.NeighborSolicit
			},
			expectedHolderLinkAddress: "",
		},
		{
			name: "RxAdvert",
			rxPkt: func(e *channel.Endpoint, tgt tcpip.Address) {
				naSize := header.ICMPv6NeighborAdvertMinimumSize + header.NDPLinkLayerAddressSize
				hdr := buffer.NewPrependable(header.IPv6MinimumSize + naSize)
				pkt := header.ICMPv6(hdr.Prepend(naSize))
				pkt.SetType(header.ICMPv6NeighborAdvert)
				na := header.NDPNeighborAdvert(pkt.MessageBody())
				na.SetSolicitedFlag(true)
				na.SetOverrideFlag(true)
				na.SetTargetAddress(tgt)
				na.Options().Serialize(header.NDPOptionsSerializer{
					header.NDPTargetLinkLayerAddressOption(linkAddr1),
				})
				pkt.SetChecksum(header.ICMPv6Checksum(header.ICMPv6ChecksumParams{
					Header: pkt,
					Src:    tgt,
					Dst:    header.IPv6AllNodesMulticastAddress,
				}))
				payloadLength := hdr.UsedLength()
				ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize))
				ip.Encode(&header.IPv6Fields{
					PayloadLength:     uint16(payloadLength),
					TransportProtocol: icmp.ProtocolNumber6,
					HopLimit:          255,
					SrcAddr:           tgt,
					DstAddr:           header.IPv6AllNodesMulticastAddress,
				})
				e.InjectInbound(header.IPv6ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{Data: hdr.View().ToVectorisedView()}))
			},
			getStat: func(s tcpip.ICMPv6ReceivedPacketStats) *tcpip.StatCounter {
				return s.NeighborAdvert
			},
			expectedHolderLinkAddress: linkAddr1,
		},
	}

	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			ndpDisp := ndpDispatcher{
				dadC: make(chan ndpDADEvent, 1),
			}
			dadConfigs := stack.DefaultDADConfigurations()
			dadConfigs.RetransmitTimer = time.Second * 2

			e := channel.New(0, 1280, linkAddr1)
			s := stack.New(stack.Options{
				NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
					NDPDisp:    &ndpDisp,
					DADConfigs: dadConfigs,
				})},
			})
			if err := s.CreateNIC(nicID, e); err != nil {
				t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
			}

			if err := s.AddAddress(nicID, header.IPv6ProtocolNumber, addr1); err != nil {
				t.Fatalf("AddAddress(%d, %d, %s) = %s", nicID, header.IPv6ProtocolNumber, addr1, err)
			}

			// Address should not be considered bound to the NIC yet
			// (DAD ongoing).
			if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil {
				t.Fatal(err)
			}

			// Receive a packet to simulate an address conflict.
			test.rxPkt(e, addr1)

			stat := test.getStat(s.Stats().ICMP.V6.PacketsReceived)
			if got := stat.Value(); got != 1 {
				t.Fatalf("got stat = %d, want = 1", got)
			}

			// Wait for DAD to fail and make sure the address did
			// not get resolved.
			select {
			case <-time.After(time.Duration(dadConfigs.DupAddrDetectTransmits)*dadConfigs.RetransmitTimer + time.Second):
				// If we don't get a failure event after the
				// expected resolution time + extra 1s buffer,
				// something is wrong.
				t.Fatal("timed out waiting for DAD failure")
			case e := <-ndpDisp.dadC:
				if diff := checkDADEvent(e, nicID, addr1, &stack.DADDupAddrDetected{HolderLinkAddress: test.expectedHolderLinkAddress}); diff != "" {
					t.Errorf("DAD event mismatch (-want +got):\n%s", diff)
				}
			}
			if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil {
				t.Fatal(err)
			}

			// Attempting to add the address again should not fail if the address's
			// state was cleaned up when DAD failed.
			if err := s.AddAddress(nicID, header.IPv6ProtocolNumber, addr1); err != nil {
				t.Fatalf("AddAddress(%d, %d, %s) = %s", nicID, header.IPv6ProtocolNumber, addr1, err)
			}
		})
	}
}

func TestDADStop(t *testing.T) {
	const nicID = 1

	tests := []struct {
		name               string
		stopFn             func(t *testing.T, s *stack.Stack)
		skipFinalAddrCheck bool
	}{
		// Tests to make sure that DAD stops when an address is removed.
		{
			name: "Remove address",
			stopFn: func(t *testing.T, s *stack.Stack) {
				if err := s.RemoveAddress(nicID, addr1); err != nil {
					t.Fatalf("RemoveAddress(%d, %s): %s", nicID, addr1, err)
				}
			},
		},

		// Tests to make sure that DAD stops when the NIC is disabled.
		{
			name: "Disable NIC",
			stopFn: func(t *testing.T, s *stack.Stack) {
				if err := s.DisableNIC(nicID); err != nil {
					t.Fatalf("DisableNIC(%d): %s", nicID, err)
				}
			},
		},

		// Tests to make sure that DAD stops when the NIC is removed.
		{
			name: "Remove NIC",
			stopFn: func(t *testing.T, s *stack.Stack) {
				if err := s.RemoveNIC(nicID); err != nil {
					t.Fatalf("RemoveNIC(%d): %s", nicID, err)
				}
			},
			// The NIC is removed so we can't check its addresses after calling
			// stopFn.
			skipFinalAddrCheck: true,
		},
	}

	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			ndpDisp := ndpDispatcher{
				dadC: make(chan ndpDADEvent, 1),
			}

			dadConfigs := stack.DADConfigurations{
				RetransmitTimer:        time.Second,
				DupAddrDetectTransmits: 2,
			}

			e := channel.New(0, 1280, linkAddr1)
			s := stack.New(stack.Options{
				NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
					NDPDisp:    &ndpDisp,
					DADConfigs: dadConfigs,
				})},
			})
			if err := s.CreateNIC(nicID, e); err != nil {
				t.Fatalf("CreateNIC(%d, _): %s", nicID, err)
			}

			if err := s.AddAddress(nicID, header.IPv6ProtocolNumber, addr1); err != nil {
				t.Fatalf("AddAddress(%d, %d, %s): %s", nicID, header.IPv6ProtocolNumber, addr1, err)
			}

			// Address should not be considered bound to the NIC yet (DAD ongoing).
			if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil {
				t.Fatal(err)
			}

			test.stopFn(t, s)

			// Wait for DAD to fail (since the address was removed during DAD).
			select {
			case <-time.After(time.Duration(dadConfigs.DupAddrDetectTransmits)*dadConfigs.RetransmitTimer + time.Second):
				// If we don't get a failure event after the expected resolution
				// time + extra 1s buffer, something is wrong.
				t.Fatal("timed out waiting for DAD failure")
			case e := <-ndpDisp.dadC:
				if diff := checkDADEvent(e, nicID, addr1, &stack.DADAborted{}); diff != "" {
					t.Errorf("DAD event mismatch (-want +got):\n%s", diff)
				}
			}

			if !test.skipFinalAddrCheck {
				if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil {
					t.Fatal(err)
				}
			}

			// Should not have sent more than 1 NS message.
			if got := s.Stats().ICMP.V6.PacketsSent.NeighborSolicit.Value(); got > 1 {
				t.Errorf("got NeighborSolicit = %d, want <= 1", got)
			}
		})
	}
}

// TestSetNDPConfigurations tests that we can update and use per-interface NDP
// configurations without affecting the default NDP configurations or other
// interfaces' configurations.
func TestSetNDPConfigurations(t *testing.T) {
	const nicID1 = 1
	const nicID2 = 2
	const nicID3 = 3

	tests := []struct {
		name                    string
		dupAddrDetectTransmits  uint8
		retransmitTimer         time.Duration
		expectedRetransmitTimer time.Duration
	}{
		{
			"OK",
			1,
			time.Second,
			time.Second,
		},
		{
			"Invalid Retransmit Timer",
			1,
			0,
			time.Second,
		},
	}

	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			ndpDisp := ndpDispatcher{
				dadC: make(chan ndpDADEvent, 1),
			}
			e := channel.New(0, 1280, linkAddr1)
			s := stack.New(stack.Options{
				NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
					NDPDisp: &ndpDisp,
				})},
			})

			expectDADEvent := func(nicID tcpip.NICID, addr tcpip.Address) {
				select {
				case e := <-ndpDisp.dadC:
					if diff := checkDADEvent(e, nicID, addr, &stack.DADSucceeded{}); diff != "" {
						t.Errorf("DAD event mismatch (-want +got):\n%s", diff)
					}
				default:
					t.Fatalf("expected DAD event for %s", addr)
				}
			}

			// This NIC(1)'s NDP configurations will be updated to
			// be different from the default.
			if err := s.CreateNIC(nicID1, e); err != nil {
				t.Fatalf("CreateNIC(%d, _) = %s", nicID1, err)
			}

			// Created before updating NIC(1)'s NDP configurations
			// but updating NIC(1)'s NDP configurations should not
			// affect other existing NICs.
			if err := s.CreateNIC(nicID2, e); err != nil {
				t.Fatalf("CreateNIC(%d, _) = %s", nicID2, err)
			}

			// Update the configurations on NIC(1) to use DAD.
			if ipv6Ep, err := s.GetNetworkEndpoint(nicID1, header.IPv6ProtocolNumber); err != nil {
				t.Fatalf("s.GetNetworkEndpoint(%d, %d): %s", nicID1, header.IPv6ProtocolNumber, err)
			} else {
				dad := ipv6Ep.(stack.DuplicateAddressDetector)
				dad.SetDADConfigurations(stack.DADConfigurations{
					DupAddrDetectTransmits: test.dupAddrDetectTransmits,
					RetransmitTimer:        test.retransmitTimer,
				})
			}

			// Created after updating NIC(1)'s NDP configurations
			// but the stack's default NDP configurations should not
			// have been updated.
			if err := s.CreateNIC(nicID3, e); err != nil {
				t.Fatalf("CreateNIC(%d, _) = %s", nicID3, err)
			}

			// Add addresses for each NIC.
			addrWithPrefix1 := tcpip.AddressWithPrefix{Address: addr1, PrefixLen: defaultPrefixLen}
			if err := s.AddAddressWithPrefix(nicID1, header.IPv6ProtocolNumber, addrWithPrefix1); err != nil {
				t.Fatalf("AddAddressWithPrefix(%d, %d, %s) = %s", nicID1, header.IPv6ProtocolNumber, addrWithPrefix1, err)
			}
			addrWithPrefix2 := tcpip.AddressWithPrefix{Address: addr2, PrefixLen: defaultPrefixLen}
			if err := s.AddAddressWithPrefix(nicID2, header.IPv6ProtocolNumber, addrWithPrefix2); err != nil {
				t.Fatalf("AddAddressWithPrefix(%d, %d, %s) = %s", nicID2, header.IPv6ProtocolNumber, addrWithPrefix2, err)
			}
			expectDADEvent(nicID2, addr2)
			addrWithPrefix3 := tcpip.AddressWithPrefix{Address: addr3, PrefixLen: defaultPrefixLen}
			if err := s.AddAddressWithPrefix(nicID3, header.IPv6ProtocolNumber, addrWithPrefix3); err != nil {
				t.Fatalf("AddAddressWithPrefix(%d, %d, %s) = %s", nicID3, header.IPv6ProtocolNumber, addrWithPrefix3, err)
			}
			expectDADEvent(nicID3, addr3)

			// Address should not be considered bound to NIC(1) yet
			// (DAD ongoing).
			if err := checkGetMainNICAddress(s, nicID1, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil {
				t.Fatal(err)
			}

			// Should get the address on NIC(2) and NIC(3)
			// immediately since we should not have performed DAD on
			// it as the stack was configured to not do DAD by
			// default and we only updated the NDP configurations on
			// NIC(1).
			if err := checkGetMainNICAddress(s, nicID2, header.IPv6ProtocolNumber, addrWithPrefix2); err != nil {
				t.Fatal(err)
			}
			if err := checkGetMainNICAddress(s, nicID3, header.IPv6ProtocolNumber, addrWithPrefix3); err != nil {
				t.Fatal(err)
			}

			// Sleep until right (500ms before) before resolution to
			// make sure the address didn't resolve on NIC(1) yet.
			const delta = 500 * time.Millisecond
			time.Sleep(time.Duration(test.dupAddrDetectTransmits)*test.expectedRetransmitTimer - delta)
			if err := checkGetMainNICAddress(s, nicID1, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil {
				t.Fatal(err)
			}

			// Wait for DAD to resolve.
			select {
			case <-time.After(2 * delta):
				// We should get a resolution event after 500ms
				// (delta) since we wait for 500ms less than the
				// expected resolution time above to make sure
				// that the address did not yet resolve. Waiting
				// for 1s (2x delta) without a resolution event
				// means something is wrong.
				t.Fatal("timed out waiting for DAD resolution")
			case e := <-ndpDisp.dadC:
				if diff := checkDADEvent(e, nicID1, addr1, &stack.DADSucceeded{}); diff != "" {
					t.Errorf("DAD event mismatch (-want +got):\n%s", diff)
				}
			}
			if err := checkGetMainNICAddress(s, nicID1, header.IPv6ProtocolNumber, addrWithPrefix1); err != nil {
				t.Fatal(err)
			}
		})
	}
}

// raBufWithOptsAndDHCPv6 returns a valid NDP Router Advertisement with options
// and DHCPv6 configurations specified.
func raBufWithOptsAndDHCPv6(ip tcpip.Address, rl uint16, managedAddress, otherConfigurations bool, optSer header.NDPOptionsSerializer) *stack.PacketBuffer {
	icmpSize := header.ICMPv6HeaderSize + header.NDPRAMinimumSize + int(optSer.Length())
	hdr := buffer.NewPrependable(header.IPv6MinimumSize + icmpSize)
	pkt := header.ICMPv6(hdr.Prepend(icmpSize))
	pkt.SetType(header.ICMPv6RouterAdvert)
	pkt.SetCode(0)
	raPayload := pkt.MessageBody()
	ra := header.NDPRouterAdvert(raPayload)
	// Populate the Router Lifetime.
	binary.BigEndian.PutUint16(raPayload[2:], rl)
	// Populate the Managed Address flag field.
	if managedAddress {
		// The Managed Addresses flag field is the 7th bit of byte #1 (0-indexing)
		// of the RA payload.
		raPayload[1] |= (1 << 7)
	}
	// Populate the Other Configurations flag field.
	if otherConfigurations {
		// The Other Configurations flag field is the 6th bit of byte #1
		// (0-indexing) of the RA payload.
		raPayload[1] |= (1 << 6)
	}
	opts := ra.Options()
	opts.Serialize(optSer)
	pkt.SetChecksum(header.ICMPv6Checksum(header.ICMPv6ChecksumParams{
		Header: pkt,
		Src:    ip,
		Dst:    header.IPv6AllNodesMulticastAddress,
	}))
	payloadLength := hdr.UsedLength()
	iph := header.IPv6(hdr.Prepend(header.IPv6MinimumSize))
	iph.Encode(&header.IPv6Fields{
		PayloadLength:     uint16(payloadLength),
		TransportProtocol: icmp.ProtocolNumber6,
		HopLimit:          header.NDPHopLimit,
		SrcAddr:           ip,
		DstAddr:           header.IPv6AllNodesMulticastAddress,
	})

	return stack.NewPacketBuffer(stack.PacketBufferOptions{
		Data: hdr.View().ToVectorisedView(),
	})
}

// raBufWithOpts returns a valid NDP Router Advertisement with options.
//
// Note, raBufWithOpts does not populate any of the RA fields other than the
// Router Lifetime.
func raBufWithOpts(ip tcpip.Address, rl uint16, optSer header.NDPOptionsSerializer) *stack.PacketBuffer {
	return raBufWithOptsAndDHCPv6(ip, rl, false, false, optSer)
}

// raBufWithDHCPv6 returns a valid NDP Router Advertisement with DHCPv6 related
// fields set.
//
// Note, raBufWithDHCPv6 does not populate any of the RA fields other than the
// DHCPv6 related ones.
func raBufWithDHCPv6(ip tcpip.Address, managedAddresses, otherConfiguratiosns bool) *stack.PacketBuffer {
	return raBufWithOptsAndDHCPv6(ip, 0, managedAddresses, otherConfiguratiosns, header.NDPOptionsSerializer{})
}

// raBuf returns a valid NDP Router Advertisement.
//
// Note, raBuf does not populate any of the RA fields other than the
// Router Lifetime.
func raBuf(ip tcpip.Address, rl uint16) *stack.PacketBuffer {
	return raBufWithOpts(ip, rl, header.NDPOptionsSerializer{})
}

// raBufWithPI returns a valid NDP Router Advertisement with a single Prefix
// Information option.
//
// Note, raBufWithPI does not populate any of the RA fields other than the
// Router Lifetime.
func raBufWithPI(ip tcpip.Address, rl uint16, prefix tcpip.AddressWithPrefix, onLink, auto bool, vl, pl uint32) *stack.PacketBuffer {
	flags := uint8(0)
	if onLink {
		// The OnLink flag is the 7th bit in the flags byte.
		flags |= 1 << 7
	}
	if auto {
		// The Address Auto-Configuration flag is the 6th bit in the
		// flags byte.
		flags |= 1 << 6
	}

	// A valid header.NDPPrefixInformation must be 30 bytes.
	buf := [30]byte{}
	// The first byte in a header.NDPPrefixInformation is the Prefix Length
	// field.
	buf[0] = uint8(prefix.PrefixLen)
	// The 2nd byte within a header.NDPPrefixInformation is the Flags field.
	buf[1] = flags
	// The Valid Lifetime field starts after the 2nd byte within a
	// header.NDPPrefixInformation.
	binary.BigEndian.PutUint32(buf[2:], vl)
	// The Preferred Lifetime field starts after the 6th byte within a
	// header.NDPPrefixInformation.
	binary.BigEndian.PutUint32(buf[6:], pl)
	// The Prefix Address field starts after the 14th byte within a
	// header.NDPPrefixInformation.
	copy(buf[14:], prefix.Address)
	return raBufWithOpts(ip, rl, header.NDPOptionsSerializer{
		header.NDPPrefixInformation(buf[:]),
	})
}

// TestNoRouterDiscovery tests that router discovery will not be performed if
// configured not to.
func TestNoRouterDiscovery(t *testing.T) {
	// Being configured to discover routers means handle and
	// discover are set to true and forwarding is set to false.
	// This tests all possible combinations of the configurations,
	// except for the configuration where handle = true, discover =
	// true and forwarding = false (the required configuration to do
	// router discovery) - that will done in other tests.
	for i := 0; i < 7; i++ {
		handle := i&1 != 0
		discover := i&2 != 0
		forwarding := i&4 == 0

		t.Run(fmt.Sprintf("HandleRAs(%t), DiscoverDefaultRouters(%t), Forwarding(%t)", handle, discover, forwarding), func(t *testing.T) {
			ndpDisp := ndpDispatcher{
				routerC: make(chan ndpRouterEvent, 1),
			}
			e := channel.New(0, 1280, linkAddr1)
			s := stack.New(stack.Options{
				NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
					NDPConfigs: ipv6.NDPConfigurations{
						HandleRAs:              handle,
						DiscoverDefaultRouters: discover,
					},
					NDPDisp: &ndpDisp,
				})},
			})
			s.SetForwarding(ipv6.ProtocolNumber, forwarding)

			if err := s.CreateNIC(1, e); err != nil {
				t.Fatalf("CreateNIC(1) = %s", err)
			}

			// Rx an RA with non-zero lifetime.
			e.InjectInbound(header.IPv6ProtocolNumber, raBuf(llAddr2, 1000))
			select {
			case <-ndpDisp.routerC:
				t.Fatal("unexpectedly discovered a router when configured not to")
			default:
			}
		})
	}
}

// Check e to make sure that the event is for addr on nic with ID 1, and the
// discovered flag set to discovered.
func checkRouterEvent(e ndpRouterEvent, addr tcpip.Address, discovered bool) string {
	return cmp.Diff(ndpRouterEvent{nicID: 1, addr: addr, discovered: discovered}, e, cmp.AllowUnexported(e))
}

// TestRouterDiscoveryDispatcherNoRemember tests that the stack does not
// remember a discovered router when the dispatcher asks it not to.
func TestRouterDiscoveryDispatcherNoRemember(t *testing.T) {
	ndpDisp := ndpDispatcher{
		routerC: make(chan ndpRouterEvent, 1),
	}
	e := channel.New(0, 1280, linkAddr1)
	s := stack.New(stack.Options{
		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
			NDPConfigs: ipv6.NDPConfigurations{
				HandleRAs:              true,
				DiscoverDefaultRouters: true,
			},
			NDPDisp: &ndpDisp,
		})},
	})

	if err := s.CreateNIC(1, e); err != nil {
		t.Fatalf("CreateNIC(1) = %s", err)
	}

	// Receive an RA for a router we should not remember.
	const lifetimeSeconds = 1
	e.InjectInbound(header.IPv6ProtocolNumber, raBuf(llAddr2, lifetimeSeconds))
	select {
	case e := <-ndpDisp.routerC:
		if diff := checkRouterEvent(e, llAddr2, true); diff != "" {
			t.Errorf("router event mismatch (-want +got):\n%s", diff)
		}
	default:
		t.Fatal("expected router discovery event")
	}

	// Wait for the invalidation time plus some buffer to make sure we do
	// not actually receive any invalidation events as we should not have
	// remembered the router in the first place.
	select {
	case <-ndpDisp.routerC:
		t.Fatal("should not have received any router events")
	case <-time.After(lifetimeSeconds*time.Second + defaultAsyncNegativeEventTimeout):
	}
}

func TestRouterDiscovery(t *testing.T) {
	ndpDisp := ndpDispatcher{
		routerC:        make(chan ndpRouterEvent, 1),
		rememberRouter: true,
	}
	e := channel.New(0, 1280, linkAddr1)
	s := stack.New(stack.Options{
		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
			NDPConfigs: ipv6.NDPConfigurations{
				HandleRAs:              true,
				DiscoverDefaultRouters: true,
			},
			NDPDisp: &ndpDisp,
		})},
	})

	expectRouterEvent := func(addr tcpip.Address, discovered bool) {
		t.Helper()

		select {
		case e := <-ndpDisp.routerC:
			if diff := checkRouterEvent(e, addr, discovered); diff != "" {
				t.Errorf("router event mismatch (-want +got):\n%s", diff)
			}
		default:
			t.Fatal("expected router discovery event")
		}
	}

	expectAsyncRouterInvalidationEvent := func(addr tcpip.Address, timeout time.Duration) {
		t.Helper()

		select {
		case e := <-ndpDisp.routerC:
			if diff := checkRouterEvent(e, addr, false); diff != "" {
				t.Errorf("router event mismatch (-want +got):\n%s", diff)
			}
		case <-time.After(timeout):
			t.Fatal("timed out waiting for router discovery event")
		}
	}

	if err := s.CreateNIC(1, e); err != nil {
		t.Fatalf("CreateNIC(1) = %s", err)
	}

	// Rx an RA from lladdr2 with zero lifetime. It should not be
	// remembered.
	e.InjectInbound(header.IPv6ProtocolNumber, raBuf(llAddr2, 0))
	select {
	case <-ndpDisp.routerC:
		t.Fatal("unexpectedly discovered a router with 0 lifetime")
	default:
	}

	// Rx an RA from lladdr2 with a huge lifetime.
	e.InjectInbound(header.IPv6ProtocolNumber, raBuf(llAddr2, 1000))
	expectRouterEvent(llAddr2, true)

	// Rx an RA from another router (lladdr3) with non-zero lifetime.
	const l3LifetimeSeconds = 6
	e.InjectInbound(header.IPv6ProtocolNumber, raBuf(llAddr3, l3LifetimeSeconds))
	expectRouterEvent(llAddr3, true)

	// Rx an RA from lladdr2 with lesser lifetime.
	const l2LifetimeSeconds = 2
	e.InjectInbound(header.IPv6ProtocolNumber, raBuf(llAddr2, l2LifetimeSeconds))
	select {
	case <-ndpDisp.routerC:
		t.Fatal("Should not receive a router event when updating lifetimes for known routers")
	default:
	}

	// Wait for lladdr2's router invalidation job to execute. The lifetime
	// of the router should have been updated to the most recent (smaller)
	// lifetime.
	//
	// Wait for the normal lifetime plus an extra bit for the
	// router to get invalidated. If we don't get an invalidation
	// event after this time, then something is wrong.
	expectAsyncRouterInvalidationEvent(llAddr2, l2LifetimeSeconds*time.Second+defaultAsyncPositiveEventTimeout)

	// Rx an RA from lladdr2 with huge lifetime.
	e.InjectInbound(header.IPv6ProtocolNumber, raBuf(llAddr2, 1000))
	expectRouterEvent(llAddr2, true)

	// Rx an RA from lladdr2 with zero lifetime. It should be invalidated.
	e.InjectInbound(header.IPv6ProtocolNumber, raBuf(llAddr2, 0))
	expectRouterEvent(llAddr2, false)

	// Wait for lladdr3's router invalidation job to execute. The lifetime
	// of the router should have been updated to the most recent (smaller)
	// lifetime.
	//
	// Wait for the normal lifetime plus an extra bit for the
	// router to get invalidated. If we don't get an invalidation
	// event after this time, then something is wrong.
	expectAsyncRouterInvalidationEvent(llAddr3, l3LifetimeSeconds*time.Second+defaultAsyncPositiveEventTimeout)
}

// TestRouterDiscoveryMaxRouters tests that only
// ipv6.MaxDiscoveredDefaultRouters discovered routers are remembered.
func TestRouterDiscoveryMaxRouters(t *testing.T) {
	ndpDisp := ndpDispatcher{
		routerC:        make(chan ndpRouterEvent, 1),
		rememberRouter: true,
	}
	e := channel.New(0, 1280, linkAddr1)
	s := stack.New(stack.Options{
		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
			NDPConfigs: ipv6.NDPConfigurations{
				HandleRAs:              true,
				DiscoverDefaultRouters: true,
			},
			NDPDisp: &ndpDisp,
		})},
	})

	if err := s.CreateNIC(1, e); err != nil {
		t.Fatalf("CreateNIC(1) = %s", err)
	}

	// Receive an RA from 2 more than the max number of discovered routers.
	for i := 1; i <= ipv6.MaxDiscoveredDefaultRouters+2; i++ {
		linkAddr := []byte{2, 2, 3, 4, 5, 0}
		linkAddr[5] = byte(i)
		llAddr := header.LinkLocalAddr(tcpip.LinkAddress(linkAddr))

		e.InjectInbound(header.IPv6ProtocolNumber, raBuf(llAddr, 5))

		if i <= ipv6.MaxDiscoveredDefaultRouters {
			select {
			case e := <-ndpDisp.routerC:
				if diff := checkRouterEvent(e, llAddr, true); diff != "" {
					t.Errorf("router event mismatch (-want +got):\n%s", diff)
				}
			default:
				t.Fatal("expected router discovery event")
			}

		} else {
			select {
			case <-ndpDisp.routerC:
				t.Fatal("should not have discovered a new router after we already discovered the max number of routers")
			default:
			}
		}
	}
}

// TestNoPrefixDiscovery tests that prefix discovery will not be performed if
// configured not to.
func TestNoPrefixDiscovery(t *testing.T) {
	prefix := tcpip.AddressWithPrefix{
		Address:   tcpip.Address("\x01\x02\x03\x04\x05\x06\x07\x08\x00\x00\x00\x00\x00\x00\x00\x00"),
		PrefixLen: 64,
	}

	// Being configured to discover prefixes means handle and
	// discover are set to true and forwarding is set to false.
	// This tests all possible combinations of the configurations,
	// except for the configuration where handle = true, discover =
	// true and forwarding = false (the required configuration to do
	// prefix discovery) - that will done in other tests.
	for i := 0; i < 7; i++ {
		handle := i&1 != 0
		discover := i&2 != 0
		forwarding := i&4 == 0

		t.Run(fmt.Sprintf("HandleRAs(%t), DiscoverOnLinkPrefixes(%t), Forwarding(%t)", handle, discover, forwarding), func(t *testing.T) {
			ndpDisp := ndpDispatcher{
				prefixC: make(chan ndpPrefixEvent, 1),
			}
			e := channel.New(0, 1280, linkAddr1)
			s := stack.New(stack.Options{
				NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
					NDPConfigs: ipv6.NDPConfigurations{
						HandleRAs:              handle,
						DiscoverOnLinkPrefixes: discover,
					},
					NDPDisp: &ndpDisp,
				})},
			})
			s.SetForwarding(ipv6.ProtocolNumber, forwarding)

			if err := s.CreateNIC(1, e); err != nil {
				t.Fatalf("CreateNIC(1) = %s", err)
			}

			// Rx an RA with prefix with non-zero lifetime.
			e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, false, 10, 0))

			select {
			case <-ndpDisp.prefixC:
				t.Fatal("unexpectedly discovered a prefix when configured not to")
			default:
			}
		})
	}
}

// Check e to make sure that the event is for prefix on nic with ID 1, and the
// discovered flag set to discovered.
func checkPrefixEvent(e ndpPrefixEvent, prefix tcpip.Subnet, discovered bool) string {
	return cmp.Diff(ndpPrefixEvent{nicID: 1, prefix: prefix, discovered: discovered}, e, cmp.AllowUnexported(e))
}

// TestPrefixDiscoveryDispatcherNoRemember tests that the stack does not
// remember a discovered on-link prefix when the dispatcher asks it not to.
func TestPrefixDiscoveryDispatcherNoRemember(t *testing.T) {
	prefix, subnet, _ := prefixSubnetAddr(0, "")

	ndpDisp := ndpDispatcher{
		prefixC: make(chan ndpPrefixEvent, 1),
	}
	e := channel.New(0, 1280, linkAddr1)
	s := stack.New(stack.Options{
		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
			NDPConfigs: ipv6.NDPConfigurations{
				HandleRAs:              true,
				DiscoverDefaultRouters: false,
				DiscoverOnLinkPrefixes: true,
			},
			NDPDisp: &ndpDisp,
		})},
	})

	if err := s.CreateNIC(1, e); err != nil {
		t.Fatalf("CreateNIC(1) = %s", err)
	}

	// Receive an RA with prefix that we should not remember.
	const lifetimeSeconds = 1
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, false, lifetimeSeconds, 0))
	select {
	case e := <-ndpDisp.prefixC:
		if diff := checkPrefixEvent(e, subnet, true); diff != "" {
			t.Errorf("prefix event mismatch (-want +got):\n%s", diff)
		}
	default:
		t.Fatal("expected prefix discovery event")
	}

	// Wait for the invalidation time plus some buffer to make sure we do
	// not actually receive any invalidation events as we should not have
	// remembered the prefix in the first place.
	select {
	case <-ndpDisp.prefixC:
		t.Fatal("should not have received any prefix events")
	case <-time.After(lifetimeSeconds*time.Second + defaultAsyncNegativeEventTimeout):
	}
}

func TestPrefixDiscovery(t *testing.T) {
	prefix1, subnet1, _ := prefixSubnetAddr(0, "")
	prefix2, subnet2, _ := prefixSubnetAddr(1, "")
	prefix3, subnet3, _ := prefixSubnetAddr(2, "")

	ndpDisp := ndpDispatcher{
		prefixC:        make(chan ndpPrefixEvent, 1),
		rememberPrefix: true,
	}
	e := channel.New(0, 1280, linkAddr1)
	s := stack.New(stack.Options{
		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
			NDPConfigs: ipv6.NDPConfigurations{
				HandleRAs:              true,
				DiscoverOnLinkPrefixes: true,
			},
			NDPDisp: &ndpDisp,
		})},
	})

	if err := s.CreateNIC(1, e); err != nil {
		t.Fatalf("CreateNIC(1) = %s", err)
	}

	expectPrefixEvent := func(prefix tcpip.Subnet, discovered bool) {
		t.Helper()

		select {
		case e := <-ndpDisp.prefixC:
			if diff := checkPrefixEvent(e, prefix, discovered); diff != "" {
				t.Errorf("prefix event mismatch (-want +got):\n%s", diff)
			}
		default:
			t.Fatal("expected prefix discovery event")
		}
	}

	// Receive an RA with prefix1 in an NDP Prefix Information option (PI)
	// with zero valid lifetime.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, false, 0, 0))
	select {
	case <-ndpDisp.prefixC:
		t.Fatal("unexpectedly discovered a prefix with 0 lifetime")
	default:
	}

	// Receive an RA with prefix1 in an NDP Prefix Information option (PI)
	// with non-zero lifetime.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, false, 100, 0))
	expectPrefixEvent(subnet1, true)

	// Receive an RA with prefix2 in a PI.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix2, true, false, 100, 0))
	expectPrefixEvent(subnet2, true)

	// Receive an RA with prefix3 in a PI.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix3, true, false, 100, 0))
	expectPrefixEvent(subnet3, true)

	// Receive an RA with prefix1 in a PI with lifetime = 0.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, false, 0, 0))
	expectPrefixEvent(subnet1, false)

	// Receive an RA with prefix2 in a PI with lesser lifetime.
	lifetime := uint32(2)
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix2, true, false, lifetime, 0))
	select {
	case <-ndpDisp.prefixC:
		t.Fatal("unexpectedly received prefix event when updating lifetime")
	default:
	}

	// Wait for prefix2's most recent invalidation job plus some buffer to
	// expire.
	select {
	case e := <-ndpDisp.prefixC:
		if diff := checkPrefixEvent(e, subnet2, false); diff != "" {
			t.Errorf("prefix event mismatch (-want +got):\n%s", diff)
		}
	case <-time.After(time.Duration(lifetime)*time.Second + defaultAsyncPositiveEventTimeout):
		t.Fatal("timed out waiting for prefix discovery event")
	}

	// Receive RA to invalidate prefix3.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix3, true, false, 0, 0))
	expectPrefixEvent(subnet3, false)
}

func TestPrefixDiscoveryWithInfiniteLifetime(t *testing.T) {
	// Update the infinite lifetime value to a smaller value so we can test
	// that when we receive a PI with such a lifetime value, we do not
	// invalidate the prefix.
	const testInfiniteLifetimeSeconds = 2
	const testInfiniteLifetime = testInfiniteLifetimeSeconds * time.Second
	saved := header.NDPInfiniteLifetime
	header.NDPInfiniteLifetime = testInfiniteLifetime
	defer func() {
		header.NDPInfiniteLifetime = saved
	}()

	prefix := tcpip.AddressWithPrefix{
		Address:   tcpip.Address("\x01\x02\x03\x04\x05\x06\x07\x08\x00\x00\x00\x00\x00\x00\x00\x00"),
		PrefixLen: 64,
	}
	subnet := prefix.Subnet()

	ndpDisp := ndpDispatcher{
		prefixC:        make(chan ndpPrefixEvent, 1),
		rememberPrefix: true,
	}
	e := channel.New(0, 1280, linkAddr1)
	s := stack.New(stack.Options{
		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
			NDPConfigs: ipv6.NDPConfigurations{
				HandleRAs:              true,
				DiscoverOnLinkPrefixes: true,
			},
			NDPDisp: &ndpDisp,
		})},
	})

	if err := s.CreateNIC(1, e); err != nil {
		t.Fatalf("CreateNIC(1) = %s", err)
	}

	expectPrefixEvent := func(prefix tcpip.Subnet, discovered bool) {
		t.Helper()

		select {
		case e := <-ndpDisp.prefixC:
			if diff := checkPrefixEvent(e, prefix, discovered); diff != "" {
				t.Errorf("prefix event mismatch (-want +got):\n%s", diff)
			}
		default:
			t.Fatal("expected prefix discovery event")
		}
	}

	// Receive an RA with prefix in an NDP Prefix Information option (PI)
	// with infinite valid lifetime which should not get invalidated.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, false, testInfiniteLifetimeSeconds, 0))
	expectPrefixEvent(subnet, true)
	select {
	case <-ndpDisp.prefixC:
		t.Fatal("unexpectedly invalidated a prefix with infinite lifetime")
	case <-time.After(testInfiniteLifetime + defaultAsyncNegativeEventTimeout):
	}

	// Receive an RA with finite lifetime.
	// The prefix should get invalidated after 1s.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, false, testInfiniteLifetimeSeconds-1, 0))
	select {
	case e := <-ndpDisp.prefixC:
		if diff := checkPrefixEvent(e, subnet, false); diff != "" {
			t.Errorf("prefix event mismatch (-want +got):\n%s", diff)
		}
	case <-time.After(testInfiniteLifetime):
		t.Fatal("timed out waiting for prefix discovery event")
	}

	// Receive an RA with finite lifetime.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, false, testInfiniteLifetimeSeconds-1, 0))
	expectPrefixEvent(subnet, true)

	// Receive an RA with prefix with an infinite lifetime.
	// The prefix should not be invalidated.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, false, testInfiniteLifetimeSeconds, 0))
	select {
	case <-ndpDisp.prefixC:
		t.Fatal("unexpectedly invalidated a prefix with infinite lifetime")
	case <-time.After(testInfiniteLifetime + defaultAsyncNegativeEventTimeout):
	}

	// Receive an RA with a prefix with a lifetime value greater than the
	// set infinite lifetime value.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, false, testInfiniteLifetimeSeconds+1, 0))
	select {
	case <-ndpDisp.prefixC:
		t.Fatal("unexpectedly invalidated a prefix with infinite lifetime")
	case <-time.After((testInfiniteLifetimeSeconds+1)*time.Second + defaultAsyncNegativeEventTimeout):
	}

	// Receive an RA with 0 lifetime.
	// The prefix should get invalidated.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, false, 0, 0))
	expectPrefixEvent(subnet, false)
}

// TestPrefixDiscoveryMaxRouters tests that only
// ipv6.MaxDiscoveredOnLinkPrefixes discovered on-link prefixes are remembered.
func TestPrefixDiscoveryMaxOnLinkPrefixes(t *testing.T) {
	ndpDisp := ndpDispatcher{
		prefixC:        make(chan ndpPrefixEvent, ipv6.MaxDiscoveredOnLinkPrefixes+3),
		rememberPrefix: true,
	}
	e := channel.New(0, 1280, linkAddr1)
	s := stack.New(stack.Options{
		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
			NDPConfigs: ipv6.NDPConfigurations{
				HandleRAs:              true,
				DiscoverDefaultRouters: false,
				DiscoverOnLinkPrefixes: true,
			},
			NDPDisp: &ndpDisp,
		})},
	})

	if err := s.CreateNIC(1, e); err != nil {
		t.Fatalf("CreateNIC(1) = %s", err)
	}

	optSer := make(header.NDPOptionsSerializer, ipv6.MaxDiscoveredOnLinkPrefixes+2)
	prefixes := [ipv6.MaxDiscoveredOnLinkPrefixes + 2]tcpip.Subnet{}

	// Receive an RA with 2 more than the max number of discovered on-link
	// prefixes.
	for i := 0; i < ipv6.MaxDiscoveredOnLinkPrefixes+2; i++ {
		prefixAddr := [16]byte{1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0}
		prefixAddr[7] = byte(i)
		prefix := tcpip.AddressWithPrefix{
			Address:   tcpip.Address(prefixAddr[:]),
			PrefixLen: 64,
		}
		prefixes[i] = prefix.Subnet()
		buf := [30]byte{}
		buf[0] = uint8(prefix.PrefixLen)
		buf[1] = 128
		binary.BigEndian.PutUint32(buf[2:], 10)
		copy(buf[14:], prefix.Address)

		optSer[i] = header.NDPPrefixInformation(buf[:])
	}

	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithOpts(llAddr1, 0, optSer))
	for i := 0; i < ipv6.MaxDiscoveredOnLinkPrefixes+2; i++ {
		if i < ipv6.MaxDiscoveredOnLinkPrefixes {
			select {
			case e := <-ndpDisp.prefixC:
				if diff := checkPrefixEvent(e, prefixes[i], true); diff != "" {
					t.Errorf("prefix event mismatch (-want +got):\n%s", diff)
				}
			default:
				t.Fatal("expected prefix discovery event")
			}
		} else {
			select {
			case <-ndpDisp.prefixC:
				t.Fatal("should not have discovered a new prefix after we already discovered the max number of prefixes")
			default:
			}
		}
	}
}

// Checks to see if list contains an IPv6 address, item.
func containsV6Addr(list []tcpip.ProtocolAddress, item tcpip.AddressWithPrefix) bool {
	protocolAddress := tcpip.ProtocolAddress{
		Protocol:          header.IPv6ProtocolNumber,
		AddressWithPrefix: item,
	}

	return containsAddr(list, protocolAddress)
}

// TestNoAutoGenAddr tests that SLAAC is not performed when configured not to.
func TestNoAutoGenAddr(t *testing.T) {
	prefix, _, _ := prefixSubnetAddr(0, "")

	// Being configured to auto-generate addresses means handle and
	// autogen are set to true and forwarding is set to false.
	// This tests all possible combinations of the configurations,
	// except for the configuration where handle = true, autogen =
	// true and forwarding = false (the required configuration to do
	// SLAAC) - that will done in other tests.
	for i := 0; i < 7; i++ {
		handle := i&1 != 0
		autogen := i&2 != 0
		forwarding := i&4 == 0

		t.Run(fmt.Sprintf("HandleRAs(%t), AutoGenAddr(%t), Forwarding(%t)", handle, autogen, forwarding), func(t *testing.T) {
			ndpDisp := ndpDispatcher{
				autoGenAddrC: make(chan ndpAutoGenAddrEvent, 1),
			}
			e := channel.New(0, 1280, linkAddr1)
			s := stack.New(stack.Options{
				NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
					NDPConfigs: ipv6.NDPConfigurations{
						HandleRAs:              handle,
						AutoGenGlobalAddresses: autogen,
					},
					NDPDisp: &ndpDisp,
				})},
			})
			s.SetForwarding(ipv6.ProtocolNumber, forwarding)

			if err := s.CreateNIC(1, e); err != nil {
				t.Fatalf("CreateNIC(1) = %s", err)
			}

			// Rx an RA with prefix with non-zero lifetime.
			e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, false, true, 10, 0))

			select {
			case <-ndpDisp.autoGenAddrC:
				t.Fatal("unexpectedly auto-generated an address when configured not to")
			default:
			}
		})
	}
}

// Check e to make sure that the event is for addr on nic with ID 1, and the
// event type is set to eventType.
func checkAutoGenAddrEvent(e ndpAutoGenAddrEvent, addr tcpip.AddressWithPrefix, eventType ndpAutoGenAddrEventType) string {
	return cmp.Diff(ndpAutoGenAddrEvent{nicID: 1, addr: addr, eventType: eventType}, e, cmp.AllowUnexported(e))
}

// TestAutoGenAddr tests that an address is properly generated and invalidated
// when configured to do so.
func TestAutoGenAddr2(t *testing.T) {
	const newMinVL = 2
	newMinVLDuration := newMinVL * time.Second
	saved := ipv6.MinPrefixInformationValidLifetimeForUpdate
	defer func() {
		ipv6.MinPrefixInformationValidLifetimeForUpdate = saved
	}()
	ipv6.MinPrefixInformationValidLifetimeForUpdate = newMinVLDuration

	prefix1, _, addr1 := prefixSubnetAddr(0, linkAddr1)
	prefix2, _, addr2 := prefixSubnetAddr(1, linkAddr1)

	ndpDisp := ndpDispatcher{
		autoGenAddrC: make(chan ndpAutoGenAddrEvent, 1),
	}
	e := channel.New(0, 1280, linkAddr1)
	s := stack.New(stack.Options{
		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
			NDPConfigs: ipv6.NDPConfigurations{
				HandleRAs:              true,
				AutoGenGlobalAddresses: true,
			},
			NDPDisp: &ndpDisp,
		})},
	})

	if err := s.CreateNIC(1, e); err != nil {
		t.Fatalf("CreateNIC(1) = %s", err)
	}

	expectAutoGenAddrEvent := func(addr tcpip.AddressWithPrefix, eventType ndpAutoGenAddrEventType) {
		t.Helper()

		select {
		case e := <-ndpDisp.autoGenAddrC:
			if diff := checkAutoGenAddrEvent(e, addr, eventType); diff != "" {
				t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
			}
		default:
			t.Fatal("expected addr auto gen event")
		}
	}

	// Receive an RA with prefix1 in an NDP Prefix Information option (PI)
	// with zero valid lifetime.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, 0, 0))
	select {
	case <-ndpDisp.autoGenAddrC:
		t.Fatal("unexpectedly auto-generated an address with 0 lifetime")
	default:
	}

	// Receive an RA with prefix1 in an NDP Prefix Information option (PI)
	// with non-zero lifetime.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, 100, 0))
	expectAutoGenAddrEvent(addr1, newAddr)
	if !containsV6Addr(s.NICInfo()[1].ProtocolAddresses, addr1) {
		t.Fatalf("Should have %s in the list of addresses", addr1)
	}

	// Receive an RA with prefix2 in an NDP Prefix Information option (PI)
	// with preferred lifetime > valid lifetime
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, 5, 6))
	select {
	case <-ndpDisp.autoGenAddrC:
		t.Fatal("unexpectedly auto-generated an address with preferred lifetime > valid lifetime")
	default:
	}

	// Receive an RA with prefix2 in a PI.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix2, true, true, 100, 0))
	expectAutoGenAddrEvent(addr2, newAddr)
	if !containsV6Addr(s.NICInfo()[1].ProtocolAddresses, addr1) {
		t.Fatalf("Should have %s in the list of addresses", addr1)
	}
	if !containsV6Addr(s.NICInfo()[1].ProtocolAddresses, addr2) {
		t.Fatalf("Should have %s in the list of addresses", addr2)
	}

	// Refresh valid lifetime for addr of prefix1.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, newMinVL, 0))
	select {
	case <-ndpDisp.autoGenAddrC:
		t.Fatal("unexpectedly auto-generated an address when we already have an address for a prefix")
	default:
	}

	// Wait for addr of prefix1 to be invalidated.
	select {
	case e := <-ndpDisp.autoGenAddrC:
		if diff := checkAutoGenAddrEvent(e, addr1, invalidatedAddr); diff != "" {
			t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
		}
	case <-time.After(newMinVLDuration + defaultAsyncPositiveEventTimeout):
		t.Fatal("timed out waiting for addr auto gen event")
	}
	if containsV6Addr(s.NICInfo()[1].ProtocolAddresses, addr1) {
		t.Fatalf("Should not have %s in the list of addresses", addr1)
	}
	if !containsV6Addr(s.NICInfo()[1].ProtocolAddresses, addr2) {
		t.Fatalf("Should have %s in the list of addresses", addr2)
	}
}

func addressCheck(addrs []tcpip.ProtocolAddress, containList, notContainList []tcpip.AddressWithPrefix) string {
	ret := ""
	for _, c := range containList {
		if !containsV6Addr(addrs, c) {
			ret += fmt.Sprintf("should have %s in the list of addresses\n", c)
		}
	}
	for _, c := range notContainList {
		if containsV6Addr(addrs, c) {
			ret += fmt.Sprintf("should not have %s in the list of addresses\n", c)
		}
	}
	return ret
}

// TestAutoGenTempAddr tests that temporary SLAAC addresses are generated when
// configured to do so as part of IPv6 Privacy Extensions.
func TestAutoGenTempAddr(t *testing.T) {
	const (
		nicID            = 1
		newMinVL         = 5
		newMinVLDuration = newMinVL * time.Second
	)

	savedMinPrefixInformationValidLifetimeForUpdate := ipv6.MinPrefixInformationValidLifetimeForUpdate
	savedMaxDesync := ipv6.MaxDesyncFactor
	defer func() {
		ipv6.MinPrefixInformationValidLifetimeForUpdate = savedMinPrefixInformationValidLifetimeForUpdate
		ipv6.MaxDesyncFactor = savedMaxDesync
	}()
	ipv6.MinPrefixInformationValidLifetimeForUpdate = newMinVLDuration
	ipv6.MaxDesyncFactor = time.Nanosecond

	prefix1, _, addr1 := prefixSubnetAddr(0, linkAddr1)
	prefix2, _, addr2 := prefixSubnetAddr(1, linkAddr1)

	tests := []struct {
		name             string
		dupAddrTransmits uint8
		retransmitTimer  time.Duration
	}{
		{
			name: "DAD disabled",
		},
		{
			name:             "DAD enabled",
			dupAddrTransmits: 1,
			retransmitTimer:  time.Second,
		},
	}

	// This Run will not return until the parallel tests finish.
	//
	// We need this because we need to do some teardown work after the
	// parallel tests complete.
	//
	// See https://godoc.org/testing#hdr-Subtests_and_Sub_benchmarks for
	// more details.
	t.Run("group", func(t *testing.T) {
		for i, test := range tests {
			i := i
			test := test

			t.Run(test.name, func(t *testing.T) {
				t.Parallel()

				seed := []byte{uint8(i)}
				var tempIIDHistory [header.IIDSize]byte
				header.InitialTempIID(tempIIDHistory[:], seed, nicID)
				newTempAddr := func(stableAddr tcpip.Address) tcpip.AddressWithPrefix {
					return header.GenerateTempIPv6SLAACAddr(tempIIDHistory[:], stableAddr)
				}

				ndpDisp := ndpDispatcher{
					dadC:         make(chan ndpDADEvent, 2),
					autoGenAddrC: make(chan ndpAutoGenAddrEvent, 2),
				}
				e := channel.New(0, 1280, linkAddr1)
				s := stack.New(stack.Options{
					NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
						DADConfigs: stack.DADConfigurations{
							DupAddrDetectTransmits: test.dupAddrTransmits,
							RetransmitTimer:        test.retransmitTimer,
						},
						NDPConfigs: ipv6.NDPConfigurations{
							HandleRAs:                  true,
							AutoGenGlobalAddresses:     true,
							AutoGenTempGlobalAddresses: true,
						},
						NDPDisp:     &ndpDisp,
						TempIIDSeed: seed,
					})},
				})

				if err := s.CreateNIC(nicID, e); err != nil {
					t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
				}

				expectAutoGenAddrEvent := func(addr tcpip.AddressWithPrefix, eventType ndpAutoGenAddrEventType) {
					t.Helper()

					select {
					case e := <-ndpDisp.autoGenAddrC:
						if diff := checkAutoGenAddrEvent(e, addr, eventType); diff != "" {
							t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
						}
					default:
						t.Fatal("expected addr auto gen event")
					}
				}

				expectAutoGenAddrEventAsync := func(addr tcpip.AddressWithPrefix, eventType ndpAutoGenAddrEventType) {
					t.Helper()

					select {
					case e := <-ndpDisp.autoGenAddrC:
						if diff := checkAutoGenAddrEvent(e, addr, eventType); diff != "" {
							t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
						}
					case <-time.After(defaultAsyncPositiveEventTimeout):
						t.Fatal("timed out waiting for addr auto gen event")
					}
				}

				expectDADEventAsync := func(addr tcpip.Address) {
					t.Helper()

					select {
					case e := <-ndpDisp.dadC:
						if diff := checkDADEvent(e, nicID, addr, &stack.DADSucceeded{}); diff != "" {
							t.Errorf("DAD event mismatch (-want +got):\n%s", diff)
						}
					case <-time.After(time.Duration(test.dupAddrTransmits)*test.retransmitTimer + defaultAsyncPositiveEventTimeout):
						t.Fatal("timed out waiting for DAD event")
					}
				}

				// Receive an RA with prefix1 in an NDP Prefix Information option (PI)
				// with zero valid lifetime.
				e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, 0, 0))
				select {
				case e := <-ndpDisp.autoGenAddrC:
					t.Fatalf("unexpectedly auto-generated an address with 0 lifetime; event = %+v", e)
				default:
				}

				// Receive an RA with prefix1 in an NDP Prefix Information option (PI)
				// with non-zero valid lifetime.
				e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, 100, 0))
				expectAutoGenAddrEvent(addr1, newAddr)
				expectDADEventAsync(addr1.Address)
				select {
				case e := <-ndpDisp.autoGenAddrC:
					t.Fatalf("unexpectedly got an auto gen addr event = %+v", e)
				default:
				}
				if mismatch := addressCheck(s.NICInfo()[nicID].ProtocolAddresses, []tcpip.AddressWithPrefix{addr1}, nil); mismatch != "" {
					t.Fatal(mismatch)
				}

				// Receive an RA with prefix1 in an NDP Prefix Information option (PI)
				// with non-zero valid & preferred lifetimes.
				tempAddr1 := newTempAddr(addr1.Address)
				e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, 100, 100))
				expectAutoGenAddrEvent(tempAddr1, newAddr)
				expectDADEventAsync(tempAddr1.Address)
				if mismatch := addressCheck(s.NICInfo()[1].ProtocolAddresses, []tcpip.AddressWithPrefix{addr1, tempAddr1}, nil); mismatch != "" {
					t.Fatal(mismatch)
				}

				// Receive an RA with prefix2 in an NDP Prefix Information option (PI)
				// with preferred lifetime > valid lifetime
				e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, 5, 6))
				select {
				case e := <-ndpDisp.autoGenAddrC:
					t.Fatalf("unexpectedly auto-generated an address with preferred lifetime > valid lifetime; event = %+v", e)
				default:
				}
				if mismatch := addressCheck(s.NICInfo()[nicID].ProtocolAddresses, []tcpip.AddressWithPrefix{addr1, tempAddr1}, nil); mismatch != "" {
					t.Fatal(mismatch)
				}

				// Receive an RA with prefix2 in a PI w/ non-zero valid and preferred
				// lifetimes.
				tempAddr2 := newTempAddr(addr2.Address)
				e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix2, true, true, 100, 100))
				expectAutoGenAddrEvent(addr2, newAddr)
				expectDADEventAsync(addr2.Address)
				expectAutoGenAddrEventAsync(tempAddr2, newAddr)
				expectDADEventAsync(tempAddr2.Address)
				if mismatch := addressCheck(s.NICInfo()[nicID].ProtocolAddresses, []tcpip.AddressWithPrefix{addr1, tempAddr1, addr2, tempAddr2}, nil); mismatch != "" {
					t.Fatal(mismatch)
				}

				// Deprecate prefix1.
				e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, 100, 0))
				expectAutoGenAddrEvent(addr1, deprecatedAddr)
				expectAutoGenAddrEvent(tempAddr1, deprecatedAddr)
				if mismatch := addressCheck(s.NICInfo()[nicID].ProtocolAddresses, []tcpip.AddressWithPrefix{addr1, tempAddr1, addr2, tempAddr2}, nil); mismatch != "" {
					t.Fatal(mismatch)
				}

				// Refresh lifetimes for prefix1.
				e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, 100, 100))
				if mismatch := addressCheck(s.NICInfo()[nicID].ProtocolAddresses, []tcpip.AddressWithPrefix{addr1, tempAddr1, addr2, tempAddr2}, nil); mismatch != "" {
					t.Fatal(mismatch)
				}

				// Reduce valid lifetime and deprecate addresses of prefix1.
				e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, newMinVL, 0))
				expectAutoGenAddrEvent(addr1, deprecatedAddr)
				expectAutoGenAddrEvent(tempAddr1, deprecatedAddr)
				if mismatch := addressCheck(s.NICInfo()[nicID].ProtocolAddresses, []tcpip.AddressWithPrefix{addr1, tempAddr1, addr2, tempAddr2}, nil); mismatch != "" {
					t.Fatal(mismatch)
				}

				// Wait for addrs of prefix1 to be invalidated. They should be
				// invalidated at the same time.
				select {
				case e := <-ndpDisp.autoGenAddrC:
					var nextAddr tcpip.AddressWithPrefix
					if e.addr == addr1 {
						if diff := checkAutoGenAddrEvent(e, addr1, invalidatedAddr); diff != "" {
							t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
						}
						nextAddr = tempAddr1
					} else {
						if diff := checkAutoGenAddrEvent(e, tempAddr1, invalidatedAddr); diff != "" {
							t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
						}
						nextAddr = addr1
					}

					select {
					case e := <-ndpDisp.autoGenAddrC:
						if diff := checkAutoGenAddrEvent(e, nextAddr, invalidatedAddr); diff != "" {
							t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
						}
					case <-time.After(defaultAsyncPositiveEventTimeout):
						t.Fatal("timed out waiting for addr auto gen event")
					}
				case <-time.After(newMinVLDuration + defaultAsyncPositiveEventTimeout):
					t.Fatal("timed out waiting for addr auto gen event")
				}
				if mismatch := addressCheck(s.NICInfo()[nicID].ProtocolAddresses, []tcpip.AddressWithPrefix{addr2, tempAddr2}, []tcpip.AddressWithPrefix{addr1, tempAddr1}); mismatch != "" {
					t.Fatal(mismatch)
				}

				// Receive an RA with prefix2 in a PI w/ 0 lifetimes.
				e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix2, true, true, 0, 0))
				expectAutoGenAddrEvent(addr2, deprecatedAddr)
				expectAutoGenAddrEvent(tempAddr2, deprecatedAddr)
				select {
				case e := <-ndpDisp.autoGenAddrC:
					t.Errorf("got unexpected auto gen addr event = %+v", e)
				default:
				}
				if mismatch := addressCheck(s.NICInfo()[nicID].ProtocolAddresses, []tcpip.AddressWithPrefix{addr2, tempAddr2}, []tcpip.AddressWithPrefix{addr1, tempAddr1}); mismatch != "" {
					t.Fatal(mismatch)
				}
			})
		}
	})
}

// TestNoAutoGenTempAddrForLinkLocal test that temporary SLAAC addresses are not
// generated for auto generated link-local addresses.
func TestNoAutoGenTempAddrForLinkLocal(t *testing.T) {
	const nicID = 1

	savedMaxDesyncFactor := ipv6.MaxDesyncFactor
	defer func() {
		ipv6.MaxDesyncFactor = savedMaxDesyncFactor
	}()
	ipv6.MaxDesyncFactor = time.Nanosecond

	tests := []struct {
		name             string
		dupAddrTransmits uint8
		retransmitTimer  time.Duration
	}{
		{
			name: "DAD disabled",
		},
		{
			name:             "DAD enabled",
			dupAddrTransmits: 1,
			retransmitTimer:  time.Second,
		},
	}

	// This Run will not return until the parallel tests finish.
	//
	// We need this because we need to do some teardown work after the
	// parallel tests complete.
	//
	// See https://godoc.org/testing#hdr-Subtests_and_Sub_benchmarks for
	// more details.
	t.Run("group", func(t *testing.T) {
		for _, test := range tests {
			test := test

			t.Run(test.name, func(t *testing.T) {
				t.Parallel()

				ndpDisp := ndpDispatcher{
					dadC:         make(chan ndpDADEvent, 1),
					autoGenAddrC: make(chan ndpAutoGenAddrEvent, 1),
				}
				e := channel.New(0, 1280, linkAddr1)
				s := stack.New(stack.Options{
					NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
						NDPConfigs: ipv6.NDPConfigurations{
							AutoGenTempGlobalAddresses: true,
						},
						NDPDisp:          &ndpDisp,
						AutoGenLinkLocal: true,
					})},
				})

				if err := s.CreateNIC(nicID, e); err != nil {
					t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
				}

				// The stable link-local address should auto-generate and resolve DAD.
				select {
				case e := <-ndpDisp.autoGenAddrC:
					if diff := checkAutoGenAddrEvent(e, tcpip.AddressWithPrefix{Address: llAddr1, PrefixLen: header.IIDOffsetInIPv6Address * 8}, newAddr); diff != "" {
						t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
					}
				default:
					t.Fatal("expected addr auto gen event")
				}
				select {
				case e := <-ndpDisp.dadC:
					if diff := checkDADEvent(e, nicID, llAddr1, &stack.DADSucceeded{}); diff != "" {
						t.Errorf("DAD event mismatch (-want +got):\n%s", diff)
					}
				case <-time.After(time.Duration(test.dupAddrTransmits)*test.retransmitTimer + defaultAsyncPositiveEventTimeout):
					t.Fatal("timed out waiting for DAD event")
				}

				// No new addresses should be generated.
				select {
				case e := <-ndpDisp.autoGenAddrC:
					t.Errorf("got unxpected auto gen addr event = %+v", e)
				case <-time.After(defaultAsyncNegativeEventTimeout):
				}
			})
		}
	})
}

// TestNoAutoGenTempAddrWithoutStableAddr tests that a temporary SLAAC address
// will not be generated until after DAD completes, even if a new Router
// Advertisement is received to refresh lifetimes.
func TestNoAutoGenTempAddrWithoutStableAddr(t *testing.T) {
	const (
		nicID           = 1
		dadTransmits    = 1
		retransmitTimer = 2 * time.Second
	)

	savedMaxDesyncFactor := ipv6.MaxDesyncFactor
	defer func() {
		ipv6.MaxDesyncFactor = savedMaxDesyncFactor
	}()
	ipv6.MaxDesyncFactor = 0

	prefix, _, addr := prefixSubnetAddr(0, linkAddr1)
	var tempIIDHistory [header.IIDSize]byte
	header.InitialTempIID(tempIIDHistory[:], nil, nicID)
	tempAddr := header.GenerateTempIPv6SLAACAddr(tempIIDHistory[:], addr.Address)

	ndpDisp := ndpDispatcher{
		dadC:         make(chan ndpDADEvent, 1),
		autoGenAddrC: make(chan ndpAutoGenAddrEvent, 1),
	}
	e := channel.New(0, 1280, linkAddr1)
	s := stack.New(stack.Options{
		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
			DADConfigs: stack.DADConfigurations{
				DupAddrDetectTransmits: dadTransmits,
				RetransmitTimer:        retransmitTimer,
			},
			NDPConfigs: ipv6.NDPConfigurations{
				HandleRAs:                  true,
				AutoGenGlobalAddresses:     true,
				AutoGenTempGlobalAddresses: true,
			},
			NDPDisp: &ndpDisp,
		})},
	})

	if err := s.CreateNIC(nicID, e); err != nil {
		t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
	}

	// Receive an RA to trigger SLAAC for prefix.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, 100, 100))
	select {
	case e := <-ndpDisp.autoGenAddrC:
		if diff := checkAutoGenAddrEvent(e, addr, newAddr); diff != "" {
			t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
		}
	default:
		t.Fatal("expected addr auto gen event")
	}

	// DAD on the stable address for prefix has not yet completed. Receiving a new
	// RA that would refresh lifetimes should not generate a temporary SLAAC
	// address for the prefix.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, 100, 100))
	select {
	case e := <-ndpDisp.autoGenAddrC:
		t.Fatalf("unexpected auto gen addr event = %+v", e)
	default:
	}

	// Wait for DAD to complete for the stable address then expect the temporary
	// address to be generated.
	select {
	case e := <-ndpDisp.dadC:
		if diff := checkDADEvent(e, nicID, addr.Address, &stack.DADSucceeded{}); diff != "" {
			t.Errorf("DAD event mismatch (-want +got):\n%s", diff)
		}
	case <-time.After(dadTransmits*retransmitTimer + defaultAsyncPositiveEventTimeout):
		t.Fatal("timed out waiting for DAD event")
	}
	select {
	case e := <-ndpDisp.autoGenAddrC:
		if diff := checkAutoGenAddrEvent(e, tempAddr, newAddr); diff != "" {
			t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
		}
	case <-time.After(defaultAsyncPositiveEventTimeout):
		t.Fatal("timed out waiting for addr auto gen event")
	}
}

// TestAutoGenTempAddrRegen tests that temporary SLAAC addresses are
// regenerated.
func TestAutoGenTempAddrRegen(t *testing.T) {
	const (
		nicID            = 1
		regenAfter       = 2 * time.Second
		newMinVL         = 10
		newMinVLDuration = newMinVL * time.Second
	)

	savedMaxDesyncFactor := ipv6.MaxDesyncFactor
	savedMinMaxTempAddrPreferredLifetime := ipv6.MinMaxTempAddrPreferredLifetime
	savedMinMaxTempAddrValidLifetime := ipv6.MinMaxTempAddrValidLifetime
	defer func() {
		ipv6.MaxDesyncFactor = savedMaxDesyncFactor
		ipv6.MinMaxTempAddrPreferredLifetime = savedMinMaxTempAddrPreferredLifetime
		ipv6.MinMaxTempAddrValidLifetime = savedMinMaxTempAddrValidLifetime
	}()
	ipv6.MaxDesyncFactor = 0
	ipv6.MinMaxTempAddrPreferredLifetime = newMinVLDuration
	ipv6.MinMaxTempAddrValidLifetime = newMinVLDuration

	prefix, _, addr := prefixSubnetAddr(0, linkAddr1)
	var tempIIDHistory [header.IIDSize]byte
	header.InitialTempIID(tempIIDHistory[:], nil, nicID)
	tempAddr1 := header.GenerateTempIPv6SLAACAddr(tempIIDHistory[:], addr.Address)
	tempAddr2 := header.GenerateTempIPv6SLAACAddr(tempIIDHistory[:], addr.Address)
	tempAddr3 := header.GenerateTempIPv6SLAACAddr(tempIIDHistory[:], addr.Address)

	ndpDisp := ndpDispatcher{
		autoGenAddrC: make(chan ndpAutoGenAddrEvent, 2),
	}
	e := channel.New(0, 1280, linkAddr1)
	ndpConfigs := ipv6.NDPConfigurations{
		HandleRAs:                  true,
		AutoGenGlobalAddresses:     true,
		AutoGenTempGlobalAddresses: true,
		RegenAdvanceDuration:       newMinVLDuration - regenAfter,
	}
	s := stack.New(stack.Options{
		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
			NDPConfigs: ndpConfigs,
			NDPDisp:    &ndpDisp,
		})},
	})

	if err := s.CreateNIC(nicID, e); err != nil {
		t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
	}

	expectAutoGenAddrEvent := func(addr tcpip.AddressWithPrefix, eventType ndpAutoGenAddrEventType) {
		t.Helper()

		select {
		case e := <-ndpDisp.autoGenAddrC:
			if diff := checkAutoGenAddrEvent(e, addr, eventType); diff != "" {
				t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
			}
		default:
			t.Fatal("expected addr auto gen event")
		}
	}

	expectAutoGenAddrEventAsync := func(addr tcpip.AddressWithPrefix, eventType ndpAutoGenAddrEventType, timeout time.Duration) {
		t.Helper()

		select {
		case e := <-ndpDisp.autoGenAddrC:
			if diff := checkAutoGenAddrEvent(e, addr, eventType); diff != "" {
				t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
			}
		case <-time.After(timeout):
			t.Fatal("timed out waiting for addr auto gen event")
		}
	}

	// Receive an RA with prefix1 in an NDP Prefix Information option (PI)
	// with non-zero valid & preferred lifetimes.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, 100, 100))
	expectAutoGenAddrEvent(addr, newAddr)
	expectAutoGenAddrEvent(tempAddr1, newAddr)
	if mismatch := addressCheck(s.NICInfo()[nicID].ProtocolAddresses, []tcpip.AddressWithPrefix{addr, tempAddr1}, nil); mismatch != "" {
		t.Fatal(mismatch)
	}

	// Wait for regeneration
	expectAutoGenAddrEventAsync(tempAddr2, newAddr, regenAfter+defaultAsyncPositiveEventTimeout)
	if mismatch := addressCheck(s.NICInfo()[nicID].ProtocolAddresses, []tcpip.AddressWithPrefix{addr, tempAddr1, tempAddr2}, nil); mismatch != "" {
		t.Fatal(mismatch)
	}

	// Wait for regeneration
	expectAutoGenAddrEventAsync(tempAddr3, newAddr, regenAfter+defaultAsyncPositiveEventTimeout)
	if mismatch := addressCheck(s.NICInfo()[nicID].ProtocolAddresses, []tcpip.AddressWithPrefix{addr, tempAddr1, tempAddr2, tempAddr3}, nil); mismatch != "" {
		t.Fatal(mismatch)
	}

	// Stop generating temporary addresses
	ndpConfigs.AutoGenTempGlobalAddresses = false
	if ipv6Ep, err := s.GetNetworkEndpoint(nicID, header.IPv6ProtocolNumber); err != nil {
		t.Fatalf("s.GetNetworkEndpoint(%d, %d): %s", nicID, header.IPv6ProtocolNumber, err)
	} else {
		ndpEP := ipv6Ep.(ipv6.NDPEndpoint)
		ndpEP.SetNDPConfigurations(ndpConfigs)
	}

	// Wait for all the temporary addresses to get invalidated.
	tempAddrs := []tcpip.AddressWithPrefix{tempAddr1, tempAddr2, tempAddr3}
	invalidateAfter := newMinVLDuration - 2*regenAfter
	for _, addr := range tempAddrs {
		// Wait for a deprecation then invalidation event, or just an invalidation
		// event. We need to cover both cases but cannot deterministically hit both
		// cases because the deprecation and invalidation jobs could execute in any
		// order.
		select {
		case e := <-ndpDisp.autoGenAddrC:
			if diff := checkAutoGenAddrEvent(e, addr, deprecatedAddr); diff == "" {
				// If we get a deprecation event first, we should get an invalidation
				// event almost immediately after.
				select {
				case e := <-ndpDisp.autoGenAddrC:
					if diff := checkAutoGenAddrEvent(e, addr, invalidatedAddr); diff != "" {
						t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
					}
				case <-time.After(defaultAsyncPositiveEventTimeout):
					t.Fatal("timed out waiting for addr auto gen event")
				}
			} else if diff := checkAutoGenAddrEvent(e, addr, invalidatedAddr); diff == "" {
				// If we get an invalidation event first, we shouldn't get a deprecation
				// event after.
				select {
				case e := <-ndpDisp.autoGenAddrC:
					t.Fatalf("unexpectedly got an auto-generated event = %+v", e)
				case <-time.After(defaultAsyncNegativeEventTimeout):
				}
			} else {
				t.Fatalf("got unexpected auto-generated event = %+v", e)
			}
		case <-time.After(invalidateAfter + defaultAsyncPositiveEventTimeout):
			t.Fatal("timed out waiting for addr auto gen event")
		}

		invalidateAfter = regenAfter
	}
	if mismatch := addressCheck(s.NICInfo()[1].ProtocolAddresses, []tcpip.AddressWithPrefix{addr}, tempAddrs); mismatch != "" {
		t.Fatal(mismatch)
	}
}

// TestAutoGenTempAddrRegenJobUpdates tests that a temporary address's
// regeneration job gets updated when refreshing the address's lifetimes.
func TestAutoGenTempAddrRegenJobUpdates(t *testing.T) {
	const (
		nicID            = 1
		regenAfter       = 2 * time.Second
		newMinVL         = 10
		newMinVLDuration = newMinVL * time.Second
	)

	savedMaxDesyncFactor := ipv6.MaxDesyncFactor
	savedMinMaxTempAddrPreferredLifetime := ipv6.MinMaxTempAddrPreferredLifetime
	savedMinMaxTempAddrValidLifetime := ipv6.MinMaxTempAddrValidLifetime
	defer func() {
		ipv6.MaxDesyncFactor = savedMaxDesyncFactor
		ipv6.MinMaxTempAddrPreferredLifetime = savedMinMaxTempAddrPreferredLifetime
		ipv6.MinMaxTempAddrValidLifetime = savedMinMaxTempAddrValidLifetime
	}()
	ipv6.MaxDesyncFactor = 0
	ipv6.MinMaxTempAddrPreferredLifetime = newMinVLDuration
	ipv6.MinMaxTempAddrValidLifetime = newMinVLDuration

	prefix, _, addr := prefixSubnetAddr(0, linkAddr1)
	var tempIIDHistory [header.IIDSize]byte
	header.InitialTempIID(tempIIDHistory[:], nil, nicID)
	tempAddr1 := header.GenerateTempIPv6SLAACAddr(tempIIDHistory[:], addr.Address)
	tempAddr2 := header.GenerateTempIPv6SLAACAddr(tempIIDHistory[:], addr.Address)
	tempAddr3 := header.GenerateTempIPv6SLAACAddr(tempIIDHistory[:], addr.Address)

	ndpDisp := ndpDispatcher{
		autoGenAddrC: make(chan ndpAutoGenAddrEvent, 2),
	}
	e := channel.New(0, 1280, linkAddr1)
	ndpConfigs := ipv6.NDPConfigurations{
		HandleRAs:                  true,
		AutoGenGlobalAddresses:     true,
		AutoGenTempGlobalAddresses: true,
		RegenAdvanceDuration:       newMinVLDuration - regenAfter,
	}
	s := stack.New(stack.Options{
		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
			NDPConfigs: ndpConfigs,
			NDPDisp:    &ndpDisp,
		})},
	})

	if err := s.CreateNIC(nicID, e); err != nil {
		t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
	}

	expectAutoGenAddrEvent := func(addr tcpip.AddressWithPrefix, eventType ndpAutoGenAddrEventType) {
		t.Helper()

		select {
		case e := <-ndpDisp.autoGenAddrC:
			if diff := checkAutoGenAddrEvent(e, addr, eventType); diff != "" {
				t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
			}
		default:
			t.Fatal("expected addr auto gen event")
		}
	}

	expectAutoGenAddrEventAsync := func(addr tcpip.AddressWithPrefix, eventType ndpAutoGenAddrEventType, timeout time.Duration) {
		t.Helper()

		select {
		case e := <-ndpDisp.autoGenAddrC:
			if diff := checkAutoGenAddrEvent(e, addr, eventType); diff != "" {
				t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
			}
		case <-time.After(timeout):
			t.Fatal("timed out waiting for addr auto gen event")
		}
	}

	// Receive an RA with prefix1 in an NDP Prefix Information option (PI)
	// with non-zero valid & preferred lifetimes.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, 100, 100))
	expectAutoGenAddrEvent(addr, newAddr)
	expectAutoGenAddrEvent(tempAddr1, newAddr)
	if mismatch := addressCheck(s.NICInfo()[nicID].ProtocolAddresses, []tcpip.AddressWithPrefix{addr, tempAddr1}, nil); mismatch != "" {
		t.Fatal(mismatch)
	}

	// Deprecate the prefix.
	//
	// A new temporary address should be generated after the regeneration
	// time has passed since the prefix is deprecated.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, 100, 0))
	expectAutoGenAddrEvent(addr, deprecatedAddr)
	expectAutoGenAddrEvent(tempAddr1, deprecatedAddr)
	select {
	case e := <-ndpDisp.autoGenAddrC:
		t.Fatalf("unexpected auto gen addr event = %+v", e)
	case <-time.After(regenAfter + defaultAsyncNegativeEventTimeout):
	}

	// Prefer the prefix again.
	//
	// A new temporary address should immediately be generated since the
	// regeneration time has already passed since the last address was generated
	// - this regeneration does not depend on a job.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, 100, 100))
	expectAutoGenAddrEvent(tempAddr2, newAddr)

	// Increase the maximum lifetimes for temporary addresses to large values
	// then refresh the lifetimes of the prefix.
	//
	// A new address should not be generated after the regeneration time that was
	// expected for the previous check. This is because the preferred lifetime for
	// the temporary addresses has increased, so it will take more time to
	// regenerate a new temporary address. Note, new addresses are only
	// regenerated after the preferred lifetime - the regenerate advance duration
	// as paased.
	ndpConfigs.MaxTempAddrValidLifetime = 100 * time.Second
	ndpConfigs.MaxTempAddrPreferredLifetime = 100 * time.Second
	ipv6Ep, err := s.GetNetworkEndpoint(nicID, header.IPv6ProtocolNumber)
	if err != nil {
		t.Fatalf("s.GetNetworkEndpoint(%d, %d): %s", nicID, header.IPv6ProtocolNumber, err)
	}
	ndpEP := ipv6Ep.(ipv6.NDPEndpoint)
	ndpEP.SetNDPConfigurations(ndpConfigs)
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, 100, 100))
	select {
	case e := <-ndpDisp.autoGenAddrC:
		t.Fatalf("unexpected auto gen addr event = %+v", e)
	case <-time.After(regenAfter + defaultAsyncNegativeEventTimeout):
	}

	// Set the maximum lifetimes for temporary addresses such that on the next
	// RA, the regeneration job gets scheduled again.
	//
	// The maximum lifetime is the sum of the minimum lifetimes for temporary
	// addresses + the time that has already passed since the last address was
	// generated so that the regeneration job is needed to generate the next
	// address.
	newLifetimes := newMinVLDuration + regenAfter + defaultAsyncNegativeEventTimeout
	ndpConfigs.MaxTempAddrValidLifetime = newLifetimes
	ndpConfigs.MaxTempAddrPreferredLifetime = newLifetimes
	ndpEP.SetNDPConfigurations(ndpConfigs)
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, 100, 100))
	expectAutoGenAddrEventAsync(tempAddr3, newAddr, regenAfter+defaultAsyncPositiveEventTimeout)
}

// TestMixedSLAACAddrConflictRegen tests SLAAC address regeneration in response
// to a mix of DAD conflicts and NIC-local conflicts.
func TestMixedSLAACAddrConflictRegen(t *testing.T) {
	const (
		nicID           = 1
		nicName         = "nic"
		lifetimeSeconds = 9999
		// From stack.maxSLAACAddrLocalRegenAttempts
		maxSLAACAddrLocalRegenAttempts = 10
		// We use 2 more addreses than the maximum local regeneration attempts
		// because we want to also trigger regeneration in response to a DAD
		// conflicts for this test.
		maxAddrs         = maxSLAACAddrLocalRegenAttempts + 2
		dupAddrTransmits = 1
		retransmitTimer  = time.Second
	)

	var tempIIDHistoryWithModifiedEUI64 [header.IIDSize]byte
	header.InitialTempIID(tempIIDHistoryWithModifiedEUI64[:], nil, nicID)

	var tempIIDHistoryWithOpaqueIID [header.IIDSize]byte
	header.InitialTempIID(tempIIDHistoryWithOpaqueIID[:], nil, nicID)

	prefix, subnet, stableAddrWithModifiedEUI64 := prefixSubnetAddr(0, linkAddr1)
	var stableAddrsWithOpaqueIID [maxAddrs]tcpip.AddressWithPrefix
	var tempAddrsWithOpaqueIID [maxAddrs]tcpip.AddressWithPrefix
	var tempAddrsWithModifiedEUI64 [maxAddrs]tcpip.AddressWithPrefix
	addrBytes := []byte(subnet.ID())
	for i := 0; i < maxAddrs; i++ {
		stableAddrsWithOpaqueIID[i] = tcpip.AddressWithPrefix{
			Address:   tcpip.Address(header.AppendOpaqueInterfaceIdentifier(addrBytes[:header.IIDOffsetInIPv6Address], subnet, nicName, uint8(i), nil)),
			PrefixLen: header.IIDOffsetInIPv6Address * 8,
		}
		// When generating temporary addresses, the resolved stable address for the
		// SLAAC prefix will be the first address stable address generated for the
		// prefix as we will not simulate address conflicts for the stable addresses
		// in tests involving temporary addresses. Address conflicts for stable
		// addresses will be done in their own tests.
		tempAddrsWithOpaqueIID[i] = header.GenerateTempIPv6SLAACAddr(tempIIDHistoryWithOpaqueIID[:], stableAddrsWithOpaqueIID[0].Address)
		tempAddrsWithModifiedEUI64[i] = header.GenerateTempIPv6SLAACAddr(tempIIDHistoryWithModifiedEUI64[:], stableAddrWithModifiedEUI64.Address)
	}

	tests := []struct {
		name          string
		addrs         []tcpip.AddressWithPrefix
		tempAddrs     bool
		initialExpect tcpip.AddressWithPrefix
		maxAddrs      int
		nicNameFromID func(tcpip.NICID, string) string
	}{
		{
			name:     "Stable addresses with opaque IIDs",
			addrs:    stableAddrsWithOpaqueIID[:],
			maxAddrs: 1,
			nicNameFromID: func(tcpip.NICID, string) string {
				return nicName
			},
		},
		{
			name:          "Temporary addresses with opaque IIDs",
			addrs:         tempAddrsWithOpaqueIID[:],
			tempAddrs:     true,
			initialExpect: stableAddrsWithOpaqueIID[0],
			maxAddrs:      1 /* initial (stable) address */ + maxSLAACAddrLocalRegenAttempts,
			nicNameFromID: func(tcpip.NICID, string) string {
				return nicName
			},
		},
		{
			name:          "Temporary addresses with modified EUI64",
			addrs:         tempAddrsWithModifiedEUI64[:],
			tempAddrs:     true,
			maxAddrs:      1 /* initial (stable) address */ + maxSLAACAddrLocalRegenAttempts,
			initialExpect: stableAddrWithModifiedEUI64,
		},
	}

	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			ndpDisp := ndpDispatcher{
				// We may receive a deprecated and invalidated event for each SLAAC
				// address that is assigned.
				autoGenAddrC: make(chan ndpAutoGenAddrEvent, test.maxAddrs*2),
			}
			e := channel.New(0, 1280, linkAddr1)
			clock := faketime.NewManualClock()
			s := stack.New(stack.Options{
				Clock: clock,
				NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
					NDPConfigs: ipv6.NDPConfigurations{
						HandleRAs:                     true,
						AutoGenGlobalAddresses:        true,
						AutoGenTempGlobalAddresses:    test.tempAddrs,
						AutoGenAddressConflictRetries: 1,
					},
					NDPDisp: &ndpDisp,
					OpaqueIIDOpts: ipv6.OpaqueInterfaceIdentifierOptions{
						NICNameFromID: test.nicNameFromID,
					},
				})},
				TransportProtocols: []stack.TransportProtocolFactory{udp.NewProtocol},
			})

			s.SetRouteTable([]tcpip.Route{{
				Destination: header.IPv6EmptySubnet,
				Gateway:     llAddr2,
				NIC:         nicID,
			}})

			if err := s.CreateNIC(nicID, e); err != nil {
				t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
			}

			manuallyAssignedAddresses := make(map[tcpip.Address]struct{})
			for j := 0; j < len(test.addrs)-1; j++ {
				// The NIC will not attempt to generate an address in response to a
				// NIC-local conflict after some maximum number of attempts. We skip
				// creating a conflict for the address that would be generated as part
				// of the last attempt so we can simulate a DAD conflict for this
				// address and restart the NIC-local generation process.
				if j == maxSLAACAddrLocalRegenAttempts-1 {
					continue
				}

				if err := s.AddAddress(nicID, ipv6.ProtocolNumber, test.addrs[j].Address); err != nil {
					t.Fatalf("s.AddAddress(%d, %d, %s): %s", nicID, ipv6.ProtocolNumber, test.addrs[j].Address, err)
				}

				manuallyAssignedAddresses[test.addrs[j].Address] = struct{}{}
			}

			expectAutoGenAddrEvent := func(addr tcpip.AddressWithPrefix, eventType ndpAutoGenAddrEventType) {
				t.Helper()

				select {
				case e := <-ndpDisp.autoGenAddrC:
					if diff := checkAutoGenAddrEvent(e, addr, eventType); diff != "" {
						t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
					}
				default:
					t.Fatal("expected addr auto gen event")
				}
			}

			expectAutoGenAddrAsyncEvent := func(addr tcpip.AddressWithPrefix, eventType ndpAutoGenAddrEventType) {
				t.Helper()

				if diff := checkAutoGenAddrEvent(<-ndpDisp.autoGenAddrC, addr, eventType); diff != "" {
					t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
				}
			}

			expectDADEventAsync := func(addr tcpip.Address) {
				t.Helper()

				clock.Advance(dupAddrTransmits * retransmitTimer)
				if diff := checkDADEvent(<-ndpDisp.dadC, nicID, addr, &stack.DADSucceeded{}); diff != "" {
					t.Errorf("DAD event mismatch (-want +got):\n%s", diff)
				}
			}

			// Enable DAD.
			ndpDisp.dadC = make(chan ndpDADEvent, 2)
			if ipv6Ep, err := s.GetNetworkEndpoint(nicID, header.IPv6ProtocolNumber); err != nil {
				t.Fatalf("s.GetNetworkEndpoint(%d, %d): %s", nicID, header.IPv6ProtocolNumber, err)
			} else {
				ndpEP := ipv6Ep.(stack.DuplicateAddressDetector)
				ndpEP.SetDADConfigurations(stack.DADConfigurations{
					DupAddrDetectTransmits: dupAddrTransmits,
					RetransmitTimer:        retransmitTimer,
				})
			}

			// Do SLAAC for prefix.
			e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, lifetimeSeconds, lifetimeSeconds))
			if test.initialExpect != (tcpip.AddressWithPrefix{}) {
				expectAutoGenAddrEvent(test.initialExpect, newAddr)
				expectDADEventAsync(test.initialExpect.Address)
			}

			// The last local generation attempt should succeed, but we introduce a
			// DAD failure to restart the local generation process.
			addr := test.addrs[maxSLAACAddrLocalRegenAttempts-1]
			expectAutoGenAddrAsyncEvent(addr, newAddr)
			rxNDPSolicit(e, addr.Address)
			select {
			case e := <-ndpDisp.dadC:
				if diff := checkDADEvent(e, nicID, addr.Address, &stack.DADDupAddrDetected{}); diff != "" {
					t.Errorf("DAD event mismatch (-want +got):\n%s", diff)
				}
			default:
				t.Fatal("expected DAD event")
			}
			expectAutoGenAddrEvent(addr, invalidatedAddr)

			// The last address generated should resolve DAD.
			addr = test.addrs[len(test.addrs)-1]
			expectAutoGenAddrAsyncEvent(addr, newAddr)
			expectDADEventAsync(addr.Address)

			select {
			case e := <-ndpDisp.autoGenAddrC:
				t.Fatalf("unexpected auto gen addr event = %+v", e)
			default:
			}

			// Wait for all the SLAAC addresses to be invalidated.
			clock.Advance(lifetimeSeconds * time.Second)
			gotAddresses := make(map[tcpip.Address]struct{})
			for _, a := range s.NICInfo()[nicID].ProtocolAddresses {
				gotAddresses[a.AddressWithPrefix.Address] = struct{}{}
			}
			if diff := cmp.Diff(manuallyAssignedAddresses, gotAddresses); diff != "" {
				t.Fatalf("assigned addresses mismatch (-want +got):\n%s", diff)
			}
		})
	}
}

// stackAndNdpDispatcherWithDefaultRoute returns an ndpDispatcher,
// channel.Endpoint and stack.Stack.
//
// stack.Stack will have a default route through the router (llAddr3) installed
// and a static link-address (linkAddr3) added to the link address cache for the
// router.
func stackAndNdpDispatcherWithDefaultRoute(t *testing.T, nicID tcpip.NICID) (*ndpDispatcher, *channel.Endpoint, *stack.Stack) {
	t.Helper()
	ndpDisp := &ndpDispatcher{
		autoGenAddrC: make(chan ndpAutoGenAddrEvent, 1),
	}
	e := channel.New(0, 1280, linkAddr1)
	e.LinkEPCapabilities |= stack.CapabilityResolutionRequired
	s := stack.New(stack.Options{
		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
			NDPConfigs: ipv6.NDPConfigurations{
				HandleRAs:              true,
				AutoGenGlobalAddresses: true,
			},
			NDPDisp: ndpDisp,
		})},
		TransportProtocols: []stack.TransportProtocolFactory{udp.NewProtocol},
	})
	if err := s.CreateNIC(nicID, e); err != nil {
		t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
	}
	s.SetRouteTable([]tcpip.Route{{
		Destination: header.IPv6EmptySubnet,
		Gateway:     llAddr3,
		NIC:         nicID,
	}})

	if err := s.AddStaticNeighbor(nicID, ipv6.ProtocolNumber, llAddr3, linkAddr3); err != nil {
		t.Fatalf("s.AddStaticNeighbor(%d, %d, %s, %s): %s", nicID, ipv6.ProtocolNumber, llAddr3, linkAddr3, err)
	}
	return ndpDisp, e, s
}

// addrForNewConnectionTo returns the local address used when creating a new
// connection to addr.
func addrForNewConnectionTo(t *testing.T, s *stack.Stack, addr tcpip.FullAddress) tcpip.Address {
	t.Helper()

	wq := waiter.Queue{}
	we, ch := waiter.NewChannelEntry(nil)
	wq.EventRegister(&we, waiter.EventIn)
	defer wq.EventUnregister(&we)
	defer close(ch)
	ep, err := s.NewEndpoint(header.UDPProtocolNumber, header.IPv6ProtocolNumber, &wq)
	if err != nil {
		t.Fatalf("s.NewEndpoint(%d, %d, _): %s", header.UDPProtocolNumber, header.IPv6ProtocolNumber, err)
	}
	defer ep.Close()
	ep.SocketOptions().SetV6Only(true)
	if err := ep.Connect(addr); err != nil {
		t.Fatalf("ep.Connect(%+v): %s", addr, err)
	}
	got, err := ep.GetLocalAddress()
	if err != nil {
		t.Fatalf("ep.GetLocalAddress(): %s", err)
	}
	return got.Addr
}

// addrForNewConnection returns the local address used when creating a new
// connection.
func addrForNewConnection(t *testing.T, s *stack.Stack) tcpip.Address {
	t.Helper()

	return addrForNewConnectionTo(t, s, dstAddr)
}

// addrForNewConnectionWithAddr returns the local address used when creating a
// new connection with a specific local address.
func addrForNewConnectionWithAddr(t *testing.T, s *stack.Stack, addr tcpip.FullAddress) tcpip.Address {
	t.Helper()

	wq := waiter.Queue{}
	we, ch := waiter.NewChannelEntry(nil)
	wq.EventRegister(&we, waiter.EventIn)
	defer wq.EventUnregister(&we)
	defer close(ch)
	ep, err := s.NewEndpoint(header.UDPProtocolNumber, header.IPv6ProtocolNumber, &wq)
	if err != nil {
		t.Fatalf("s.NewEndpoint(%d, %d, _): %s", header.UDPProtocolNumber, header.IPv6ProtocolNumber, err)
	}
	defer ep.Close()
	ep.SocketOptions().SetV6Only(true)
	if err := ep.Bind(addr); err != nil {
		t.Fatalf("ep.Bind(%+v): %s", addr, err)
	}
	if err := ep.Connect(dstAddr); err != nil {
		t.Fatalf("ep.Connect(%+v): %s", dstAddr, err)
	}
	got, err := ep.GetLocalAddress()
	if err != nil {
		t.Fatalf("ep.GetLocalAddress(): %s", err)
	}
	return got.Addr
}

// TestAutoGenAddrDeprecateFromPI tests deprecating a SLAAC address when
// receiving a PI with 0 preferred lifetime.
func TestAutoGenAddrDeprecateFromPI(t *testing.T) {
	const nicID = 1

	prefix1, _, addr1 := prefixSubnetAddr(0, linkAddr1)
	prefix2, _, addr2 := prefixSubnetAddr(1, linkAddr1)

	ndpDisp, e, s := stackAndNdpDispatcherWithDefaultRoute(t, nicID)

	expectAutoGenAddrEvent := func(addr tcpip.AddressWithPrefix, eventType ndpAutoGenAddrEventType) {
		t.Helper()

		select {
		case e := <-ndpDisp.autoGenAddrC:
			if diff := checkAutoGenAddrEvent(e, addr, eventType); diff != "" {
				t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
			}
		default:
			t.Fatal("expected addr auto gen event")
		}
	}

	expectPrimaryAddr := func(addr tcpip.AddressWithPrefix) {
		t.Helper()

		if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, addr); err != nil {
			t.Fatal(err)
		}

		if got := addrForNewConnection(t, s); got != addr.Address {
			t.Errorf("got addrForNewConnection = %s, want = %s", got, addr.Address)
		}
	}

	// Receive PI for prefix1.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, 100, 100))
	expectAutoGenAddrEvent(addr1, newAddr)
	if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr1) {
		t.Fatalf("should have %s in the list of addresses", addr1)
	}
	expectPrimaryAddr(addr1)

	// Deprecate addr for prefix1 immedaitely.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, 100, 0))
	expectAutoGenAddrEvent(addr1, deprecatedAddr)
	if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr1) {
		t.Fatalf("should have %s in the list of addresses", addr1)
	}
	// addr should still be the primary endpoint as there are no other addresses.
	expectPrimaryAddr(addr1)

	// Refresh lifetimes of addr generated from prefix1.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, 100, 100))
	select {
	case <-ndpDisp.autoGenAddrC:
		t.Fatal("unexpectedly got an auto-generated event")
	default:
	}
	expectPrimaryAddr(addr1)

	// Receive PI for prefix2.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix2, true, true, 100, 100))
	expectAutoGenAddrEvent(addr2, newAddr)
	if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr2) {
		t.Fatalf("should have %s in the list of addresses", addr2)
	}
	expectPrimaryAddr(addr2)

	// Deprecate addr for prefix2 immedaitely.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix2, true, true, 100, 0))
	expectAutoGenAddrEvent(addr2, deprecatedAddr)
	if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr2) {
		t.Fatalf("should have %s in the list of addresses", addr2)
	}
	// addr1 should be the primary endpoint now since addr2 is deprecated but
	// addr1 is not.
	expectPrimaryAddr(addr1)
	// addr2 is deprecated but if explicitly requested, it should be used.
	fullAddr2 := tcpip.FullAddress{Addr: addr2.Address, NIC: nicID}
	if got := addrForNewConnectionWithAddr(t, s, fullAddr2); got != addr2.Address {
		t.Errorf("got addrForNewConnectionWithAddr(_, _, %+v) = %s, want = %s", fullAddr2, got, addr2.Address)
	}

	// Another PI w/ 0 preferred lifetime should not result in a deprecation
	// event.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix2, true, true, 100, 0))
	select {
	case <-ndpDisp.autoGenAddrC:
		t.Fatal("unexpectedly got an auto-generated event")
	default:
	}
	expectPrimaryAddr(addr1)
	if got := addrForNewConnectionWithAddr(t, s, fullAddr2); got != addr2.Address {
		t.Errorf("got addrForNewConnectionWithAddr(_, _, %+v) = %s, want = %s", fullAddr2, got, addr2.Address)
	}

	// Refresh lifetimes of addr generated from prefix2.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix2, true, true, 100, 100))
	select {
	case <-ndpDisp.autoGenAddrC:
		t.Fatal("unexpectedly got an auto-generated event")
	default:
	}
	expectPrimaryAddr(addr2)
}

// TestAutoGenAddrJobDeprecation tests that an address is properly deprecated
// when its preferred lifetime expires.
func TestAutoGenAddrJobDeprecation(t *testing.T) {
	const nicID = 1
	const newMinVL = 2
	newMinVLDuration := newMinVL * time.Second

	saved := ipv6.MinPrefixInformationValidLifetimeForUpdate
	defer func() {
		ipv6.MinPrefixInformationValidLifetimeForUpdate = saved
	}()
	ipv6.MinPrefixInformationValidLifetimeForUpdate = newMinVLDuration

	prefix1, _, addr1 := prefixSubnetAddr(0, linkAddr1)
	prefix2, _, addr2 := prefixSubnetAddr(1, linkAddr1)

	ndpDisp, e, s := stackAndNdpDispatcherWithDefaultRoute(t, nicID)

	expectAutoGenAddrEvent := func(addr tcpip.AddressWithPrefix, eventType ndpAutoGenAddrEventType) {
		t.Helper()

		select {
		case e := <-ndpDisp.autoGenAddrC:
			if diff := checkAutoGenAddrEvent(e, addr, eventType); diff != "" {
				t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
			}
		default:
			t.Fatal("expected addr auto gen event")
		}
	}

	expectAutoGenAddrEventAfter := func(addr tcpip.AddressWithPrefix, eventType ndpAutoGenAddrEventType, timeout time.Duration) {
		t.Helper()

		select {
		case e := <-ndpDisp.autoGenAddrC:
			if diff := checkAutoGenAddrEvent(e, addr, eventType); diff != "" {
				t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
			}
		case <-time.After(timeout):
			t.Fatal("timed out waiting for addr auto gen event")
		}
	}

	expectPrimaryAddr := func(addr tcpip.AddressWithPrefix) {
		t.Helper()

		if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, addr); err != nil {
			t.Fatal(err)
		}

		if got := addrForNewConnection(t, s); got != addr.Address {
			t.Errorf("got addrForNewConnection = %s, want = %s", got, addr.Address)
		}
	}

	// Receive PI for prefix2.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix2, true, true, 100, 100))
	expectAutoGenAddrEvent(addr2, newAddr)
	if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr2) {
		t.Fatalf("should have %s in the list of addresses", addr2)
	}
	expectPrimaryAddr(addr2)

	// Receive a PI for prefix1.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, 100, 90))
	expectAutoGenAddrEvent(addr1, newAddr)
	if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr1) {
		t.Fatalf("should have %s in the list of addresses", addr1)
	}
	if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr2) {
		t.Fatalf("should have %s in the list of addresses", addr2)
	}
	expectPrimaryAddr(addr1)

	// Refresh lifetime for addr of prefix1.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, newMinVL, newMinVL-1))
	select {
	case <-ndpDisp.autoGenAddrC:
		t.Fatal("unexpectedly got an auto-generated event")
	default:
	}
	expectPrimaryAddr(addr1)

	// Wait for addr of prefix1 to be deprecated.
	expectAutoGenAddrEventAfter(addr1, deprecatedAddr, newMinVLDuration-time.Second+defaultAsyncPositiveEventTimeout)
	if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr1) {
		t.Fatalf("should not have %s in the list of addresses", addr1)
	}
	if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr2) {
		t.Fatalf("should have %s in the list of addresses", addr2)
	}
	// addr2 should be the primary endpoint now since addr1 is deprecated but
	// addr2 is not.
	expectPrimaryAddr(addr2)
	// addr1 is deprecated but if explicitly requested, it should be used.
	fullAddr1 := tcpip.FullAddress{Addr: addr1.Address, NIC: nicID}
	if got := addrForNewConnectionWithAddr(t, s, fullAddr1); got != addr1.Address {
		t.Errorf("got addrForNewConnectionWithAddr(_, _, %+v) = %s, want = %s", fullAddr1, got, addr1.Address)
	}

	// Refresh valid lifetime for addr of prefix1, w/ 0 preferred lifetime to make
	// sure we do not get a deprecation event again.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, newMinVL, 0))
	select {
	case <-ndpDisp.autoGenAddrC:
		t.Fatal("unexpectedly got an auto-generated event")
	default:
	}
	expectPrimaryAddr(addr2)
	if got := addrForNewConnectionWithAddr(t, s, fullAddr1); got != addr1.Address {
		t.Errorf("got addrForNewConnectionWithAddr(_, _, %+v) = %s, want = %s", fullAddr1, got, addr1.Address)
	}

	// Refresh lifetimes for addr of prefix1.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, newMinVL, newMinVL-1))
	select {
	case <-ndpDisp.autoGenAddrC:
		t.Fatal("unexpectedly got an auto-generated event")
	default:
	}
	// addr1 is the primary endpoint again since it is non-deprecated now.
	expectPrimaryAddr(addr1)

	// Wait for addr of prefix1 to be deprecated.
	expectAutoGenAddrEventAfter(addr1, deprecatedAddr, newMinVLDuration-time.Second+defaultAsyncPositiveEventTimeout)
	if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr1) {
		t.Fatalf("should not have %s in the list of addresses", addr1)
	}
	if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr2) {
		t.Fatalf("should have %s in the list of addresses", addr2)
	}
	// addr2 should be the primary endpoint now since it is not deprecated.
	expectPrimaryAddr(addr2)
	if got := addrForNewConnectionWithAddr(t, s, fullAddr1); got != addr1.Address {
		t.Errorf("got addrForNewConnectionWithAddr(_, _, %+v) = %s, want = %s", fullAddr1, got, addr1.Address)
	}

	// Wait for addr of prefix1 to be invalidated.
	expectAutoGenAddrEventAfter(addr1, invalidatedAddr, time.Second+defaultAsyncPositiveEventTimeout)
	if containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr1) {
		t.Fatalf("should not have %s in the list of addresses", addr1)
	}
	if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr2) {
		t.Fatalf("should have %s in the list of addresses", addr2)
	}
	expectPrimaryAddr(addr2)

	// Refresh both lifetimes for addr of prefix2 to the same value.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix2, true, true, newMinVL, newMinVL))
	select {
	case <-ndpDisp.autoGenAddrC:
		t.Fatal("unexpectedly got an auto-generated event")
	default:
	}

	// Wait for a deprecation then invalidation events, or just an invalidation
	// event. We need to cover both cases but cannot deterministically hit both
	// cases because the deprecation and invalidation handlers could be handled in
	// either deprecation then invalidation, or invalidation then deprecation
	// (which should be cancelled by the invalidation handler).
	select {
	case e := <-ndpDisp.autoGenAddrC:
		if diff := checkAutoGenAddrEvent(e, addr2, deprecatedAddr); diff == "" {
			// If we get a deprecation event first, we should get an invalidation
			// event almost immediately after.
			select {
			case e := <-ndpDisp.autoGenAddrC:
				if diff := checkAutoGenAddrEvent(e, addr2, invalidatedAddr); diff != "" {
					t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
				}
			case <-time.After(defaultAsyncPositiveEventTimeout):
				t.Fatal("timed out waiting for addr auto gen event")
			}
		} else if diff := checkAutoGenAddrEvent(e, addr2, invalidatedAddr); diff == "" {
			// If we get an invalidation  event first, we should not get a deprecation
			// event after.
			select {
			case <-ndpDisp.autoGenAddrC:
				t.Fatal("unexpectedly got an auto-generated event")
			case <-time.After(defaultAsyncNegativeEventTimeout):
			}
		} else {
			t.Fatalf("got unexpected auto-generated event")
		}
	case <-time.After(newMinVLDuration + defaultAsyncPositiveEventTimeout):
		t.Fatal("timed out waiting for addr auto gen event")
	}
	if containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr1) {
		t.Fatalf("should not have %s in the list of addresses", addr1)
	}
	if containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr2) {
		t.Fatalf("should not have %s in the list of addresses", addr2)
	}
	// Should not have any primary endpoints.
	if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil {
		t.Fatal(err)
	}
	wq := waiter.Queue{}
	we, ch := waiter.NewChannelEntry(nil)
	wq.EventRegister(&we, waiter.EventIn)
	defer wq.EventUnregister(&we)
	defer close(ch)
	ep, err := s.NewEndpoint(header.UDPProtocolNumber, header.IPv6ProtocolNumber, &wq)
	if err != nil {
		t.Fatalf("s.NewEndpoint(%d, %d, _): %s", header.UDPProtocolNumber, header.IPv6ProtocolNumber, err)
	}
	defer ep.Close()
	ep.SocketOptions().SetV6Only(true)

	{
		err := ep.Connect(dstAddr)
		if _, ok := err.(*tcpip.ErrNoRoute); !ok {
			t.Errorf("got ep.Connect(%+v) = %s, want = %s", dstAddr, err, &tcpip.ErrNoRoute{})
		}
	}
}

// Tests transitioning a SLAAC address's valid lifetime between finite and
// infinite values.
func TestAutoGenAddrFiniteToInfiniteToFiniteVL(t *testing.T) {
	const infiniteVLSeconds = 2
	const minVLSeconds = 1
	savedIL := header.NDPInfiniteLifetime
	savedMinVL := ipv6.MinPrefixInformationValidLifetimeForUpdate
	defer func() {
		ipv6.MinPrefixInformationValidLifetimeForUpdate = savedMinVL
		header.NDPInfiniteLifetime = savedIL
	}()
	ipv6.MinPrefixInformationValidLifetimeForUpdate = minVLSeconds * time.Second
	header.NDPInfiniteLifetime = infiniteVLSeconds * time.Second

	prefix, _, addr := prefixSubnetAddr(0, linkAddr1)

	tests := []struct {
		name       string
		infiniteVL uint32
	}{
		{
			name:       "EqualToInfiniteVL",
			infiniteVL: infiniteVLSeconds,
		},
		// Our implementation supports changing header.NDPInfiniteLifetime for tests
		// such that a packet can be received where the lifetime field has a value
		// greater than header.NDPInfiniteLifetime. Because of this, we test to make
		// sure that receiving a value greater than header.NDPInfiniteLifetime is
		// handled the same as when receiving a value equal to
		// header.NDPInfiniteLifetime.
		{
			name:       "MoreThanInfiniteVL",
			infiniteVL: infiniteVLSeconds + 1,
		},
	}

	// This Run will not return until the parallel tests finish.
	//
	// We need this because we need to do some teardown work after the
	// parallel tests complete.
	//
	// See https://godoc.org/testing#hdr-Subtests_and_Sub_benchmarks for
	// more details.
	t.Run("group", func(t *testing.T) {
		for _, test := range tests {
			test := test

			t.Run(test.name, func(t *testing.T) {
				t.Parallel()

				ndpDisp := ndpDispatcher{
					autoGenAddrC: make(chan ndpAutoGenAddrEvent, 1),
				}
				e := channel.New(0, 1280, linkAddr1)
				s := stack.New(stack.Options{
					NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
						NDPConfigs: ipv6.NDPConfigurations{
							HandleRAs:              true,
							AutoGenGlobalAddresses: true,
						},
						NDPDisp: &ndpDisp,
					})},
				})

				if err := s.CreateNIC(1, e); err != nil {
					t.Fatalf("CreateNIC(1) = %s", err)
				}

				// Receive an RA with finite prefix.
				e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, minVLSeconds, 0))
				select {
				case e := <-ndpDisp.autoGenAddrC:
					if diff := checkAutoGenAddrEvent(e, addr, newAddr); diff != "" {
						t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
					}

				default:
					t.Fatal("expected addr auto gen event")
				}

				// Receive an new RA with prefix with infinite VL.
				e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, test.infiniteVL, 0))

				// Receive a new RA with prefix with finite VL.
				e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, minVLSeconds, 0))

				select {
				case e := <-ndpDisp.autoGenAddrC:
					if diff := checkAutoGenAddrEvent(e, addr, invalidatedAddr); diff != "" {
						t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
					}

				case <-time.After(minVLSeconds*time.Second + defaultAsyncPositiveEventTimeout):
					t.Fatal("timeout waiting for addr auto gen event")
				}
			})
		}
	})
}

// TestAutoGenAddrValidLifetimeUpdates tests that the valid lifetime of an
// auto-generated address only gets updated when required to, as specified in
// RFC 4862 section 5.5.3.e.
func TestAutoGenAddrValidLifetimeUpdates(t *testing.T) {
	const infiniteVL = 4294967295
	const newMinVL = 4
	saved := ipv6.MinPrefixInformationValidLifetimeForUpdate
	defer func() {
		ipv6.MinPrefixInformationValidLifetimeForUpdate = saved
	}()
	ipv6.MinPrefixInformationValidLifetimeForUpdate = newMinVL * time.Second

	prefix, _, addr := prefixSubnetAddr(0, linkAddr1)

	tests := []struct {
		name string
		ovl  uint32
		nvl  uint32
		evl  uint32
	}{
		// Should update the VL to the minimum VL for updating if the
		// new VL is less than newMinVL but was originally greater than
		// it.
		{
			"LargeVLToVLLessThanMinVLForUpdate",
			9999,
			1,
			newMinVL,
		},
		{
			"LargeVLTo0",
			9999,
			0,
			newMinVL,
		},
		{
			"InfiniteVLToVLLessThanMinVLForUpdate",
			infiniteVL,
			1,
			newMinVL,
		},
		{
			"InfiniteVLTo0",
			infiniteVL,
			0,
			newMinVL,
		},

		// Should not update VL if original VL was less than newMinVL
		// and the new VL is also less than newMinVL.
		{
			"ShouldNotUpdateWhenBothOldAndNewAreLessThanMinVLForUpdate",
			newMinVL - 1,
			newMinVL - 3,
			newMinVL - 1,
		},

		// Should take the new VL if the new VL is greater than the
		// remaining time or is greater than newMinVL.
		{
			"MorethanMinVLToLesserButStillMoreThanMinVLForUpdate",
			newMinVL + 5,
			newMinVL + 3,
			newMinVL + 3,
		},
		{
			"SmallVLToGreaterVLButStillLessThanMinVLForUpdate",
			newMinVL - 3,
			newMinVL - 1,
			newMinVL - 1,
		},
		{
			"SmallVLToGreaterVLThatIsMoreThaMinVLForUpdate",
			newMinVL - 3,
			newMinVL + 1,
			newMinVL + 1,
		},
	}

	// This Run will not return until the parallel tests finish.
	//
	// We need this because we need to do some teardown work after the
	// parallel tests complete.
	//
	// See https://godoc.org/testing#hdr-Subtests_and_Sub_benchmarks for
	// more details.
	t.Run("group", func(t *testing.T) {
		for _, test := range tests {
			test := test

			t.Run(test.name, func(t *testing.T) {
				t.Parallel()

				ndpDisp := ndpDispatcher{
					autoGenAddrC: make(chan ndpAutoGenAddrEvent, 10),
				}
				e := channel.New(10, 1280, linkAddr1)
				s := stack.New(stack.Options{
					NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
						NDPConfigs: ipv6.NDPConfigurations{
							HandleRAs:              true,
							AutoGenGlobalAddresses: true,
						},
						NDPDisp: &ndpDisp,
					})},
				})

				if err := s.CreateNIC(1, e); err != nil {
					t.Fatalf("CreateNIC(1) = %s", err)
				}

				// Receive an RA with prefix with initial VL,
				// test.ovl.
				e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, test.ovl, 0))
				select {
				case e := <-ndpDisp.autoGenAddrC:
					if diff := checkAutoGenAddrEvent(e, addr, newAddr); diff != "" {
						t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
					}
				default:
					t.Fatal("expected addr auto gen event")
				}

				// Receive an new RA with prefix with new VL,
				// test.nvl.
				e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, test.nvl, 0))

				//
				// Validate that the VL for the address got set
				// to test.evl.
				//

				// The address should not be invalidated until the effective valid
				// lifetime has passed.
				select {
				case <-ndpDisp.autoGenAddrC:
					t.Fatal("unexpectedly received an auto gen addr event")
				case <-time.After(time.Duration(test.evl)*time.Second - defaultAsyncNegativeEventTimeout):
				}

				// Wait for the invalidation event.
				select {
				case e := <-ndpDisp.autoGenAddrC:
					if diff := checkAutoGenAddrEvent(e, addr, invalidatedAddr); diff != "" {
						t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
					}
				case <-time.After(defaultAsyncPositiveEventTimeout):
					t.Fatal("timeout waiting for addr auto gen event")
				}
			})
		}
	})
}

// TestAutoGenAddrRemoval tests that when auto-generated addresses are removed
// by the user, its resources will be cleaned up and an invalidation event will
// be sent to the integrator.
func TestAutoGenAddrRemoval(t *testing.T) {
	prefix, _, addr := prefixSubnetAddr(0, linkAddr1)

	ndpDisp := ndpDispatcher{
		autoGenAddrC: make(chan ndpAutoGenAddrEvent, 1),
	}
	e := channel.New(0, 1280, linkAddr1)
	s := stack.New(stack.Options{
		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
			NDPConfigs: ipv6.NDPConfigurations{
				HandleRAs:              true,
				AutoGenGlobalAddresses: true,
			},
			NDPDisp: &ndpDisp,
		})},
	})

	if err := s.CreateNIC(1, e); err != nil {
		t.Fatalf("CreateNIC(1) = %s", err)
	}

	expectAutoGenAddrEvent := func(addr tcpip.AddressWithPrefix, eventType ndpAutoGenAddrEventType) {
		t.Helper()

		select {
		case e := <-ndpDisp.autoGenAddrC:
			if diff := checkAutoGenAddrEvent(e, addr, eventType); diff != "" {
				t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
			}
		default:
			t.Fatal("expected addr auto gen event")
		}
	}

	// Receive a PI to auto-generate an address.
	const lifetimeSeconds = 1
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, lifetimeSeconds, 0))
	expectAutoGenAddrEvent(addr, newAddr)

	// Removing the address should result in an invalidation event
	// immediately.
	if err := s.RemoveAddress(1, addr.Address); err != nil {
		t.Fatalf("RemoveAddress(_, %s) = %s", addr.Address, err)
	}
	expectAutoGenAddrEvent(addr, invalidatedAddr)

	// Wait for the original valid lifetime to make sure the original job got
	// cancelled/cleaned up.
	select {
	case <-ndpDisp.autoGenAddrC:
		t.Fatal("unexpectedly received an auto gen addr event")
	case <-time.After(lifetimeSeconds*time.Second + defaultAsyncNegativeEventTimeout):
	}
}

// TestAutoGenAddrAfterRemoval tests adding a SLAAC address that was previously
// assigned to the NIC but is in the permanentExpired state.
func TestAutoGenAddrAfterRemoval(t *testing.T) {
	const nicID = 1

	prefix1, _, addr1 := prefixSubnetAddr(0, linkAddr1)
	prefix2, _, addr2 := prefixSubnetAddr(1, linkAddr1)
	ndpDisp, e, s := stackAndNdpDispatcherWithDefaultRoute(t, nicID)

	expectAutoGenAddrEvent := func(addr tcpip.AddressWithPrefix, eventType ndpAutoGenAddrEventType) {
		t.Helper()

		select {
		case e := <-ndpDisp.autoGenAddrC:
			if diff := checkAutoGenAddrEvent(e, addr, eventType); diff != "" {
				t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
			}
		default:
			t.Fatal("expected addr auto gen event")
		}
	}

	expectPrimaryAddr := func(addr tcpip.AddressWithPrefix) {
		t.Helper()

		if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, addr); err != nil {
			t.Fatal(err)
		}

		if got := addrForNewConnection(t, s); got != addr.Address {
			t.Errorf("got addrForNewConnection = %s, want = %s", got, addr.Address)
		}
	}

	// Receive a PI to auto-generate addr1 with a large valid and preferred
	// lifetime.
	const largeLifetimeSeconds = 999
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr3, 0, prefix1, true, true, largeLifetimeSeconds, largeLifetimeSeconds))
	expectAutoGenAddrEvent(addr1, newAddr)
	expectPrimaryAddr(addr1)

	// Add addr2 as a static address.
	protoAddr2 := tcpip.ProtocolAddress{
		Protocol:          header.IPv6ProtocolNumber,
		AddressWithPrefix: addr2,
	}
	if err := s.AddProtocolAddressWithOptions(nicID, protoAddr2, stack.FirstPrimaryEndpoint); err != nil {
		t.Fatalf("AddProtocolAddressWithOptions(%d, %+v, %d) = %s", nicID, protoAddr2, stack.FirstPrimaryEndpoint, err)
	}
	// addr2 should be more preferred now since it is at the front of the primary
	// list.
	expectPrimaryAddr(addr2)

	// Get a route using addr2 to increment its reference count then remove it
	// to leave it in the permanentExpired state.
	r, err := s.FindRoute(nicID, addr2.Address, addr3, header.IPv6ProtocolNumber, false)
	if err != nil {
		t.Fatalf("FindRoute(%d, %s, %s, %d, false): %s", nicID, addr2.Address, addr3, header.IPv6ProtocolNumber, err)
	}
	defer r.Release()
	if err := s.RemoveAddress(nicID, addr2.Address); err != nil {
		t.Fatalf("s.RemoveAddress(%d, %s): %s", nicID, addr2.Address, err)
	}
	// addr1 should be preferred again since addr2 is in the expired state.
	expectPrimaryAddr(addr1)

	// Receive a PI to auto-generate addr2 as valid and preferred.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr3, 0, prefix2, true, true, largeLifetimeSeconds, largeLifetimeSeconds))
	expectAutoGenAddrEvent(addr2, newAddr)
	// addr2 should be more preferred now that it is closer to the front of the
	// primary list and not deprecated.
	expectPrimaryAddr(addr2)

	// Removing the address should result in an invalidation event immediately.
	// It should still be in the permanentExpired state because r is still held.
	//
	// We remove addr2 here to make sure addr2 was marked as a SLAAC address
	// (it was previously marked as a static address).
	if err := s.RemoveAddress(1, addr2.Address); err != nil {
		t.Fatalf("RemoveAddress(_, %s) = %s", addr2.Address, err)
	}
	expectAutoGenAddrEvent(addr2, invalidatedAddr)
	// addr1 should be more preferred since addr2 is in the expired state.
	expectPrimaryAddr(addr1)

	// Receive a PI to auto-generate addr2 as valid and deprecated.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr3, 0, prefix2, true, true, largeLifetimeSeconds, 0))
	expectAutoGenAddrEvent(addr2, newAddr)
	// addr1 should still be more preferred since addr2 is deprecated, even though
	// it is closer to the front of the primary list.
	expectPrimaryAddr(addr1)

	// Receive a PI to refresh addr2's preferred lifetime.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr3, 0, prefix2, true, true, largeLifetimeSeconds, largeLifetimeSeconds))
	select {
	case <-ndpDisp.autoGenAddrC:
		t.Fatal("unexpectedly got an auto gen addr event")
	default:
	}
	// addr2 should be more preferred now that it is not deprecated.
	expectPrimaryAddr(addr2)

	if err := s.RemoveAddress(1, addr2.Address); err != nil {
		t.Fatalf("RemoveAddress(_, %s) = %s", addr2.Address, err)
	}
	expectAutoGenAddrEvent(addr2, invalidatedAddr)
	expectPrimaryAddr(addr1)
}

// TestAutoGenAddrStaticConflict tests that if SLAAC generates an address that
// is already assigned to the NIC, the static address remains.
func TestAutoGenAddrStaticConflict(t *testing.T) {
	prefix, _, addr := prefixSubnetAddr(0, linkAddr1)

	ndpDisp := ndpDispatcher{
		autoGenAddrC: make(chan ndpAutoGenAddrEvent, 1),
	}
	e := channel.New(0, 1280, linkAddr1)
	s := stack.New(stack.Options{
		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
			NDPConfigs: ipv6.NDPConfigurations{
				HandleRAs:              true,
				AutoGenGlobalAddresses: true,
			},
			NDPDisp: &ndpDisp,
		})},
	})

	if err := s.CreateNIC(1, e); err != nil {
		t.Fatalf("CreateNIC(1) = %s", err)
	}

	// Add the address as a static address before SLAAC tries to add it.
	if err := s.AddProtocolAddress(1, tcpip.ProtocolAddress{Protocol: header.IPv6ProtocolNumber, AddressWithPrefix: addr}); err != nil {
		t.Fatalf("AddAddress(_, %d, %s) = %s", header.IPv6ProtocolNumber, addr.Address, err)
	}
	if !containsV6Addr(s.NICInfo()[1].ProtocolAddresses, addr) {
		t.Fatalf("Should have %s in the list of addresses", addr1)
	}

	// Receive a PI where the generated address will be the same as the one
	// that we already have assigned statically.
	const lifetimeSeconds = 1
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, lifetimeSeconds, 0))
	select {
	case <-ndpDisp.autoGenAddrC:
		t.Fatal("unexpectedly received an auto gen addr event for an address we already have statically")
	default:
	}
	if !containsV6Addr(s.NICInfo()[1].ProtocolAddresses, addr) {
		t.Fatalf("Should have %s in the list of addresses", addr1)
	}

	// Should not get an invalidation event after the PI's invalidation
	// time.
	select {
	case <-ndpDisp.autoGenAddrC:
		t.Fatal("unexpectedly received an auto gen addr event")
	case <-time.After(lifetimeSeconds*time.Second + defaultAsyncNegativeEventTimeout):
	}
	if !containsV6Addr(s.NICInfo()[1].ProtocolAddresses, addr) {
		t.Fatalf("Should have %s in the list of addresses", addr1)
	}
}

// TestAutoGenAddrWithOpaqueIID tests that SLAAC generated addresses will use
// opaque interface identifiers when configured to do so.
func TestAutoGenAddrWithOpaqueIID(t *testing.T) {
	const nicID = 1
	const nicName = "nic1"
	var secretKeyBuf [header.OpaqueIIDSecretKeyMinBytes]byte
	secretKey := secretKeyBuf[:]
	n, err := rand.Read(secretKey)
	if err != nil {
		t.Fatalf("rand.Read(_): %s", err)
	}
	if n != header.OpaqueIIDSecretKeyMinBytes {
		t.Fatalf("got rand.Read(_) = (%d, _), want = (%d, _)", n, header.OpaqueIIDSecretKeyMinBytes)
	}

	prefix1, subnet1, _ := prefixSubnetAddr(0, linkAddr1)
	prefix2, subnet2, _ := prefixSubnetAddr(1, linkAddr1)
	// addr1 and addr2 are the addresses that are expected to be generated when
	// stack.Stack is configured to generate opaque interface identifiers as
	// defined by RFC 7217.
	addrBytes := []byte(subnet1.ID())
	addr1 := tcpip.AddressWithPrefix{
		Address:   tcpip.Address(header.AppendOpaqueInterfaceIdentifier(addrBytes[:header.IIDOffsetInIPv6Address], subnet1, nicName, 0, secretKey)),
		PrefixLen: 64,
	}
	addrBytes = []byte(subnet2.ID())
	addr2 := tcpip.AddressWithPrefix{
		Address:   tcpip.Address(header.AppendOpaqueInterfaceIdentifier(addrBytes[:header.IIDOffsetInIPv6Address], subnet2, nicName, 0, secretKey)),
		PrefixLen: 64,
	}

	ndpDisp := ndpDispatcher{
		autoGenAddrC: make(chan ndpAutoGenAddrEvent, 1),
	}
	e := channel.New(0, 1280, linkAddr1)
	s := stack.New(stack.Options{
		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
			NDPConfigs: ipv6.NDPConfigurations{
				HandleRAs:              true,
				AutoGenGlobalAddresses: true,
			},
			NDPDisp: &ndpDisp,
			OpaqueIIDOpts: ipv6.OpaqueInterfaceIdentifierOptions{
				NICNameFromID: func(_ tcpip.NICID, nicName string) string {
					return nicName
				},
				SecretKey: secretKey,
			},
		})},
	})
	opts := stack.NICOptions{Name: nicName}
	if err := s.CreateNICWithOptions(nicID, e, opts); err != nil {
		t.Fatalf("CreateNICWithOptions(%d, _, %+v, _) = %s", nicID, opts, err)
	}

	expectAutoGenAddrEvent := func(addr tcpip.AddressWithPrefix, eventType ndpAutoGenAddrEventType) {
		t.Helper()

		select {
		case e := <-ndpDisp.autoGenAddrC:
			if diff := checkAutoGenAddrEvent(e, addr, eventType); diff != "" {
				t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
			}
		default:
			t.Fatal("expected addr auto gen event")
		}
	}

	// Receive an RA with prefix1 in a PI.
	const validLifetimeSecondPrefix1 = 1
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix1, true, true, validLifetimeSecondPrefix1, 0))
	expectAutoGenAddrEvent(addr1, newAddr)
	if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr1) {
		t.Fatalf("should have %s in the list of addresses", addr1)
	}

	// Receive an RA with prefix2 in a PI with a large valid lifetime.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix2, true, true, 100, 0))
	expectAutoGenAddrEvent(addr2, newAddr)
	if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr1) {
		t.Fatalf("should have %s in the list of addresses", addr1)
	}
	if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr2) {
		t.Fatalf("should have %s in the list of addresses", addr2)
	}

	// Wait for addr of prefix1 to be invalidated.
	select {
	case e := <-ndpDisp.autoGenAddrC:
		if diff := checkAutoGenAddrEvent(e, addr1, invalidatedAddr); diff != "" {
			t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
		}
	case <-time.After(validLifetimeSecondPrefix1*time.Second + defaultAsyncPositiveEventTimeout):
		t.Fatal("timed out waiting for addr auto gen event")
	}
	if containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr1) {
		t.Fatalf("should not have %s in the list of addresses", addr1)
	}
	if !containsV6Addr(s.NICInfo()[nicID].ProtocolAddresses, addr2) {
		t.Fatalf("should have %s in the list of addresses", addr2)
	}
}

func TestAutoGenAddrInResponseToDADConflicts(t *testing.T) {
	const nicID = 1
	const nicName = "nic"
	const dadTransmits = 1
	const retransmitTimer = time.Second
	const maxMaxRetries = 3
	const lifetimeSeconds = 10

	// Needed for the temporary address sub test.
	savedMaxDesync := ipv6.MaxDesyncFactor
	defer func() {
		ipv6.MaxDesyncFactor = savedMaxDesync
	}()
	ipv6.MaxDesyncFactor = time.Nanosecond

	var secretKeyBuf [header.OpaqueIIDSecretKeyMinBytes]byte
	secretKey := secretKeyBuf[:]
	n, err := rand.Read(secretKey)
	if err != nil {
		t.Fatalf("rand.Read(_): %s", err)
	}
	if n != header.OpaqueIIDSecretKeyMinBytes {
		t.Fatalf("got rand.Read(_) = (%d, _), want = (%d, _)", n, header.OpaqueIIDSecretKeyMinBytes)
	}

	prefix, subnet, _ := prefixSubnetAddr(0, linkAddr1)

	addrForSubnet := func(subnet tcpip.Subnet, dadCounter uint8) tcpip.AddressWithPrefix {
		addrBytes := []byte(subnet.ID())
		return tcpip.AddressWithPrefix{
			Address:   tcpip.Address(header.AppendOpaqueInterfaceIdentifier(addrBytes[:header.IIDOffsetInIPv6Address], subnet, nicName, dadCounter, secretKey)),
			PrefixLen: 64,
		}
	}

	expectAutoGenAddrEvent := func(t *testing.T, ndpDisp *ndpDispatcher, addr tcpip.AddressWithPrefix, eventType ndpAutoGenAddrEventType) {
		t.Helper()

		select {
		case e := <-ndpDisp.autoGenAddrC:
			if diff := checkAutoGenAddrEvent(e, addr, eventType); diff != "" {
				t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
			}
		default:
			t.Fatal("expected addr auto gen event")
		}
	}

	expectAutoGenAddrEventAsync := func(t *testing.T, ndpDisp *ndpDispatcher, addr tcpip.AddressWithPrefix, eventType ndpAutoGenAddrEventType) {
		t.Helper()

		select {
		case e := <-ndpDisp.autoGenAddrC:
			if diff := checkAutoGenAddrEvent(e, addr, eventType); diff != "" {
				t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
			}
		case <-time.After(defaultAsyncPositiveEventTimeout):
			t.Fatal("timed out waiting for addr auto gen event")
		}
	}

	expectDADEvent := func(t *testing.T, ndpDisp *ndpDispatcher, addr tcpip.Address, res stack.DADResult) {
		t.Helper()

		select {
		case e := <-ndpDisp.dadC:
			if diff := checkDADEvent(e, nicID, addr, res); diff != "" {
				t.Errorf("DAD event mismatch (-want +got):\n%s", diff)
			}
		default:
			t.Fatal("expected DAD event")
		}
	}

	expectDADEventAsync := func(t *testing.T, ndpDisp *ndpDispatcher, addr tcpip.Address, res stack.DADResult) {
		t.Helper()

		select {
		case e := <-ndpDisp.dadC:
			if diff := checkDADEvent(e, nicID, addr, res); diff != "" {
				t.Errorf("DAD event mismatch (-want +got):\n%s", diff)
			}
		case <-time.After(dadTransmits*retransmitTimer + defaultAsyncPositiveEventTimeout):
			t.Fatal("timed out waiting for DAD event")
		}
	}

	stableAddrForTempAddrTest := addrForSubnet(subnet, 0)

	addrTypes := []struct {
		name             string
		ndpConfigs       ipv6.NDPConfigurations
		autoGenLinkLocal bool
		prepareFn        func(t *testing.T, ndpDisp *ndpDispatcher, e *channel.Endpoint, tempIIDHistory []byte) []tcpip.AddressWithPrefix
		addrGenFn        func(dadCounter uint8, tempIIDHistory []byte) tcpip.AddressWithPrefix
	}{
		{
			name: "Global address",
			ndpConfigs: ipv6.NDPConfigurations{
				HandleRAs:              true,
				AutoGenGlobalAddresses: true,
			},
			prepareFn: func(_ *testing.T, _ *ndpDispatcher, e *channel.Endpoint, _ []byte) []tcpip.AddressWithPrefix {
				// Receive an RA with prefix1 in a PI.
				e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, lifetimeSeconds, lifetimeSeconds))
				return nil

			},
			addrGenFn: func(dadCounter uint8, _ []byte) tcpip.AddressWithPrefix {
				return addrForSubnet(subnet, dadCounter)
			},
		},
		{
			name:             "LinkLocal address",
			ndpConfigs:       ipv6.NDPConfigurations{},
			autoGenLinkLocal: true,
			prepareFn: func(*testing.T, *ndpDispatcher, *channel.Endpoint, []byte) []tcpip.AddressWithPrefix {
				return nil
			},
			addrGenFn: func(dadCounter uint8, _ []byte) tcpip.AddressWithPrefix {
				return addrForSubnet(header.IPv6LinkLocalPrefix.Subnet(), dadCounter)
			},
		},
		{
			name: "Temporary address",
			ndpConfigs: ipv6.NDPConfigurations{
				HandleRAs:                  true,
				AutoGenGlobalAddresses:     true,
				AutoGenTempGlobalAddresses: true,
			},
			prepareFn: func(t *testing.T, ndpDisp *ndpDispatcher, e *channel.Endpoint, tempIIDHistory []byte) []tcpip.AddressWithPrefix {
				header.InitialTempIID(tempIIDHistory, nil, nicID)

				// Generate a stable SLAAC address so temporary addresses will be
				// generated.
				e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, 100, 100))
				expectAutoGenAddrEvent(t, ndpDisp, stableAddrForTempAddrTest, newAddr)
				expectDADEventAsync(t, ndpDisp, stableAddrForTempAddrTest.Address, &stack.DADSucceeded{})

				// The stable address will be assigned throughout the test.
				return []tcpip.AddressWithPrefix{stableAddrForTempAddrTest}
			},
			addrGenFn: func(_ uint8, tempIIDHistory []byte) tcpip.AddressWithPrefix {
				return header.GenerateTempIPv6SLAACAddr(tempIIDHistory, stableAddrForTempAddrTest.Address)
			},
		},
	}

	for _, addrType := range addrTypes {
		// This Run will not return until the parallel tests finish.
		//
		// We need this because we need to do some teardown work after the parallel
		// tests complete and limit the number of parallel tests running at the same
		// time to reduce flakes.
		//
		// See https://godoc.org/testing#hdr-Subtests_and_Sub_benchmarks for
		// more details.
		t.Run(addrType.name, func(t *testing.T) {
			for maxRetries := uint8(0); maxRetries <= maxMaxRetries; maxRetries++ {
				for numFailures := uint8(0); numFailures <= maxRetries+1; numFailures++ {
					maxRetries := maxRetries
					numFailures := numFailures
					addrType := addrType

					t.Run(fmt.Sprintf("%d max retries and %d failures", maxRetries, numFailures), func(t *testing.T) {
						t.Parallel()

						ndpDisp := ndpDispatcher{
							dadC:         make(chan ndpDADEvent, 1),
							autoGenAddrC: make(chan ndpAutoGenAddrEvent, 2),
						}
						e := channel.New(0, 1280, linkAddr1)
						ndpConfigs := addrType.ndpConfigs
						ndpConfigs.AutoGenAddressConflictRetries = maxRetries
						s := stack.New(stack.Options{
							NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
								AutoGenLinkLocal: addrType.autoGenLinkLocal,
								DADConfigs: stack.DADConfigurations{
									DupAddrDetectTransmits: dadTransmits,
									RetransmitTimer:        retransmitTimer,
								},
								NDPConfigs: ndpConfigs,
								NDPDisp:    &ndpDisp,
								OpaqueIIDOpts: ipv6.OpaqueInterfaceIdentifierOptions{
									NICNameFromID: func(_ tcpip.NICID, nicName string) string {
										return nicName
									},
									SecretKey: secretKey,
								},
							})},
						})
						opts := stack.NICOptions{Name: nicName}
						if err := s.CreateNICWithOptions(nicID, e, opts); err != nil {
							t.Fatalf("CreateNICWithOptions(%d, _, %+v) = %s", nicID, opts, err)
						}

						var tempIIDHistory [header.IIDSize]byte
						stableAddrs := addrType.prepareFn(t, &ndpDisp, e, tempIIDHistory[:])

						// Simulate DAD conflicts so the address is regenerated.
						for i := uint8(0); i < numFailures; i++ {
							addr := addrType.addrGenFn(i, tempIIDHistory[:])
							expectAutoGenAddrEventAsync(t, &ndpDisp, addr, newAddr)

							// Should not have any new addresses assigned to the NIC.
							if mismatch := addressCheck(s.NICInfo()[nicID].ProtocolAddresses, stableAddrs, nil); mismatch != "" {
								t.Fatal(mismatch)
							}

							// Simulate a DAD conflict.
							rxNDPSolicit(e, addr.Address)
							expectAutoGenAddrEvent(t, &ndpDisp, addr, invalidatedAddr)
							expectDADEvent(t, &ndpDisp, addr.Address, &stack.DADDupAddrDetected{})

							// Attempting to add the address manually should not fail if the
							// address's state was cleaned up when DAD failed.
							if err := s.AddAddress(nicID, header.IPv6ProtocolNumber, addr.Address); err != nil {
								t.Fatalf("AddAddress(%d, %d, %s) = %s", nicID, header.IPv6ProtocolNumber, addr.Address, err)
							}
							if err := s.RemoveAddress(nicID, addr.Address); err != nil {
								t.Fatalf("RemoveAddress(%d, %s) = %s", nicID, addr.Address, err)
							}
							expectDADEvent(t, &ndpDisp, addr.Address, &stack.DADAborted{})
						}

						// Should not have any new addresses assigned to the NIC.
						if mismatch := addressCheck(s.NICInfo()[nicID].ProtocolAddresses, stableAddrs, nil); mismatch != "" {
							t.Fatal(mismatch)
						}

						// If we had less failures than generation attempts, we should have
						// an address after DAD resolves.
						if maxRetries+1 > numFailures {
							addr := addrType.addrGenFn(numFailures, tempIIDHistory[:])
							expectAutoGenAddrEventAsync(t, &ndpDisp, addr, newAddr)
							expectDADEventAsync(t, &ndpDisp, addr.Address, &stack.DADSucceeded{})
							if mismatch := addressCheck(s.NICInfo()[nicID].ProtocolAddresses, append(stableAddrs, addr), nil); mismatch != "" {
								t.Fatal(mismatch)
							}
						}

						// Should not attempt address generation again.
						select {
						case e := <-ndpDisp.autoGenAddrC:
							t.Fatalf("unexpectedly got an auto-generated address event = %+v", e)
						case <-time.After(defaultAsyncNegativeEventTimeout):
						}
					})
				}
			}
		})
	}
}

// TestAutoGenAddrWithEUI64IIDNoDADRetries tests that a regeneration attempt is
// not made for SLAAC addresses generated with an IID based on the NIC's link
// address.
func TestAutoGenAddrWithEUI64IIDNoDADRetries(t *testing.T) {
	const nicID = 1
	const dadTransmits = 1
	const retransmitTimer = time.Second
	const maxRetries = 3
	const lifetimeSeconds = 10

	prefix, subnet, _ := prefixSubnetAddr(0, linkAddr1)

	addrTypes := []struct {
		name             string
		ndpConfigs       ipv6.NDPConfigurations
		autoGenLinkLocal bool
		subnet           tcpip.Subnet
		triggerSLAACFn   func(e *channel.Endpoint)
	}{
		{
			name: "Global address",
			ndpConfigs: ipv6.NDPConfigurations{
				HandleRAs:                     true,
				AutoGenGlobalAddresses:        true,
				AutoGenAddressConflictRetries: maxRetries,
			},
			subnet: subnet,
			triggerSLAACFn: func(e *channel.Endpoint) {
				// Receive an RA with prefix1 in a PI.
				e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, lifetimeSeconds, lifetimeSeconds))

			},
		},
		{
			name: "LinkLocal address",
			ndpConfigs: ipv6.NDPConfigurations{
				AutoGenAddressConflictRetries: maxRetries,
			},
			autoGenLinkLocal: true,
			subnet:           header.IPv6LinkLocalPrefix.Subnet(),
			triggerSLAACFn:   func(e *channel.Endpoint) {},
		},
	}

	for _, addrType := range addrTypes {
		addrType := addrType

		t.Run(addrType.name, func(t *testing.T) {
			t.Parallel()

			ndpDisp := ndpDispatcher{
				dadC:         make(chan ndpDADEvent, 1),
				autoGenAddrC: make(chan ndpAutoGenAddrEvent, 2),
			}
			e := channel.New(0, 1280, linkAddr1)
			s := stack.New(stack.Options{
				NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
					AutoGenLinkLocal: addrType.autoGenLinkLocal,
					NDPConfigs:       addrType.ndpConfigs,
					NDPDisp:          &ndpDisp,
					DADConfigs: stack.DADConfigurations{
						DupAddrDetectTransmits: dadTransmits,
						RetransmitTimer:        retransmitTimer,
					},
				})},
			})
			if err := s.CreateNIC(nicID, e); err != nil {
				t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
			}

			expectAutoGenAddrEvent := func(addr tcpip.AddressWithPrefix, eventType ndpAutoGenAddrEventType) {
				t.Helper()

				select {
				case e := <-ndpDisp.autoGenAddrC:
					if diff := checkAutoGenAddrEvent(e, addr, eventType); diff != "" {
						t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
					}
				default:
					t.Fatal("expected addr auto gen event")
				}
			}

			addrType.triggerSLAACFn(e)

			addrBytes := []byte(addrType.subnet.ID())
			header.EthernetAdddressToModifiedEUI64IntoBuf(linkAddr1, addrBytes[header.IIDOffsetInIPv6Address:])
			addr := tcpip.AddressWithPrefix{
				Address:   tcpip.Address(addrBytes),
				PrefixLen: 64,
			}
			expectAutoGenAddrEvent(addr, newAddr)

			// Simulate a DAD conflict.
			rxNDPSolicit(e, addr.Address)
			expectAutoGenAddrEvent(addr, invalidatedAddr)
			select {
			case e := <-ndpDisp.dadC:
				if diff := checkDADEvent(e, nicID, addr.Address, &stack.DADDupAddrDetected{}); diff != "" {
					t.Errorf("DAD event mismatch (-want +got):\n%s", diff)
				}
			default:
				t.Fatal("expected DAD event")
			}

			// Should not attempt address regeneration.
			select {
			case e := <-ndpDisp.autoGenAddrC:
				t.Fatalf("unexpectedly got an auto-generated address event = %+v", e)
			case <-time.After(defaultAsyncNegativeEventTimeout):
			}
		})
	}
}

// TestAutoGenAddrContinuesLifetimesAfterRetry tests that retrying address
// generation in response to DAD conflicts does not refresh the lifetimes.
func TestAutoGenAddrContinuesLifetimesAfterRetry(t *testing.T) {
	const nicID = 1
	const nicName = "nic"
	const dadTransmits = 1
	const retransmitTimer = 2 * time.Second
	const failureTimer = time.Second
	const maxRetries = 1
	const lifetimeSeconds = 5

	var secretKeyBuf [header.OpaqueIIDSecretKeyMinBytes]byte
	secretKey := secretKeyBuf[:]
	n, err := rand.Read(secretKey)
	if err != nil {
		t.Fatalf("rand.Read(_): %s", err)
	}
	if n != header.OpaqueIIDSecretKeyMinBytes {
		t.Fatalf("got rand.Read(_) = (%d, _), want = (%d, _)", n, header.OpaqueIIDSecretKeyMinBytes)
	}

	prefix, subnet, _ := prefixSubnetAddr(0, linkAddr1)

	ndpDisp := ndpDispatcher{
		dadC:         make(chan ndpDADEvent, 1),
		autoGenAddrC: make(chan ndpAutoGenAddrEvent, 2),
	}
	e := channel.New(0, 1280, linkAddr1)
	s := stack.New(stack.Options{
		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
			DADConfigs: stack.DADConfigurations{
				DupAddrDetectTransmits: dadTransmits,
				RetransmitTimer:        retransmitTimer,
			},
			NDPConfigs: ipv6.NDPConfigurations{
				HandleRAs:                     true,
				AutoGenGlobalAddresses:        true,
				AutoGenAddressConflictRetries: maxRetries,
			},
			NDPDisp: &ndpDisp,
			OpaqueIIDOpts: ipv6.OpaqueInterfaceIdentifierOptions{
				NICNameFromID: func(_ tcpip.NICID, nicName string) string {
					return nicName
				},
				SecretKey: secretKey,
			},
		})},
	})
	opts := stack.NICOptions{Name: nicName}
	if err := s.CreateNICWithOptions(nicID, e, opts); err != nil {
		t.Fatalf("CreateNICWithOptions(%d, _, %+v) = %s", nicID, opts, err)
	}

	expectAutoGenAddrEvent := func(addr tcpip.AddressWithPrefix, eventType ndpAutoGenAddrEventType) {
		t.Helper()

		select {
		case e := <-ndpDisp.autoGenAddrC:
			if diff := checkAutoGenAddrEvent(e, addr, eventType); diff != "" {
				t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
			}
		default:
			t.Fatal("expected addr auto gen event")
		}
	}

	// Receive an RA with prefix in a PI.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr2, 0, prefix, true, true, lifetimeSeconds, lifetimeSeconds))

	addrBytes := []byte(subnet.ID())
	addr := tcpip.AddressWithPrefix{
		Address:   tcpip.Address(header.AppendOpaqueInterfaceIdentifier(addrBytes[:header.IIDOffsetInIPv6Address], subnet, nicName, 0, secretKey)),
		PrefixLen: 64,
	}
	expectAutoGenAddrEvent(addr, newAddr)

	// Simulate a DAD conflict after some time has passed.
	time.Sleep(failureTimer)
	rxNDPSolicit(e, addr.Address)
	expectAutoGenAddrEvent(addr, invalidatedAddr)
	select {
	case e := <-ndpDisp.dadC:
		if diff := checkDADEvent(e, nicID, addr.Address, &stack.DADDupAddrDetected{}); diff != "" {
			t.Errorf("DAD event mismatch (-want +got):\n%s", diff)
		}
	default:
		t.Fatal("expected DAD event")
	}

	// Let the next address resolve.
	addr.Address = tcpip.Address(header.AppendOpaqueInterfaceIdentifier(addrBytes[:header.IIDOffsetInIPv6Address], subnet, nicName, 1, secretKey))
	expectAutoGenAddrEvent(addr, newAddr)
	select {
	case e := <-ndpDisp.dadC:
		if diff := checkDADEvent(e, nicID, addr.Address, &stack.DADSucceeded{}); diff != "" {
			t.Errorf("DAD event mismatch (-want +got):\n%s", diff)
		}
	case <-time.After(dadTransmits*retransmitTimer + defaultAsyncPositiveEventTimeout):
		t.Fatal("timed out waiting for DAD event")
	}

	// Address should be deprecated/invalidated after the lifetime expires.
	//
	// Note, the remaining lifetime is calculated from when the PI was first
	// processed. Since we wait for some time before simulating a DAD conflict
	// and more time for the new address to resolve, the new address is only
	// expected to be valid for the remaining time. The DAD conflict should
	// not have reset the lifetimes.
	//
	// We expect either just the invalidation event or the deprecation event
	// followed by the invalidation event.
	select {
	case e := <-ndpDisp.autoGenAddrC:
		if e.eventType == deprecatedAddr {
			if diff := checkAutoGenAddrEvent(e, addr, deprecatedAddr); diff != "" {
				t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
			}

			select {
			case e := <-ndpDisp.autoGenAddrC:
				if diff := checkAutoGenAddrEvent(e, addr, invalidatedAddr); diff != "" {
					t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
				}
			case <-time.After(defaultAsyncPositiveEventTimeout):
				t.Fatal("timed out waiting for invalidated auto gen addr event after deprecation")
			}
		} else {
			if diff := checkAutoGenAddrEvent(e, addr, invalidatedAddr); diff != "" {
				t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
			}
		}
	case <-time.After(lifetimeSeconds*time.Second - failureTimer - dadTransmits*retransmitTimer + defaultAsyncPositiveEventTimeout):
		t.Fatal("timed out waiting for auto gen addr event")
	}
}

// TestNDPRecursiveDNSServerDispatch tests that we properly dispatch an event
// to the integrator when an RA is received with the NDP Recursive DNS Server
// option with at least one valid address.
func TestNDPRecursiveDNSServerDispatch(t *testing.T) {
	tests := []struct {
		name     string
		opt      header.NDPRecursiveDNSServer
		expected *ndpRDNSS
	}{
		{
			"Unspecified",
			header.NDPRecursiveDNSServer([]byte{
				0, 0,
				0, 0, 0, 2,
				0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			}),
			nil,
		},
		{
			"Multicast",
			header.NDPRecursiveDNSServer([]byte{
				0, 0,
				0, 0, 0, 2,
				255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
			}),
			nil,
		},
		{
			"OptionTooSmall",
			header.NDPRecursiveDNSServer([]byte{
				0, 0,
				0, 0, 0, 2,
				1, 2, 3, 4, 5, 6, 7, 8,
			}),
			nil,
		},
		{
			"0Addresses",
			header.NDPRecursiveDNSServer([]byte{
				0, 0,
				0, 0, 0, 2,
			}),
			nil,
		},
		{
			"Valid1Address",
			header.NDPRecursiveDNSServer([]byte{
				0, 0,
				0, 0, 0, 2,
				1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 1,
			}),
			&ndpRDNSS{
				[]tcpip.Address{
					"\x01\x02\x03\x04\x05\x06\x07\x08\x00\x00\x00\x00\x00\x00\x00\x01",
				},
				2 * time.Second,
			},
		},
		{
			"Valid2Addresses",
			header.NDPRecursiveDNSServer([]byte{
				0, 0,
				0, 0, 0, 1,
				1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 1,
				1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 2,
			}),
			&ndpRDNSS{
				[]tcpip.Address{
					"\x01\x02\x03\x04\x05\x06\x07\x08\x00\x00\x00\x00\x00\x00\x00\x01",
					"\x01\x02\x03\x04\x05\x06\x07\x08\x00\x00\x00\x00\x00\x00\x00\x02",
				},
				time.Second,
			},
		},
		{
			"Valid3Addresses",
			header.NDPRecursiveDNSServer([]byte{
				0, 0,
				0, 0, 0, 0,
				1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 1,
				1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 2,
				1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 3,
			}),
			&ndpRDNSS{
				[]tcpip.Address{
					"\x01\x02\x03\x04\x05\x06\x07\x08\x00\x00\x00\x00\x00\x00\x00\x01",
					"\x01\x02\x03\x04\x05\x06\x07\x08\x00\x00\x00\x00\x00\x00\x00\x02",
					"\x01\x02\x03\x04\x05\x06\x07\x08\x00\x00\x00\x00\x00\x00\x00\x03",
				},
				0,
			},
		},
	}

	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			ndpDisp := ndpDispatcher{
				// We do not expect more than a single RDNSS
				// event at any time for this test.
				rdnssC: make(chan ndpRDNSSEvent, 1),
			}
			e := channel.New(0, 1280, linkAddr1)
			s := stack.New(stack.Options{
				NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
					NDPConfigs: ipv6.NDPConfigurations{
						HandleRAs: true,
					},
					NDPDisp: &ndpDisp,
				})},
			})
			if err := s.CreateNIC(1, e); err != nil {
				t.Fatalf("CreateNIC(1) = %s", err)
			}

			e.InjectInbound(header.IPv6ProtocolNumber, raBufWithOpts(llAddr1, 0, header.NDPOptionsSerializer{test.opt}))

			if test.expected != nil {
				select {
				case e := <-ndpDisp.rdnssC:
					if e.nicID != 1 {
						t.Errorf("got rdnss nicID = %d, want = 1", e.nicID)
					}
					if diff := cmp.Diff(e.rdnss.addrs, test.expected.addrs); diff != "" {
						t.Errorf("rdnss addrs mismatch (-want +got):\n%s", diff)
					}
					if e.rdnss.lifetime != test.expected.lifetime {
						t.Errorf("got rdnss lifetime = %s, want = %s", e.rdnss.lifetime, test.expected.lifetime)
					}
				default:
					t.Fatal("expected an RDNSS option event")
				}
			}

			// Should have no more RDNSS options.
			select {
			case e := <-ndpDisp.rdnssC:
				t.Fatalf("unexpectedly got a new RDNSS option event: %+v", e)
			default:
			}
		})
	}
}

// TestNDPDNSSearchListDispatch tests that the integrator is informed when an
// NDP DNS Search List option is received with at least one domain name in the
// search list.
func TestNDPDNSSearchListDispatch(t *testing.T) {
	const nicID = 1

	ndpDisp := ndpDispatcher{
		dnsslC: make(chan ndpDNSSLEvent, 3),
	}
	e := channel.New(0, 1280, linkAddr1)
	s := stack.New(stack.Options{
		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
			NDPConfigs: ipv6.NDPConfigurations{
				HandleRAs: true,
			},
			NDPDisp: &ndpDisp,
		})},
	})
	if err := s.CreateNIC(nicID, e); err != nil {
		t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
	}

	optSer := header.NDPOptionsSerializer{
		header.NDPDNSSearchList([]byte{
			0, 0,
			0, 0, 0, 0,
			2, 'h', 'i',
			0,
		}),
		header.NDPDNSSearchList([]byte{
			0, 0,
			0, 0, 0, 1,
			1, 'i',
			0,
			2, 'a', 'm',
			2, 'm', 'e',
			0,
		}),
		header.NDPDNSSearchList([]byte{
			0, 0,
			0, 0, 1, 0,
			3, 'x', 'y', 'z',
			0,
			5, 'h', 'e', 'l', 'l', 'o',
			5, 'w', 'o', 'r', 'l', 'd',
			0,
			4, 't', 'h', 'i', 's',
			2, 'i', 's',
			1, 'a',
			4, 't', 'e', 's', 't',
			0,
		}),
	}
	expected := []struct {
		domainNames []string
		lifetime    time.Duration
	}{
		{
			domainNames: []string{
				"hi",
			},
			lifetime: 0,
		},
		{
			domainNames: []string{
				"i",
				"am.me",
			},
			lifetime: time.Second,
		},
		{
			domainNames: []string{
				"xyz",
				"hello.world",
				"this.is.a.test",
			},
			lifetime: 256 * time.Second,
		},
	}

	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithOpts(llAddr1, 0, optSer))

	for i, expected := range expected {
		select {
		case dnssl := <-ndpDisp.dnsslC:
			if dnssl.nicID != nicID {
				t.Errorf("got %d-th dnssl nicID = %d, want = %d", i, dnssl.nicID, nicID)
			}
			if diff := cmp.Diff(dnssl.domainNames, expected.domainNames); diff != "" {
				t.Errorf("%d-th dnssl domain names mismatch (-want +got):\n%s", i, diff)
			}
			if dnssl.lifetime != expected.lifetime {
				t.Errorf("got %d-th dnssl lifetime = %s, want = %s", i, dnssl.lifetime, expected.lifetime)
			}
		default:
			t.Fatal("expected a DNSSL event")
		}
	}

	// Should have no more DNSSL options.
	select {
	case <-ndpDisp.dnsslC:
		t.Fatal("unexpectedly got a DNSSL event")
	default:
	}
}

// TestCleanupNDPState tests that all discovered routers and prefixes, and
// auto-generated addresses are invalidated when a NIC becomes a router.
func TestCleanupNDPState(t *testing.T) {
	const (
		lifetimeSeconds          = 5
		maxRouterAndPrefixEvents = 4
		nicID1                   = 1
		nicID2                   = 2
	)

	prefix1, subnet1, e1Addr1 := prefixSubnetAddr(0, linkAddr1)
	prefix2, subnet2, e1Addr2 := prefixSubnetAddr(1, linkAddr1)
	e2Addr1 := addrForSubnet(subnet1, linkAddr2)
	e2Addr2 := addrForSubnet(subnet2, linkAddr2)
	llAddrWithPrefix1 := tcpip.AddressWithPrefix{
		Address:   llAddr1,
		PrefixLen: 64,
	}
	llAddrWithPrefix2 := tcpip.AddressWithPrefix{
		Address:   llAddr2,
		PrefixLen: 64,
	}

	tests := []struct {
		name                 string
		cleanupFn            func(t *testing.T, s *stack.Stack)
		keepAutoGenLinkLocal bool
		maxAutoGenAddrEvents int
		skipFinalAddrCheck   bool
	}{
		// A NIC should still keep its auto-generated link-local address when
		// becoming a router.
		{
			name: "Enable forwarding",
			cleanupFn: func(t *testing.T, s *stack.Stack) {
				t.Helper()
				s.SetForwarding(ipv6.ProtocolNumber, true)
			},
			keepAutoGenLinkLocal: true,
			maxAutoGenAddrEvents: 4,
		},

		// A NIC should cleanup all NDP state when it is disabled.
		{
			name: "Disable NIC",
			cleanupFn: func(t *testing.T, s *stack.Stack) {
				t.Helper()

				if err := s.DisableNIC(nicID1); err != nil {
					t.Fatalf("s.DisableNIC(%d): %s", nicID1, err)
				}
				if err := s.DisableNIC(nicID2); err != nil {
					t.Fatalf("s.DisableNIC(%d): %s", nicID2, err)
				}
			},
			keepAutoGenLinkLocal: false,
			maxAutoGenAddrEvents: 6,
		},

		// A NIC should cleanup all NDP state when it is removed.
		{
			name: "Remove NIC",
			cleanupFn: func(t *testing.T, s *stack.Stack) {
				t.Helper()

				if err := s.RemoveNIC(nicID1); err != nil {
					t.Fatalf("s.RemoveNIC(%d): %s", nicID1, err)
				}
				if err := s.RemoveNIC(nicID2); err != nil {
					t.Fatalf("s.RemoveNIC(%d): %s", nicID2, err)
				}
			},
			keepAutoGenLinkLocal: false,
			maxAutoGenAddrEvents: 6,
			// The NICs are removed so we can't check their addresses after calling
			// stopFn.
			skipFinalAddrCheck: true,
		},
	}

	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			ndpDisp := ndpDispatcher{
				routerC:        make(chan ndpRouterEvent, maxRouterAndPrefixEvents),
				rememberRouter: true,
				prefixC:        make(chan ndpPrefixEvent, maxRouterAndPrefixEvents),
				rememberPrefix: true,
				autoGenAddrC:   make(chan ndpAutoGenAddrEvent, test.maxAutoGenAddrEvents),
			}
			s := stack.New(stack.Options{
				NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
					AutoGenLinkLocal: true,
					NDPConfigs: ipv6.NDPConfigurations{
						HandleRAs:              true,
						DiscoverDefaultRouters: true,
						DiscoverOnLinkPrefixes: true,
						AutoGenGlobalAddresses: true,
					},
					NDPDisp: &ndpDisp,
				})},
			})

			expectRouterEvent := func() (bool, ndpRouterEvent) {
				select {
				case e := <-ndpDisp.routerC:
					return true, e
				default:
				}

				return false, ndpRouterEvent{}
			}

			expectPrefixEvent := func() (bool, ndpPrefixEvent) {
				select {
				case e := <-ndpDisp.prefixC:
					return true, e
				default:
				}

				return false, ndpPrefixEvent{}
			}

			expectAutoGenAddrEvent := func() (bool, ndpAutoGenAddrEvent) {
				select {
				case e := <-ndpDisp.autoGenAddrC:
					return true, e
				default:
				}

				return false, ndpAutoGenAddrEvent{}
			}

			e1 := channel.New(0, 1280, linkAddr1)
			if err := s.CreateNIC(nicID1, e1); err != nil {
				t.Fatalf("CreateNIC(%d, _) = %s", nicID1, err)
			}
			// We have other tests that make sure we receive the *correct* events
			// on normal discovery of routers/prefixes, and auto-generated
			// addresses. Here we just make sure we get an event and let other tests
			// handle the correctness check.
			expectAutoGenAddrEvent()

			e2 := channel.New(0, 1280, linkAddr2)
			if err := s.CreateNIC(nicID2, e2); err != nil {
				t.Fatalf("CreateNIC(%d, _) = %s", nicID2, err)
			}
			expectAutoGenAddrEvent()

			// Receive RAs on NIC(1) and NIC(2) from default routers (llAddr3 and
			// llAddr4) w/ PI (for prefix1 in RA from llAddr3 and prefix2 in RA from
			// llAddr4) to discover multiple routers and prefixes, and auto-gen
			// multiple addresses.

			e1.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr3, lifetimeSeconds, prefix1, true, true, lifetimeSeconds, lifetimeSeconds))
			if ok, _ := expectRouterEvent(); !ok {
				t.Errorf("expected router event for %s on NIC(%d)", llAddr3, nicID1)
			}
			if ok, _ := expectPrefixEvent(); !ok {
				t.Errorf("expected prefix event for %s on NIC(%d)", prefix1, nicID1)
			}
			if ok, _ := expectAutoGenAddrEvent(); !ok {
				t.Errorf("expected auto-gen addr event for %s on NIC(%d)", e1Addr1, nicID1)
			}

			e1.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr4, lifetimeSeconds, prefix2, true, true, lifetimeSeconds, lifetimeSeconds))
			if ok, _ := expectRouterEvent(); !ok {
				t.Errorf("expected router event for %s on NIC(%d)", llAddr4, nicID1)
			}
			if ok, _ := expectPrefixEvent(); !ok {
				t.Errorf("expected prefix event for %s on NIC(%d)", prefix2, nicID1)
			}
			if ok, _ := expectAutoGenAddrEvent(); !ok {
				t.Errorf("expected auto-gen addr event for %s on NIC(%d)", e1Addr2, nicID1)
			}

			e2.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr3, lifetimeSeconds, prefix1, true, true, lifetimeSeconds, lifetimeSeconds))
			if ok, _ := expectRouterEvent(); !ok {
				t.Errorf("expected router event for %s on NIC(%d)", llAddr3, nicID2)
			}
			if ok, _ := expectPrefixEvent(); !ok {
				t.Errorf("expected prefix event for %s on NIC(%d)", prefix1, nicID2)
			}
			if ok, _ := expectAutoGenAddrEvent(); !ok {
				t.Errorf("expected auto-gen addr event for %s on NIC(%d)", e1Addr2, nicID2)
			}

			e2.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr4, lifetimeSeconds, prefix2, true, true, lifetimeSeconds, lifetimeSeconds))
			if ok, _ := expectRouterEvent(); !ok {
				t.Errorf("expected router event for %s on NIC(%d)", llAddr4, nicID2)
			}
			if ok, _ := expectPrefixEvent(); !ok {
				t.Errorf("expected prefix event for %s on NIC(%d)", prefix2, nicID2)
			}
			if ok, _ := expectAutoGenAddrEvent(); !ok {
				t.Errorf("expected auto-gen addr event for %s on NIC(%d)", e2Addr2, nicID2)
			}

			// We should have the auto-generated addresses added.
			nicinfo := s.NICInfo()
			nic1Addrs := nicinfo[nicID1].ProtocolAddresses
			nic2Addrs := nicinfo[nicID2].ProtocolAddresses
			if !containsV6Addr(nic1Addrs, llAddrWithPrefix1) {
				t.Errorf("missing %s from the list of addresses for NIC(%d): %+v", llAddrWithPrefix1, nicID1, nic1Addrs)
			}
			if !containsV6Addr(nic1Addrs, e1Addr1) {
				t.Errorf("missing %s from the list of addresses for NIC(%d): %+v", e1Addr1, nicID1, nic1Addrs)
			}
			if !containsV6Addr(nic1Addrs, e1Addr2) {
				t.Errorf("missing %s from the list of addresses for NIC(%d): %+v", e1Addr2, nicID1, nic1Addrs)
			}
			if !containsV6Addr(nic2Addrs, llAddrWithPrefix2) {
				t.Errorf("missing %s from the list of addresses for NIC(%d): %+v", llAddrWithPrefix2, nicID2, nic2Addrs)
			}
			if !containsV6Addr(nic2Addrs, e2Addr1) {
				t.Errorf("missing %s from the list of addresses for NIC(%d): %+v", e2Addr1, nicID2, nic2Addrs)
			}
			if !containsV6Addr(nic2Addrs, e2Addr2) {
				t.Errorf("missing %s from the list of addresses for NIC(%d): %+v", e2Addr2, nicID2, nic2Addrs)
			}

			// We can't proceed any further if we already failed the test (missing
			// some discovery/auto-generated address events or addresses).
			if t.Failed() {
				t.FailNow()
			}

			test.cleanupFn(t, s)

			// Collect invalidation events after having NDP state cleaned up.
			gotRouterEvents := make(map[ndpRouterEvent]int)
			for i := 0; i < maxRouterAndPrefixEvents; i++ {
				ok, e := expectRouterEvent()
				if !ok {
					t.Errorf("expected %d router events after becoming a router; got = %d", maxRouterAndPrefixEvents, i)
					break
				}
				gotRouterEvents[e]++
			}
			gotPrefixEvents := make(map[ndpPrefixEvent]int)
			for i := 0; i < maxRouterAndPrefixEvents; i++ {
				ok, e := expectPrefixEvent()
				if !ok {
					t.Errorf("expected %d prefix events after becoming a router; got = %d", maxRouterAndPrefixEvents, i)
					break
				}
				gotPrefixEvents[e]++
			}
			gotAutoGenAddrEvents := make(map[ndpAutoGenAddrEvent]int)
			for i := 0; i < test.maxAutoGenAddrEvents; i++ {
				ok, e := expectAutoGenAddrEvent()
				if !ok {
					t.Errorf("expected %d auto-generated address events after becoming a router; got = %d", test.maxAutoGenAddrEvents, i)
					break
				}
				gotAutoGenAddrEvents[e]++
			}

			// No need to proceed any further if we already failed the test (missing
			// some invalidation events).
			if t.Failed() {
				t.FailNow()
			}

			expectedRouterEvents := map[ndpRouterEvent]int{
				{nicID: nicID1, addr: llAddr3, discovered: false}: 1,
				{nicID: nicID1, addr: llAddr4, discovered: false}: 1,
				{nicID: nicID2, addr: llAddr3, discovered: false}: 1,
				{nicID: nicID2, addr: llAddr4, discovered: false}: 1,
			}
			if diff := cmp.Diff(expectedRouterEvents, gotRouterEvents); diff != "" {
				t.Errorf("router events mismatch (-want +got):\n%s", diff)
			}
			expectedPrefixEvents := map[ndpPrefixEvent]int{
				{nicID: nicID1, prefix: subnet1, discovered: false}: 1,
				{nicID: nicID1, prefix: subnet2, discovered: false}: 1,
				{nicID: nicID2, prefix: subnet1, discovered: false}: 1,
				{nicID: nicID2, prefix: subnet2, discovered: false}: 1,
			}
			if diff := cmp.Diff(expectedPrefixEvents, gotPrefixEvents); diff != "" {
				t.Errorf("prefix events mismatch (-want +got):\n%s", diff)
			}
			expectedAutoGenAddrEvents := map[ndpAutoGenAddrEvent]int{
				{nicID: nicID1, addr: e1Addr1, eventType: invalidatedAddr}: 1,
				{nicID: nicID1, addr: e1Addr2, eventType: invalidatedAddr}: 1,
				{nicID: nicID2, addr: e2Addr1, eventType: invalidatedAddr}: 1,
				{nicID: nicID2, addr: e2Addr2, eventType: invalidatedAddr}: 1,
			}

			if !test.keepAutoGenLinkLocal {
				expectedAutoGenAddrEvents[ndpAutoGenAddrEvent{nicID: nicID1, addr: llAddrWithPrefix1, eventType: invalidatedAddr}] = 1
				expectedAutoGenAddrEvents[ndpAutoGenAddrEvent{nicID: nicID2, addr: llAddrWithPrefix2, eventType: invalidatedAddr}] = 1
			}

			if diff := cmp.Diff(expectedAutoGenAddrEvents, gotAutoGenAddrEvents); diff != "" {
				t.Errorf("auto-generated address events mismatch (-want +got):\n%s", diff)
			}

			if !test.skipFinalAddrCheck {
				// Make sure the auto-generated addresses got removed.
				nicinfo = s.NICInfo()
				nic1Addrs = nicinfo[nicID1].ProtocolAddresses
				nic2Addrs = nicinfo[nicID2].ProtocolAddresses
				if containsV6Addr(nic1Addrs, llAddrWithPrefix1) != test.keepAutoGenLinkLocal {
					if test.keepAutoGenLinkLocal {
						t.Errorf("missing %s from the list of addresses for NIC(%d): %+v", llAddrWithPrefix1, nicID1, nic1Addrs)
					} else {
						t.Errorf("still have %s in the list of addresses for NIC(%d): %+v", llAddrWithPrefix1, nicID1, nic1Addrs)
					}
				}
				if containsV6Addr(nic1Addrs, e1Addr1) {
					t.Errorf("still have %s in the list of addresses for NIC(%d): %+v", e1Addr1, nicID1, nic1Addrs)
				}
				if containsV6Addr(nic1Addrs, e1Addr2) {
					t.Errorf("still have %s in the list of addresses for NIC(%d): %+v", e1Addr2, nicID1, nic1Addrs)
				}
				if containsV6Addr(nic2Addrs, llAddrWithPrefix2) != test.keepAutoGenLinkLocal {
					if test.keepAutoGenLinkLocal {
						t.Errorf("missing %s from the list of addresses for NIC(%d): %+v", llAddrWithPrefix2, nicID2, nic2Addrs)
					} else {
						t.Errorf("still have %s in the list of addresses for NIC(%d): %+v", llAddrWithPrefix2, nicID2, nic2Addrs)
					}
				}
				if containsV6Addr(nic2Addrs, e2Addr1) {
					t.Errorf("still have %s in the list of addresses for NIC(%d): %+v", e2Addr1, nicID2, nic2Addrs)
				}
				if containsV6Addr(nic2Addrs, e2Addr2) {
					t.Errorf("still have %s in the list of addresses for NIC(%d): %+v", e2Addr2, nicID2, nic2Addrs)
				}
			}

			// Should not get any more events (invalidation timers should have been
			// cancelled when the NDP state was cleaned up).
			time.Sleep(lifetimeSeconds*time.Second + defaultAsyncNegativeEventTimeout)
			select {
			case <-ndpDisp.routerC:
				t.Error("unexpected router event")
			default:
			}
			select {
			case <-ndpDisp.prefixC:
				t.Error("unexpected prefix event")
			default:
			}
			select {
			case <-ndpDisp.autoGenAddrC:
				t.Error("unexpected auto-generated address event")
			default:
			}
		})
	}
}

// TestDHCPv6ConfigurationFromNDPDA tests that the NDPDispatcher is properly
// informed when new information about what configurations are available via
// DHCPv6 is learned.
func TestDHCPv6ConfigurationFromNDPDA(t *testing.T) {
	const nicID = 1

	ndpDisp := ndpDispatcher{
		dhcpv6ConfigurationC: make(chan ndpDHCPv6Event, 1),
		rememberRouter:       true,
	}
	e := channel.New(0, 1280, linkAddr1)
	s := stack.New(stack.Options{
		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
			NDPConfigs: ipv6.NDPConfigurations{
				HandleRAs: true,
			},
			NDPDisp: &ndpDisp,
		})},
	})

	if err := s.CreateNIC(nicID, e); err != nil {
		t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
	}

	expectDHCPv6Event := func(configuration ipv6.DHCPv6ConfigurationFromNDPRA) {
		t.Helper()
		select {
		case e := <-ndpDisp.dhcpv6ConfigurationC:
			if diff := cmp.Diff(ndpDHCPv6Event{nicID: nicID, configuration: configuration}, e, cmp.AllowUnexported(e)); diff != "" {
				t.Errorf("dhcpv6 event mismatch (-want +got):\n%s", diff)
			}
		default:
			t.Fatal("expected DHCPv6 configuration event")
		}
	}

	expectNoDHCPv6Event := func() {
		t.Helper()
		select {
		case <-ndpDisp.dhcpv6ConfigurationC:
			t.Fatal("unexpected DHCPv6 configuration event")
		default:
		}
	}

	// Even if the first RA reports no DHCPv6 configurations are available, the
	// dispatcher should get an event.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, false, false))
	expectDHCPv6Event(ipv6.DHCPv6NoConfiguration)
	// Receiving the same update again should not result in an event to the
	// dispatcher.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, false, false))
	expectNoDHCPv6Event()

	// Receive an RA that updates the DHCPv6 configuration to Other
	// Configurations.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, false, true))
	expectDHCPv6Event(ipv6.DHCPv6OtherConfigurations)
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, false, true))
	expectNoDHCPv6Event()

	// Receive an RA that updates the DHCPv6 configuration to Managed Address.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, true, false))
	expectDHCPv6Event(ipv6.DHCPv6ManagedAddress)
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, true, false))
	expectNoDHCPv6Event()

	// Receive an RA that updates the DHCPv6 configuration to none.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, false, false))
	expectDHCPv6Event(ipv6.DHCPv6NoConfiguration)
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, false, false))
	expectNoDHCPv6Event()

	// Receive an RA that updates the DHCPv6 configuration to Managed Address.
	//
	// Note, when the M flag is set, the O flag is redundant.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, true, true))
	expectDHCPv6Event(ipv6.DHCPv6ManagedAddress)
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, true, true))
	expectNoDHCPv6Event()
	// Even though the DHCPv6 flags are different, the effective configuration is
	// the same so we should not receive a new event.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, true, false))
	expectNoDHCPv6Event()
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, true, true))
	expectNoDHCPv6Event()

	// Receive an RA that updates the DHCPv6 configuration to Other
	// Configurations.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, false, true))
	expectDHCPv6Event(ipv6.DHCPv6OtherConfigurations)
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, false, true))
	expectNoDHCPv6Event()

	// Cycling the NIC should cause the last DHCPv6 configuration to be cleared.
	if err := s.DisableNIC(nicID); err != nil {
		t.Fatalf("s.DisableNIC(%d): %s", nicID, err)
	}
	if err := s.EnableNIC(nicID); err != nil {
		t.Fatalf("s.EnableNIC(%d): %s", nicID, err)
	}

	// Receive an RA that updates the DHCPv6 configuration to Other
	// Configurations.
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, false, true))
	expectDHCPv6Event(ipv6.DHCPv6OtherConfigurations)
	e.InjectInbound(header.IPv6ProtocolNumber, raBufWithDHCPv6(llAddr2, false, true))
	expectNoDHCPv6Event()
}

// TestRouterSolicitation tests the initial Router Solicitations that are sent
// when a NIC newly becomes enabled.
func TestRouterSolicitation(t *testing.T) {
	const nicID = 1

	tests := []struct {
		name                        string
		linkHeaderLen               uint16
		linkAddr                    tcpip.LinkAddress
		nicAddr                     tcpip.Address
		expectedSrcAddr             tcpip.Address
		expectedNDPOpts             []header.NDPOption
		maxRtrSolicit               uint8
		rtrSolicitInt               time.Duration
		effectiveRtrSolicitInt      time.Duration
		maxRtrSolicitDelay          time.Duration
		effectiveMaxRtrSolicitDelay time.Duration
	}{
		{
			name:                        "Single RS with 2s delay and interval",
			expectedSrcAddr:             header.IPv6Any,
			maxRtrSolicit:               1,
			rtrSolicitInt:               2 * time.Second,
			effectiveRtrSolicitInt:      2 * time.Second,
			maxRtrSolicitDelay:          2 * time.Second,
			effectiveMaxRtrSolicitDelay: 2 * time.Second,
		},
		{
			name:                        "Single RS with 4s delay and interval",
			expectedSrcAddr:             header.IPv6Any,
			maxRtrSolicit:               1,
			rtrSolicitInt:               4 * time.Second,
			effectiveRtrSolicitInt:      4 * time.Second,
			maxRtrSolicitDelay:          4 * time.Second,
			effectiveMaxRtrSolicitDelay: 4 * time.Second,
		},
		{
			name:                        "Two RS with delay",
			linkHeaderLen:               1,
			nicAddr:                     llAddr1,
			expectedSrcAddr:             llAddr1,
			maxRtrSolicit:               2,
			rtrSolicitInt:               2 * time.Second,
			effectiveRtrSolicitInt:      2 * time.Second,
			maxRtrSolicitDelay:          500 * time.Millisecond,
			effectiveMaxRtrSolicitDelay: 500 * time.Millisecond,
		},
		{
			name:            "Single RS without delay",
			linkHeaderLen:   2,
			linkAddr:        linkAddr1,
			nicAddr:         llAddr1,
			expectedSrcAddr: llAddr1,
			expectedNDPOpts: []header.NDPOption{
				header.NDPSourceLinkLayerAddressOption(linkAddr1),
			},
			maxRtrSolicit:               1,
			rtrSolicitInt:               2 * time.Second,
			effectiveRtrSolicitInt:      2 * time.Second,
			maxRtrSolicitDelay:          0,
			effectiveMaxRtrSolicitDelay: 0,
		},
		{
			name:                        "Two RS without delay and invalid zero interval",
			linkHeaderLen:               3,
			linkAddr:                    linkAddr1,
			expectedSrcAddr:             header.IPv6Any,
			maxRtrSolicit:               2,
			rtrSolicitInt:               0,
			effectiveRtrSolicitInt:      4 * time.Second,
			maxRtrSolicitDelay:          0,
			effectiveMaxRtrSolicitDelay: 0,
		},
		{
			name:                        "Three RS without delay",
			linkAddr:                    linkAddr1,
			expectedSrcAddr:             header.IPv6Any,
			maxRtrSolicit:               3,
			rtrSolicitInt:               500 * time.Millisecond,
			effectiveRtrSolicitInt:      500 * time.Millisecond,
			maxRtrSolicitDelay:          0,
			effectiveMaxRtrSolicitDelay: 0,
		},
		{
			name:                        "Two RS with invalid negative delay",
			linkAddr:                    linkAddr1,
			expectedSrcAddr:             header.IPv6Any,
			maxRtrSolicit:               2,
			rtrSolicitInt:               time.Second,
			effectiveRtrSolicitInt:      time.Second,
			maxRtrSolicitDelay:          -3 * time.Second,
			effectiveMaxRtrSolicitDelay: time.Second,
		},
	}

	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			clock := faketime.NewManualClock()
			e := channelLinkWithHeaderLength{
				Endpoint:     channel.New(int(test.maxRtrSolicit), 1280, test.linkAddr),
				headerLength: test.linkHeaderLen,
			}
			e.Endpoint.LinkEPCapabilities |= stack.CapabilityResolutionRequired
			waitForPkt := func(timeout time.Duration) {
				t.Helper()

				clock.Advance(timeout)
				p, ok := e.Read()
				if !ok {
					t.Fatal("expected router solicitation packet")
				}

				if p.Proto != header.IPv6ProtocolNumber {
					t.Fatalf("got Proto = %d, want = %d", p.Proto, header.IPv6ProtocolNumber)
				}

				// Make sure the right remote link address is used.
				if want := header.EthernetAddressFromMulticastIPv6Address(header.IPv6AllRoutersMulticastAddress); p.Route.RemoteLinkAddress != want {
					t.Errorf("got remote link address = %s, want = %s", p.Route.RemoteLinkAddress, want)
				}

				checker.IPv6(t, stack.PayloadSince(p.Pkt.NetworkHeader()),
					checker.SrcAddr(test.expectedSrcAddr),
					checker.DstAddr(header.IPv6AllRoutersMulticastAddress),
					checker.TTL(header.NDPHopLimit),
					checker.NDPRS(checker.NDPRSOptions(test.expectedNDPOpts)),
				)

				if l, want := p.Pkt.AvailableHeaderBytes(), int(test.linkHeaderLen); l != want {
					t.Errorf("got p.Pkt.AvailableHeaderBytes() = %d; want = %d", l, want)
				}
			}
			waitForNothing := func(timeout time.Duration) {
				t.Helper()

				clock.Advance(timeout)
				if p, ok := e.Read(); ok {
					t.Fatalf("unexpectedly got a packet = %#v", p)
				}
			}
			s := stack.New(stack.Options{
				NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
					NDPConfigs: ipv6.NDPConfigurations{
						MaxRtrSolicitations:     test.maxRtrSolicit,
						RtrSolicitationInterval: test.rtrSolicitInt,
						MaxRtrSolicitationDelay: test.maxRtrSolicitDelay,
					},
				})},
				Clock: clock,
			})
			if err := s.CreateNIC(nicID, &e); err != nil {
				t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
			}

			if addr := test.nicAddr; addr != "" {
				if err := s.AddAddress(nicID, header.IPv6ProtocolNumber, addr); err != nil {
					t.Fatalf("AddAddress(%d, %d, %s) = %s", nicID, header.IPv6ProtocolNumber, addr, err)
				}
			}

			// Make sure each RS is sent at the right time.
			remaining := test.maxRtrSolicit
			if remaining > 0 {
				waitForPkt(test.effectiveMaxRtrSolicitDelay)
				remaining--
			}

			for ; remaining > 0; remaining-- {
				if test.effectiveRtrSolicitInt > defaultAsyncPositiveEventTimeout {
					waitForNothing(test.effectiveRtrSolicitInt - time.Nanosecond)
					waitForPkt(time.Nanosecond)
				} else {
					waitForPkt(test.effectiveRtrSolicitInt)
				}
			}

			// Make sure no more RS.
			if test.effectiveRtrSolicitInt > test.effectiveMaxRtrSolicitDelay {
				waitForNothing(test.effectiveRtrSolicitInt)
			} else {
				waitForNothing(test.effectiveMaxRtrSolicitDelay)
			}

			if got, want := s.Stats().ICMP.V6.PacketsSent.RouterSolicit.Value(), uint64(test.maxRtrSolicit); got != want {
				t.Fatalf("got sent RouterSolicit = %d, want = %d", got, want)
			}
		})
	}
}

func TestStopStartSolicitingRouters(t *testing.T) {
	const nicID = 1
	const delay = 0
	const interval = 500 * time.Millisecond
	const maxRtrSolicitations = 3

	tests := []struct {
		name    string
		startFn func(t *testing.T, s *stack.Stack)
		// first is used to tell stopFn that it is being called for the first time
		// after router solicitations were last enabled.
		stopFn func(t *testing.T, s *stack.Stack, first bool)
	}{
		// Tests that when forwarding is enabled or disabled, router solicitations
		// are stopped or started, respectively.
		{
			name: "Enable and disable forwarding",
			startFn: func(t *testing.T, s *stack.Stack) {
				t.Helper()
				s.SetForwarding(ipv6.ProtocolNumber, false)
			},
			stopFn: func(t *testing.T, s *stack.Stack, _ bool) {
				t.Helper()
				s.SetForwarding(ipv6.ProtocolNumber, true)
			},
		},

		// Tests that when a NIC is enabled or disabled, router solicitations
		// are started or stopped, respectively.
		{
			name: "Enable and disable NIC",
			startFn: func(t *testing.T, s *stack.Stack) {
				t.Helper()

				if err := s.EnableNIC(nicID); err != nil {
					t.Fatalf("s.EnableNIC(%d): %s", nicID, err)
				}
			},
			stopFn: func(t *testing.T, s *stack.Stack, _ bool) {
				t.Helper()

				if err := s.DisableNIC(nicID); err != nil {
					t.Fatalf("s.DisableNIC(%d): %s", nicID, err)
				}
			},
		},

		// Tests that when a NIC is removed, router solicitations are stopped. We
		// cannot start router solications on a removed NIC.
		{
			name: "Remove NIC",
			stopFn: func(t *testing.T, s *stack.Stack, first bool) {
				t.Helper()

				// Only try to remove the NIC the first time stopFn is called since it's
				// impossible to remove an already removed NIC.
				if !first {
					return
				}

				if err := s.RemoveNIC(nicID); err != nil {
					t.Fatalf("s.RemoveNIC(%d): %s", nicID, err)
				}
			},
		},
	}

	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			e := channel.New(maxRtrSolicitations, 1280, linkAddr1)
			waitForPkt := func(timeout time.Duration) {
				t.Helper()

				ctx, cancel := context.WithTimeout(context.Background(), timeout)
				defer cancel()
				p, ok := e.ReadContext(ctx)
				if !ok {
					t.Fatal("timed out waiting for packet")
				}

				if p.Proto != header.IPv6ProtocolNumber {
					t.Fatalf("got Proto = %d, want = %d", p.Proto, header.IPv6ProtocolNumber)
				}
				checker.IPv6(t, stack.PayloadSince(p.Pkt.NetworkHeader()),
					checker.SrcAddr(header.IPv6Any),
					checker.DstAddr(header.IPv6AllRoutersMulticastAddress),
					checker.TTL(header.NDPHopLimit),
					checker.NDPRS())
			}
			s := stack.New(stack.Options{
				NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
					NDPConfigs: ipv6.NDPConfigurations{
						MaxRtrSolicitations:     maxRtrSolicitations,
						RtrSolicitationInterval: interval,
						MaxRtrSolicitationDelay: delay,
					},
				})},
			})
			if err := s.CreateNIC(nicID, e); err != nil {
				t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
			}

			// Stop soliciting routers.
			test.stopFn(t, s, true /* first */)
			ctx, cancel := context.WithTimeout(context.Background(), delay+defaultAsyncNegativeEventTimeout)
			defer cancel()
			if _, ok := e.ReadContext(ctx); ok {
				// A single RS may have been sent before solicitations were stopped.
				ctx, cancel := context.WithTimeout(context.Background(), interval+defaultAsyncNegativeEventTimeout)
				defer cancel()
				if _, ok = e.ReadContext(ctx); ok {
					t.Fatal("should not have sent more than one RS message")
				}
			}

			// Stopping router solicitations after it has already been stopped should
			// do nothing.
			test.stopFn(t, s, false /* first */)
			ctx, cancel = context.WithTimeout(context.Background(), delay+defaultAsyncNegativeEventTimeout)
			defer cancel()
			if _, ok := e.ReadContext(ctx); ok {
				t.Fatal("unexpectedly got a packet after router solicitation has been stopepd")
			}

			// If test.startFn is nil, there is no way to restart router solications.
			if test.startFn == nil {
				return
			}

			// Start soliciting routers.
			test.startFn(t, s)
			waitForPkt(delay + defaultAsyncPositiveEventTimeout)
			waitForPkt(interval + defaultAsyncPositiveEventTimeout)
			waitForPkt(interval + defaultAsyncPositiveEventTimeout)
			ctx, cancel = context.WithTimeout(context.Background(), interval+defaultAsyncNegativeEventTimeout)
			defer cancel()
			if _, ok := e.ReadContext(ctx); ok {
				t.Fatal("unexpectedly got an extra packet after sending out the expected RSs")
			}

			// Starting router solicitations after it has already completed should do
			// nothing.
			test.startFn(t, s)
			ctx, cancel = context.WithTimeout(context.Background(), delay+defaultAsyncNegativeEventTimeout)
			defer cancel()
			if _, ok := e.ReadContext(ctx); ok {
				t.Fatal("unexpectedly got a packet after finishing router solicitations")
			}
		})
	}
}
