// Copyright 2018 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 ipv6

import (
	"bytes"
	"context"
	"net"
	"reflect"
	"strings"
	"testing"
	"time"

	"github.com/google/go-cmp/cmp"
	"gvisor.dev/gvisor/pkg/tcpip"
	"gvisor.dev/gvisor/pkg/tcpip/buffer"
	"gvisor.dev/gvisor/pkg/tcpip/checker"
	"gvisor.dev/gvisor/pkg/tcpip/header"
	"gvisor.dev/gvisor/pkg/tcpip/link/channel"
	"gvisor.dev/gvisor/pkg/tcpip/link/sniffer"
	"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 (
	nicID = 1

	linkAddr0 = tcpip.LinkAddress("\x02\x02\x03\x04\x05\x06")
	linkAddr1 = tcpip.LinkAddress("\x0a\x0b\x0c\x0d\x0e\x0e")
	linkAddr2 = tcpip.LinkAddress("\x0a\x0b\x0c\x0d\x0e\x0f")

	defaultChannelSize = 1
	defaultMTU         = 65536

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

	arbitraryHopLimit = 42
)

var (
	lladdr0 = header.LinkLocalAddr(linkAddr0)
	lladdr1 = header.LinkLocalAddr(linkAddr1)
	lladdr2 = header.LinkLocalAddr(linkAddr2)
)

type stubLinkEndpoint struct {
	stack.LinkEndpoint
}

func (*stubLinkEndpoint) MTU() uint32 {
	return defaultMTU
}

func (*stubLinkEndpoint) Capabilities() stack.LinkEndpointCapabilities {
	// Indicate that resolution for link layer addresses is required to send
	// packets over this link. This is needed so the NIC knows to allocate a
	// neighbor table.
	return stack.CapabilityResolutionRequired
}

func (*stubLinkEndpoint) MaxHeaderLength() uint16 {
	return 0
}

func (*stubLinkEndpoint) LinkAddress() tcpip.LinkAddress {
	return ""
}

func (*stubLinkEndpoint) WritePacket(stack.RouteInfo, *stack.GSO, tcpip.NetworkProtocolNumber, *stack.PacketBuffer) tcpip.Error {
	return nil
}

func (*stubLinkEndpoint) Attach(stack.NetworkDispatcher) {}

type stubDispatcher struct {
	stack.TransportDispatcher
}

func (*stubDispatcher) DeliverTransportPacket(tcpip.TransportProtocolNumber, *stack.PacketBuffer) stack.TransportPacketDisposition {
	return stack.TransportPacketHandled
}

var _ stack.NetworkInterface = (*testInterface)(nil)

type testInterface struct {
	stack.LinkEndpoint

	probeCount        int
	confirmationCount int

	nicID tcpip.NICID
}

func (*testInterface) ID() tcpip.NICID {
	return nicID
}

func (*testInterface) IsLoopback() bool {
	return false
}

func (*testInterface) Name() string {
	return ""
}

func (*testInterface) Enabled() bool {
	return true
}

func (*testInterface) Promiscuous() bool {
	return false
}

func (*testInterface) Spoofing() bool {
	return false
}

func (t *testInterface) WritePacket(r *stack.Route, gso *stack.GSO, protocol tcpip.NetworkProtocolNumber, pkt *stack.PacketBuffer) tcpip.Error {
	return t.LinkEndpoint.WritePacket(r.Fields(), gso, protocol, pkt)
}

func (t *testInterface) WritePackets(r *stack.Route, gso *stack.GSO, pkts stack.PacketBufferList, protocol tcpip.NetworkProtocolNumber) (int, tcpip.Error) {
	return t.LinkEndpoint.WritePackets(r.Fields(), gso, pkts, protocol)
}

func (t *testInterface) WritePacketToRemote(remoteLinkAddr tcpip.LinkAddress, gso *stack.GSO, protocol tcpip.NetworkProtocolNumber, pkt *stack.PacketBuffer) tcpip.Error {
	var r stack.RouteInfo
	r.NetProto = protocol
	r.RemoteLinkAddress = remoteLinkAddr
	return t.LinkEndpoint.WritePacket(r, gso, protocol, pkt)
}

func (t *testInterface) HandleNeighborProbe(tcpip.NetworkProtocolNumber, tcpip.Address, tcpip.LinkAddress) tcpip.Error {
	t.probeCount++
	return nil
}

func (t *testInterface) HandleNeighborConfirmation(tcpip.NetworkProtocolNumber, tcpip.Address, tcpip.LinkAddress, stack.ReachabilityConfirmationFlags) tcpip.Error {
	t.confirmationCount++
	return nil
}

func (*testInterface) PrimaryAddress(tcpip.NetworkProtocolNumber) (tcpip.AddressWithPrefix, tcpip.Error) {
	return tcpip.AddressWithPrefix{}, nil
}

func (*testInterface) CheckLocalAddress(tcpip.NetworkProtocolNumber, tcpip.Address) bool {
	return false
}

func handleICMPInIPv6(ep stack.NetworkEndpoint, src, dst tcpip.Address, icmp header.ICMPv6, hopLimit uint8, includeRouterAlert bool) {
	var extensionHeaders header.IPv6ExtHdrSerializer
	if includeRouterAlert {
		extensionHeaders = header.IPv6ExtHdrSerializer{
			header.IPv6SerializableHopByHopExtHdr{
				&header.IPv6RouterAlertOption{Value: header.IPv6RouterAlertMLD},
			},
		}
	}
	ip := buffer.NewView(header.IPv6MinimumSize + extensionHeaders.Length())
	header.IPv6(ip).Encode(&header.IPv6Fields{
		PayloadLength:     uint16(len(icmp)),
		TransportProtocol: header.ICMPv6ProtocolNumber,
		HopLimit:          hopLimit,
		SrcAddr:           src,
		DstAddr:           dst,
		ExtensionHeaders:  extensionHeaders,
	})

	vv := ip.ToVectorisedView()
	vv.AppendView(buffer.View(icmp))
	ep.HandlePacket(stack.NewPacketBuffer(stack.PacketBufferOptions{
		Data: vv,
	}))
}

func TestICMPCounts(t *testing.T) {
	s := stack.New(stack.Options{
		NetworkProtocols:   []stack.NetworkProtocolFactory{NewProtocol},
		TransportProtocols: []stack.TransportProtocolFactory{icmp.NewProtocol6},
	})
	if err := s.CreateNIC(nicID, &stubLinkEndpoint{}); err != nil {
		t.Fatalf("CreateNIC(_, _) = %s", err)
	}
	{
		subnet, err := tcpip.NewSubnet(lladdr1, tcpip.AddressMask(strings.Repeat("\xff", len(lladdr1))))
		if err != nil {
			t.Fatal(err)
		}
		s.SetRouteTable(
			[]tcpip.Route{{
				Destination: subnet,
				NIC:         nicID,
			}},
		)
	}

	netProto := s.NetworkProtocolInstance(ProtocolNumber)
	if netProto == nil {
		t.Fatalf("cannot find protocol instance for network protocol %d", ProtocolNumber)
	}
	ep := netProto.NewEndpoint(&testInterface{}, &stubDispatcher{})
	defer ep.Close()

	if err := ep.Enable(); err != nil {
		t.Fatalf("ep.Enable(): %s", err)
	}

	addressableEndpoint, ok := ep.(stack.AddressableEndpoint)
	if !ok {
		t.Fatalf("expected network endpoint to implement stack.AddressableEndpoint")
	}
	addr := lladdr0.WithPrefix()
	if ep, err := addressableEndpoint.AddAndAcquirePermanentAddress(addr, stack.CanBePrimaryEndpoint, stack.AddressConfigStatic, false /* deprecated */); err != nil {
		t.Fatalf("addressableEndpoint.AddAndAcquirePermanentAddress(%s, CanBePrimaryEndpoint, AddressConfigStatic, false): %s", addr, err)
	} else {
		ep.DecRef()
	}

	var tllData [header.NDPLinkLayerAddressSize]byte
	header.NDPOptions(tllData[:]).Serialize(header.NDPOptionsSerializer{
		header.NDPTargetLinkLayerAddressOption(linkAddr1),
	})

	types := []struct {
		typ                header.ICMPv6Type
		hopLimit           uint8
		includeRouterAlert bool
		size               int
		extraData          []byte
	}{
		{
			typ:      header.ICMPv6DstUnreachable,
			hopLimit: arbitraryHopLimit,
			size:     header.ICMPv6DstUnreachableMinimumSize,
		},
		{
			typ:      header.ICMPv6PacketTooBig,
			hopLimit: arbitraryHopLimit,
			size:     header.ICMPv6PacketTooBigMinimumSize,
		},
		{
			typ:      header.ICMPv6TimeExceeded,
			hopLimit: arbitraryHopLimit,
			size:     header.ICMPv6MinimumSize,
		},
		{
			typ:      header.ICMPv6ParamProblem,
			hopLimit: arbitraryHopLimit,
			size:     header.ICMPv6MinimumSize,
		},
		{
			typ:      header.ICMPv6EchoRequest,
			hopLimit: arbitraryHopLimit,
			size:     header.ICMPv6EchoMinimumSize,
		},
		{
			typ:      header.ICMPv6EchoReply,
			hopLimit: arbitraryHopLimit,
			size:     header.ICMPv6EchoMinimumSize,
		},
		{
			typ:      header.ICMPv6RouterSolicit,
			hopLimit: header.NDPHopLimit,
			size:     header.ICMPv6MinimumSize,
		},
		{
			typ:      header.ICMPv6RouterAdvert,
			hopLimit: header.NDPHopLimit,
			size:     header.ICMPv6HeaderSize + header.NDPRAMinimumSize,
		},
		{
			typ:      header.ICMPv6NeighborSolicit,
			hopLimit: header.NDPHopLimit,
			size:     header.ICMPv6NeighborSolicitMinimumSize,
		},
		{
			typ:       header.ICMPv6NeighborAdvert,
			hopLimit:  header.NDPHopLimit,
			size:      header.ICMPv6NeighborAdvertMinimumSize,
			extraData: tllData[:],
		},
		{
			typ:      header.ICMPv6RedirectMsg,
			hopLimit: header.NDPHopLimit,
			size:     header.ICMPv6MinimumSize,
		},
		{
			typ:                header.ICMPv6MulticastListenerQuery,
			hopLimit:           header.MLDHopLimit,
			includeRouterAlert: true,
			size:               header.MLDMinimumSize + header.ICMPv6HeaderSize,
		},
		{
			typ:                header.ICMPv6MulticastListenerReport,
			hopLimit:           header.MLDHopLimit,
			includeRouterAlert: true,
			size:               header.MLDMinimumSize + header.ICMPv6HeaderSize,
		},
		{
			typ:                header.ICMPv6MulticastListenerDone,
			hopLimit:           header.MLDHopLimit,
			includeRouterAlert: true,
			size:               header.MLDMinimumSize + header.ICMPv6HeaderSize,
		},
		{
			typ:  255, /* Unrecognized */
			size: 50,
		},
	}

	for _, typ := range types {
		icmp := header.ICMPv6(buffer.NewView(typ.size + len(typ.extraData)))
		copy(icmp[typ.size:], typ.extraData)
		icmp.SetType(typ.typ)
		icmp.SetChecksum(header.ICMPv6Checksum(header.ICMPv6ChecksumParams{
			Header:      icmp[:typ.size],
			Src:         lladdr0,
			Dst:         lladdr1,
			PayloadCsum: header.Checksum(typ.extraData, 0 /* initial */),
			PayloadLen:  len(typ.extraData),
		}))
		handleICMPInIPv6(ep, lladdr1, lladdr0, icmp, typ.hopLimit, typ.includeRouterAlert)
	}

	// Construct an empty ICMP packet so that
	// Stats().ICMP.ICMPv6ReceivedPacketStats.Invalid is incremented.
	handleICMPInIPv6(ep, lladdr1, lladdr0, header.ICMPv6(buffer.NewView(header.IPv6MinimumSize)), arbitraryHopLimit, false)

	icmpv6Stats := s.Stats().ICMP.V6.PacketsReceived
	visitStats(reflect.ValueOf(&icmpv6Stats).Elem(), func(name string, s *tcpip.StatCounter) {
		if got, want := s.Value(), uint64(1); got != want {
			t.Errorf("got %s = %d, want = %d", name, got, want)
		}
	})
	if t.Failed() {
		t.Logf("stats:\n%+v", s.Stats())
	}
}

func visitStats(v reflect.Value, f func(string, *tcpip.StatCounter)) {
	t := v.Type()
	for i := 0; i < v.NumField(); i++ {
		v := v.Field(i)
		if s, ok := v.Interface().(*tcpip.StatCounter); ok {
			f(t.Field(i).Name, s)
		} else {
			visitStats(v, f)
		}
	}
}

type testContext struct {
	s0 *stack.Stack
	s1 *stack.Stack

	linkEP0 *channel.Endpoint
	linkEP1 *channel.Endpoint
}

type endpointWithResolutionCapability struct {
	stack.LinkEndpoint
}

func (e endpointWithResolutionCapability) Capabilities() stack.LinkEndpointCapabilities {
	return e.LinkEndpoint.Capabilities() | stack.CapabilityResolutionRequired
}

func newTestContext(t *testing.T) *testContext {
	c := &testContext{
		s0: stack.New(stack.Options{
			NetworkProtocols:   []stack.NetworkProtocolFactory{NewProtocol},
			TransportProtocols: []stack.TransportProtocolFactory{icmp.NewProtocol6},
		}),
		s1: stack.New(stack.Options{
			NetworkProtocols:   []stack.NetworkProtocolFactory{NewProtocol},
			TransportProtocols: []stack.TransportProtocolFactory{icmp.NewProtocol6},
		}),
	}

	c.linkEP0 = channel.New(defaultChannelSize, defaultMTU, linkAddr0)

	wrappedEP0 := stack.LinkEndpoint(endpointWithResolutionCapability{LinkEndpoint: c.linkEP0})
	if testing.Verbose() {
		wrappedEP0 = sniffer.New(wrappedEP0)
	}
	if err := c.s0.CreateNIC(nicID, wrappedEP0); err != nil {
		t.Fatalf("CreateNIC s0: %v", err)
	}
	if err := c.s0.AddAddress(nicID, ProtocolNumber, lladdr0); err != nil {
		t.Fatalf("AddAddress lladdr0: %v", err)
	}

	c.linkEP1 = channel.New(defaultChannelSize, defaultMTU, linkAddr1)
	wrappedEP1 := stack.LinkEndpoint(endpointWithResolutionCapability{LinkEndpoint: c.linkEP1})
	if err := c.s1.CreateNIC(nicID, wrappedEP1); err != nil {
		t.Fatalf("CreateNIC failed: %v", err)
	}
	if err := c.s1.AddAddress(nicID, ProtocolNumber, lladdr1); err != nil {
		t.Fatalf("AddAddress lladdr1: %v", err)
	}

	subnet0, err := tcpip.NewSubnet(lladdr1, tcpip.AddressMask(strings.Repeat("\xff", len(lladdr1))))
	if err != nil {
		t.Fatal(err)
	}
	c.s0.SetRouteTable(
		[]tcpip.Route{{
			Destination: subnet0,
			NIC:         nicID,
		}},
	)
	subnet1, err := tcpip.NewSubnet(lladdr0, tcpip.AddressMask(strings.Repeat("\xff", len(lladdr0))))
	if err != nil {
		t.Fatal(err)
	}
	c.s1.SetRouteTable(
		[]tcpip.Route{{
			Destination: subnet1,
			NIC:         nicID,
		}},
	)

	t.Cleanup(func() {
		if err := c.s0.RemoveNIC(nicID); err != nil {
			t.Errorf("c.s0.RemoveNIC(%d): %s", nicID, err)
		}
		if err := c.s1.RemoveNIC(nicID); err != nil {
			t.Errorf("c.s1.RemoveNIC(%d): %s", nicID, err)
		}

		c.linkEP0.Close()
		c.linkEP1.Close()
	})

	return c
}

type routeArgs struct {
	src, dst       *channel.Endpoint
	typ            header.ICMPv6Type
	remoteLinkAddr tcpip.LinkAddress
}

func routeICMPv6Packet(t *testing.T, args routeArgs, fn func(*testing.T, header.ICMPv6)) {
	t.Helper()

	pi, _ := args.src.ReadContext(context.Background())

	{
		pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{
			Data: buffer.NewVectorisedView(pi.Pkt.Size(), pi.Pkt.Views()),
		})
		args.dst.InjectLinkAddr(pi.Proto, args.dst.LinkAddress(), pkt)
	}

	if pi.Proto != ProtocolNumber {
		t.Errorf("unexpected protocol number %d", pi.Proto)
		return
	}

	if len(args.remoteLinkAddr) != 0 && pi.Route.RemoteLinkAddress != args.remoteLinkAddr {
		t.Errorf("got remote link address = %s, want = %s", pi.Route.RemoteLinkAddress, args.remoteLinkAddr)
	}

	// Pull the full payload since network header. Needed for header.IPv6 to
	// extract its payload.
	ipv6 := header.IPv6(stack.PayloadSince(pi.Pkt.NetworkHeader()))
	transProto := tcpip.TransportProtocolNumber(ipv6.NextHeader())
	if transProto != header.ICMPv6ProtocolNumber {
		t.Errorf("unexpected transport protocol number %d", transProto)
		return
	}
	icmpv6 := header.ICMPv6(ipv6.Payload())
	if got, want := icmpv6.Type(), args.typ; got != want {
		t.Errorf("got ICMPv6 type = %d, want = %d", got, want)
		return
	}
	if fn != nil {
		fn(t, icmpv6)
	}
}

func TestLinkResolution(t *testing.T) {
	c := newTestContext(t)

	r, err := c.s0.FindRoute(nicID, lladdr0, lladdr1, ProtocolNumber, false /* multicastLoop */)
	if err != nil {
		t.Fatalf("FindRoute(%d, %s, %s, _, false) = (_, %s), want = (_, nil)", nicID, lladdr0, lladdr1, err)
	}
	defer r.Release()

	hdr := buffer.NewPrependable(int(r.MaxHeaderLength()) + header.IPv6MinimumSize + header.ICMPv6EchoMinimumSize)
	pkt := header.ICMPv6(hdr.Prepend(header.ICMPv6EchoMinimumSize))
	pkt.SetType(header.ICMPv6EchoRequest)
	pkt.SetChecksum(header.ICMPv6Checksum(header.ICMPv6ChecksumParams{
		Header: pkt,
		Src:    r.LocalAddress(),
		Dst:    r.RemoteAddress(),
	}))

	// We can't send our payload directly over the route because that
	// doesn't provoke NDP discovery.
	var wq waiter.Queue
	ep, err := c.s0.NewEndpoint(header.ICMPv6ProtocolNumber, ProtocolNumber, &wq)
	if err != nil {
		t.Fatalf("NewEndpoint(_) = (_, %s), want = (_, nil)", err)
	}

	{
		var r bytes.Reader
		r.Reset(hdr.View())
		if _, err := ep.Write(&r, tcpip.WriteOptions{To: &tcpip.FullAddress{NIC: nicID, Addr: lladdr1}}); err != nil {
			t.Fatalf("ep.Write(_): %s", err)
		}
	}
	for _, args := range []routeArgs{
		{src: c.linkEP0, dst: c.linkEP1, typ: header.ICMPv6NeighborSolicit, remoteLinkAddr: header.EthernetAddressFromMulticastIPv6Address(header.SolicitedNodeAddr(lladdr1))},
		{src: c.linkEP1, dst: c.linkEP0, typ: header.ICMPv6NeighborAdvert},
	} {
		routeICMPv6Packet(t, args, func(t *testing.T, icmpv6 header.ICMPv6) {
			if got, want := tcpip.Address(icmpv6[8:][:16]), lladdr1; got != want {
				t.Errorf("%d: got target = %s, want = %s", icmpv6.Type(), got, want)
			}
		})
	}

	for _, args := range []routeArgs{
		{src: c.linkEP0, dst: c.linkEP1, typ: header.ICMPv6EchoRequest},
		{src: c.linkEP1, dst: c.linkEP0, typ: header.ICMPv6EchoReply},
	} {
		routeICMPv6Packet(t, args, nil)
	}
}

func TestICMPChecksumValidationSimple(t *testing.T) {
	var tllData [header.NDPLinkLayerAddressSize]byte
	header.NDPOptions(tllData[:]).Serialize(header.NDPOptionsSerializer{
		header.NDPTargetLinkLayerAddressOption(linkAddr1),
	})

	types := []struct {
		name        string
		typ         header.ICMPv6Type
		size        int
		extraData   []byte
		statCounter func(tcpip.ICMPv6ReceivedPacketStats) *tcpip.StatCounter
		routerOnly  bool
	}{
		{
			name: "DstUnreachable",
			typ:  header.ICMPv6DstUnreachable,
			size: header.ICMPv6DstUnreachableMinimumSize,
			statCounter: func(stats tcpip.ICMPv6ReceivedPacketStats) *tcpip.StatCounter {
				return stats.DstUnreachable
			},
		},
		{
			name: "PacketTooBig",
			typ:  header.ICMPv6PacketTooBig,
			size: header.ICMPv6PacketTooBigMinimumSize,
			statCounter: func(stats tcpip.ICMPv6ReceivedPacketStats) *tcpip.StatCounter {
				return stats.PacketTooBig
			},
		},
		{
			name: "TimeExceeded",
			typ:  header.ICMPv6TimeExceeded,
			size: header.ICMPv6MinimumSize,
			statCounter: func(stats tcpip.ICMPv6ReceivedPacketStats) *tcpip.StatCounter {
				return stats.TimeExceeded
			},
		},
		{
			name: "ParamProblem",
			typ:  header.ICMPv6ParamProblem,
			size: header.ICMPv6MinimumSize,
			statCounter: func(stats tcpip.ICMPv6ReceivedPacketStats) *tcpip.StatCounter {
				return stats.ParamProblem
			},
		},
		{
			name: "EchoRequest",
			typ:  header.ICMPv6EchoRequest,
			size: header.ICMPv6EchoMinimumSize,
			statCounter: func(stats tcpip.ICMPv6ReceivedPacketStats) *tcpip.StatCounter {
				return stats.EchoRequest
			},
		},
		{
			name: "EchoReply",
			typ:  header.ICMPv6EchoReply,
			size: header.ICMPv6EchoMinimumSize,
			statCounter: func(stats tcpip.ICMPv6ReceivedPacketStats) *tcpip.StatCounter {
				return stats.EchoReply
			},
		},
		{
			name: "RouterSolicit",
			typ:  header.ICMPv6RouterSolicit,
			size: header.ICMPv6MinimumSize,
			statCounter: func(stats tcpip.ICMPv6ReceivedPacketStats) *tcpip.StatCounter {
				return stats.RouterSolicit
			},
			// Hosts MUST silently discard any received Router Solicitation messages.
			routerOnly: true,
		},
		{
			name: "RouterAdvert",
			typ:  header.ICMPv6RouterAdvert,
			size: header.ICMPv6HeaderSize + header.NDPRAMinimumSize,
			statCounter: func(stats tcpip.ICMPv6ReceivedPacketStats) *tcpip.StatCounter {
				return stats.RouterAdvert
			},
		},
		{
			name: "NeighborSolicit",
			typ:  header.ICMPv6NeighborSolicit,
			size: header.ICMPv6NeighborSolicitMinimumSize,
			statCounter: func(stats tcpip.ICMPv6ReceivedPacketStats) *tcpip.StatCounter {
				return stats.NeighborSolicit
			},
		},
		{
			name:      "NeighborAdvert",
			typ:       header.ICMPv6NeighborAdvert,
			size:      header.ICMPv6NeighborAdvertMinimumSize,
			extraData: tllData[:],
			statCounter: func(stats tcpip.ICMPv6ReceivedPacketStats) *tcpip.StatCounter {
				return stats.NeighborAdvert
			},
		},
		{
			name: "RedirectMsg",
			typ:  header.ICMPv6RedirectMsg,
			size: header.ICMPv6MinimumSize,
			statCounter: func(stats tcpip.ICMPv6ReceivedPacketStats) *tcpip.StatCounter {
				return stats.RedirectMsg
			},
		},
	}

	for _, typ := range types {
		for _, isRouter := range []bool{false, true} {
			name := typ.name
			if isRouter {
				name += " (Router)"
			}
			t.Run(name, func(t *testing.T) {
				e := channel.New(0, 1280, linkAddr0)

				// Indicate that resolution for link layer addresses is required to
				// send packets over this link. This is needed so the NIC knows to
				// allocate a neighbor table.
				e.LinkEPCapabilities |= stack.CapabilityResolutionRequired

				s := stack.New(stack.Options{
					NetworkProtocols: []stack.NetworkProtocolFactory{NewProtocol},
				})
				if isRouter {
					// Enabling forwarding makes the stack act as a router.
					s.SetForwarding(ProtocolNumber, true)
				}
				if err := s.CreateNIC(nicID, e); err != nil {
					t.Fatalf("CreateNIC(_, _) = %s", err)
				}

				if err := s.AddAddress(nicID, ProtocolNumber, lladdr0); err != nil {
					t.Fatalf("AddAddress(_, %d, %s) = %s", ProtocolNumber, lladdr0, err)
				}
				{
					subnet, err := tcpip.NewSubnet(lladdr1, tcpip.AddressMask(strings.Repeat("\xff", len(lladdr1))))
					if err != nil {
						t.Fatal(err)
					}
					s.SetRouteTable(
						[]tcpip.Route{{
							Destination: subnet,
							NIC:         nicID,
						}},
					)
				}

				handleIPv6Payload := func(checksum bool) {
					icmp := header.ICMPv6(buffer.NewView(typ.size + len(typ.extraData)))
					copy(icmp[typ.size:], typ.extraData)
					icmp.SetType(typ.typ)
					if checksum {
						icmp.SetChecksum(header.ICMPv6Checksum(header.ICMPv6ChecksumParams{
							Header: icmp,
							Src:    lladdr1,
							Dst:    lladdr0,
						}))
					}
					ip := header.IPv6(buffer.NewView(header.IPv6MinimumSize))
					ip.Encode(&header.IPv6Fields{
						PayloadLength:     uint16(len(icmp)),
						TransportProtocol: header.ICMPv6ProtocolNumber,
						HopLimit:          header.NDPHopLimit,
						SrcAddr:           lladdr1,
						DstAddr:           lladdr0,
					})
					pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{
						Data: buffer.NewVectorisedView(len(ip)+len(icmp), []buffer.View{buffer.View(ip), buffer.View(icmp)}),
					})
					e.InjectInbound(ProtocolNumber, pkt)
				}

				stats := s.Stats().ICMP.V6.PacketsReceived
				invalid := stats.Invalid
				routerOnly := stats.RouterOnlyPacketsDroppedByHost
				typStat := typ.statCounter(stats)

				// Initial stat counts should be 0.
				if got := invalid.Value(); got != 0 {
					t.Fatalf("got invalid = %d, want = 0", got)
				}
				if got := routerOnly.Value(); got != 0 {
					t.Fatalf("got RouterOnlyPacketsReceivedByHost = %d, want = 0", got)
				}
				if got := typStat.Value(); got != 0 {
					t.Fatalf("got %s = %d, want = 0", typ.name, got)
				}

				// Without setting checksum, the incoming packet should
				// be invalid.
				handleIPv6Payload(false)
				if got := invalid.Value(); got != 1 {
					t.Fatalf("got invalid = %d, want = 1", got)
				}
				// Router only count should not have increased.
				if got := routerOnly.Value(); got != 0 {
					t.Fatalf("got RouterOnlyPacketsReceivedByHost = %d, want = 0", got)
				}
				// Rx count of type typ.typ should not have increased.
				if got := typStat.Value(); got != 0 {
					t.Fatalf("got %s = %d, want = 0", typ.name, got)
				}

				// When checksum is set, it should be received.
				handleIPv6Payload(true)
				if got := typStat.Value(); got != 1 {
					t.Fatalf("got %s = %d, want = 1", typ.name, got)
				}
				// Invalid count should not have increased again.
				if got := invalid.Value(); got != 1 {
					t.Fatalf("got invalid = %d, want = 1", got)
				}
				if !isRouter && typ.routerOnly {
					// Router only count should have increased.
					if got := routerOnly.Value(); got != 1 {
						t.Fatalf("got RouterOnlyPacketsReceivedByHost = %d, want = 1", got)
					}
				}
			})
		}
	}
}

func TestICMPChecksumValidationWithPayload(t *testing.T) {
	const simpleBodySize = 64
	simpleBody := func(view buffer.View) {
		for i := 0; i < simpleBodySize; i++ {
			view[i] = uint8(i)
		}
	}

	const errorICMPBodySize = header.IPv6MinimumSize + simpleBodySize
	errorICMPBody := func(view buffer.View) {
		ip := header.IPv6(view)
		ip.Encode(&header.IPv6Fields{
			PayloadLength:     simpleBodySize,
			TransportProtocol: 10,
			HopLimit:          20,
			SrcAddr:           lladdr0,
			DstAddr:           lladdr1,
		})
		simpleBody(view[header.IPv6MinimumSize:])
	}

	types := []struct {
		name        string
		typ         header.ICMPv6Type
		size        int
		statCounter func(tcpip.ICMPv6ReceivedPacketStats) *tcpip.StatCounter
		payloadSize int
		payload     func(buffer.View)
	}{
		{
			"DstUnreachable",
			header.ICMPv6DstUnreachable,
			header.ICMPv6DstUnreachableMinimumSize,
			func(stats tcpip.ICMPv6ReceivedPacketStats) *tcpip.StatCounter {
				return stats.DstUnreachable
			},
			errorICMPBodySize,
			errorICMPBody,
		},
		{
			"PacketTooBig",
			header.ICMPv6PacketTooBig,
			header.ICMPv6PacketTooBigMinimumSize,
			func(stats tcpip.ICMPv6ReceivedPacketStats) *tcpip.StatCounter {
				return stats.PacketTooBig
			},
			errorICMPBodySize,
			errorICMPBody,
		},
		{
			"TimeExceeded",
			header.ICMPv6TimeExceeded,
			header.ICMPv6MinimumSize,
			func(stats tcpip.ICMPv6ReceivedPacketStats) *tcpip.StatCounter {
				return stats.TimeExceeded
			},
			errorICMPBodySize,
			errorICMPBody,
		},
		{
			"ParamProblem",
			header.ICMPv6ParamProblem,
			header.ICMPv6MinimumSize,
			func(stats tcpip.ICMPv6ReceivedPacketStats) *tcpip.StatCounter {
				return stats.ParamProblem
			},
			errorICMPBodySize,
			errorICMPBody,
		},
		{
			"EchoRequest",
			header.ICMPv6EchoRequest,
			header.ICMPv6EchoMinimumSize,
			func(stats tcpip.ICMPv6ReceivedPacketStats) *tcpip.StatCounter {
				return stats.EchoRequest
			},
			simpleBodySize,
			simpleBody,
		},
		{
			"EchoReply",
			header.ICMPv6EchoReply,
			header.ICMPv6EchoMinimumSize,
			func(stats tcpip.ICMPv6ReceivedPacketStats) *tcpip.StatCounter {
				return stats.EchoReply
			},
			simpleBodySize,
			simpleBody,
		},
	}

	for _, typ := range types {
		t.Run(typ.name, func(t *testing.T) {
			e := channel.New(10, 1280, linkAddr0)
			s := stack.New(stack.Options{
				NetworkProtocols: []stack.NetworkProtocolFactory{NewProtocol},
			})
			if err := s.CreateNIC(nicID, e); err != nil {
				t.Fatalf("CreateNIC(_, _) = %s", err)
			}

			if err := s.AddAddress(nicID, ProtocolNumber, lladdr0); err != nil {
				t.Fatalf("AddAddress(_, %d, %s) = %s", ProtocolNumber, lladdr0, err)
			}
			{
				subnet, err := tcpip.NewSubnet(lladdr1, tcpip.AddressMask(strings.Repeat("\xff", len(lladdr1))))
				if err != nil {
					t.Fatal(err)
				}
				s.SetRouteTable(
					[]tcpip.Route{{
						Destination: subnet,
						NIC:         nicID,
					}},
				)
			}

			handleIPv6Payload := func(typ header.ICMPv6Type, size, payloadSize int, payloadFn func(buffer.View), checksum bool) {
				icmpSize := size + payloadSize
				hdr := buffer.NewPrependable(header.IPv6MinimumSize + icmpSize)
				icmpHdr := header.ICMPv6(hdr.Prepend(icmpSize))
				icmpHdr.SetType(typ)
				payloadFn(icmpHdr.Payload())

				if checksum {
					icmpHdr.SetChecksum(header.ICMPv6Checksum(header.ICMPv6ChecksumParams{
						Header: icmpHdr,
						Src:    lladdr1,
						Dst:    lladdr0,
					}))
				}

				ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize))
				ip.Encode(&header.IPv6Fields{
					PayloadLength:     uint16(icmpSize),
					TransportProtocol: header.ICMPv6ProtocolNumber,
					HopLimit:          header.NDPHopLimit,
					SrcAddr:           lladdr1,
					DstAddr:           lladdr0,
				})
				pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{
					Data: hdr.View().ToVectorisedView(),
				})
				e.InjectInbound(ProtocolNumber, pkt)
			}

			stats := s.Stats().ICMP.V6.PacketsReceived
			invalid := stats.Invalid
			typStat := typ.statCounter(stats)

			// Initial stat counts should be 0.
			if got := invalid.Value(); got != 0 {
				t.Fatalf("got invalid = %d, want = 0", got)
			}
			if got := typStat.Value(); got != 0 {
				t.Fatalf("got = %d, want = 0", got)
			}

			// Without setting checksum, the incoming packet should
			// be invalid.
			handleIPv6Payload(typ.typ, typ.size, typ.payloadSize, typ.payload, false)
			if got := invalid.Value(); got != 1 {
				t.Fatalf("got invalid = %d, want = 1", got)
			}
			// Rx count of type typ.typ should not have increased.
			if got := typStat.Value(); got != 0 {
				t.Fatalf("got = %d, want = 0", got)
			}

			// When checksum is set, it should be received.
			handleIPv6Payload(typ.typ, typ.size, typ.payloadSize, typ.payload, true)
			if got := typStat.Value(); got != 1 {
				t.Fatalf("got = %d, want = 0", got)
			}
			// Invalid count should not have increased again.
			if got := invalid.Value(); got != 1 {
				t.Fatalf("got invalid = %d, want = 1", got)
			}
		})
	}
}

func TestICMPChecksumValidationWithPayloadMultipleViews(t *testing.T) {
	const simpleBodySize = 64
	simpleBody := func(view buffer.View) {
		for i := 0; i < simpleBodySize; i++ {
			view[i] = uint8(i)
		}
	}

	const errorICMPBodySize = header.IPv6MinimumSize + simpleBodySize
	errorICMPBody := func(view buffer.View) {
		ip := header.IPv6(view)
		ip.Encode(&header.IPv6Fields{
			PayloadLength:     simpleBodySize,
			TransportProtocol: 10,
			HopLimit:          20,
			SrcAddr:           lladdr0,
			DstAddr:           lladdr1,
		})
		simpleBody(view[header.IPv6MinimumSize:])
	}

	types := []struct {
		name        string
		typ         header.ICMPv6Type
		size        int
		statCounter func(tcpip.ICMPv6ReceivedPacketStats) *tcpip.StatCounter
		payloadSize int
		payload     func(buffer.View)
	}{
		{
			"DstUnreachable",
			header.ICMPv6DstUnreachable,
			header.ICMPv6DstUnreachableMinimumSize,
			func(stats tcpip.ICMPv6ReceivedPacketStats) *tcpip.StatCounter {
				return stats.DstUnreachable
			},
			errorICMPBodySize,
			errorICMPBody,
		},
		{
			"PacketTooBig",
			header.ICMPv6PacketTooBig,
			header.ICMPv6PacketTooBigMinimumSize,
			func(stats tcpip.ICMPv6ReceivedPacketStats) *tcpip.StatCounter {
				return stats.PacketTooBig
			},
			errorICMPBodySize,
			errorICMPBody,
		},
		{
			"TimeExceeded",
			header.ICMPv6TimeExceeded,
			header.ICMPv6MinimumSize,
			func(stats tcpip.ICMPv6ReceivedPacketStats) *tcpip.StatCounter {
				return stats.TimeExceeded
			},
			errorICMPBodySize,
			errorICMPBody,
		},
		{
			"ParamProblem",
			header.ICMPv6ParamProblem,
			header.ICMPv6MinimumSize,
			func(stats tcpip.ICMPv6ReceivedPacketStats) *tcpip.StatCounter {
				return stats.ParamProblem
			},
			errorICMPBodySize,
			errorICMPBody,
		},
		{
			"EchoRequest",
			header.ICMPv6EchoRequest,
			header.ICMPv6EchoMinimumSize,
			func(stats tcpip.ICMPv6ReceivedPacketStats) *tcpip.StatCounter {
				return stats.EchoRequest
			},
			simpleBodySize,
			simpleBody,
		},
		{
			"EchoReply",
			header.ICMPv6EchoReply,
			header.ICMPv6EchoMinimumSize,
			func(stats tcpip.ICMPv6ReceivedPacketStats) *tcpip.StatCounter {
				return stats.EchoReply
			},
			simpleBodySize,
			simpleBody,
		},
	}

	for _, typ := range types {
		t.Run(typ.name, func(t *testing.T) {
			e := channel.New(10, 1280, linkAddr0)
			s := stack.New(stack.Options{
				NetworkProtocols: []stack.NetworkProtocolFactory{NewProtocol},
			})
			if err := s.CreateNIC(nicID, e); err != nil {
				t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
			}

			if err := s.AddAddress(nicID, ProtocolNumber, lladdr0); err != nil {
				t.Fatalf("AddAddress(%d, %d, %s) = %s", nicID, ProtocolNumber, lladdr0, err)
			}
			{
				subnet, err := tcpip.NewSubnet(lladdr1, tcpip.AddressMask(strings.Repeat("\xff", len(lladdr1))))
				if err != nil {
					t.Fatal(err)
				}
				s.SetRouteTable(
					[]tcpip.Route{{
						Destination: subnet,
						NIC:         nicID,
					}},
				)
			}

			handleIPv6Payload := func(typ header.ICMPv6Type, size, payloadSize int, payloadFn func(buffer.View), checksum bool) {
				hdr := buffer.NewPrependable(header.IPv6MinimumSize + size)
				icmpHdr := header.ICMPv6(hdr.Prepend(size))
				icmpHdr.SetType(typ)

				payload := buffer.NewView(payloadSize)
				payloadFn(payload)

				if checksum {
					icmpHdr.SetChecksum(header.ICMPv6Checksum(header.ICMPv6ChecksumParams{
						Header:      icmpHdr,
						Src:         lladdr1,
						Dst:         lladdr0,
						PayloadCsum: header.Checksum(payload, 0 /* initial */),
						PayloadLen:  len(payload),
					}))
				}

				ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize))
				ip.Encode(&header.IPv6Fields{
					PayloadLength:     uint16(size + payloadSize),
					TransportProtocol: header.ICMPv6ProtocolNumber,
					HopLimit:          header.NDPHopLimit,
					SrcAddr:           lladdr1,
					DstAddr:           lladdr0,
				})
				pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{
					Data: buffer.NewVectorisedView(header.IPv6MinimumSize+size+payloadSize, []buffer.View{hdr.View(), payload}),
				})
				e.InjectInbound(ProtocolNumber, pkt)
			}

			stats := s.Stats().ICMP.V6.PacketsReceived
			invalid := stats.Invalid
			typStat := typ.statCounter(stats)

			// Initial stat counts should be 0.
			if got := invalid.Value(); got != 0 {
				t.Fatalf("got invalid = %d, want = 0", got)
			}
			if got := typStat.Value(); got != 0 {
				t.Fatalf("got = %d, want = 0", got)
			}

			// Without setting checksum, the incoming packet should
			// be invalid.
			handleIPv6Payload(typ.typ, typ.size, typ.payloadSize, typ.payload, false)
			if got := invalid.Value(); got != 1 {
				t.Fatalf("got invalid = %d, want = 1", got)
			}
			// Rx count of type typ.typ should not have increased.
			if got := typStat.Value(); got != 0 {
				t.Fatalf("got = %d, want = 0", got)
			}

			// When checksum is set, it should be received.
			handleIPv6Payload(typ.typ, typ.size, typ.payloadSize, typ.payload, true)
			if got := typStat.Value(); got != 1 {
				t.Fatalf("got = %d, want = 0", got)
			}
			// Invalid count should not have increased again.
			if got := invalid.Value(); got != 1 {
				t.Fatalf("got invalid = %d, want = 1", got)
			}
		})
	}
}

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

	snaddr := header.SolicitedNodeAddr(lladdr0)
	mcaddr := header.EthernetAddressFromMulticastIPv6Address(snaddr)

	tests := []struct {
		name           string
		nicAddr        tcpip.Address
		localAddr      tcpip.Address
		remoteLinkAddr tcpip.LinkAddress

		expectedErr            tcpip.Error
		expectedRemoteAddr     tcpip.Address
		expectedRemoteLinkAddr tcpip.LinkAddress
	}{
		{
			name:                   "Unicast",
			nicAddr:                lladdr1,
			localAddr:              lladdr1,
			remoteLinkAddr:         linkAddr1,
			expectedRemoteAddr:     lladdr0,
			expectedRemoteLinkAddr: linkAddr1,
		},
		{
			name:                   "Multicast",
			nicAddr:                lladdr1,
			localAddr:              lladdr1,
			remoteLinkAddr:         "",
			expectedRemoteAddr:     snaddr,
			expectedRemoteLinkAddr: mcaddr,
		},
		{
			name:                   "Unicast with unspecified source",
			nicAddr:                lladdr1,
			remoteLinkAddr:         linkAddr1,
			expectedRemoteAddr:     lladdr0,
			expectedRemoteLinkAddr: linkAddr1,
		},
		{
			name:                   "Multicast with unspecified source",
			nicAddr:                lladdr1,
			remoteLinkAddr:         "",
			expectedRemoteAddr:     snaddr,
			expectedRemoteLinkAddr: mcaddr,
		},
		{
			name:           "Unicast with unassigned address",
			localAddr:      lladdr1,
			remoteLinkAddr: linkAddr1,
			expectedErr:    &tcpip.ErrBadLocalAddress{},
		},
		{
			name:           "Multicast with unassigned address",
			localAddr:      lladdr1,
			remoteLinkAddr: "",
			expectedErr:    &tcpip.ErrBadLocalAddress{},
		},
		{
			name:           "Unicast with no local address available",
			remoteLinkAddr: linkAddr1,
			expectedErr:    &tcpip.ErrNetworkUnreachable{},
		},
		{
			name:           "Multicast with no local address available",
			remoteLinkAddr: "",
			expectedErr:    &tcpip.ErrNetworkUnreachable{},
		},
	}

	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			s := stack.New(stack.Options{
				NetworkProtocols: []stack.NetworkProtocolFactory{NewProtocol},
			})

			linkEP := channel.New(defaultChannelSize, defaultMTU, linkAddr0)
			if err := s.CreateNIC(nicID, linkEP); err != nil {
				t.Fatalf("s.CreateNIC(%d, _): %s", nicID, err)
			}

			ep, err := s.GetNetworkEndpoint(nicID, ProtocolNumber)
			if err != nil {
				t.Fatalf("s.GetNetworkEndpoint(%d, %d): %s", nicID, ProtocolNumber, err)
			}
			linkRes, ok := ep.(stack.LinkAddressResolver)
			if !ok {
				t.Fatalf("expected %T to implement stack.LinkAddressResolver", ep)
			}

			if len(test.nicAddr) != 0 {
				if err := s.AddAddress(nicID, ProtocolNumber, test.nicAddr); err != nil {
					t.Fatalf("s.AddAddress(%d, %d, %s): %s", nicID, ProtocolNumber, test.nicAddr, err)
				}
			}

			{
				err := linkRes.LinkAddressRequest(lladdr0, test.localAddr, test.remoteLinkAddr)
				if diff := cmp.Diff(test.expectedErr, err); diff != "" {
					t.Fatalf("unexpected error from p.LinkAddressRequest(%s, %s, %s, _), (-want, +got):\n%s", lladdr0, test.localAddr, test.remoteLinkAddr, diff)
				}
			}

			if test.expectedErr != nil {
				return
			}

			pkt, ok := linkEP.Read()
			if !ok {
				t.Fatal("expected to send a link address request")
			}

			var want stack.RouteInfo
			want.NetProto = ProtocolNumber
			want.RemoteLinkAddress = test.expectedRemoteLinkAddr
			if diff := cmp.Diff(want, pkt.Route, cmp.AllowUnexported(want)); diff != "" {
				t.Errorf("route info mismatch (-want +got):\n%s", diff)
			}
			checker.IPv6(t, stack.PayloadSince(pkt.Pkt.NetworkHeader()),
				checker.SrcAddr(lladdr1),
				checker.DstAddr(test.expectedRemoteAddr),
				checker.TTL(header.NDPHopLimit),
				checker.NDPNS(
					checker.NDPNSTargetAddress(lladdr0),
					checker.NDPNSOptions([]header.NDPOption{header.NDPSourceLinkLayerAddressOption(linkAddr0)}),
				))
		})
	}
}

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

	var (
		host1NICLinkAddr = tcpip.LinkAddress("\x02\x03\x03\x04\x05\x06")
		host2NICLinkAddr = tcpip.LinkAddress("\x02\x03\x03\x04\x05\x09")

		host1IPv6Addr = tcpip.ProtocolAddress{
			Protocol: ProtocolNumber,
			AddressWithPrefix: tcpip.AddressWithPrefix{
				Address:   tcpip.Address(net.ParseIP("a::1").To16()),
				PrefixLen: 64,
			},
		}
		host2IPv6Addr = tcpip.ProtocolAddress{
			Protocol: ProtocolNumber,
			AddressWithPrefix: tcpip.AddressWithPrefix{
				Address:   tcpip.Address(net.ParseIP("a::2").To16()),
				PrefixLen: 64,
			},
		}
	)

	tests := []struct {
		name      string
		rxPkt     func(*channel.Endpoint)
		checkResp func(*testing.T, *channel.Endpoint)
	}{
		{
			name: "ICMP Error",
			rxPkt: func(e *channel.Endpoint) {
				hdr := buffer.NewPrependable(header.IPv6MinimumSize + header.UDPMinimumSize)
				u := header.UDP(hdr.Prepend(header.UDPMinimumSize))
				u.Encode(&header.UDPFields{
					SrcPort: 5555,
					DstPort: 80,
					Length:  header.UDPMinimumSize,
				})
				sum := header.PseudoHeaderChecksum(udp.ProtocolNumber, host2IPv6Addr.AddressWithPrefix.Address, host1IPv6Addr.AddressWithPrefix.Address, header.UDPMinimumSize)
				sum = header.Checksum(header.UDP([]byte{}), sum)
				u.SetChecksum(^u.CalculateChecksum(sum))
				payloadLength := hdr.UsedLength()
				ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize))
				ip.Encode(&header.IPv6Fields{
					PayloadLength:     uint16(payloadLength),
					TransportProtocol: udp.ProtocolNumber,
					HopLimit:          DefaultTTL,
					SrcAddr:           host2IPv6Addr.AddressWithPrefix.Address,
					DstAddr:           host1IPv6Addr.AddressWithPrefix.Address,
				})
				e.InjectInbound(ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
					Data: hdr.View().ToVectorisedView(),
				}))
			},
			checkResp: func(t *testing.T, e *channel.Endpoint) {
				p, ok := e.ReadContext(context.Background())
				if !ok {
					t.Fatalf("timed out waiting for packet")
				}
				if p.Proto != ProtocolNumber {
					t.Errorf("got p.Proto = %d, want = %d", p.Proto, ProtocolNumber)
				}
				if p.Route.RemoteLinkAddress != host2NICLinkAddr {
					t.Errorf("got p.Route.RemoteLinkAddress = %s, want = %s", p.Route.RemoteLinkAddress, host2NICLinkAddr)
				}
				checker.IPv6(t, stack.PayloadSince(p.Pkt.NetworkHeader()),
					checker.SrcAddr(host1IPv6Addr.AddressWithPrefix.Address),
					checker.DstAddr(host2IPv6Addr.AddressWithPrefix.Address),
					checker.ICMPv6(
						checker.ICMPv6Type(header.ICMPv6DstUnreachable),
						checker.ICMPv6Code(header.ICMPv6PortUnreachable)))
			},
		},

		{
			name: "Ping",
			rxPkt: func(e *channel.Endpoint) {
				totalLen := header.IPv6MinimumSize + header.ICMPv6MinimumSize
				hdr := buffer.NewPrependable(totalLen)
				pkt := header.ICMPv6(hdr.Prepend(header.ICMPv6MinimumSize))
				pkt.SetType(header.ICMPv6EchoRequest)
				pkt.SetCode(0)
				pkt.SetChecksum(0)
				pkt.SetChecksum(header.ICMPv6Checksum(header.ICMPv6ChecksumParams{
					Header: pkt,
					Src:    host2IPv6Addr.AddressWithPrefix.Address,
					Dst:    host1IPv6Addr.AddressWithPrefix.Address,
				}))
				ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize))
				ip.Encode(&header.IPv6Fields{
					PayloadLength:     header.ICMPv6MinimumSize,
					TransportProtocol: icmp.ProtocolNumber6,
					HopLimit:          DefaultTTL,
					SrcAddr:           host2IPv6Addr.AddressWithPrefix.Address,
					DstAddr:           host1IPv6Addr.AddressWithPrefix.Address,
				})
				e.InjectInbound(header.IPv6ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
					Data: hdr.View().ToVectorisedView(),
				}))
			},
			checkResp: func(t *testing.T, e *channel.Endpoint) {
				p, ok := e.ReadContext(context.Background())
				if !ok {
					t.Fatalf("timed out waiting for packet")
				}
				if p.Proto != ProtocolNumber {
					t.Errorf("got p.Proto = %d, want = %d", p.Proto, ProtocolNumber)
				}
				if p.Route.RemoteLinkAddress != host2NICLinkAddr {
					t.Errorf("got p.Route.RemoteLinkAddress = %s, want = %s", p.Route.RemoteLinkAddress, host2NICLinkAddr)
				}
				checker.IPv6(t, stack.PayloadSince(p.Pkt.NetworkHeader()),
					checker.SrcAddr(host1IPv6Addr.AddressWithPrefix.Address),
					checker.DstAddr(host2IPv6Addr.AddressWithPrefix.Address),
					checker.ICMPv6(
						checker.ICMPv6Type(header.ICMPv6EchoReply),
						checker.ICMPv6Code(header.ICMPv6UnusedCode)))
			},
		},
	}

	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {

			e := channel.New(1, header.IPv6MinimumMTU, host1NICLinkAddr)
			e.LinkEPCapabilities |= stack.CapabilityResolutionRequired
			s := stack.New(stack.Options{
				NetworkProtocols:   []stack.NetworkProtocolFactory{NewProtocol},
				TransportProtocols: []stack.TransportProtocolFactory{udp.NewProtocol},
			})

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

			s.SetRouteTable([]tcpip.Route{
				{
					Destination: host1IPv6Addr.AddressWithPrefix.Subnet(),
					NIC:         nicID,
				},
			})

			// Receive a packet to trigger link resolution before a response is sent.
			test.rxPkt(e)

			// Wait for a neighbor solicitation since link address resolution should
			// be performed.
			{
				p, ok := e.ReadContext(context.Background())
				if !ok {
					t.Fatalf("timed out waiting for packet")
				}
				if p.Proto != ProtocolNumber {
					t.Errorf("got Proto = %d, want = %d", p.Proto, ProtocolNumber)
				}
				snmc := header.SolicitedNodeAddr(host2IPv6Addr.AddressWithPrefix.Address)
				if want := header.EthernetAddressFromMulticastIPv6Address(snmc); p.Route.RemoteLinkAddress != want {
					t.Errorf("got p.Route.RemoteLinkAddress = %s, want = %s", p.Route.RemoteLinkAddress, want)
				}
				checker.IPv6(t, stack.PayloadSince(p.Pkt.NetworkHeader()),
					checker.SrcAddr(host1IPv6Addr.AddressWithPrefix.Address),
					checker.DstAddr(snmc),
					checker.TTL(header.NDPHopLimit),
					checker.NDPNS(
						checker.NDPNSTargetAddress(host2IPv6Addr.AddressWithPrefix.Address),
						checker.NDPNSOptions([]header.NDPOption{header.NDPSourceLinkLayerAddressOption(host1NICLinkAddr)}),
					))
			}

			// Send a neighbor advertisement to complete link address resolution.
			{
				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(host2IPv6Addr.AddressWithPrefix.Address)
				na.Options().Serialize(header.NDPOptionsSerializer{
					header.NDPTargetLinkLayerAddressOption(host2NICLinkAddr),
				})
				pkt.SetChecksum(header.ICMPv6Checksum(header.ICMPv6ChecksumParams{
					Header: pkt,
					Src:    host2IPv6Addr.AddressWithPrefix.Address,
					Dst:    host1IPv6Addr.AddressWithPrefix.Address,
				}))
				payloadLength := hdr.UsedLength()
				ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize))
				ip.Encode(&header.IPv6Fields{
					PayloadLength:     uint16(payloadLength),
					TransportProtocol: icmp.ProtocolNumber6,
					HopLimit:          header.NDPHopLimit,
					SrcAddr:           host2IPv6Addr.AddressWithPrefix.Address,
					DstAddr:           host1IPv6Addr.AddressWithPrefix.Address,
				})
				e.InjectInbound(ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
					Data: hdr.View().ToVectorisedView(),
				}))
			}

			// Expect the response now that the link address has resolved.
			test.checkResp(t, e)

			// Since link resolution was already performed, it shouldn't be performed
			// again.
			test.rxPkt(e)
			test.checkResp(t, e)
		})
	}
}

func TestCallsToNeighborCache(t *testing.T) {
	tests := []struct {
		name                  string
		createPacket          func() header.ICMPv6
		multicast             bool
		source                tcpip.Address
		destination           tcpip.Address
		wantProbeCount        int
		wantConfirmationCount int
	}{
		{
			name: "Unicast Neighbor Solicitation without source link-layer address option",
			createPacket: func() header.ICMPv6 {
				nsSize := header.ICMPv6NeighborSolicitMinimumSize + header.NDPLinkLayerAddressSize
				icmp := header.ICMPv6(buffer.NewView(nsSize))
				icmp.SetType(header.ICMPv6NeighborSolicit)
				ns := header.NDPNeighborSolicit(icmp.MessageBody())
				ns.SetTargetAddress(lladdr0)
				return icmp
			},
			source:      lladdr1,
			destination: lladdr0,
			// "The source link-layer address option SHOULD be included in unicast
			//  solicitations." - RFC 4861 section 4.3
			//
			// A Neighbor Advertisement needs to be sent in response, but the
			// Neighbor Cache shouldn't be updated since we have no useful
			// information about the sender.
			wantProbeCount: 0,
		},
		{
			name: "Unicast Neighbor Solicitation with source link-layer address option",
			createPacket: func() header.ICMPv6 {
				nsSize := header.ICMPv6NeighborSolicitMinimumSize + header.NDPLinkLayerAddressSize
				icmp := header.ICMPv6(buffer.NewView(nsSize))
				icmp.SetType(header.ICMPv6NeighborSolicit)
				ns := header.NDPNeighborSolicit(icmp.MessageBody())
				ns.SetTargetAddress(lladdr0)
				ns.Options().Serialize(header.NDPOptionsSerializer{
					header.NDPSourceLinkLayerAddressOption(linkAddr1),
				})
				return icmp
			},
			source:         lladdr1,
			destination:    lladdr0,
			wantProbeCount: 1,
		},
		{
			name: "Multicast Neighbor Solicitation without source link-layer address option",
			createPacket: func() header.ICMPv6 {
				nsSize := header.ICMPv6NeighborSolicitMinimumSize + header.NDPLinkLayerAddressSize
				icmp := header.ICMPv6(buffer.NewView(nsSize))
				icmp.SetType(header.ICMPv6NeighborSolicit)
				ns := header.NDPNeighborSolicit(icmp.MessageBody())
				ns.SetTargetAddress(lladdr0)
				return icmp
			},
			source:      lladdr1,
			destination: header.SolicitedNodeAddr(lladdr0),
			// "The source link-layer address option MUST be included in multicast
			//  solicitations." - RFC 4861 section 4.3
			wantProbeCount: 0,
		},
		{
			name: "Multicast Neighbor Solicitation with source link-layer address option",
			createPacket: func() header.ICMPv6 {
				nsSize := header.ICMPv6NeighborSolicitMinimumSize + header.NDPLinkLayerAddressSize
				icmp := header.ICMPv6(buffer.NewView(nsSize))
				icmp.SetType(header.ICMPv6NeighborSolicit)
				ns := header.NDPNeighborSolicit(icmp.MessageBody())
				ns.SetTargetAddress(lladdr0)
				ns.Options().Serialize(header.NDPOptionsSerializer{
					header.NDPSourceLinkLayerAddressOption(linkAddr1),
				})
				return icmp
			},
			source:         lladdr1,
			destination:    header.SolicitedNodeAddr(lladdr0),
			wantProbeCount: 1,
		},
		{
			name: "Unicast Neighbor Advertisement without target link-layer address option",
			createPacket: func() header.ICMPv6 {
				naSize := header.ICMPv6NeighborAdvertMinimumSize
				icmp := header.ICMPv6(buffer.NewView(naSize))
				icmp.SetType(header.ICMPv6NeighborAdvert)
				na := header.NDPNeighborAdvert(icmp.MessageBody())
				na.SetSolicitedFlag(true)
				na.SetOverrideFlag(false)
				na.SetTargetAddress(lladdr1)
				return icmp
			},
			source:      lladdr1,
			destination: lladdr0,
			// "When responding to unicast solicitations, the target link-layer
			//  address option can be omitted since the sender of the solicitation has
			//  the correct link-layer address; otherwise, it would not be able to
			//  send the unicast solicitation in the first place."
			//   - RFC 4861 section 4.4
			wantConfirmationCount: 1,
		},
		{
			name: "Unicast Neighbor Advertisement with target link-layer address option",
			createPacket: func() header.ICMPv6 {
				naSize := header.ICMPv6NeighborAdvertMinimumSize + header.NDPLinkLayerAddressSize
				icmp := header.ICMPv6(buffer.NewView(naSize))
				icmp.SetType(header.ICMPv6NeighborAdvert)
				na := header.NDPNeighborAdvert(icmp.MessageBody())
				na.SetSolicitedFlag(true)
				na.SetOverrideFlag(false)
				na.SetTargetAddress(lladdr1)
				na.Options().Serialize(header.NDPOptionsSerializer{
					header.NDPTargetLinkLayerAddressOption(linkAddr1),
				})
				return icmp
			},
			source:                lladdr1,
			destination:           lladdr0,
			wantConfirmationCount: 1,
		},
		{
			name: "Multicast Neighbor Advertisement without target link-layer address option",
			createPacket: func() header.ICMPv6 {
				naSize := header.ICMPv6NeighborAdvertMinimumSize + header.NDPLinkLayerAddressSize
				icmp := header.ICMPv6(buffer.NewView(naSize))
				icmp.SetType(header.ICMPv6NeighborAdvert)
				na := header.NDPNeighborAdvert(icmp.MessageBody())
				na.SetSolicitedFlag(false)
				na.SetOverrideFlag(false)
				na.SetTargetAddress(lladdr1)
				return icmp
			},
			source:      lladdr1,
			destination: header.IPv6AllNodesMulticastAddress,
			// "Target link-layer address MUST be included for multicast solicitations
			//  in order to avoid infinite Neighbor Solicitation "recursion" when the
			//  peer node does not have a cache entry to return a Neighbor
			//  Advertisements message." - RFC 4861 section 4.4
			wantConfirmationCount: 0,
		},
		{
			name: "Multicast Neighbor Advertisement with target link-layer address option",
			createPacket: func() header.ICMPv6 {
				naSize := header.ICMPv6NeighborAdvertMinimumSize + header.NDPLinkLayerAddressSize
				icmp := header.ICMPv6(buffer.NewView(naSize))
				icmp.SetType(header.ICMPv6NeighborAdvert)
				na := header.NDPNeighborAdvert(icmp.MessageBody())
				na.SetSolicitedFlag(false)
				na.SetOverrideFlag(false)
				na.SetTargetAddress(lladdr1)
				na.Options().Serialize(header.NDPOptionsSerializer{
					header.NDPTargetLinkLayerAddressOption(linkAddr1),
				})
				return icmp
			},
			source:                lladdr1,
			destination:           header.IPv6AllNodesMulticastAddress,
			wantConfirmationCount: 1,
		},
	}

	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			s := stack.New(stack.Options{
				NetworkProtocols:   []stack.NetworkProtocolFactory{NewProtocol},
				TransportProtocols: []stack.TransportProtocolFactory{icmp.NewProtocol6},
			})
			{
				if err := s.CreateNIC(nicID, &stubLinkEndpoint{}); err != nil {
					t.Fatalf("CreateNIC(_, _) = %s", err)
				}
				if err := s.AddAddress(nicID, ProtocolNumber, lladdr0); err != nil {
					t.Fatalf("AddAddress(_, %d, %s) = %s", ProtocolNumber, lladdr0, err)
				}
			}
			{
				subnet, err := tcpip.NewSubnet(lladdr1, tcpip.AddressMask(strings.Repeat("\xff", len(lladdr1))))
				if err != nil {
					t.Fatal(err)
				}
				s.SetRouteTable(
					[]tcpip.Route{{
						Destination: subnet,
						NIC:         nicID,
					}},
				)
			}

			netProto := s.NetworkProtocolInstance(ProtocolNumber)
			if netProto == nil {
				t.Fatalf("cannot find protocol instance for network protocol %d", ProtocolNumber)
			}

			testInterface := testInterface{LinkEndpoint: channel.New(0, header.IPv6MinimumMTU, linkAddr0)}
			ep := netProto.NewEndpoint(&testInterface, &stubDispatcher{})
			defer ep.Close()

			if err := ep.Enable(); err != nil {
				t.Fatalf("ep.Enable(): %s", err)
			}

			addressableEndpoint, ok := ep.(stack.AddressableEndpoint)
			if !ok {
				t.Fatalf("expected network endpoint to implement stack.AddressableEndpoint")
			}
			addr := lladdr0.WithPrefix()
			if ep, err := addressableEndpoint.AddAndAcquirePermanentAddress(addr, stack.CanBePrimaryEndpoint, stack.AddressConfigStatic, false /* deprecated */); err != nil {
				t.Fatalf("addressableEndpoint.AddAndAcquirePermanentAddress(%s, CanBePrimaryEndpoint, AddressConfigStatic, false): %s", addr, err)
			} else {
				ep.DecRef()
			}

			icmp := test.createPacket()
			icmp.SetChecksum(header.ICMPv6Checksum(header.ICMPv6ChecksumParams{
				Header: icmp,
				Src:    test.source,
				Dst:    test.destination,
			}))
			handleICMPInIPv6(ep, test.source, test.destination, icmp, header.NDPHopLimit, false)

			// Confirm the endpoint calls the correct NUDHandler method.
			if testInterface.probeCount != test.wantProbeCount {
				t.Errorf("got testInterface.probeCount = %d, want = %d", testInterface.probeCount, test.wantProbeCount)
			}
			if testInterface.confirmationCount != test.wantConfirmationCount {
				t.Errorf("got testInterface.confirmationCount = %d, want = %d", testInterface.confirmationCount, test.wantConfirmationCount)
			}
		})
	}
}
