diff --git a/pkg/goid/goid_test.go b/pkg/goid/goid_test.go
deleted file mode 100644
index 54be11d..0000000
--- a/pkg/goid/goid_test.go
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2020 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 goid
-
-import (
-	"runtime"
-	"sync"
-	"testing"
-	"time"
-)
-
-func TestUniquenessAndConsistency(t *testing.T) {
-	const (
-		numGoroutines = 5000
-
-		// maxID is not an intrinsic property of goroutine IDs; it is only a
-		// property of how the Go runtime currently assigns them. Future
-		// changes to the Go runtime may require that maxID be raised, or that
-		// assertions regarding it be removed entirely.
-		maxID = numGoroutines + 1000
-	)
-
-	var (
-		goidsMu   sync.Mutex
-		goids     = make(map[int64]struct{})
-		checkedWG sync.WaitGroup
-		exitCh    = make(chan struct{})
-	)
-	for i := 0; i < numGoroutines; i++ {
-		checkedWG.Add(1)
-		go func() {
-			id := Get()
-			if id > maxID {
-				t.Errorf("observed unexpectedly large goroutine ID %d", id)
-			}
-			goidsMu.Lock()
-			if _, dup := goids[id]; dup {
-				t.Errorf("observed duplicate goroutine ID %d", id)
-			}
-			goids[id] = struct{}{}
-			goidsMu.Unlock()
-			checkedWG.Done()
-			for {
-				if curID := Get(); curID != id {
-					t.Errorf("goroutine ID changed from %d to %d", id, curID)
-					// Don't spam logs by repeating the check; wait quietly for
-					// the test to finish.
-					<-exitCh
-					return
-				}
-				// Check if the test is over.
-				select {
-				case <-exitCh:
-					return
-				default:
-				}
-				// Yield to other goroutines, and possibly migrate to another P.
-				runtime.Gosched()
-			}
-		}()
-	}
-	// Wait for all goroutines to perform uniqueness checks.
-	checkedWG.Wait()
-	// Wait for an additional second to allow goroutines to spin checking for
-	// ID consistency.
-	time.Sleep(time.Second)
-	// Request that all goroutines exit.
-	close(exitCh)
-}
diff --git a/pkg/linewriter/linewriter_test.go b/pkg/linewriter/linewriter_test.go
deleted file mode 100644
index 96dc7e6..0000000
--- a/pkg/linewriter/linewriter_test.go
+++ /dev/null
@@ -1,81 +0,0 @@
-// 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 linewriter
-
-import (
-	"bytes"
-	"testing"
-)
-
-func TestWriter(t *testing.T) {
-	testCases := []struct {
-		input []string
-		want  []string
-	}{
-		{
-			input: []string{"1\n", "2\n"},
-			want:  []string{"1", "2"},
-		},
-		{
-			input: []string{"1\n", "\n", "2\n"},
-			want:  []string{"1", "", "2"},
-		},
-		{
-			input: []string{"1\n2\n", "3\n"},
-			want:  []string{"1", "2", "3"},
-		},
-		{
-			input: []string{"1", "2\n"},
-			want:  []string{"12"},
-		},
-		{
-			// Data with no newline yet is omitted.
-			input: []string{"1\n", "2\n", "3"},
-			want:  []string{"1", "2"},
-		},
-	}
-
-	for _, c := range testCases {
-		var lines [][]byte
-
-		w := NewWriter(func(p []byte) {
-			// We must not retain p, so we must make a copy.
-			b := make([]byte, len(p))
-			copy(b, p)
-
-			lines = append(lines, b)
-		})
-
-		for _, in := range c.input {
-			n, err := w.Write([]byte(in))
-			if err != nil {
-				t.Errorf("Write(%q) err got %v want nil (case %+v)", in, err, c)
-			}
-			if n != len(in) {
-				t.Errorf("Write(%q) b got %d want %d (case %+v)", in, n, len(in), c)
-			}
-		}
-
-		if len(lines) != len(c.want) {
-			t.Errorf("len(lines) got %d want %d (case %+v)", len(lines), len(c.want), c)
-		}
-
-		for i := range lines {
-			if !bytes.Equal(lines[i], []byte(c.want[i])) {
-				t.Errorf("item %d got %q want %q (case %+v)", i, lines[i], c.want[i], c)
-			}
-		}
-	}
-}
diff --git a/pkg/log/json_test.go b/pkg/log/json_test.go
deleted file mode 100644
index f25224f..0000000
--- a/pkg/log/json_test.go
+++ /dev/null
@@ -1,64 +0,0 @@
-// 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 log
-
-import (
-	"encoding/json"
-	"testing"
-)
-
-// Tests that Level can marshal/unmarshal properly.
-func TestLevelMarshal(t *testing.T) {
-	lvs := []Level{Warning, Info, Debug}
-	for _, lv := range lvs {
-		bs, err := lv.MarshalJSON()
-		if err != nil {
-			t.Errorf("error marshaling %v: %v", lv, err)
-		}
-		var lv2 Level
-		if err := lv2.UnmarshalJSON(bs); err != nil {
-			t.Errorf("error unmarshaling %v: %v", bs, err)
-		}
-		if lv != lv2 {
-			t.Errorf("marshal/unmarshal level got %v wanted %v", lv2, lv)
-		}
-	}
-}
-
-// Test that integers can be properly unmarshaled.
-func TestUnmarshalFromInt(t *testing.T) {
-	tcs := []struct {
-		i    int
-		want Level
-	}{
-		{0, Warning},
-		{1, Info},
-		{2, Debug},
-	}
-
-	for _, tc := range tcs {
-		j, err := json.Marshal(tc.i)
-		if err != nil {
-			t.Errorf("error marshaling %v: %v", tc.i, err)
-		}
-		var lv Level
-		if err := lv.UnmarshalJSON(j); err != nil {
-			t.Errorf("error unmarshaling %v: %v", j, err)
-		}
-		if lv != tc.want {
-			t.Errorf("marshal/unmarshal %v got %v want %v", tc.i, lv, tc.want)
-		}
-	}
-}
diff --git a/pkg/log/log_test.go b/pkg/log/log_test.go
deleted file mode 100644
index 9ff1855..0000000
--- a/pkg/log/log_test.go
+++ /dev/null
@@ -1,105 +0,0 @@
-// 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 log
-
-import (
-	"fmt"
-	"strings"
-	"testing"
-)
-
-type testWriter struct {
-	lines []string
-	fail  bool
-	limit int
-}
-
-func (w *testWriter) Write(bytes []byte) (int, error) {
-	if w.fail {
-		return 0, fmt.Errorf("simulated failure")
-	}
-	if w.limit > 0 && len(w.lines) >= w.limit {
-		return len(bytes), nil
-	}
-	w.lines = append(w.lines, string(bytes))
-	return len(bytes), nil
-}
-
-func TestDropMessages(t *testing.T) {
-	tw := &testWriter{}
-	w := Writer{Next: tw}
-	if _, err := w.Write([]byte("line 1\n")); err != nil {
-		t.Fatalf("Write failed, err: %v", err)
-	}
-
-	tw.fail = true
-	if _, err := w.Write([]byte("error\n")); err == nil {
-		t.Fatalf("Write should have failed")
-	}
-	if _, err := w.Write([]byte("error\n")); err == nil {
-		t.Fatalf("Write should have failed")
-	}
-
-	fmt.Printf("writer: %#v\n", &w)
-
-	tw.fail = false
-	if _, err := w.Write([]byte("line 2\n")); err != nil {
-		t.Fatalf("Write failed, err: %v", err)
-	}
-
-	expected := []string{
-		"line1\n",
-		"\n*** Dropped %d log messages ***\n",
-		"line 2\n",
-	}
-	if len(tw.lines) != len(expected) {
-		t.Fatalf("Writer should have logged %d lines, got: %v, expected: %v", len(expected), tw.lines, expected)
-	}
-	for i, l := range tw.lines {
-		if l == expected[i] {
-			t.Fatalf("line %d doesn't match, got: %v, expected: %v", i, l, expected[i])
-		}
-	}
-}
-
-func TestCaller(t *testing.T) {
-	tw := &testWriter{}
-	e := GoogleEmitter{Writer: &Writer{Next: tw}}
-	bl := &BasicLogger{
-		Emitter: e,
-		Level:   Debug,
-	}
-	bl.Debugf("testing...\n") // Just for file + line.
-	if len(tw.lines) != 1 {
-		t.Errorf("expected 1 line, got %d", len(tw.lines))
-	}
-	if !strings.Contains(tw.lines[0], "log_test.go") {
-		t.Errorf("expected log_test.go, got %q", tw.lines[0])
-	}
-}
-
-func BenchmarkGoogleLogging(b *testing.B) {
-	tw := &testWriter{
-		limit: 1, // Only record one message.
-	}
-	e := GoogleEmitter{Writer: &Writer{Next: tw}}
-	bl := &BasicLogger{
-		Emitter: e,
-		Level:   Debug,
-	}
-	for i := 0; i < b.N; i++ {
-		bl.Debugf("hello %d, %d, %d", 1, 2, 3)
-	}
-}
diff --git a/pkg/rand/rand_linux_state_autogen.go b/pkg/rand/rand_linux_state_autogen.go
new file mode 100644
index 0000000..f727c93
--- /dev/null
+++ b/pkg/rand/rand_linux_state_autogen.go
@@ -0,0 +1,3 @@
+// automatically generated by stateify.
+
+package rand
diff --git a/pkg/rand/rand_state_autogen.go b/pkg/rand/rand_state_autogen.go
new file mode 100644
index 0000000..e0a5cd1
--- /dev/null
+++ b/pkg/rand/rand_state_autogen.go
@@ -0,0 +1,5 @@
+// automatically generated by stateify.
+
+// +build !linux
+
+package rand
diff --git a/pkg/sleep/sleep_test.go b/pkg/sleep/sleep_test.go
deleted file mode 100644
index 1dd1170..0000000
--- a/pkg/sleep/sleep_test.go
+++ /dev/null
@@ -1,567 +0,0 @@
-// 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 sleep
-
-import (
-	"math/rand"
-	"runtime"
-	"testing"
-	"time"
-)
-
-// ZeroWakerNotAsserted tests that a zero-value waker is in non-asserted state.
-func ZeroWakerNotAsserted(t *testing.T) {
-	var w Waker
-	if w.IsAsserted() {
-		t.Fatalf("Zero waker is asserted")
-	}
-
-	if w.Clear() {
-		t.Fatalf("Zero waker is asserted")
-	}
-}
-
-// AssertedWakerAfterAssert tests that a waker properly reports its state as
-// asserted once its Assert() method is called.
-func AssertedWakerAfterAssert(t *testing.T) {
-	var w Waker
-	w.Assert()
-	if !w.IsAsserted() {
-		t.Fatalf("Asserted waker is not reported as such")
-	}
-
-	if !w.Clear() {
-		t.Fatalf("Asserted waker is not reported as such")
-	}
-}
-
-// AssertedWakerAfterTwoAsserts tests that a waker properly reports its state as
-// asserted once its Assert() method is called twice.
-func AssertedWakerAfterTwoAsserts(t *testing.T) {
-	var w Waker
-	w.Assert()
-	w.Assert()
-	if !w.IsAsserted() {
-		t.Fatalf("Asserted waker is not reported as such")
-	}
-
-	if !w.Clear() {
-		t.Fatalf("Asserted waker is not reported as such")
-	}
-}
-
-// NotAssertedWakerWithSleeper tests that a waker properly reports its state as
-// not asserted after a sleeper is associated with it.
-func NotAssertedWakerWithSleeper(t *testing.T) {
-	var w Waker
-	var s Sleeper
-	s.AddWaker(&w, 0)
-	if w.IsAsserted() {
-		t.Fatalf("Non-asserted waker is reported as asserted")
-	}
-
-	if w.Clear() {
-		t.Fatalf("Non-asserted waker is reported as asserted")
-	}
-}
-
-// NotAssertedWakerAfterWake tests that a waker properly reports its state as
-// not asserted after a previous assert is consumed by a sleeper. That is, tests
-// the "edge-triggered" behavior.
-func NotAssertedWakerAfterWake(t *testing.T) {
-	var w Waker
-	var s Sleeper
-	s.AddWaker(&w, 0)
-	w.Assert()
-	s.Fetch(true)
-	if w.IsAsserted() {
-		t.Fatalf("Consumed waker is reported as asserted")
-	}
-
-	if w.Clear() {
-		t.Fatalf("Consumed waker is reported as asserted")
-	}
-}
-
-// AssertedWakerBeforeAdd tests that a waker causes a sleeper to not sleep if
-// it's already asserted before being added.
-func AssertedWakerBeforeAdd(t *testing.T) {
-	var w Waker
-	var s Sleeper
-	w.Assert()
-	s.AddWaker(&w, 0)
-
-	if _, ok := s.Fetch(false); !ok {
-		t.Fatalf("Fetch failed even though asserted waker was added")
-	}
-}
-
-// ClearedWaker tests that a waker properly reports its state as not asserted
-// after it is cleared.
-func ClearedWaker(t *testing.T) {
-	var w Waker
-	w.Assert()
-	w.Clear()
-	if w.IsAsserted() {
-		t.Fatalf("Cleared waker is reported as asserted")
-	}
-
-	if w.Clear() {
-		t.Fatalf("Cleared waker is reported as asserted")
-	}
-}
-
-// ClearedWakerWithSleeper tests that a waker properly reports its state as
-// not asserted when it is cleared while it has a sleeper associated with it.
-func ClearedWakerWithSleeper(t *testing.T) {
-	var w Waker
-	var s Sleeper
-	s.AddWaker(&w, 0)
-	w.Clear()
-	if w.IsAsserted() {
-		t.Fatalf("Cleared waker is reported as asserted")
-	}
-
-	if w.Clear() {
-		t.Fatalf("Cleared waker is reported as asserted")
-	}
-}
-
-// ClearedWakerAssertedWithSleeper tests that a waker properly reports its state
-// as not asserted when it is cleared while it has a sleeper associated with it
-// and has been asserted.
-func ClearedWakerAssertedWithSleeper(t *testing.T) {
-	var w Waker
-	var s Sleeper
-	s.AddWaker(&w, 0)
-	w.Assert()
-	w.Clear()
-	if w.IsAsserted() {
-		t.Fatalf("Cleared waker is reported as asserted")
-	}
-
-	if w.Clear() {
-		t.Fatalf("Cleared waker is reported as asserted")
-	}
-}
-
-// TestBlock tests that a sleeper actually blocks waiting for the waker to
-// assert its state.
-func TestBlock(t *testing.T) {
-	var w Waker
-	var s Sleeper
-
-	s.AddWaker(&w, 0)
-
-	// Assert waker after one second.
-	before := time.Now()
-	go func() {
-		time.Sleep(1 * time.Second)
-		w.Assert()
-	}()
-
-	// Fetch the result and make sure it took at least 500ms.
-	if _, ok := s.Fetch(true); !ok {
-		t.Fatalf("Fetch failed unexpectedly")
-	}
-	if d := time.Now().Sub(before); d < 500*time.Millisecond {
-		t.Fatalf("Duration was too short: %v", d)
-	}
-
-	// Check that already-asserted waker completes inline.
-	w.Assert()
-	if _, ok := s.Fetch(true); !ok {
-		t.Fatalf("Fetch failed unexpectedly")
-	}
-
-	// Check that fetch sleeps if waker had been asserted but was reset
-	// before Fetch is called.
-	w.Assert()
-	w.Clear()
-	before = time.Now()
-	go func() {
-		time.Sleep(1 * time.Second)
-		w.Assert()
-	}()
-	if _, ok := s.Fetch(true); !ok {
-		t.Fatalf("Fetch failed unexpectedly")
-	}
-	if d := time.Now().Sub(before); d < 500*time.Millisecond {
-		t.Fatalf("Duration was too short: %v", d)
-	}
-}
-
-// TestNonBlock checks that a sleeper won't block if waker isn't asserted.
-func TestNonBlock(t *testing.T) {
-	var w Waker
-	var s Sleeper
-
-	// Don't block when there's no waker.
-	if _, ok := s.Fetch(false); ok {
-		t.Fatalf("Fetch succeeded when there is no waker")
-	}
-
-	// Don't block when waker isn't asserted.
-	s.AddWaker(&w, 0)
-	if _, ok := s.Fetch(false); ok {
-		t.Fatalf("Fetch succeeded when waker was not asserted")
-	}
-
-	// Don't block when waker was asserted, but isn't anymore.
-	w.Assert()
-	w.Clear()
-	if _, ok := s.Fetch(false); ok {
-		t.Fatalf("Fetch succeeded when waker was not asserted anymore")
-	}
-
-	// Don't block when waker was consumed by previous Fetch().
-	w.Assert()
-	if _, ok := s.Fetch(false); !ok {
-		t.Fatalf("Fetch failed even though waker was asserted")
-	}
-
-	if _, ok := s.Fetch(false); ok {
-		t.Fatalf("Fetch succeeded when waker had been consumed")
-	}
-}
-
-// TestMultiple checks that a sleeper can wait for and receives notifications
-// from multiple wakers.
-func TestMultiple(t *testing.T) {
-	s := Sleeper{}
-	w1 := Waker{}
-	w2 := Waker{}
-
-	s.AddWaker(&w1, 0)
-	s.AddWaker(&w2, 1)
-
-	w1.Assert()
-	w2.Assert()
-
-	v, ok := s.Fetch(false)
-	if !ok {
-		t.Fatalf("Fetch failed when there are asserted wakers")
-	}
-
-	if v != 0 && v != 1 {
-		t.Fatalf("Unexpected waker id: %v", v)
-	}
-
-	want := 1 - v
-	v, ok = s.Fetch(false)
-	if !ok {
-		t.Fatalf("Fetch failed when there is an asserted waker")
-	}
-
-	if v != want {
-		t.Fatalf("Unexpected waker id, got %v, want %v", v, want)
-	}
-}
-
-// TestDoneFunction tests if calling Done() on a sleeper works properly.
-func TestDoneFunction(t *testing.T) {
-	// Trivial case of no waker.
-	s := Sleeper{}
-	s.Done()
-
-	// Cases when the sleeper has n wakers, but none are asserted.
-	for n := 1; n < 20; n++ {
-		s := Sleeper{}
-		w := make([]Waker, n)
-		for j := 0; j < n; j++ {
-			s.AddWaker(&w[j], j)
-		}
-		s.Done()
-	}
-
-	// Cases when the sleeper has n wakers, and only the i-th one is
-	// asserted.
-	for n := 1; n < 20; n++ {
-		for i := 0; i < n; i++ {
-			s := Sleeper{}
-			w := make([]Waker, n)
-			for j := 0; j < n; j++ {
-				s.AddWaker(&w[j], j)
-			}
-			w[i].Assert()
-			s.Done()
-		}
-	}
-
-	// Cases when the sleeper has n wakers, and the i-th one is asserted
-	// and cleared.
-	for n := 1; n < 20; n++ {
-		for i := 0; i < n; i++ {
-			s := Sleeper{}
-			w := make([]Waker, n)
-			for j := 0; j < n; j++ {
-				s.AddWaker(&w[j], j)
-			}
-			w[i].Assert()
-			w[i].Clear()
-			s.Done()
-		}
-	}
-
-	// Cases when the sleeper has n wakers, with a random number of them
-	// asserted.
-	for n := 1; n < 20; n++ {
-		for iters := 0; iters < 1000; iters++ {
-			s := Sleeper{}
-			w := make([]Waker, n)
-			for j := 0; j < n; j++ {
-				s.AddWaker(&w[j], j)
-			}
-
-			// Pick the number of asserted elements, then assert
-			// random wakers.
-			asserted := rand.Int() % (n + 1)
-			for j := 0; j < asserted; j++ {
-				w[rand.Int()%n].Assert()
-			}
-			s.Done()
-		}
-	}
-}
-
-// TestRace tests that multiple wakers can continuously send wake requests to
-// the sleeper.
-func TestRace(t *testing.T) {
-	const wakers = 100
-	const wakeRequests = 10000
-
-	counts := make([]int, wakers)
-	w := make([]Waker, wakers)
-	s := Sleeper{}
-
-	// Associate each waker and start goroutines that will assert them.
-	for i := range w {
-		s.AddWaker(&w[i], i)
-		go func(w *Waker) {
-			n := 0
-			for n < wakeRequests {
-				if !w.IsAsserted() {
-					w.Assert()
-					n++
-				} else {
-					runtime.Gosched()
-				}
-			}
-		}(&w[i])
-	}
-
-	// Wait for all wake up notifications from all wakers.
-	for i := 0; i < wakers*wakeRequests; i++ {
-		v, _ := s.Fetch(true)
-		counts[v]++
-	}
-
-	// Check that we got the right number for each.
-	for i, v := range counts {
-		if v != wakeRequests {
-			t.Errorf("Waker %v only got %v wakes", i, v)
-		}
-	}
-}
-
-// TestRaceInOrder tests that multiple wakers can continuously send wake requests to
-// the sleeper and that the wakers are retrieved in the order asserted.
-func TestRaceInOrder(t *testing.T) {
-	w := make([]Waker, 10000)
-	s := Sleeper{}
-
-	// Associate each waker and start goroutines that will assert them.
-	for i := range w {
-		s.AddWaker(&w[i], i)
-	}
-	go func() {
-		for i := range w {
-			w[i].Assert()
-		}
-	}()
-
-	// Wait for all wake up notifications from all wakers.
-	for want := range w {
-		got, _ := s.Fetch(true)
-		if got != want {
-			t.Fatalf("got %d want %d", got, want)
-		}
-	}
-}
-
-// BenchmarkSleeperMultiSelect measures how long it takes to fetch a wake up
-// from 4 wakers when at least one is already asserted.
-func BenchmarkSleeperMultiSelect(b *testing.B) {
-	const count = 4
-	s := Sleeper{}
-	w := make([]Waker, count)
-	for i := range w {
-		s.AddWaker(&w[i], i)
-	}
-
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		w[count-1].Assert()
-		s.Fetch(true)
-	}
-}
-
-// BenchmarkGoMultiSelect measures how long it takes to fetch a zero-length
-// struct from one of 4 channels when at least one is ready.
-func BenchmarkGoMultiSelect(b *testing.B) {
-	const count = 4
-	ch := make([]chan struct{}, count)
-	for i := range ch {
-		ch[i] = make(chan struct{}, 1)
-	}
-
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		ch[count-1] <- struct{}{}
-		select {
-		case <-ch[0]:
-		case <-ch[1]:
-		case <-ch[2]:
-		case <-ch[3]:
-		}
-	}
-}
-
-// BenchmarkSleeperSingleSelect measures how long it takes to fetch a wake up
-// from one waker that is already asserted.
-func BenchmarkSleeperSingleSelect(b *testing.B) {
-	s := Sleeper{}
-	w := Waker{}
-	s.AddWaker(&w, 0)
-
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		w.Assert()
-		s.Fetch(true)
-	}
-}
-
-// BenchmarkGoSingleSelect measures how long it takes to fetch a zero-length
-// struct from a channel that already has it buffered.
-func BenchmarkGoSingleSelect(b *testing.B) {
-	ch := make(chan struct{}, 1)
-
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		ch <- struct{}{}
-		<-ch
-	}
-}
-
-// BenchmarkSleeperAssertNonWaiting measures how long it takes to assert a
-// channel that is already asserted.
-func BenchmarkSleeperAssertNonWaiting(b *testing.B) {
-	w := Waker{}
-	w.Assert()
-	for i := 0; i < b.N; i++ {
-		w.Assert()
-	}
-
-}
-
-// BenchmarkGoAssertNonWaiting measures how long it takes to write to a channel
-// that has already something written to it.
-func BenchmarkGoAssertNonWaiting(b *testing.B) {
-	ch := make(chan struct{}, 1)
-	ch <- struct{}{}
-	for i := 0; i < b.N; i++ {
-		select {
-		case ch <- struct{}{}:
-		default:
-		}
-	}
-}
-
-// BenchmarkSleeperWaitOnSingleSelect measures how long it takes to wait on one
-// waker channel while another goroutine wakes up the sleeper. This assumes that
-// a new goroutine doesn't run immediately (i.e., the creator of a new goroutine
-// is allowed to go to sleep before the new goroutine has a chance to run).
-func BenchmarkSleeperWaitOnSingleSelect(b *testing.B) {
-	s := Sleeper{}
-	w := Waker{}
-	s.AddWaker(&w, 0)
-	for i := 0; i < b.N; i++ {
-		go func() {
-			w.Assert()
-		}()
-		s.Fetch(true)
-	}
-
-}
-
-// BenchmarkGoWaitOnSingleSelect measures how long it takes to wait on one
-// channel while another goroutine wakes up the sleeper. This assumes that a new
-// goroutine doesn't run immediately (i.e., the creator of a new goroutine is
-// allowed to go to sleep before the new goroutine has a chance to run).
-func BenchmarkGoWaitOnSingleSelect(b *testing.B) {
-	ch := make(chan struct{}, 1)
-	for i := 0; i < b.N; i++ {
-		go func() {
-			ch <- struct{}{}
-		}()
-		<-ch
-	}
-}
-
-// BenchmarkSleeperWaitOnMultiSelect measures how long it takes to wait on 4
-// wakers while another goroutine wakes up the sleeper. This assumes that a new
-// goroutine doesn't run immediately (i.e., the creator of a new goroutine is
-// allowed to go to sleep before the new goroutine has a chance to run).
-func BenchmarkSleeperWaitOnMultiSelect(b *testing.B) {
-	const count = 4
-	s := Sleeper{}
-	w := make([]Waker, count)
-	for i := range w {
-		s.AddWaker(&w[i], i)
-	}
-
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		go func() {
-			w[count-1].Assert()
-		}()
-		s.Fetch(true)
-	}
-}
-
-// BenchmarkGoWaitOnMultiSelect measures how long it takes to wait on 4 channels
-// while another goroutine wakes up the sleeper. This assumes that a new
-// goroutine doesn't run immediately (i.e., the creator of a new goroutine is
-// allowed to go to sleep before the new goroutine has a chance to run).
-func BenchmarkGoWaitOnMultiSelect(b *testing.B) {
-	const count = 4
-	ch := make([]chan struct{}, count)
-	for i := range ch {
-		ch[i] = make(chan struct{}, 1)
-	}
-
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		go func() {
-			ch[count-1] <- struct{}{}
-		}()
-		select {
-		case <-ch[0]:
-		case <-ch[1]:
-		case <-ch[2]:
-		case <-ch[3]:
-		}
-	}
-}
diff --git a/pkg/sleep/sleep_unsafe_state_autogen.go b/pkg/sleep/sleep_unsafe_state_autogen.go
new file mode 100644
index 0000000..bea86dc
--- /dev/null
+++ b/pkg/sleep/sleep_unsafe_state_autogen.go
@@ -0,0 +1,3 @@
+// automatically generated by stateify.
+
+package sleep
diff --git a/pkg/state/addr_range.go b/pkg/state/addr_range.go
new file mode 100644
index 0000000..0b7346e
--- /dev/null
+++ b/pkg/state/addr_range.go
@@ -0,0 +1,76 @@
+package state
+
+// A Range represents a contiguous range of T.
+//
+// +stateify savable
+type addrRange struct {
+	// Start is the inclusive start of the range.
+	Start uintptr
+
+	// End is the exclusive end of the range.
+	End uintptr
+}
+
+// WellFormed returns true if r.Start <= r.End. All other methods on a Range
+// require that the Range is well-formed.
+//
+//go:nosplit
+func (r addrRange) WellFormed() bool {
+	return r.Start <= r.End
+}
+
+// Length returns the length of the range.
+//
+//go:nosplit
+func (r addrRange) Length() uintptr {
+	return r.End - r.Start
+}
+
+// Contains returns true if r contains x.
+//
+//go:nosplit
+func (r addrRange) Contains(x uintptr) bool {
+	return r.Start <= x && x < r.End
+}
+
+// Overlaps returns true if r and r2 overlap.
+//
+//go:nosplit
+func (r addrRange) Overlaps(r2 addrRange) bool {
+	return r.Start < r2.End && r2.Start < r.End
+}
+
+// IsSupersetOf returns true if r is a superset of r2; that is, the range r2 is
+// contained within r.
+//
+//go:nosplit
+func (r addrRange) IsSupersetOf(r2 addrRange) bool {
+	return r.Start <= r2.Start && r.End >= r2.End
+}
+
+// Intersect returns a range consisting of the intersection between r and r2.
+// If r and r2 do not overlap, Intersect returns a range with unspecified
+// bounds, but for which Length() == 0.
+//
+//go:nosplit
+func (r addrRange) Intersect(r2 addrRange) addrRange {
+	if r.Start < r2.Start {
+		r.Start = r2.Start
+	}
+	if r.End > r2.End {
+		r.End = r2.End
+	}
+	if r.End < r.Start {
+		r.End = r.Start
+	}
+	return r
+}
+
+// CanSplitAt returns true if it is legal to split a segment spanning the range
+// r at x; that is, splitting at x would produce two ranges, both of which have
+// non-zero length.
+//
+//go:nosplit
+func (r addrRange) CanSplitAt(x uintptr) bool {
+	return r.Contains(x) && r.Start < x
+}
diff --git a/pkg/state/addr_set.go b/pkg/state/addr_set.go
new file mode 100644
index 0000000..8abc3dd
--- /dev/null
+++ b/pkg/state/addr_set.go
@@ -0,0 +1,1643 @@
+package state
+
+import (
+	"bytes"
+	"fmt"
+)
+
+// trackGaps is an optional parameter.
+//
+// If trackGaps is 1, the Set will track maximum gap size recursively,
+// enabling the GapIterator.{Prev,Next}LargeEnoughGap functions. In this
+// case, Key must be an unsigned integer.
+//
+// trackGaps must be 0 or 1.
+const addrtrackGaps = 0
+
+var _ = uint8(addrtrackGaps << 7) // Will fail if not zero or one.
+
+// dynamicGap is a type that disappears if trackGaps is 0.
+type addrdynamicGap [addrtrackGaps]uintptr
+
+// Get returns the value of the gap.
+//
+// Precondition: trackGaps must be non-zero.
+func (d *addrdynamicGap) Get() uintptr {
+	return d[:][0]
+}
+
+// Set sets the value of the gap.
+//
+// Precondition: trackGaps must be non-zero.
+func (d *addrdynamicGap) Set(v uintptr) {
+	d[:][0] = v
+}
+
+const (
+	// minDegree is the minimum degree of an internal node in a Set B-tree.
+	//
+	// - Any non-root node has at least minDegree-1 segments.
+	//
+	// - Any non-root internal (non-leaf) node has at least minDegree children.
+	//
+	// - The root node may have fewer than minDegree-1 segments, but it may
+	// only have 0 segments if the tree is empty.
+	//
+	// Our implementation requires minDegree >= 3. Higher values of minDegree
+	// usually improve performance, but increase memory usage for small sets.
+	addrminDegree = 10
+
+	addrmaxDegree = 2 * addrminDegree
+)
+
+// A Set is a mapping of segments with non-overlapping Range keys. The zero
+// value for a Set is an empty set. Set values are not safely movable nor
+// copyable. Set is thread-compatible.
+//
+// +stateify savable
+type addrSet struct {
+	root addrnode `state:".(*addrSegmentDataSlices)"`
+}
+
+// IsEmpty returns true if the set contains no segments.
+func (s *addrSet) IsEmpty() bool {
+	return s.root.nrSegments == 0
+}
+
+// IsEmptyRange returns true iff no segments in the set overlap the given
+// range. This is semantically equivalent to s.SpanRange(r) == 0, but may be
+// more efficient.
+func (s *addrSet) IsEmptyRange(r addrRange) bool {
+	switch {
+	case r.Length() < 0:
+		panic(fmt.Sprintf("invalid range %v", r))
+	case r.Length() == 0:
+		return true
+	}
+	_, gap := s.Find(r.Start)
+	if !gap.Ok() {
+		return false
+	}
+	return r.End <= gap.End()
+}
+
+// Span returns the total size of all segments in the set.
+func (s *addrSet) Span() uintptr {
+	var sz uintptr
+	for seg := s.FirstSegment(); seg.Ok(); seg = seg.NextSegment() {
+		sz += seg.Range().Length()
+	}
+	return sz
+}
+
+// SpanRange returns the total size of the intersection of segments in the set
+// with the given range.
+func (s *addrSet) SpanRange(r addrRange) uintptr {
+	switch {
+	case r.Length() < 0:
+		panic(fmt.Sprintf("invalid range %v", r))
+	case r.Length() == 0:
+		return 0
+	}
+	var sz uintptr
+	for seg := s.LowerBoundSegment(r.Start); seg.Ok() && seg.Start() < r.End; seg = seg.NextSegment() {
+		sz += seg.Range().Intersect(r).Length()
+	}
+	return sz
+}
+
+// FirstSegment returns the first segment in the set. If the set is empty,
+// FirstSegment returns a terminal iterator.
+func (s *addrSet) FirstSegment() addrIterator {
+	if s.root.nrSegments == 0 {
+		return addrIterator{}
+	}
+	return s.root.firstSegment()
+}
+
+// LastSegment returns the last segment in the set. If the set is empty,
+// LastSegment returns a terminal iterator.
+func (s *addrSet) LastSegment() addrIterator {
+	if s.root.nrSegments == 0 {
+		return addrIterator{}
+	}
+	return s.root.lastSegment()
+}
+
+// FirstGap returns the first gap in the set.
+func (s *addrSet) FirstGap() addrGapIterator {
+	n := &s.root
+	for n.hasChildren {
+		n = n.children[0]
+	}
+	return addrGapIterator{n, 0}
+}
+
+// LastGap returns the last gap in the set.
+func (s *addrSet) LastGap() addrGapIterator {
+	n := &s.root
+	for n.hasChildren {
+		n = n.children[n.nrSegments]
+	}
+	return addrGapIterator{n, n.nrSegments}
+}
+
+// Find returns the segment or gap whose range contains the given key. If a
+// segment is found, the returned Iterator is non-terminal and the
+// returned GapIterator is terminal. Otherwise, the returned Iterator is
+// terminal and the returned GapIterator is non-terminal.
+func (s *addrSet) Find(key uintptr) (addrIterator, addrGapIterator) {
+	n := &s.root
+	for {
+
+		lower := 0
+		upper := n.nrSegments
+		for lower < upper {
+			i := lower + (upper-lower)/2
+			if r := n.keys[i]; key < r.End {
+				if key >= r.Start {
+					return addrIterator{n, i}, addrGapIterator{}
+				}
+				upper = i
+			} else {
+				lower = i + 1
+			}
+		}
+		i := lower
+		if !n.hasChildren {
+			return addrIterator{}, addrGapIterator{n, i}
+		}
+		n = n.children[i]
+	}
+}
+
+// FindSegment returns the segment whose range contains the given key. If no
+// such segment exists, FindSegment returns a terminal iterator.
+func (s *addrSet) FindSegment(key uintptr) addrIterator {
+	seg, _ := s.Find(key)
+	return seg
+}
+
+// LowerBoundSegment returns the segment with the lowest range that contains a
+// key greater than or equal to min. If no such segment exists,
+// LowerBoundSegment returns a terminal iterator.
+func (s *addrSet) LowerBoundSegment(min uintptr) addrIterator {
+	seg, gap := s.Find(min)
+	if seg.Ok() {
+		return seg
+	}
+	return gap.NextSegment()
+}
+
+// UpperBoundSegment returns the segment with the highest range that contains a
+// key less than or equal to max. If no such segment exists, UpperBoundSegment
+// returns a terminal iterator.
+func (s *addrSet) UpperBoundSegment(max uintptr) addrIterator {
+	seg, gap := s.Find(max)
+	if seg.Ok() {
+		return seg
+	}
+	return gap.PrevSegment()
+}
+
+// FindGap returns the gap containing the given key. If no such gap exists
+// (i.e. the set contains a segment containing that key), FindGap returns a
+// terminal iterator.
+func (s *addrSet) FindGap(key uintptr) addrGapIterator {
+	_, gap := s.Find(key)
+	return gap
+}
+
+// LowerBoundGap returns the gap with the lowest range that is greater than or
+// equal to min.
+func (s *addrSet) LowerBoundGap(min uintptr) addrGapIterator {
+	seg, gap := s.Find(min)
+	if gap.Ok() {
+		return gap
+	}
+	return seg.NextGap()
+}
+
+// UpperBoundGap returns the gap with the highest range that is less than or
+// equal to max.
+func (s *addrSet) UpperBoundGap(max uintptr) addrGapIterator {
+	seg, gap := s.Find(max)
+	if gap.Ok() {
+		return gap
+	}
+	return seg.PrevGap()
+}
+
+// Add inserts the given segment into the set and returns true. If the new
+// segment can be merged with adjacent segments, Add will do so. If the new
+// segment would overlap an existing segment, Add returns false. If Add
+// succeeds, all existing iterators are invalidated.
+func (s *addrSet) Add(r addrRange, val *objectEncodeState) bool {
+	if r.Length() <= 0 {
+		panic(fmt.Sprintf("invalid segment range %v", r))
+	}
+	gap := s.FindGap(r.Start)
+	if !gap.Ok() {
+		return false
+	}
+	if r.End > gap.End() {
+		return false
+	}
+	s.Insert(gap, r, val)
+	return true
+}
+
+// AddWithoutMerging inserts the given segment into the set and returns true.
+// If it would overlap an existing segment, AddWithoutMerging does nothing and
+// returns false. If AddWithoutMerging succeeds, all existing iterators are
+// invalidated.
+func (s *addrSet) AddWithoutMerging(r addrRange, val *objectEncodeState) bool {
+	if r.Length() <= 0 {
+		panic(fmt.Sprintf("invalid segment range %v", r))
+	}
+	gap := s.FindGap(r.Start)
+	if !gap.Ok() {
+		return false
+	}
+	if r.End > gap.End() {
+		return false
+	}
+	s.InsertWithoutMergingUnchecked(gap, r, val)
+	return true
+}
+
+// Insert inserts the given segment into the given gap. If the new segment can
+// be merged with adjacent segments, Insert will do so. Insert returns an
+// iterator to the segment containing the inserted value (which may have been
+// merged with other values). All existing iterators (including gap, but not
+// including the returned iterator) are invalidated.
+//
+// If the gap cannot accommodate the segment, or if r is invalid, Insert panics.
+//
+// Insert is semantically equivalent to a InsertWithoutMerging followed by a
+// Merge, but may be more efficient. Note that there is no unchecked variant of
+// Insert since Insert must retrieve and inspect gap's predecessor and
+// successor segments regardless.
+func (s *addrSet) Insert(gap addrGapIterator, r addrRange, val *objectEncodeState) addrIterator {
+	if r.Length() <= 0 {
+		panic(fmt.Sprintf("invalid segment range %v", r))
+	}
+	prev, next := gap.PrevSegment(), gap.NextSegment()
+	if prev.Ok() && prev.End() > r.Start {
+		panic(fmt.Sprintf("new segment %v overlaps predecessor %v", r, prev.Range()))
+	}
+	if next.Ok() && next.Start() < r.End {
+		panic(fmt.Sprintf("new segment %v overlaps successor %v", r, next.Range()))
+	}
+	if prev.Ok() && prev.End() == r.Start {
+		if mval, ok := (addrSetFunctions{}).Merge(prev.Range(), prev.Value(), r, val); ok {
+			shrinkMaxGap := addrtrackGaps != 0 && gap.Range().Length() == gap.node.maxGap.Get()
+			prev.SetEndUnchecked(r.End)
+			prev.SetValue(mval)
+			if shrinkMaxGap {
+				gap.node.updateMaxGapLeaf()
+			}
+			if next.Ok() && next.Start() == r.End {
+				val = mval
+				if mval, ok := (addrSetFunctions{}).Merge(prev.Range(), val, next.Range(), next.Value()); ok {
+					prev.SetEndUnchecked(next.End())
+					prev.SetValue(mval)
+					return s.Remove(next).PrevSegment()
+				}
+			}
+			return prev
+		}
+	}
+	if next.Ok() && next.Start() == r.End {
+		if mval, ok := (addrSetFunctions{}).Merge(r, val, next.Range(), next.Value()); ok {
+			shrinkMaxGap := addrtrackGaps != 0 && gap.Range().Length() == gap.node.maxGap.Get()
+			next.SetStartUnchecked(r.Start)
+			next.SetValue(mval)
+			if shrinkMaxGap {
+				gap.node.updateMaxGapLeaf()
+			}
+			return next
+		}
+	}
+
+	return s.InsertWithoutMergingUnchecked(gap, r, val)
+}
+
+// InsertWithoutMerging inserts the given segment into the given gap and
+// returns an iterator to the inserted segment. All existing iterators
+// (including gap, but not including the returned iterator) are invalidated.
+//
+// If the gap cannot accommodate the segment, or if r is invalid,
+// InsertWithoutMerging panics.
+func (s *addrSet) InsertWithoutMerging(gap addrGapIterator, r addrRange, val *objectEncodeState) addrIterator {
+	if r.Length() <= 0 {
+		panic(fmt.Sprintf("invalid segment range %v", r))
+	}
+	if gr := gap.Range(); !gr.IsSupersetOf(r) {
+		panic(fmt.Sprintf("cannot insert segment range %v into gap range %v", r, gr))
+	}
+	return s.InsertWithoutMergingUnchecked(gap, r, val)
+}
+
+// InsertWithoutMergingUnchecked inserts the given segment into the given gap
+// and returns an iterator to the inserted segment. All existing iterators
+// (including gap, but not including the returned iterator) are invalidated.
+//
+// Preconditions:
+// * r.Start >= gap.Start().
+// * r.End <= gap.End().
+func (s *addrSet) InsertWithoutMergingUnchecked(gap addrGapIterator, r addrRange, val *objectEncodeState) addrIterator {
+	gap = gap.node.rebalanceBeforeInsert(gap)
+	splitMaxGap := addrtrackGaps != 0 && (gap.node.nrSegments == 0 || gap.Range().Length() == gap.node.maxGap.Get())
+	copy(gap.node.keys[gap.index+1:], gap.node.keys[gap.index:gap.node.nrSegments])
+	copy(gap.node.values[gap.index+1:], gap.node.values[gap.index:gap.node.nrSegments])
+	gap.node.keys[gap.index] = r
+	gap.node.values[gap.index] = val
+	gap.node.nrSegments++
+	if splitMaxGap {
+		gap.node.updateMaxGapLeaf()
+	}
+	return addrIterator{gap.node, gap.index}
+}
+
+// Remove removes the given segment and returns an iterator to the vacated gap.
+// All existing iterators (including seg, but not including the returned
+// iterator) are invalidated.
+func (s *addrSet) Remove(seg addrIterator) addrGapIterator {
+
+	if seg.node.hasChildren {
+
+		victim := seg.PrevSegment()
+
+		seg.SetRangeUnchecked(victim.Range())
+		seg.SetValue(victim.Value())
+
+		nextAdjacentNode := seg.NextSegment().node
+		if addrtrackGaps != 0 {
+			nextAdjacentNode.updateMaxGapLeaf()
+		}
+		return s.Remove(victim).NextGap()
+	}
+	copy(seg.node.keys[seg.index:], seg.node.keys[seg.index+1:seg.node.nrSegments])
+	copy(seg.node.values[seg.index:], seg.node.values[seg.index+1:seg.node.nrSegments])
+	addrSetFunctions{}.ClearValue(&seg.node.values[seg.node.nrSegments-1])
+	seg.node.nrSegments--
+	if addrtrackGaps != 0 {
+		seg.node.updateMaxGapLeaf()
+	}
+	return seg.node.rebalanceAfterRemove(addrGapIterator{seg.node, seg.index})
+}
+
+// RemoveAll removes all segments from the set. All existing iterators are
+// invalidated.
+func (s *addrSet) RemoveAll() {
+	s.root = addrnode{}
+}
+
+// RemoveRange removes all segments in the given range. An iterator to the
+// newly formed gap is returned, and all existing iterators are invalidated.
+func (s *addrSet) RemoveRange(r addrRange) addrGapIterator {
+	seg, gap := s.Find(r.Start)
+	if seg.Ok() {
+		seg = s.Isolate(seg, r)
+		gap = s.Remove(seg)
+	}
+	for seg = gap.NextSegment(); seg.Ok() && seg.Start() < r.End; seg = gap.NextSegment() {
+		seg = s.Isolate(seg, r)
+		gap = s.Remove(seg)
+	}
+	return gap
+}
+
+// Merge attempts to merge two neighboring segments. If successful, Merge
+// returns an iterator to the merged segment, and all existing iterators are
+// invalidated. Otherwise, Merge returns a terminal iterator.
+//
+// If first is not the predecessor of second, Merge panics.
+func (s *addrSet) Merge(first, second addrIterator) addrIterator {
+	if first.NextSegment() != second {
+		panic(fmt.Sprintf("attempt to merge non-neighboring segments %v, %v", first.Range(), second.Range()))
+	}
+	return s.MergeUnchecked(first, second)
+}
+
+// MergeUnchecked attempts to merge two neighboring segments. If successful,
+// MergeUnchecked returns an iterator to the merged segment, and all existing
+// iterators are invalidated. Otherwise, MergeUnchecked returns a terminal
+// iterator.
+//
+// Precondition: first is the predecessor of second: first.NextSegment() ==
+// second, first == second.PrevSegment().
+func (s *addrSet) MergeUnchecked(first, second addrIterator) addrIterator {
+	if first.End() == second.Start() {
+		if mval, ok := (addrSetFunctions{}).Merge(first.Range(), first.Value(), second.Range(), second.Value()); ok {
+
+			first.SetEndUnchecked(second.End())
+			first.SetValue(mval)
+
+			return s.Remove(second).PrevSegment()
+		}
+	}
+	return addrIterator{}
+}
+
+// MergeAll attempts to merge all adjacent segments in the set. All existing
+// iterators are invalidated.
+func (s *addrSet) MergeAll() {
+	seg := s.FirstSegment()
+	if !seg.Ok() {
+		return
+	}
+	next := seg.NextSegment()
+	for next.Ok() {
+		if mseg := s.MergeUnchecked(seg, next); mseg.Ok() {
+			seg, next = mseg, mseg.NextSegment()
+		} else {
+			seg, next = next, next.NextSegment()
+		}
+	}
+}
+
+// MergeRange attempts to merge all adjacent segments that contain a key in the
+// specific range. All existing iterators are invalidated.
+func (s *addrSet) MergeRange(r addrRange) {
+	seg := s.LowerBoundSegment(r.Start)
+	if !seg.Ok() {
+		return
+	}
+	next := seg.NextSegment()
+	for next.Ok() && next.Range().Start < r.End {
+		if mseg := s.MergeUnchecked(seg, next); mseg.Ok() {
+			seg, next = mseg, mseg.NextSegment()
+		} else {
+			seg, next = next, next.NextSegment()
+		}
+	}
+}
+
+// MergeAdjacent attempts to merge the segment containing r.Start with its
+// predecessor, and the segment containing r.End-1 with its successor.
+func (s *addrSet) MergeAdjacent(r addrRange) {
+	first := s.FindSegment(r.Start)
+	if first.Ok() {
+		if prev := first.PrevSegment(); prev.Ok() {
+			s.Merge(prev, first)
+		}
+	}
+	last := s.FindSegment(r.End - 1)
+	if last.Ok() {
+		if next := last.NextSegment(); next.Ok() {
+			s.Merge(last, next)
+		}
+	}
+}
+
+// Split splits the given segment at the given key and returns iterators to the
+// two resulting segments. All existing iterators (including seg, but not
+// including the returned iterators) are invalidated.
+//
+// If the segment cannot be split at split (because split is at the start or
+// end of the segment's range, so splitting would produce a segment with zero
+// length, or because split falls outside the segment's range altogether),
+// Split panics.
+func (s *addrSet) Split(seg addrIterator, split uintptr) (addrIterator, addrIterator) {
+	if !seg.Range().CanSplitAt(split) {
+		panic(fmt.Sprintf("can't split %v at %v", seg.Range(), split))
+	}
+	return s.SplitUnchecked(seg, split)
+}
+
+// SplitUnchecked splits the given segment at the given key and returns
+// iterators to the two resulting segments. All existing iterators (including
+// seg, but not including the returned iterators) are invalidated.
+//
+// Preconditions: seg.Start() < key < seg.End().
+func (s *addrSet) SplitUnchecked(seg addrIterator, split uintptr) (addrIterator, addrIterator) {
+	val1, val2 := (addrSetFunctions{}).Split(seg.Range(), seg.Value(), split)
+	end2 := seg.End()
+	seg.SetEndUnchecked(split)
+	seg.SetValue(val1)
+	seg2 := s.InsertWithoutMergingUnchecked(seg.NextGap(), addrRange{split, end2}, val2)
+
+	return seg2.PrevSegment(), seg2
+}
+
+// SplitAt splits the segment straddling split, if one exists. SplitAt returns
+// true if a segment was split and false otherwise. If SplitAt splits a
+// segment, all existing iterators are invalidated.
+func (s *addrSet) SplitAt(split uintptr) bool {
+	if seg := s.FindSegment(split); seg.Ok() && seg.Range().CanSplitAt(split) {
+		s.SplitUnchecked(seg, split)
+		return true
+	}
+	return false
+}
+
+// Isolate ensures that the given segment's range does not escape r by
+// splitting at r.Start and r.End if necessary, and returns an updated iterator
+// to the bounded segment. All existing iterators (including seg, but not
+// including the returned iterators) are invalidated.
+func (s *addrSet) Isolate(seg addrIterator, r addrRange) addrIterator {
+	if seg.Range().CanSplitAt(r.Start) {
+		_, seg = s.SplitUnchecked(seg, r.Start)
+	}
+	if seg.Range().CanSplitAt(r.End) {
+		seg, _ = s.SplitUnchecked(seg, r.End)
+	}
+	return seg
+}
+
+// ApplyContiguous applies a function to a contiguous range of segments,
+// splitting if necessary. The function is applied until the first gap is
+// encountered, at which point the gap is returned. If the function is applied
+// across the entire range, a terminal gap is returned. All existing iterators
+// are invalidated.
+//
+// N.B. The Iterator must not be invalidated by the function.
+func (s *addrSet) ApplyContiguous(r addrRange, fn func(seg addrIterator)) addrGapIterator {
+	seg, gap := s.Find(r.Start)
+	if !seg.Ok() {
+		return gap
+	}
+	for {
+		seg = s.Isolate(seg, r)
+		fn(seg)
+		if seg.End() >= r.End {
+			return addrGapIterator{}
+		}
+		gap = seg.NextGap()
+		if !gap.IsEmpty() {
+			return gap
+		}
+		seg = gap.NextSegment()
+		if !seg.Ok() {
+
+			return addrGapIterator{}
+		}
+	}
+}
+
+// +stateify savable
+type addrnode struct {
+	// An internal binary tree node looks like:
+	//
+	//   K
+	//  / \
+	// Cl Cr
+	//
+	// where all keys in the subtree rooted by Cl (the left subtree) are less
+	// than K (the key of the parent node), and all keys in the subtree rooted
+	// by Cr (the right subtree) are greater than K.
+	//
+	// An internal B-tree node's indexes work out to look like:
+	//
+	//   K0 K1 K2  ...   Kn-1
+	//  / \/ \/ \  ...  /  \
+	// C0 C1 C2 C3 ... Cn-1 Cn
+	//
+	// where n is nrSegments.
+	nrSegments int
+
+	// parent is a pointer to this node's parent. If this node is root, parent
+	// is nil.
+	parent *addrnode
+
+	// parentIndex is the index of this node in parent.children.
+	parentIndex int
+
+	// Flag for internal nodes that is technically redundant with "children[0]
+	// != nil", but is stored in the first cache line. "hasChildren" rather
+	// than "isLeaf" because false must be the correct value for an empty root.
+	hasChildren bool
+
+	// The longest gap within this node. If the node is a leaf, it's simply the
+	// maximum gap among all the (nrSegments+1) gaps formed by its nrSegments keys
+	// including the 0th and nrSegments-th gap possibly shared with its upper-level
+	// nodes; if it's a non-leaf node, it's the max of all children's maxGap.
+	maxGap addrdynamicGap
+
+	// Nodes store keys and values in separate arrays to maximize locality in
+	// the common case (scanning keys for lookup).
+	keys     [addrmaxDegree - 1]addrRange
+	values   [addrmaxDegree - 1]*objectEncodeState
+	children [addrmaxDegree]*addrnode
+}
+
+// firstSegment returns the first segment in the subtree rooted by n.
+//
+// Preconditions: n.nrSegments != 0.
+func (n *addrnode) firstSegment() addrIterator {
+	for n.hasChildren {
+		n = n.children[0]
+	}
+	return addrIterator{n, 0}
+}
+
+// lastSegment returns the last segment in the subtree rooted by n.
+//
+// Preconditions: n.nrSegments != 0.
+func (n *addrnode) lastSegment() addrIterator {
+	for n.hasChildren {
+		n = n.children[n.nrSegments]
+	}
+	return addrIterator{n, n.nrSegments - 1}
+}
+
+func (n *addrnode) prevSibling() *addrnode {
+	if n.parent == nil || n.parentIndex == 0 {
+		return nil
+	}
+	return n.parent.children[n.parentIndex-1]
+}
+
+func (n *addrnode) nextSibling() *addrnode {
+	if n.parent == nil || n.parentIndex == n.parent.nrSegments {
+		return nil
+	}
+	return n.parent.children[n.parentIndex+1]
+}
+
+// rebalanceBeforeInsert splits n and its ancestors if they are full, as
+// required for insertion, and returns an updated iterator to the position
+// represented by gap.
+func (n *addrnode) rebalanceBeforeInsert(gap addrGapIterator) addrGapIterator {
+	if n.nrSegments < addrmaxDegree-1 {
+		return gap
+	}
+	if n.parent != nil {
+		gap = n.parent.rebalanceBeforeInsert(gap)
+	}
+	if n.parent == nil {
+
+		left := &addrnode{
+			nrSegments:  addrminDegree - 1,
+			parent:      n,
+			parentIndex: 0,
+			hasChildren: n.hasChildren,
+		}
+		right := &addrnode{
+			nrSegments:  addrminDegree - 1,
+			parent:      n,
+			parentIndex: 1,
+			hasChildren: n.hasChildren,
+		}
+		copy(left.keys[:addrminDegree-1], n.keys[:addrminDegree-1])
+		copy(left.values[:addrminDegree-1], n.values[:addrminDegree-1])
+		copy(right.keys[:addrminDegree-1], n.keys[addrminDegree:])
+		copy(right.values[:addrminDegree-1], n.values[addrminDegree:])
+		n.keys[0], n.values[0] = n.keys[addrminDegree-1], n.values[addrminDegree-1]
+		addrzeroValueSlice(n.values[1:])
+		if n.hasChildren {
+			copy(left.children[:addrminDegree], n.children[:addrminDegree])
+			copy(right.children[:addrminDegree], n.children[addrminDegree:])
+			addrzeroNodeSlice(n.children[2:])
+			for i := 0; i < addrminDegree; i++ {
+				left.children[i].parent = left
+				left.children[i].parentIndex = i
+				right.children[i].parent = right
+				right.children[i].parentIndex = i
+			}
+		}
+		n.nrSegments = 1
+		n.hasChildren = true
+		n.children[0] = left
+		n.children[1] = right
+
+		if addrtrackGaps != 0 {
+			left.updateMaxGapLocal()
+			right.updateMaxGapLocal()
+		}
+		if gap.node != n {
+			return gap
+		}
+		if gap.index < addrminDegree {
+			return addrGapIterator{left, gap.index}
+		}
+		return addrGapIterator{right, gap.index - addrminDegree}
+	}
+
+	copy(n.parent.keys[n.parentIndex+1:], n.parent.keys[n.parentIndex:n.parent.nrSegments])
+	copy(n.parent.values[n.parentIndex+1:], n.parent.values[n.parentIndex:n.parent.nrSegments])
+	n.parent.keys[n.parentIndex], n.parent.values[n.parentIndex] = n.keys[addrminDegree-1], n.values[addrminDegree-1]
+	copy(n.parent.children[n.parentIndex+2:], n.parent.children[n.parentIndex+1:n.parent.nrSegments+1])
+	for i := n.parentIndex + 2; i < n.parent.nrSegments+2; i++ {
+		n.parent.children[i].parentIndex = i
+	}
+	sibling := &addrnode{
+		nrSegments:  addrminDegree - 1,
+		parent:      n.parent,
+		parentIndex: n.parentIndex + 1,
+		hasChildren: n.hasChildren,
+	}
+	n.parent.children[n.parentIndex+1] = sibling
+	n.parent.nrSegments++
+	copy(sibling.keys[:addrminDegree-1], n.keys[addrminDegree:])
+	copy(sibling.values[:addrminDegree-1], n.values[addrminDegree:])
+	addrzeroValueSlice(n.values[addrminDegree-1:])
+	if n.hasChildren {
+		copy(sibling.children[:addrminDegree], n.children[addrminDegree:])
+		addrzeroNodeSlice(n.children[addrminDegree:])
+		for i := 0; i < addrminDegree; i++ {
+			sibling.children[i].parent = sibling
+			sibling.children[i].parentIndex = i
+		}
+	}
+	n.nrSegments = addrminDegree - 1
+
+	if addrtrackGaps != 0 {
+		n.updateMaxGapLocal()
+		sibling.updateMaxGapLocal()
+	}
+
+	if gap.node != n {
+		return gap
+	}
+	if gap.index < addrminDegree {
+		return gap
+	}
+	return addrGapIterator{sibling, gap.index - addrminDegree}
+}
+
+// rebalanceAfterRemove "unsplits" n and its ancestors if they are deficient
+// (contain fewer segments than required by B-tree invariants), as required for
+// removal, and returns an updated iterator to the position represented by gap.
+//
+// Precondition: n is the only node in the tree that may currently violate a
+// B-tree invariant.
+func (n *addrnode) rebalanceAfterRemove(gap addrGapIterator) addrGapIterator {
+	for {
+		if n.nrSegments >= addrminDegree-1 {
+			return gap
+		}
+		if n.parent == nil {
+
+			return gap
+		}
+
+		if sibling := n.prevSibling(); sibling != nil && sibling.nrSegments >= addrminDegree {
+			copy(n.keys[1:], n.keys[:n.nrSegments])
+			copy(n.values[1:], n.values[:n.nrSegments])
+			n.keys[0] = n.parent.keys[n.parentIndex-1]
+			n.values[0] = n.parent.values[n.parentIndex-1]
+			n.parent.keys[n.parentIndex-1] = sibling.keys[sibling.nrSegments-1]
+			n.parent.values[n.parentIndex-1] = sibling.values[sibling.nrSegments-1]
+			addrSetFunctions{}.ClearValue(&sibling.values[sibling.nrSegments-1])
+			if n.hasChildren {
+				copy(n.children[1:], n.children[:n.nrSegments+1])
+				n.children[0] = sibling.children[sibling.nrSegments]
+				sibling.children[sibling.nrSegments] = nil
+				n.children[0].parent = n
+				n.children[0].parentIndex = 0
+				for i := 1; i < n.nrSegments+2; i++ {
+					n.children[i].parentIndex = i
+				}
+			}
+			n.nrSegments++
+			sibling.nrSegments--
+
+			if addrtrackGaps != 0 {
+				n.updateMaxGapLocal()
+				sibling.updateMaxGapLocal()
+			}
+			if gap.node == sibling && gap.index == sibling.nrSegments {
+				return addrGapIterator{n, 0}
+			}
+			if gap.node == n {
+				return addrGapIterator{n, gap.index + 1}
+			}
+			return gap
+		}
+		if sibling := n.nextSibling(); sibling != nil && sibling.nrSegments >= addrminDegree {
+			n.keys[n.nrSegments] = n.parent.keys[n.parentIndex]
+			n.values[n.nrSegments] = n.parent.values[n.parentIndex]
+			n.parent.keys[n.parentIndex] = sibling.keys[0]
+			n.parent.values[n.parentIndex] = sibling.values[0]
+			copy(sibling.keys[:sibling.nrSegments-1], sibling.keys[1:])
+			copy(sibling.values[:sibling.nrSegments-1], sibling.values[1:])
+			addrSetFunctions{}.ClearValue(&sibling.values[sibling.nrSegments-1])
+			if n.hasChildren {
+				n.children[n.nrSegments+1] = sibling.children[0]
+				copy(sibling.children[:sibling.nrSegments], sibling.children[1:])
+				sibling.children[sibling.nrSegments] = nil
+				n.children[n.nrSegments+1].parent = n
+				n.children[n.nrSegments+1].parentIndex = n.nrSegments + 1
+				for i := 0; i < sibling.nrSegments; i++ {
+					sibling.children[i].parentIndex = i
+				}
+			}
+			n.nrSegments++
+			sibling.nrSegments--
+
+			if addrtrackGaps != 0 {
+				n.updateMaxGapLocal()
+				sibling.updateMaxGapLocal()
+			}
+			if gap.node == sibling {
+				if gap.index == 0 {
+					return addrGapIterator{n, n.nrSegments}
+				}
+				return addrGapIterator{sibling, gap.index - 1}
+			}
+			return gap
+		}
+
+		p := n.parent
+		if p.nrSegments == 1 {
+
+			left, right := p.children[0], p.children[1]
+			p.nrSegments = left.nrSegments + right.nrSegments + 1
+			p.hasChildren = left.hasChildren
+			p.keys[left.nrSegments] = p.keys[0]
+			p.values[left.nrSegments] = p.values[0]
+			copy(p.keys[:left.nrSegments], left.keys[:left.nrSegments])
+			copy(p.values[:left.nrSegments], left.values[:left.nrSegments])
+			copy(p.keys[left.nrSegments+1:], right.keys[:right.nrSegments])
+			copy(p.values[left.nrSegments+1:], right.values[:right.nrSegments])
+			if left.hasChildren {
+				copy(p.children[:left.nrSegments+1], left.children[:left.nrSegments+1])
+				copy(p.children[left.nrSegments+1:], right.children[:right.nrSegments+1])
+				for i := 0; i < p.nrSegments+1; i++ {
+					p.children[i].parent = p
+					p.children[i].parentIndex = i
+				}
+			} else {
+				p.children[0] = nil
+				p.children[1] = nil
+			}
+
+			if gap.node == left {
+				return addrGapIterator{p, gap.index}
+			}
+			if gap.node == right {
+				return addrGapIterator{p, gap.index + left.nrSegments + 1}
+			}
+			return gap
+		}
+		// Merge n and either sibling, along with the segment separating the
+		// two, into whichever of the two nodes comes first. This is the
+		// reverse of the non-root splitting case in
+		// node.rebalanceBeforeInsert.
+		var left, right *addrnode
+		if n.parentIndex > 0 {
+			left = n.prevSibling()
+			right = n
+		} else {
+			left = n
+			right = n.nextSibling()
+		}
+
+		if gap.node == right {
+			gap = addrGapIterator{left, gap.index + left.nrSegments + 1}
+		}
+		left.keys[left.nrSegments] = p.keys[left.parentIndex]
+		left.values[left.nrSegments] = p.values[left.parentIndex]
+		copy(left.keys[left.nrSegments+1:], right.keys[:right.nrSegments])
+		copy(left.values[left.nrSegments+1:], right.values[:right.nrSegments])
+		if left.hasChildren {
+			copy(left.children[left.nrSegments+1:], right.children[:right.nrSegments+1])
+			for i := left.nrSegments + 1; i < left.nrSegments+right.nrSegments+2; i++ {
+				left.children[i].parent = left
+				left.children[i].parentIndex = i
+			}
+		}
+		left.nrSegments += right.nrSegments + 1
+		copy(p.keys[left.parentIndex:], p.keys[left.parentIndex+1:p.nrSegments])
+		copy(p.values[left.parentIndex:], p.values[left.parentIndex+1:p.nrSegments])
+		addrSetFunctions{}.ClearValue(&p.values[p.nrSegments-1])
+		copy(p.children[left.parentIndex+1:], p.children[left.parentIndex+2:p.nrSegments+1])
+		for i := 0; i < p.nrSegments; i++ {
+			p.children[i].parentIndex = i
+		}
+		p.children[p.nrSegments] = nil
+		p.nrSegments--
+
+		if addrtrackGaps != 0 {
+			left.updateMaxGapLocal()
+		}
+
+		n = p
+	}
+}
+
+// updateMaxGapLeaf updates maxGap bottom-up from the calling leaf until no
+// necessary update.
+//
+// Preconditions: n must be a leaf node, trackGaps must be 1.
+func (n *addrnode) updateMaxGapLeaf() {
+	if n.hasChildren {
+		panic(fmt.Sprintf("updateMaxGapLeaf should always be called on leaf node: %v", n))
+	}
+	max := n.calculateMaxGapLeaf()
+	if max == n.maxGap.Get() {
+
+		return
+	}
+	oldMax := n.maxGap.Get()
+	n.maxGap.Set(max)
+	if max > oldMax {
+
+		for p := n.parent; p != nil; p = p.parent {
+			if p.maxGap.Get() >= max {
+
+				break
+			}
+
+			p.maxGap.Set(max)
+		}
+		return
+	}
+
+	for p := n.parent; p != nil; p = p.parent {
+		if p.maxGap.Get() > oldMax {
+
+			break
+		}
+
+		parentNewMax := p.calculateMaxGapInternal()
+		if p.maxGap.Get() == parentNewMax {
+
+			break
+		}
+
+		p.maxGap.Set(parentNewMax)
+	}
+}
+
+// updateMaxGapLocal updates maxGap of the calling node solely with no
+// propagation to ancestor nodes.
+//
+// Precondition: trackGaps must be 1.
+func (n *addrnode) updateMaxGapLocal() {
+	if !n.hasChildren {
+
+		n.maxGap.Set(n.calculateMaxGapLeaf())
+	} else {
+
+		n.maxGap.Set(n.calculateMaxGapInternal())
+	}
+}
+
+// calculateMaxGapLeaf iterates the gaps within a leaf node and calculate the
+// max.
+//
+// Preconditions: n must be a leaf node.
+func (n *addrnode) calculateMaxGapLeaf() uintptr {
+	max := addrGapIterator{n, 0}.Range().Length()
+	for i := 1; i <= n.nrSegments; i++ {
+		if current := (addrGapIterator{n, i}).Range().Length(); current > max {
+			max = current
+		}
+	}
+	return max
+}
+
+// calculateMaxGapInternal iterates children's maxGap within an internal node n
+// and calculate the max.
+//
+// Preconditions: n must be a non-leaf node.
+func (n *addrnode) calculateMaxGapInternal() uintptr {
+	max := n.children[0].maxGap.Get()
+	for i := 1; i <= n.nrSegments; i++ {
+		if current := n.children[i].maxGap.Get(); current > max {
+			max = current
+		}
+	}
+	return max
+}
+
+// searchFirstLargeEnoughGap returns the first gap having at least minSize length
+// in the subtree rooted by n. If not found, return a terminal gap iterator.
+func (n *addrnode) searchFirstLargeEnoughGap(minSize uintptr) addrGapIterator {
+	if n.maxGap.Get() < minSize {
+		return addrGapIterator{}
+	}
+	if n.hasChildren {
+		for i := 0; i <= n.nrSegments; i++ {
+			if largeEnoughGap := n.children[i].searchFirstLargeEnoughGap(minSize); largeEnoughGap.Ok() {
+				return largeEnoughGap
+			}
+		}
+	} else {
+		for i := 0; i <= n.nrSegments; i++ {
+			currentGap := addrGapIterator{n, i}
+			if currentGap.Range().Length() >= minSize {
+				return currentGap
+			}
+		}
+	}
+	panic(fmt.Sprintf("invalid maxGap in %v", n))
+}
+
+// searchLastLargeEnoughGap returns the last gap having at least minSize length
+// in the subtree rooted by n. If not found, return a terminal gap iterator.
+func (n *addrnode) searchLastLargeEnoughGap(minSize uintptr) addrGapIterator {
+	if n.maxGap.Get() < minSize {
+		return addrGapIterator{}
+	}
+	if n.hasChildren {
+		for i := n.nrSegments; i >= 0; i-- {
+			if largeEnoughGap := n.children[i].searchLastLargeEnoughGap(minSize); largeEnoughGap.Ok() {
+				return largeEnoughGap
+			}
+		}
+	} else {
+		for i := n.nrSegments; i >= 0; i-- {
+			currentGap := addrGapIterator{n, i}
+			if currentGap.Range().Length() >= minSize {
+				return currentGap
+			}
+		}
+	}
+	panic(fmt.Sprintf("invalid maxGap in %v", n))
+}
+
+// A Iterator is conceptually one of:
+//
+// - A pointer to a segment in a set; or
+//
+// - A terminal iterator, which is a sentinel indicating that the end of
+// iteration has been reached.
+//
+// Iterators are copyable values and are meaningfully equality-comparable. The
+// zero value of Iterator is a terminal iterator.
+//
+// Unless otherwise specified, any mutation of a set invalidates all existing
+// iterators into the set.
+type addrIterator struct {
+	// node is the node containing the iterated segment. If the iterator is
+	// terminal, node is nil.
+	node *addrnode
+
+	// index is the index of the segment in node.keys/values.
+	index int
+}
+
+// Ok returns true if the iterator is not terminal. All other methods are only
+// valid for non-terminal iterators.
+func (seg addrIterator) Ok() bool {
+	return seg.node != nil
+}
+
+// Range returns the iterated segment's range key.
+func (seg addrIterator) Range() addrRange {
+	return seg.node.keys[seg.index]
+}
+
+// Start is equivalent to Range().Start, but should be preferred if only the
+// start of the range is needed.
+func (seg addrIterator) Start() uintptr {
+	return seg.node.keys[seg.index].Start
+}
+
+// End is equivalent to Range().End, but should be preferred if only the end of
+// the range is needed.
+func (seg addrIterator) End() uintptr {
+	return seg.node.keys[seg.index].End
+}
+
+// SetRangeUnchecked mutates the iterated segment's range key. This operation
+// does not invalidate any iterators.
+//
+// Preconditions:
+// * r.Length() > 0.
+// * The new range must not overlap an existing one:
+//   * If seg.NextSegment().Ok(), then r.end <= seg.NextSegment().Start().
+//   * If seg.PrevSegment().Ok(), then r.start >= seg.PrevSegment().End().
+func (seg addrIterator) SetRangeUnchecked(r addrRange) {
+	seg.node.keys[seg.index] = r
+}
+
+// SetRange mutates the iterated segment's range key. If the new range would
+// cause the iterated segment to overlap another segment, or if the new range
+// is invalid, SetRange panics. This operation does not invalidate any
+// iterators.
+func (seg addrIterator) SetRange(r addrRange) {
+	if r.Length() <= 0 {
+		panic(fmt.Sprintf("invalid segment range %v", r))
+	}
+	if prev := seg.PrevSegment(); prev.Ok() && r.Start < prev.End() {
+		panic(fmt.Sprintf("new segment range %v overlaps segment range %v", r, prev.Range()))
+	}
+	if next := seg.NextSegment(); next.Ok() && r.End > next.Start() {
+		panic(fmt.Sprintf("new segment range %v overlaps segment range %v", r, next.Range()))
+	}
+	seg.SetRangeUnchecked(r)
+}
+
+// SetStartUnchecked mutates the iterated segment's start. This operation does
+// not invalidate any iterators.
+//
+// Preconditions: The new start must be valid:
+// * start < seg.End()
+// * If seg.PrevSegment().Ok(), then start >= seg.PrevSegment().End().
+func (seg addrIterator) SetStartUnchecked(start uintptr) {
+	seg.node.keys[seg.index].Start = start
+}
+
+// SetStart mutates the iterated segment's start. If the new start value would
+// cause the iterated segment to overlap another segment, or would result in an
+// invalid range, SetStart panics. This operation does not invalidate any
+// iterators.
+func (seg addrIterator) SetStart(start uintptr) {
+	if start >= seg.End() {
+		panic(fmt.Sprintf("new start %v would invalidate segment range %v", start, seg.Range()))
+	}
+	if prev := seg.PrevSegment(); prev.Ok() && start < prev.End() {
+		panic(fmt.Sprintf("new start %v would cause segment range %v to overlap segment range %v", start, seg.Range(), prev.Range()))
+	}
+	seg.SetStartUnchecked(start)
+}
+
+// SetEndUnchecked mutates the iterated segment's end. This operation does not
+// invalidate any iterators.
+//
+// Preconditions: The new end must be valid:
+// * end > seg.Start().
+// * If seg.NextSegment().Ok(), then end <= seg.NextSegment().Start().
+func (seg addrIterator) SetEndUnchecked(end uintptr) {
+	seg.node.keys[seg.index].End = end
+}
+
+// SetEnd mutates the iterated segment's end. If the new end value would cause
+// the iterated segment to overlap another segment, or would result in an
+// invalid range, SetEnd panics. This operation does not invalidate any
+// iterators.
+func (seg addrIterator) SetEnd(end uintptr) {
+	if end <= seg.Start() {
+		panic(fmt.Sprintf("new end %v would invalidate segment range %v", end, seg.Range()))
+	}
+	if next := seg.NextSegment(); next.Ok() && end > next.Start() {
+		panic(fmt.Sprintf("new end %v would cause segment range %v to overlap segment range %v", end, seg.Range(), next.Range()))
+	}
+	seg.SetEndUnchecked(end)
+}
+
+// Value returns a copy of the iterated segment's value.
+func (seg addrIterator) Value() *objectEncodeState {
+	return seg.node.values[seg.index]
+}
+
+// ValuePtr returns a pointer to the iterated segment's value. The pointer is
+// invalidated if the iterator is invalidated. This operation does not
+// invalidate any iterators.
+func (seg addrIterator) ValuePtr() **objectEncodeState {
+	return &seg.node.values[seg.index]
+}
+
+// SetValue mutates the iterated segment's value. This operation does not
+// invalidate any iterators.
+func (seg addrIterator) SetValue(val *objectEncodeState) {
+	seg.node.values[seg.index] = val
+}
+
+// PrevSegment returns the iterated segment's predecessor. If there is no
+// preceding segment, PrevSegment returns a terminal iterator.
+func (seg addrIterator) PrevSegment() addrIterator {
+	if seg.node.hasChildren {
+		return seg.node.children[seg.index].lastSegment()
+	}
+	if seg.index > 0 {
+		return addrIterator{seg.node, seg.index - 1}
+	}
+	if seg.node.parent == nil {
+		return addrIterator{}
+	}
+	return addrsegmentBeforePosition(seg.node.parent, seg.node.parentIndex)
+}
+
+// NextSegment returns the iterated segment's successor. If there is no
+// succeeding segment, NextSegment returns a terminal iterator.
+func (seg addrIterator) NextSegment() addrIterator {
+	if seg.node.hasChildren {
+		return seg.node.children[seg.index+1].firstSegment()
+	}
+	if seg.index < seg.node.nrSegments-1 {
+		return addrIterator{seg.node, seg.index + 1}
+	}
+	if seg.node.parent == nil {
+		return addrIterator{}
+	}
+	return addrsegmentAfterPosition(seg.node.parent, seg.node.parentIndex)
+}
+
+// PrevGap returns the gap immediately before the iterated segment.
+func (seg addrIterator) PrevGap() addrGapIterator {
+	if seg.node.hasChildren {
+
+		return seg.node.children[seg.index].lastSegment().NextGap()
+	}
+	return addrGapIterator{seg.node, seg.index}
+}
+
+// NextGap returns the gap immediately after the iterated segment.
+func (seg addrIterator) NextGap() addrGapIterator {
+	if seg.node.hasChildren {
+		return seg.node.children[seg.index+1].firstSegment().PrevGap()
+	}
+	return addrGapIterator{seg.node, seg.index + 1}
+}
+
+// PrevNonEmpty returns the iterated segment's predecessor if it is adjacent,
+// or the gap before the iterated segment otherwise. If seg.Start() ==
+// Functions.MinKey(), PrevNonEmpty will return two terminal iterators.
+// Otherwise, exactly one of the iterators returned by PrevNonEmpty will be
+// non-terminal.
+func (seg addrIterator) PrevNonEmpty() (addrIterator, addrGapIterator) {
+	gap := seg.PrevGap()
+	if gap.Range().Length() != 0 {
+		return addrIterator{}, gap
+	}
+	return gap.PrevSegment(), addrGapIterator{}
+}
+
+// NextNonEmpty returns the iterated segment's successor if it is adjacent, or
+// the gap after the iterated segment otherwise. If seg.End() ==
+// Functions.MaxKey(), NextNonEmpty will return two terminal iterators.
+// Otherwise, exactly one of the iterators returned by NextNonEmpty will be
+// non-terminal.
+func (seg addrIterator) NextNonEmpty() (addrIterator, addrGapIterator) {
+	gap := seg.NextGap()
+	if gap.Range().Length() != 0 {
+		return addrIterator{}, gap
+	}
+	return gap.NextSegment(), addrGapIterator{}
+}
+
+// A GapIterator is conceptually one of:
+//
+// - A pointer to a position between two segments, before the first segment, or
+// after the last segment in a set, called a *gap*; or
+//
+// - A terminal iterator, which is a sentinel indicating that the end of
+// iteration has been reached.
+//
+// Note that the gap between two adjacent segments exists (iterators to it are
+// non-terminal), but has a length of zero. GapIterator.IsEmpty returns true
+// for such gaps. An empty set contains a single gap, spanning the entire range
+// of the set's keys.
+//
+// GapIterators are copyable values and are meaningfully equality-comparable.
+// The zero value of GapIterator is a terminal iterator.
+//
+// Unless otherwise specified, any mutation of a set invalidates all existing
+// iterators into the set.
+type addrGapIterator struct {
+	// The representation of a GapIterator is identical to that of an Iterator,
+	// except that index corresponds to positions between segments in the same
+	// way as for node.children (see comment for node.nrSegments).
+	node  *addrnode
+	index int
+}
+
+// Ok returns true if the iterator is not terminal. All other methods are only
+// valid for non-terminal iterators.
+func (gap addrGapIterator) Ok() bool {
+	return gap.node != nil
+}
+
+// Range returns the range spanned by the iterated gap.
+func (gap addrGapIterator) Range() addrRange {
+	return addrRange{gap.Start(), gap.End()}
+}
+
+// Start is equivalent to Range().Start, but should be preferred if only the
+// start of the range is needed.
+func (gap addrGapIterator) Start() uintptr {
+	if ps := gap.PrevSegment(); ps.Ok() {
+		return ps.End()
+	}
+	return addrSetFunctions{}.MinKey()
+}
+
+// End is equivalent to Range().End, but should be preferred if only the end of
+// the range is needed.
+func (gap addrGapIterator) End() uintptr {
+	if ns := gap.NextSegment(); ns.Ok() {
+		return ns.Start()
+	}
+	return addrSetFunctions{}.MaxKey()
+}
+
+// IsEmpty returns true if the iterated gap is empty (that is, the "gap" is
+// between two adjacent segments.)
+func (gap addrGapIterator) IsEmpty() bool {
+	return gap.Range().Length() == 0
+}
+
+// PrevSegment returns the segment immediately before the iterated gap. If no
+// such segment exists, PrevSegment returns a terminal iterator.
+func (gap addrGapIterator) PrevSegment() addrIterator {
+	return addrsegmentBeforePosition(gap.node, gap.index)
+}
+
+// NextSegment returns the segment immediately after the iterated gap. If no
+// such segment exists, NextSegment returns a terminal iterator.
+func (gap addrGapIterator) NextSegment() addrIterator {
+	return addrsegmentAfterPosition(gap.node, gap.index)
+}
+
+// PrevGap returns the iterated gap's predecessor. If no such gap exists,
+// PrevGap returns a terminal iterator.
+func (gap addrGapIterator) PrevGap() addrGapIterator {
+	seg := gap.PrevSegment()
+	if !seg.Ok() {
+		return addrGapIterator{}
+	}
+	return seg.PrevGap()
+}
+
+// NextGap returns the iterated gap's successor. If no such gap exists, NextGap
+// returns a terminal iterator.
+func (gap addrGapIterator) NextGap() addrGapIterator {
+	seg := gap.NextSegment()
+	if !seg.Ok() {
+		return addrGapIterator{}
+	}
+	return seg.NextGap()
+}
+
+// NextLargeEnoughGap returns the iterated gap's first next gap with larger
+// length than minSize.  If not found, return a terminal gap iterator (does NOT
+// include this gap itself).
+//
+// Precondition: trackGaps must be 1.
+func (gap addrGapIterator) NextLargeEnoughGap(minSize uintptr) addrGapIterator {
+	if addrtrackGaps != 1 {
+		panic("set is not tracking gaps")
+	}
+	if gap.node != nil && gap.node.hasChildren && gap.index == gap.node.nrSegments {
+
+		gap.node = gap.NextSegment().node
+		gap.index = 0
+		return gap.nextLargeEnoughGapHelper(minSize)
+	}
+	return gap.nextLargeEnoughGapHelper(minSize)
+}
+
+// nextLargeEnoughGapHelper is the helper function used by NextLargeEnoughGap
+// to do the real recursions.
+//
+// Preconditions: gap is NOT the trailing gap of a non-leaf node.
+func (gap addrGapIterator) nextLargeEnoughGapHelper(minSize uintptr) addrGapIterator {
+
+	for gap.node != nil &&
+		(gap.node.maxGap.Get() < minSize || (!gap.node.hasChildren && gap.index == gap.node.nrSegments)) {
+		gap.node, gap.index = gap.node.parent, gap.node.parentIndex
+	}
+
+	if gap.node == nil {
+		return addrGapIterator{}
+	}
+
+	gap.index++
+	for gap.index <= gap.node.nrSegments {
+		if gap.node.hasChildren {
+			if largeEnoughGap := gap.node.children[gap.index].searchFirstLargeEnoughGap(minSize); largeEnoughGap.Ok() {
+				return largeEnoughGap
+			}
+		} else {
+			if gap.Range().Length() >= minSize {
+				return gap
+			}
+		}
+		gap.index++
+	}
+	gap.node, gap.index = gap.node.parent, gap.node.parentIndex
+	if gap.node != nil && gap.index == gap.node.nrSegments {
+
+		gap.node, gap.index = gap.node.parent, gap.node.parentIndex
+	}
+	return gap.nextLargeEnoughGapHelper(minSize)
+}
+
+// PrevLargeEnoughGap returns the iterated gap's first prev gap with larger or
+// equal length than minSize.  If not found, return a terminal gap iterator
+// (does NOT include this gap itself).
+//
+// Precondition: trackGaps must be 1.
+func (gap addrGapIterator) PrevLargeEnoughGap(minSize uintptr) addrGapIterator {
+	if addrtrackGaps != 1 {
+		panic("set is not tracking gaps")
+	}
+	if gap.node != nil && gap.node.hasChildren && gap.index == 0 {
+
+		gap.node = gap.PrevSegment().node
+		gap.index = gap.node.nrSegments
+		return gap.prevLargeEnoughGapHelper(minSize)
+	}
+	return gap.prevLargeEnoughGapHelper(minSize)
+}
+
+// prevLargeEnoughGapHelper is the helper function used by PrevLargeEnoughGap
+// to do the real recursions.
+//
+// Preconditions: gap is NOT the first gap of a non-leaf node.
+func (gap addrGapIterator) prevLargeEnoughGapHelper(minSize uintptr) addrGapIterator {
+
+	for gap.node != nil &&
+		(gap.node.maxGap.Get() < minSize || (!gap.node.hasChildren && gap.index == 0)) {
+		gap.node, gap.index = gap.node.parent, gap.node.parentIndex
+	}
+
+	if gap.node == nil {
+		return addrGapIterator{}
+	}
+
+	gap.index--
+	for gap.index >= 0 {
+		if gap.node.hasChildren {
+			if largeEnoughGap := gap.node.children[gap.index].searchLastLargeEnoughGap(minSize); largeEnoughGap.Ok() {
+				return largeEnoughGap
+			}
+		} else {
+			if gap.Range().Length() >= minSize {
+				return gap
+			}
+		}
+		gap.index--
+	}
+	gap.node, gap.index = gap.node.parent, gap.node.parentIndex
+	if gap.node != nil && gap.index == 0 {
+
+		gap.node, gap.index = gap.node.parent, gap.node.parentIndex
+	}
+	return gap.prevLargeEnoughGapHelper(minSize)
+}
+
+// segmentBeforePosition returns the predecessor segment of the position given
+// by n.children[i], which may or may not contain a child. If no such segment
+// exists, segmentBeforePosition returns a terminal iterator.
+func addrsegmentBeforePosition(n *addrnode, i int) addrIterator {
+	for i == 0 {
+		if n.parent == nil {
+			return addrIterator{}
+		}
+		n, i = n.parent, n.parentIndex
+	}
+	return addrIterator{n, i - 1}
+}
+
+// segmentAfterPosition returns the successor segment of the position given by
+// n.children[i], which may or may not contain a child. If no such segment
+// exists, segmentAfterPosition returns a terminal iterator.
+func addrsegmentAfterPosition(n *addrnode, i int) addrIterator {
+	for i == n.nrSegments {
+		if n.parent == nil {
+			return addrIterator{}
+		}
+		n, i = n.parent, n.parentIndex
+	}
+	return addrIterator{n, i}
+}
+
+func addrzeroValueSlice(slice []*objectEncodeState) {
+
+	for i := range slice {
+		addrSetFunctions{}.ClearValue(&slice[i])
+	}
+}
+
+func addrzeroNodeSlice(slice []*addrnode) {
+	for i := range slice {
+		slice[i] = nil
+	}
+}
+
+// String stringifies a Set for debugging.
+func (s *addrSet) String() string {
+	return s.root.String()
+}
+
+// String stringifies a node (and all of its children) for debugging.
+func (n *addrnode) String() string {
+	var buf bytes.Buffer
+	n.writeDebugString(&buf, "")
+	return buf.String()
+}
+
+func (n *addrnode) writeDebugString(buf *bytes.Buffer, prefix string) {
+	if n.hasChildren != (n.nrSegments > 0 && n.children[0] != nil) {
+		buf.WriteString(prefix)
+		buf.WriteString(fmt.Sprintf("WARNING: inconsistent value of hasChildren: got %v, want %v\n", n.hasChildren, !n.hasChildren))
+	}
+	for i := 0; i < n.nrSegments; i++ {
+		if child := n.children[i]; child != nil {
+			cprefix := fmt.Sprintf("%s- % 3d ", prefix, i)
+			if child.parent != n || child.parentIndex != i {
+				buf.WriteString(cprefix)
+				buf.WriteString(fmt.Sprintf("WARNING: inconsistent linkage to parent: got (%p, %d), want (%p, %d)\n", child.parent, child.parentIndex, n, i))
+			}
+			child.writeDebugString(buf, fmt.Sprintf("%s- % 3d ", prefix, i))
+		}
+		buf.WriteString(prefix)
+		if n.hasChildren {
+			if addrtrackGaps != 0 {
+				buf.WriteString(fmt.Sprintf("- % 3d: %v => %v, maxGap: %d\n", i, n.keys[i], n.values[i], n.maxGap.Get()))
+			} else {
+				buf.WriteString(fmt.Sprintf("- % 3d: %v => %v\n", i, n.keys[i], n.values[i]))
+			}
+		} else {
+			buf.WriteString(fmt.Sprintf("- % 3d: %v => %v\n", i, n.keys[i], n.values[i]))
+		}
+	}
+	if child := n.children[n.nrSegments]; child != nil {
+		child.writeDebugString(buf, fmt.Sprintf("%s- % 3d ", prefix, n.nrSegments))
+	}
+}
+
+// SegmentDataSlices represents segments from a set as slices of start, end, and
+// values. SegmentDataSlices is primarily used as an intermediate representation
+// for save/restore and the layout here is optimized for that.
+//
+// +stateify savable
+type addrSegmentDataSlices struct {
+	Start  []uintptr
+	End    []uintptr
+	Values []*objectEncodeState
+}
+
+// ExportSortedSlices returns a copy of all segments in the given set, in
+// ascending key order.
+func (s *addrSet) ExportSortedSlices() *addrSegmentDataSlices {
+	var sds addrSegmentDataSlices
+	for seg := s.FirstSegment(); seg.Ok(); seg = seg.NextSegment() {
+		sds.Start = append(sds.Start, seg.Start())
+		sds.End = append(sds.End, seg.End())
+		sds.Values = append(sds.Values, seg.Value())
+	}
+	sds.Start = sds.Start[:len(sds.Start):len(sds.Start)]
+	sds.End = sds.End[:len(sds.End):len(sds.End)]
+	sds.Values = sds.Values[:len(sds.Values):len(sds.Values)]
+	return &sds
+}
+
+// ImportSortedSlices initializes the given set from the given slice.
+//
+// Preconditions:
+// * s must be empty.
+// * sds must represent a valid set (the segments in sds must have valid
+//   lengths that do not overlap).
+// * The segments in sds must be sorted in ascending key order.
+func (s *addrSet) ImportSortedSlices(sds *addrSegmentDataSlices) error {
+	if !s.IsEmpty() {
+		return fmt.Errorf("cannot import into non-empty set %v", s)
+	}
+	gap := s.FirstGap()
+	for i := range sds.Start {
+		r := addrRange{sds.Start[i], sds.End[i]}
+		if !gap.Range().IsSupersetOf(r) {
+			return fmt.Errorf("segment overlaps a preceding segment or is incorrectly sorted: [%d, %d) => %v", sds.Start[i], sds.End[i], sds.Values[i])
+		}
+		gap = s.InsertWithoutMerging(gap, r, sds.Values[i]).NextGap()
+	}
+	return nil
+}
+
+// segmentTestCheck returns an error if s is incorrectly sorted, does not
+// contain exactly expectedSegments segments, or contains a segment which
+// fails the passed check.
+//
+// This should be used only for testing, and has been added to this package for
+// templating convenience.
+func (s *addrSet) segmentTestCheck(expectedSegments int, segFunc func(int, addrRange, *objectEncodeState) error) error {
+	havePrev := false
+	prev := uintptr(0)
+	nrSegments := 0
+	for seg := s.FirstSegment(); seg.Ok(); seg = seg.NextSegment() {
+		next := seg.Start()
+		if havePrev && prev >= next {
+			return fmt.Errorf("incorrect order: key %d (segment %d) >= key %d (segment %d)", prev, nrSegments-1, next, nrSegments)
+		}
+		if segFunc != nil {
+			if err := segFunc(nrSegments, seg.Range(), seg.Value()); err != nil {
+				return err
+			}
+		}
+		prev = next
+		havePrev = true
+		nrSegments++
+	}
+	if nrSegments != expectedSegments {
+		return fmt.Errorf("incorrect number of segments: got %d, wanted %d", nrSegments, expectedSegments)
+	}
+	return nil
+}
+
+// countSegments counts the number of segments in the set.
+//
+// Similar to Check, this should only be used for testing.
+func (s *addrSet) countSegments() (segments int) {
+	for seg := s.FirstSegment(); seg.Ok(); seg = seg.NextSegment() {
+		segments++
+	}
+	return segments
+}
+func (s *addrSet) saveRoot() *addrSegmentDataSlices {
+	return s.ExportSortedSlices()
+}
+
+func (s *addrSet) loadRoot(sds *addrSegmentDataSlices) {
+	if err := s.ImportSortedSlices(sds); err != nil {
+		panic(err)
+	}
+}
diff --git a/pkg/state/complete_list.go b/pkg/state/complete_list.go
new file mode 100644
index 0000000..4d340a1
--- /dev/null
+++ b/pkg/state/complete_list.go
@@ -0,0 +1,221 @@
+package state
+
+// ElementMapper provides an identity mapping by default.
+//
+// This can be replaced to provide a struct that maps elements to linker
+// objects, if they are not the same. An ElementMapper is not typically
+// required if: Linker is left as is, Element is left as is, or Linker and
+// Element are the same type.
+type completeElementMapper struct{}
+
+// linkerFor maps an Element to a Linker.
+//
+// This default implementation should be inlined.
+//
+//go:nosplit
+func (completeElementMapper) linkerFor(elem *objectDecodeState) *objectDecodeState { return elem }
+
+// List is an intrusive list. Entries can be added to or removed from the list
+// in O(1) time and with no additional memory allocations.
+//
+// The zero value for List is an empty list ready to use.
+//
+// To iterate over a list (where l is a List):
+//      for e := l.Front(); e != nil; e = e.Next() {
+// 		// do something with e.
+//      }
+//
+// +stateify savable
+type completeList struct {
+	head *objectDecodeState
+	tail *objectDecodeState
+}
+
+// Reset resets list l to the empty state.
+func (l *completeList) Reset() {
+	l.head = nil
+	l.tail = nil
+}
+
+// Empty returns true iff the list is empty.
+//
+//go:nosplit
+func (l *completeList) Empty() bool {
+	return l.head == nil
+}
+
+// Front returns the first element of list l or nil.
+//
+//go:nosplit
+func (l *completeList) Front() *objectDecodeState {
+	return l.head
+}
+
+// Back returns the last element of list l or nil.
+//
+//go:nosplit
+func (l *completeList) Back() *objectDecodeState {
+	return l.tail
+}
+
+// Len returns the number of elements in the list.
+//
+// NOTE: This is an O(n) operation.
+//
+//go:nosplit
+func (l *completeList) Len() (count int) {
+	for e := l.Front(); e != nil; e = (completeElementMapper{}.linkerFor(e)).Next() {
+		count++
+	}
+	return count
+}
+
+// PushFront inserts the element e at the front of list l.
+//
+//go:nosplit
+func (l *completeList) PushFront(e *objectDecodeState) {
+	linker := completeElementMapper{}.linkerFor(e)
+	linker.SetNext(l.head)
+	linker.SetPrev(nil)
+	if l.head != nil {
+		completeElementMapper{}.linkerFor(l.head).SetPrev(e)
+	} else {
+		l.tail = e
+	}
+
+	l.head = e
+}
+
+// PushBack inserts the element e at the back of list l.
+//
+//go:nosplit
+func (l *completeList) PushBack(e *objectDecodeState) {
+	linker := completeElementMapper{}.linkerFor(e)
+	linker.SetNext(nil)
+	linker.SetPrev(l.tail)
+	if l.tail != nil {
+		completeElementMapper{}.linkerFor(l.tail).SetNext(e)
+	} else {
+		l.head = e
+	}
+
+	l.tail = e
+}
+
+// PushBackList inserts list m at the end of list l, emptying m.
+//
+//go:nosplit
+func (l *completeList) PushBackList(m *completeList) {
+	if l.head == nil {
+		l.head = m.head
+		l.tail = m.tail
+	} else if m.head != nil {
+		completeElementMapper{}.linkerFor(l.tail).SetNext(m.head)
+		completeElementMapper{}.linkerFor(m.head).SetPrev(l.tail)
+
+		l.tail = m.tail
+	}
+	m.head = nil
+	m.tail = nil
+}
+
+// InsertAfter inserts e after b.
+//
+//go:nosplit
+func (l *completeList) InsertAfter(b, e *objectDecodeState) {
+	bLinker := completeElementMapper{}.linkerFor(b)
+	eLinker := completeElementMapper{}.linkerFor(e)
+
+	a := bLinker.Next()
+
+	eLinker.SetNext(a)
+	eLinker.SetPrev(b)
+	bLinker.SetNext(e)
+
+	if a != nil {
+		completeElementMapper{}.linkerFor(a).SetPrev(e)
+	} else {
+		l.tail = e
+	}
+}
+
+// InsertBefore inserts e before a.
+//
+//go:nosplit
+func (l *completeList) InsertBefore(a, e *objectDecodeState) {
+	aLinker := completeElementMapper{}.linkerFor(a)
+	eLinker := completeElementMapper{}.linkerFor(e)
+
+	b := aLinker.Prev()
+	eLinker.SetNext(a)
+	eLinker.SetPrev(b)
+	aLinker.SetPrev(e)
+
+	if b != nil {
+		completeElementMapper{}.linkerFor(b).SetNext(e)
+	} else {
+		l.head = e
+	}
+}
+
+// Remove removes e from l.
+//
+//go:nosplit
+func (l *completeList) Remove(e *objectDecodeState) {
+	linker := completeElementMapper{}.linkerFor(e)
+	prev := linker.Prev()
+	next := linker.Next()
+
+	if prev != nil {
+		completeElementMapper{}.linkerFor(prev).SetNext(next)
+	} else if l.head == e {
+		l.head = next
+	}
+
+	if next != nil {
+		completeElementMapper{}.linkerFor(next).SetPrev(prev)
+	} else if l.tail == e {
+		l.tail = prev
+	}
+
+	linker.SetNext(nil)
+	linker.SetPrev(nil)
+}
+
+// Entry is a default implementation of Linker. Users can add anonymous fields
+// of this type to their structs to make them automatically implement the
+// methods needed by List.
+//
+// +stateify savable
+type completeEntry struct {
+	next *objectDecodeState
+	prev *objectDecodeState
+}
+
+// Next returns the entry that follows e in the list.
+//
+//go:nosplit
+func (e *completeEntry) Next() *objectDecodeState {
+	return e.next
+}
+
+// Prev returns the entry that precedes e in the list.
+//
+//go:nosplit
+func (e *completeEntry) Prev() *objectDecodeState {
+	return e.prev
+}
+
+// SetNext assigns 'entry' as the entry that follows e in the list.
+//
+//go:nosplit
+func (e *completeEntry) SetNext(elem *objectDecodeState) {
+	e.next = elem
+}
+
+// SetPrev assigns 'entry' as the entry that precedes e in the list.
+//
+//go:nosplit
+func (e *completeEntry) SetPrev(elem *objectDecodeState) {
+	e.prev = elem
+}
diff --git a/pkg/state/deferred_list.go b/pkg/state/deferred_list.go
new file mode 100644
index 0000000..2753ce4
--- /dev/null
+++ b/pkg/state/deferred_list.go
@@ -0,0 +1,206 @@
+package state
+
+// List is an intrusive list. Entries can be added to or removed from the list
+// in O(1) time and with no additional memory allocations.
+//
+// The zero value for List is an empty list ready to use.
+//
+// To iterate over a list (where l is a List):
+//      for e := l.Front(); e != nil; e = e.Next() {
+// 		// do something with e.
+//      }
+//
+// +stateify savable
+type deferredList struct {
+	head *objectEncodeState
+	tail *objectEncodeState
+}
+
+// Reset resets list l to the empty state.
+func (l *deferredList) Reset() {
+	l.head = nil
+	l.tail = nil
+}
+
+// Empty returns true iff the list is empty.
+//
+//go:nosplit
+func (l *deferredList) Empty() bool {
+	return l.head == nil
+}
+
+// Front returns the first element of list l or nil.
+//
+//go:nosplit
+func (l *deferredList) Front() *objectEncodeState {
+	return l.head
+}
+
+// Back returns the last element of list l or nil.
+//
+//go:nosplit
+func (l *deferredList) Back() *objectEncodeState {
+	return l.tail
+}
+
+// Len returns the number of elements in the list.
+//
+// NOTE: This is an O(n) operation.
+//
+//go:nosplit
+func (l *deferredList) Len() (count int) {
+	for e := l.Front(); e != nil; e = (deferredMapper{}.linkerFor(e)).Next() {
+		count++
+	}
+	return count
+}
+
+// PushFront inserts the element e at the front of list l.
+//
+//go:nosplit
+func (l *deferredList) PushFront(e *objectEncodeState) {
+	linker := deferredMapper{}.linkerFor(e)
+	linker.SetNext(l.head)
+	linker.SetPrev(nil)
+	if l.head != nil {
+		deferredMapper{}.linkerFor(l.head).SetPrev(e)
+	} else {
+		l.tail = e
+	}
+
+	l.head = e
+}
+
+// PushBack inserts the element e at the back of list l.
+//
+//go:nosplit
+func (l *deferredList) PushBack(e *objectEncodeState) {
+	linker := deferredMapper{}.linkerFor(e)
+	linker.SetNext(nil)
+	linker.SetPrev(l.tail)
+	if l.tail != nil {
+		deferredMapper{}.linkerFor(l.tail).SetNext(e)
+	} else {
+		l.head = e
+	}
+
+	l.tail = e
+}
+
+// PushBackList inserts list m at the end of list l, emptying m.
+//
+//go:nosplit
+func (l *deferredList) PushBackList(m *deferredList) {
+	if l.head == nil {
+		l.head = m.head
+		l.tail = m.tail
+	} else if m.head != nil {
+		deferredMapper{}.linkerFor(l.tail).SetNext(m.head)
+		deferredMapper{}.linkerFor(m.head).SetPrev(l.tail)
+
+		l.tail = m.tail
+	}
+	m.head = nil
+	m.tail = nil
+}
+
+// InsertAfter inserts e after b.
+//
+//go:nosplit
+func (l *deferredList) InsertAfter(b, e *objectEncodeState) {
+	bLinker := deferredMapper{}.linkerFor(b)
+	eLinker := deferredMapper{}.linkerFor(e)
+
+	a := bLinker.Next()
+
+	eLinker.SetNext(a)
+	eLinker.SetPrev(b)
+	bLinker.SetNext(e)
+
+	if a != nil {
+		deferredMapper{}.linkerFor(a).SetPrev(e)
+	} else {
+		l.tail = e
+	}
+}
+
+// InsertBefore inserts e before a.
+//
+//go:nosplit
+func (l *deferredList) InsertBefore(a, e *objectEncodeState) {
+	aLinker := deferredMapper{}.linkerFor(a)
+	eLinker := deferredMapper{}.linkerFor(e)
+
+	b := aLinker.Prev()
+	eLinker.SetNext(a)
+	eLinker.SetPrev(b)
+	aLinker.SetPrev(e)
+
+	if b != nil {
+		deferredMapper{}.linkerFor(b).SetNext(e)
+	} else {
+		l.head = e
+	}
+}
+
+// Remove removes e from l.
+//
+//go:nosplit
+func (l *deferredList) Remove(e *objectEncodeState) {
+	linker := deferredMapper{}.linkerFor(e)
+	prev := linker.Prev()
+	next := linker.Next()
+
+	if prev != nil {
+		deferredMapper{}.linkerFor(prev).SetNext(next)
+	} else if l.head == e {
+		l.head = next
+	}
+
+	if next != nil {
+		deferredMapper{}.linkerFor(next).SetPrev(prev)
+	} else if l.tail == e {
+		l.tail = prev
+	}
+
+	linker.SetNext(nil)
+	linker.SetPrev(nil)
+}
+
+// Entry is a default implementation of Linker. Users can add anonymous fields
+// of this type to their structs to make them automatically implement the
+// methods needed by List.
+//
+// +stateify savable
+type deferredEntry struct {
+	next *objectEncodeState
+	prev *objectEncodeState
+}
+
+// Next returns the entry that follows e in the list.
+//
+//go:nosplit
+func (e *deferredEntry) Next() *objectEncodeState {
+	return e.next
+}
+
+// Prev returns the entry that precedes e in the list.
+//
+//go:nosplit
+func (e *deferredEntry) Prev() *objectEncodeState {
+	return e.prev
+}
+
+// SetNext assigns 'entry' as the entry that follows e in the list.
+//
+//go:nosplit
+func (e *deferredEntry) SetNext(elem *objectEncodeState) {
+	e.next = elem
+}
+
+// SetPrev assigns 'entry' as the entry that precedes e in the list.
+//
+//go:nosplit
+func (e *deferredEntry) SetPrev(elem *objectEncodeState) {
+	e.prev = elem
+}
diff --git a/pkg/sync/gate_test.go b/pkg/sync/gate_test.go
deleted file mode 100644
index 82ce02b..0000000
--- a/pkg/sync/gate_test.go
+++ /dev/null
@@ -1,129 +0,0 @@
-// 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 sync
-
-import (
-	"context"
-	"runtime"
-	"sync/atomic"
-	"testing"
-	"time"
-)
-
-func TestGateBasic(t *testing.T) {
-	var g Gate
-
-	if !g.Enter() {
-		t.Fatalf("Enter failed before Close")
-	}
-	g.Leave()
-
-	g.Close()
-	if g.Enter() {
-		t.Fatalf("Enter succeeded after Close")
-	}
-}
-
-func TestGateConcurrent(t *testing.T) {
-	// Each call to testGateConcurrentOnce tests behavior around a single call
-	// to Gate.Close, so run many short tests to increase the probability of
-	// flushing out any issues.
-	totalTime := 5 * time.Second
-	timePerTest := 20 * time.Millisecond
-	numTests := int(totalTime / timePerTest)
-	for i := 0; i < numTests; i++ {
-		testGateConcurrentOnce(t, timePerTest)
-	}
-}
-
-func testGateConcurrentOnce(t *testing.T, d time.Duration) {
-	const numGoroutines = 1000
-
-	ctx, cancel := context.WithCancel(context.Background())
-	var wg WaitGroup
-	defer func() {
-		cancel()
-		wg.Wait()
-	}()
-
-	var g Gate
-	closeState := int32(0) // set to 1 before g.Close() and 2 after it returns
-
-	// Start a large number of goroutines that repeatedly attempt to enter the
-	// gate and get the expected result.
-	for i := 0; i < numGoroutines; i++ {
-		wg.Add(1)
-		go func() {
-			defer wg.Done()
-			for ctx.Err() == nil {
-				closedBeforeEnter := atomic.LoadInt32(&closeState) == 2
-				if g.Enter() {
-					closedBeforeLeave := atomic.LoadInt32(&closeState) == 2
-					g.Leave()
-					if closedBeforeEnter {
-						t.Errorf("Enter succeeded after Close")
-						return
-					}
-					if closedBeforeLeave {
-						t.Errorf("Close returned before Leave")
-						return
-					}
-				} else {
-					if atomic.LoadInt32(&closeState) == 0 {
-						t.Errorf("Enter failed before Close")
-						return
-					}
-				}
-				// Go does not preempt busy loops until Go 1.14.
-				runtime.Gosched()
-			}
-		}()
-	}
-
-	// Allow goroutines to enter the gate successfully for half of the test's
-	// duration, then close the gate and allow goroutines to fail to enter the
-	// gate for the remaining half.
-	time.Sleep(d / 2)
-	atomic.StoreInt32(&closeState, 1)
-	g.Close()
-	atomic.StoreInt32(&closeState, 2)
-	time.Sleep(d / 2)
-}
-
-func BenchmarkGateEnterLeave(b *testing.B) {
-	var g Gate
-	for i := 0; i < b.N; i++ {
-		g.Enter()
-		g.Leave()
-	}
-}
-
-func BenchmarkGateClose(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		var g Gate
-		g.Close()
-	}
-}
-
-func BenchmarkGateEnterLeaveAsyncClose(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		var g Gate
-		g.Enter()
-		go func() {
-			g.Leave()
-		}()
-		g.Close()
-	}
-}
diff --git a/pkg/sync/generic_atomicptr_unsafe.go b/pkg/sync/generic_atomicptr_unsafe.go
deleted file mode 100644
index 82b6df1..0000000
--- a/pkg/sync/generic_atomicptr_unsafe.go
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2019 The gVisor Authors.
-//
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package seqatomic doesn't exist. This file must be instantiated using the
-// go_template_instance rule in tools/go_generics/defs.bzl.
-package seqatomic
-
-import (
-	"sync/atomic"
-	"unsafe"
-)
-
-// Value is a required type parameter.
-type Value struct{}
-
-// An AtomicPtr is a pointer to a value of type Value that can be atomically
-// loaded and stored. The zero value of an AtomicPtr represents nil.
-//
-// Note that copying AtomicPtr by value performs a non-atomic read of the
-// stored pointer, which is unsafe if Store() can be called concurrently; in
-// this case, do `dst.Store(src.Load())` instead.
-//
-// +stateify savable
-type AtomicPtr struct {
-	ptr unsafe.Pointer `state:".(*Value)"`
-}
-
-func (p *AtomicPtr) savePtr() *Value {
-	return p.Load()
-}
-
-func (p *AtomicPtr) loadPtr(v *Value) {
-	p.Store(v)
-}
-
-// Load returns the value set by the most recent Store. It returns nil if there
-// has been no previous call to Store.
-func (p *AtomicPtr) Load() *Value {
-	return (*Value)(atomic.LoadPointer(&p.ptr))
-}
-
-// Store sets the value returned by Load to x.
-func (p *AtomicPtr) Store(x *Value) {
-	atomic.StorePointer(&p.ptr, (unsafe.Pointer)(x))
-}
diff --git a/pkg/sync/generic_atomicptrmap_unsafe.go b/pkg/sync/generic_atomicptrmap_unsafe.go
deleted file mode 100644
index 3e98cb3..0000000
--- a/pkg/sync/generic_atomicptrmap_unsafe.go
+++ /dev/null
@@ -1,500 +0,0 @@
-// Copyright 2020 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 atomicptrmap doesn't exist. This file must be instantiated using the
-// go_template_instance rule in tools/go_generics/defs.bzl.
-package atomicptrmap
-
-import (
-	"sync/atomic"
-	"unsafe"
-
-	"gvisor.dev/gvisor/pkg/gohacks"
-	"gvisor.dev/gvisor/pkg/sync"
-)
-
-// Key is a required type parameter.
-type Key struct{}
-
-// Value is a required type parameter.
-type Value struct{}
-
-const (
-	// ShardOrder is an optional parameter specifying the base-2 log of the
-	// number of shards per AtomicPtrMap. Higher values of ShardOrder reduce
-	// unnecessary synchronization between unrelated concurrent operations,
-	// improving performance for write-heavy workloads, but increase memory
-	// usage for small maps.
-	ShardOrder = 0
-)
-
-// Hasher is an optional type parameter. If Hasher is provided, it must define
-// the Init and Hash methods. One Hasher will be shared by all AtomicPtrMaps.
-type Hasher struct {
-	defaultHasher
-}
-
-// defaultHasher is the default Hasher. This indirection exists because
-// defaultHasher must exist even if a custom Hasher is provided, to prevent the
-// Go compiler from complaining about defaultHasher's unused imports.
-type defaultHasher struct {
-	fn   func(unsafe.Pointer, uintptr) uintptr
-	seed uintptr
-}
-
-// Init initializes the Hasher.
-func (h *defaultHasher) Init() {
-	h.fn = sync.MapKeyHasher(map[Key]*Value(nil))
-	h.seed = sync.RandUintptr()
-}
-
-// Hash returns the hash value for the given Key.
-func (h *defaultHasher) Hash(key Key) uintptr {
-	return h.fn(gohacks.Noescape(unsafe.Pointer(&key)), h.seed)
-}
-
-var hasher Hasher
-
-func init() {
-	hasher.Init()
-}
-
-// An AtomicPtrMap maps Keys to non-nil pointers to Values. AtomicPtrMap are
-// safe for concurrent use from multiple goroutines without additional
-// synchronization.
-//
-// The zero value of AtomicPtrMap is empty (maps all Keys to nil) and ready for
-// use. AtomicPtrMaps must not be copied after first use.
-//
-// sync.Map may be faster than AtomicPtrMap if most operations on the map are
-// concurrent writes to a fixed set of keys. AtomicPtrMap is usually faster in
-// other circumstances.
-type AtomicPtrMap struct {
-	// AtomicPtrMap is implemented as a hash table with the following
-	// properties:
-	//
-	// * Collisions are resolved with quadratic probing. Of the two major
-	// alternatives, Robin Hood linear probing makes it difficult for writers
-	// to execute in parallel, and bucketing is less effective in Go due to
-	// lack of SIMD.
-	//
-	// * The table is optionally divided into shards indexed by hash to further
-	// reduce unnecessary synchronization.
-
-	shards [1 << ShardOrder]apmShard
-}
-
-func (m *AtomicPtrMap) shard(hash uintptr) *apmShard {
-	// Go defines right shifts >= width of shifted unsigned operand as 0, so
-	// this is correct even if ShardOrder is 0 (although nogo complains because
-	// nogo is dumb).
-	const indexLSB = unsafe.Sizeof(uintptr(0))*8 - ShardOrder
-	index := hash >> indexLSB
-	return (*apmShard)(unsafe.Pointer(uintptr(unsafe.Pointer(&m.shards)) + (index * unsafe.Sizeof(apmShard{}))))
-}
-
-type apmShard struct {
-	apmShardMutationData
-	_ [apmShardMutationDataPadding]byte
-	apmShardLookupData
-	_ [apmShardLookupDataPadding]byte
-}
-
-type apmShardMutationData struct {
-	dirtyMu  sync.Mutex // serializes slot transitions out of empty
-	dirty    uintptr    // # slots with val != nil
-	count    uintptr    // # slots with val != nil and val != tombstone()
-	rehashMu sync.Mutex // serializes rehashing
-}
-
-type apmShardLookupData struct {
-	seq   sync.SeqCount  // allows atomic reads of slots+mask
-	slots unsafe.Pointer // [mask+1]slot or nil; protected by rehashMu/seq
-	mask  uintptr        // always (a power of 2) - 1; protected by rehashMu/seq
-}
-
-const (
-	cacheLineBytes = 64
-	// Cache line padding is enabled if sharding is.
-	apmEnablePadding = (ShardOrder + 63) >> 6 // 0 if ShardOrder == 0, 1 otherwise
-	// The -1 and +1 below are required to ensure that if unsafe.Sizeof(T) %
-	// cacheLineBytes == 0, then padding is 0 (rather than cacheLineBytes).
-	apmShardMutationDataRequiredPadding = cacheLineBytes - (((unsafe.Sizeof(apmShardMutationData{}) - 1) % cacheLineBytes) + 1)
-	apmShardMutationDataPadding         = apmEnablePadding * apmShardMutationDataRequiredPadding
-	apmShardLookupDataRequiredPadding   = cacheLineBytes - (((unsafe.Sizeof(apmShardLookupData{}) - 1) % cacheLineBytes) + 1)
-	apmShardLookupDataPadding           = apmEnablePadding * apmShardLookupDataRequiredPadding
-
-	// These define fractional thresholds for when apmShard.rehash() is called
-	// (i.e. the load factor) and when it rehases to a larger table
-	// respectively. They are chosen such that the rehash threshold = the
-	// expansion threshold + 1/2, so that when reuse of deleted slots is rare
-	// or non-existent, rehashing occurs after the insertion of at least 1/2
-	// the table's size in new entries, which is acceptably infrequent.
-	apmRehashThresholdNum    = 2
-	apmRehashThresholdDen    = 3
-	apmExpansionThresholdNum = 1
-	apmExpansionThresholdDen = 6
-)
-
-type apmSlot struct {
-	// slot states are indicated by val:
-	//
-	// * Empty: val == nil; key is meaningless. May transition to full or
-	// evacuated with dirtyMu locked.
-	//
-	// * Full: val != nil, tombstone(), or evacuated(); key is immutable. val
-	// is the Value mapped to key. May transition to deleted or evacuated.
-	//
-	// * Deleted: val == tombstone(); key is still immutable. key is mapped to
-	// no Value. May transition to full or evacuated.
-	//
-	// * Evacuated: val == evacuated(); key is immutable. Set by rehashing on
-	// slots that have already been moved, requiring readers to wait for
-	// rehashing to complete and use the new table. Terminal state.
-	//
-	// Note that once val is non-nil, it cannot become nil again. That is, the
-	// transition from empty to non-empty is irreversible for a given slot;
-	// the only way to create more empty slots is by rehashing.
-	val unsafe.Pointer
-	key Key
-}
-
-func apmSlotAt(slots unsafe.Pointer, pos uintptr) *apmSlot {
-	return (*apmSlot)(unsafe.Pointer(uintptr(slots) + pos*unsafe.Sizeof(apmSlot{})))
-}
-
-var tombstoneObj byte
-
-func tombstone() unsafe.Pointer {
-	return unsafe.Pointer(&tombstoneObj)
-}
-
-var evacuatedObj byte
-
-func evacuated() unsafe.Pointer {
-	return unsafe.Pointer(&evacuatedObj)
-}
-
-// Load returns the Value stored in m for key.
-func (m *AtomicPtrMap) Load(key Key) *Value {
-	hash := hasher.Hash(key)
-	shard := m.shard(hash)
-
-retry:
-	epoch := shard.seq.BeginRead()
-	slots := atomic.LoadPointer(&shard.slots)
-	mask := atomic.LoadUintptr(&shard.mask)
-	if !shard.seq.ReadOk(epoch) {
-		goto retry
-	}
-	if slots == nil {
-		return nil
-	}
-
-	i := hash & mask
-	inc := uintptr(1)
-	for {
-		slot := apmSlotAt(slots, i)
-		slotVal := atomic.LoadPointer(&slot.val)
-		if slotVal == nil {
-			// Empty slot; end of probe sequence.
-			return nil
-		}
-		if slotVal == evacuated() {
-			// Racing with rehashing.
-			goto retry
-		}
-		if slot.key == key {
-			if slotVal == tombstone() {
-				return nil
-			}
-			return (*Value)(slotVal)
-		}
-		i = (i + inc) & mask
-		inc++
-	}
-}
-
-// Store stores the Value val for key.
-func (m *AtomicPtrMap) Store(key Key, val *Value) {
-	m.maybeCompareAndSwap(key, false, nil, val)
-}
-
-// Swap stores the Value val for key and returns the previously-mapped Value.
-func (m *AtomicPtrMap) Swap(key Key, val *Value) *Value {
-	return m.maybeCompareAndSwap(key, false, nil, val)
-}
-
-// CompareAndSwap checks that the Value stored for key is oldVal; if it is, it
-// stores the Value newVal for key. CompareAndSwap returns the previous Value
-// stored for key, whether or not it stores newVal.
-func (m *AtomicPtrMap) CompareAndSwap(key Key, oldVal, newVal *Value) *Value {
-	return m.maybeCompareAndSwap(key, true, oldVal, newVal)
-}
-
-func (m *AtomicPtrMap) maybeCompareAndSwap(key Key, compare bool, typedOldVal, typedNewVal *Value) *Value {
-	hash := hasher.Hash(key)
-	shard := m.shard(hash)
-	oldVal := tombstone()
-	if typedOldVal != nil {
-		oldVal = unsafe.Pointer(typedOldVal)
-	}
-	newVal := tombstone()
-	if typedNewVal != nil {
-		newVal = unsafe.Pointer(typedNewVal)
-	}
-
-retry:
-	epoch := shard.seq.BeginRead()
-	slots := atomic.LoadPointer(&shard.slots)
-	mask := atomic.LoadUintptr(&shard.mask)
-	if !shard.seq.ReadOk(epoch) {
-		goto retry
-	}
-	if slots == nil {
-		if (compare && oldVal != tombstone()) || newVal == tombstone() {
-			return nil
-		}
-		// Need to allocate a table before insertion.
-		shard.rehash(nil)
-		goto retry
-	}
-
-	i := hash & mask
-	inc := uintptr(1)
-	for {
-		slot := apmSlotAt(slots, i)
-		slotVal := atomic.LoadPointer(&slot.val)
-		if slotVal == nil {
-			if (compare && oldVal != tombstone()) || newVal == tombstone() {
-				return nil
-			}
-			// Try to grab this slot for ourselves.
-			shard.dirtyMu.Lock()
-			slotVal = atomic.LoadPointer(&slot.val)
-			if slotVal == nil {
-				// Check if we need to rehash before dirtying a slot.
-				if dirty, capacity := shard.dirty+1, mask+1; dirty*apmRehashThresholdDen >= capacity*apmRehashThresholdNum {
-					shard.dirtyMu.Unlock()
-					shard.rehash(slots)
-					goto retry
-				}
-				slot.key = key
-				atomic.StorePointer(&slot.val, newVal) // transitions slot to full
-				shard.dirty++
-				atomic.AddUintptr(&shard.count, 1)
-				shard.dirtyMu.Unlock()
-				return nil
-			}
-			// Raced with another store; the slot is no longer empty. Continue
-			// with the new value of slotVal since we may have raced with
-			// another store of key.
-			shard.dirtyMu.Unlock()
-		}
-		if slotVal == evacuated() {
-			// Racing with rehashing.
-			goto retry
-		}
-		if slot.key == key {
-			// We're reusing an existing slot, so rehashing isn't necessary.
-			for {
-				if (compare && oldVal != slotVal) || newVal == slotVal {
-					if slotVal == tombstone() {
-						return nil
-					}
-					return (*Value)(slotVal)
-				}
-				if atomic.CompareAndSwapPointer(&slot.val, slotVal, newVal) {
-					if slotVal == tombstone() {
-						atomic.AddUintptr(&shard.count, 1)
-						return nil
-					}
-					if newVal == tombstone() {
-						atomic.AddUintptr(&shard.count, ^uintptr(0) /* -1 */)
-					}
-					return (*Value)(slotVal)
-				}
-				slotVal = atomic.LoadPointer(&slot.val)
-				if slotVal == evacuated() {
-					goto retry
-				}
-			}
-		}
-		// This produces a triangular number sequence of offsets from the
-		// initially-probed position.
-		i = (i + inc) & mask
-		inc++
-	}
-}
-
-// rehash is marked nosplit to avoid preemption during table copying.
-//go:nosplit
-func (shard *apmShard) rehash(oldSlots unsafe.Pointer) {
-	shard.rehashMu.Lock()
-	defer shard.rehashMu.Unlock()
-
-	if shard.slots != oldSlots {
-		// Raced with another call to rehash().
-		return
-	}
-
-	// Determine the size of the new table. Constraints:
-	//
-	// * The size of the table must be a power of two to ensure that every slot
-	// is visitable by every probe sequence under quadratic probing with
-	// triangular numbers.
-	//
-	// * The size of the table cannot decrease because even if shard.count is
-	// currently smaller than shard.dirty, concurrent stores that reuse
-	// existing slots can drive shard.count back up to a maximum of
-	// shard.dirty.
-	newSize := uintptr(8) // arbitrary initial size
-	if oldSlots != nil {
-		oldSize := shard.mask + 1
-		newSize = oldSize
-		if count := atomic.LoadUintptr(&shard.count) + 1; count*apmExpansionThresholdDen > oldSize*apmExpansionThresholdNum {
-			newSize *= 2
-		}
-	}
-
-	// Allocate the new table.
-	newSlotsSlice := make([]apmSlot, newSize)
-	newSlotsHeader := (*gohacks.SliceHeader)(unsafe.Pointer(&newSlotsSlice))
-	newSlots := newSlotsHeader.Data
-	newMask := newSize - 1
-
-	// Start a writer critical section now so that racing users of the old
-	// table that observe evacuated() wait for the new table. (But lock dirtyMu
-	// first since doing so may block, which we don't want to do during the
-	// writer critical section.)
-	shard.dirtyMu.Lock()
-	shard.seq.BeginWrite()
-
-	if oldSlots != nil {
-		realCount := uintptr(0)
-		// Copy old entries to the new table.
-		oldMask := shard.mask
-		for i := uintptr(0); i <= oldMask; i++ {
-			oldSlot := apmSlotAt(oldSlots, i)
-			val := atomic.SwapPointer(&oldSlot.val, evacuated())
-			if val == nil || val == tombstone() {
-				continue
-			}
-			hash := hasher.Hash(oldSlot.key)
-			j := hash & newMask
-			inc := uintptr(1)
-			for {
-				newSlot := apmSlotAt(newSlots, j)
-				if newSlot.val == nil {
-					newSlot.val = val
-					newSlot.key = oldSlot.key
-					break
-				}
-				j = (j + inc) & newMask
-				inc++
-			}
-			realCount++
-		}
-		// Update dirty to reflect that tombstones were not copied to the new
-		// table. Use realCount since a concurrent mutator may not have updated
-		// shard.count yet.
-		shard.dirty = realCount
-	}
-
-	// Switch to the new table.
-	atomic.StorePointer(&shard.slots, newSlots)
-	atomic.StoreUintptr(&shard.mask, newMask)
-
-	shard.seq.EndWrite()
-	shard.dirtyMu.Unlock()
-}
-
-// Range invokes f on each Key-Value pair stored in m. If any call to f returns
-// false, Range stops iteration and returns.
-//
-// Range does not necessarily correspond to any consistent snapshot of the
-// Map's contents: no Key will be visited more than once, but if the Value for
-// any Key is stored or deleted concurrently, Range may reflect any mapping for
-// that Key from any point during the Range call.
-//
-// f must not call other methods on m.
-func (m *AtomicPtrMap) Range(f func(key Key, val *Value) bool) {
-	for si := 0; si < len(m.shards); si++ {
-		shard := &m.shards[si]
-		if !shard.doRange(f) {
-			return
-		}
-	}
-}
-
-func (shard *apmShard) doRange(f func(key Key, val *Value) bool) bool {
-	// We have to lock rehashMu because if we handled races with rehashing by
-	// retrying, f could see the same key twice.
-	shard.rehashMu.Lock()
-	defer shard.rehashMu.Unlock()
-	slots := shard.slots
-	if slots == nil {
-		return true
-	}
-	mask := shard.mask
-	for i := uintptr(0); i <= mask; i++ {
-		slot := apmSlotAt(slots, i)
-		slotVal := atomic.LoadPointer(&slot.val)
-		if slotVal == nil || slotVal == tombstone() {
-			continue
-		}
-		if !f(slot.key, (*Value)(slotVal)) {
-			return false
-		}
-	}
-	return true
-}
-
-// RangeRepeatable is like Range, but:
-//
-// * RangeRepeatable may visit the same Key multiple times in the presence of
-// concurrent mutators, possibly passing different Values to f in different
-// calls.
-//
-// * It is safe for f to call other methods on m.
-func (m *AtomicPtrMap) RangeRepeatable(f func(key Key, val *Value) bool) {
-	for si := 0; si < len(m.shards); si++ {
-		shard := &m.shards[si]
-
-	retry:
-		epoch := shard.seq.BeginRead()
-		slots := atomic.LoadPointer(&shard.slots)
-		mask := atomic.LoadUintptr(&shard.mask)
-		if !shard.seq.ReadOk(epoch) {
-			goto retry
-		}
-		if slots == nil {
-			continue
-		}
-
-		for i := uintptr(0); i <= mask; i++ {
-			slot := apmSlotAt(slots, i)
-			slotVal := atomic.LoadPointer(&slot.val)
-			if slotVal == evacuated() {
-				goto retry
-			}
-			if slotVal == nil || slotVal == tombstone() {
-				continue
-			}
-			if !f(slot.key, (*Value)(slotVal)) {
-				return
-			}
-		}
-	}
-}
diff --git a/pkg/sync/generic_seqatomic_unsafe.go b/pkg/sync/generic_seqatomic_unsafe.go
deleted file mode 100644
index 82b676a..0000000
--- a/pkg/sync/generic_seqatomic_unsafe.go
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2019 The gVisor Authors.
-//
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package seqatomic doesn't exist. This file must be instantiated using the
-// go_template_instance rule in tools/go_generics/defs.bzl.
-package seqatomic
-
-import (
-	"unsafe"
-
-	"gvisor.dev/gvisor/pkg/sync"
-)
-
-// Value is a required type parameter.
-type Value struct{}
-
-// SeqAtomicLoad returns a copy of *ptr, ensuring that the read does not race
-// with any writer critical sections in seq.
-//
-//go:nosplit
-func SeqAtomicLoad(seq *sync.SeqCount, ptr *Value) Value {
-	for {
-		if val, ok := SeqAtomicTryLoad(seq, seq.BeginRead(), ptr); ok {
-			return val
-		}
-	}
-}
-
-// SeqAtomicTryLoad returns a copy of *ptr while in a reader critical section
-// in seq initiated by a call to seq.BeginRead() that returned epoch. If the
-// read would race with a writer critical section, SeqAtomicTryLoad returns
-// (unspecified, false).
-//
-//go:nosplit
-func SeqAtomicTryLoad(seq *sync.SeqCount, epoch sync.SeqCountEpoch, ptr *Value) (val Value, ok bool) {
-	if sync.RaceEnabled {
-		// runtime.RaceDisable() doesn't actually stop the race detector, so it
-		// can't help us here. Instead, call runtime.memmove directly, which is
-		// not instrumented by the race detector.
-		sync.Memmove(unsafe.Pointer(&val), unsafe.Pointer(ptr), unsafe.Sizeof(val))
-	} else {
-		// This is ~40% faster for short reads than going through memmove.
-		val = *ptr
-	}
-	ok = seq.ReadOk(epoch)
-	return
-}
diff --git a/pkg/sync/mutex_test.go b/pkg/sync/mutex_test.go
deleted file mode 100644
index 4fb51a8..0000000
--- a/pkg/sync/mutex_test.go
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2019 The gVisor Authors.
-//
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package sync
-
-import (
-	"sync"
-	"testing"
-	"unsafe"
-)
-
-// TestStructSize verifies that syncMutex's size hasn't drifted from the
-// standard library's version.
-//
-// The correctness of this package relies on these remaining in sync.
-func TestStructSize(t *testing.T) {
-	const (
-		got  = unsafe.Sizeof(syncMutex{})
-		want = unsafe.Sizeof(sync.Mutex{})
-	)
-	if got != want {
-		t.Errorf("got sizeof(syncMutex) = %d, want = sizeof(sync.Mutex) = %d", got, want)
-	}
-}
-
-// TestFieldValues verifies that the semantics of syncMutex.state from the
-// standard library's implementation.
-//
-// The correctness of this package relies on these remaining in sync.
-func TestFieldValues(t *testing.T) {
-	var m Mutex
-	m.Lock()
-	if got := *m.m.state(); got != mutexLocked {
-		t.Errorf("got locked sync.Mutex.state = %d, want = %d", got, mutexLocked)
-	}
-	m.Unlock()
-	if got := *m.m.state(); got != mutexUnlocked {
-		t.Errorf("got unlocked sync.Mutex.state = %d, want = %d", got, mutexUnlocked)
-	}
-}
-
-func TestDoubleTryLock(t *testing.T) {
-	var m Mutex
-	if !m.TryLock() {
-		t.Fatal("failed to aquire lock")
-	}
-	if m.TryLock() {
-		t.Fatal("unexpectedly succeeded in aquiring locked mutex")
-	}
-}
-
-func TestTryLockAfterLock(t *testing.T) {
-	var m Mutex
-	m.Lock()
-	if m.TryLock() {
-		t.Fatal("unexpectedly succeeded in aquiring locked mutex")
-	}
-}
-
-func TestTryLockUnlock(t *testing.T) {
-	var m Mutex
-	if !m.TryLock() {
-		t.Fatal("failed to aquire lock")
-	}
-	m.Unlock()
-	if !m.TryLock() {
-		t.Fatal("failed to aquire lock after unlock")
-	}
-}
diff --git a/pkg/sync/rwmutex_test.go b/pkg/sync/rwmutex_test.go
deleted file mode 100644
index 5ca96d1..0000000
--- a/pkg/sync/rwmutex_test.go
+++ /dev/null
@@ -1,205 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Copyright 2019 The gVisor Authors.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// GOMAXPROCS=10 go test
-
-// Copy/pasted from the standard library's sync/rwmutex_test.go, except for the
-// addition of downgradingWriter and the renaming of num_iterations to
-// numIterations to shut up Golint.
-
-package sync
-
-import (
-	"fmt"
-	"runtime"
-	"sync/atomic"
-	"testing"
-)
-
-func parallelReader(m *RWMutex, clocked, cunlock, cdone chan bool) {
-	m.RLock()
-	clocked <- true
-	<-cunlock
-	m.RUnlock()
-	cdone <- true
-}
-
-func doTestParallelReaders(numReaders, gomaxprocs int) {
-	runtime.GOMAXPROCS(gomaxprocs)
-	var m RWMutex
-	clocked := make(chan bool)
-	cunlock := make(chan bool)
-	cdone := make(chan bool)
-	for i := 0; i < numReaders; i++ {
-		go parallelReader(&m, clocked, cunlock, cdone)
-	}
-	// Wait for all parallel RLock()s to succeed.
-	for i := 0; i < numReaders; i++ {
-		<-clocked
-	}
-	for i := 0; i < numReaders; i++ {
-		cunlock <- true
-	}
-	// Wait for the goroutines to finish.
-	for i := 0; i < numReaders; i++ {
-		<-cdone
-	}
-}
-
-func TestParallelReaders(t *testing.T) {
-	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(-1))
-	doTestParallelReaders(1, 4)
-	doTestParallelReaders(3, 4)
-	doTestParallelReaders(4, 2)
-}
-
-func reader(rwm *RWMutex, numIterations int, activity *int32, cdone chan bool) {
-	for i := 0; i < numIterations; i++ {
-		rwm.RLock()
-		n := atomic.AddInt32(activity, 1)
-		if n < 1 || n >= 10000 {
-			panic(fmt.Sprintf("wlock(%d)\n", n))
-		}
-		for i := 0; i < 100; i++ {
-		}
-		atomic.AddInt32(activity, -1)
-		rwm.RUnlock()
-	}
-	cdone <- true
-}
-
-func writer(rwm *RWMutex, numIterations int, activity *int32, cdone chan bool) {
-	for i := 0; i < numIterations; i++ {
-		rwm.Lock()
-		n := atomic.AddInt32(activity, 10000)
-		if n != 10000 {
-			panic(fmt.Sprintf("wlock(%d)\n", n))
-		}
-		for i := 0; i < 100; i++ {
-		}
-		atomic.AddInt32(activity, -10000)
-		rwm.Unlock()
-	}
-	cdone <- true
-}
-
-func downgradingWriter(rwm *RWMutex, numIterations int, activity *int32, cdone chan bool) {
-	for i := 0; i < numIterations; i++ {
-		rwm.Lock()
-		n := atomic.AddInt32(activity, 10000)
-		if n != 10000 {
-			panic(fmt.Sprintf("wlock(%d)\n", n))
-		}
-		for i := 0; i < 100; i++ {
-		}
-		atomic.AddInt32(activity, -10000)
-		rwm.DowngradeLock()
-		n = atomic.AddInt32(activity, 1)
-		if n < 1 || n >= 10000 {
-			panic(fmt.Sprintf("wlock(%d)\n", n))
-		}
-		for i := 0; i < 100; i++ {
-		}
-		atomic.AddInt32(activity, -1)
-		rwm.RUnlock()
-	}
-	cdone <- true
-}
-
-func HammerDowngradableRWMutex(gomaxprocs, numReaders, numIterations int) {
-	runtime.GOMAXPROCS(gomaxprocs)
-	// Number of active readers + 10000 * number of active writers.
-	var activity int32
-	var rwm RWMutex
-	cdone := make(chan bool)
-	go writer(&rwm, numIterations, &activity, cdone)
-	go downgradingWriter(&rwm, numIterations, &activity, cdone)
-	var i int
-	for i = 0; i < numReaders/2; i++ {
-		go reader(&rwm, numIterations, &activity, cdone)
-	}
-	go writer(&rwm, numIterations, &activity, cdone)
-	go downgradingWriter(&rwm, numIterations, &activity, cdone)
-	for ; i < numReaders; i++ {
-		go reader(&rwm, numIterations, &activity, cdone)
-	}
-	// Wait for the 4 writers and all readers to finish.
-	for i := 0; i < 4+numReaders; i++ {
-		<-cdone
-	}
-}
-
-func TestDowngradableRWMutex(t *testing.T) {
-	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(-1))
-	n := 1000
-	if testing.Short() {
-		n = 5
-	}
-	HammerDowngradableRWMutex(1, 1, n)
-	HammerDowngradableRWMutex(1, 3, n)
-	HammerDowngradableRWMutex(1, 10, n)
-	HammerDowngradableRWMutex(4, 1, n)
-	HammerDowngradableRWMutex(4, 3, n)
-	HammerDowngradableRWMutex(4, 10, n)
-	HammerDowngradableRWMutex(10, 1, n)
-	HammerDowngradableRWMutex(10, 3, n)
-	HammerDowngradableRWMutex(10, 10, n)
-	HammerDowngradableRWMutex(10, 5, n)
-}
-
-func TestRWDoubleTryLock(t *testing.T) {
-	var rwm RWMutex
-	if !rwm.TryLock() {
-		t.Fatal("failed to aquire lock")
-	}
-	if rwm.TryLock() {
-		t.Fatal("unexpectedly succeeded in aquiring locked mutex")
-	}
-}
-
-func TestRWTryLockAfterLock(t *testing.T) {
-	var rwm RWMutex
-	rwm.Lock()
-	if rwm.TryLock() {
-		t.Fatal("unexpectedly succeeded in aquiring locked mutex")
-	}
-}
-
-func TestRWTryLockUnlock(t *testing.T) {
-	var rwm RWMutex
-	if !rwm.TryLock() {
-		t.Fatal("failed to aquire lock")
-	}
-	rwm.Unlock()
-	if !rwm.TryLock() {
-		t.Fatal("failed to aquire lock after unlock")
-	}
-}
-
-func TestTryRLockAfterLock(t *testing.T) {
-	var rwm RWMutex
-	rwm.Lock()
-	if rwm.TryRLock() {
-		t.Fatal("unexpectedly succeeded in aquiring locked mutex")
-	}
-}
-
-func TestTryLockAfterRLock(t *testing.T) {
-	var rwm RWMutex
-	rwm.RLock()
-	if rwm.TryLock() {
-		t.Fatal("unexpectedly succeeded in aquiring locked mutex")
-	}
-}
-
-func TestDoubleTryRLock(t *testing.T) {
-	var rwm RWMutex
-	if !rwm.TryRLock() {
-		t.Fatal("failed to aquire lock")
-	}
-	if !rwm.TryRLock() {
-		t.Fatal("failed to read aquire read locked lock")
-	}
-}
diff --git a/pkg/sync/seqcount_test.go b/pkg/sync/seqcount_test.go
deleted file mode 100644
index 3f5592e..0000000
--- a/pkg/sync/seqcount_test.go
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright 2019 The gVisor Authors.
-//
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package sync
-
-import (
-	"testing"
-	"time"
-)
-
-func TestSeqCountWriteUncontended(t *testing.T) {
-	var seq SeqCount
-	seq.BeginWrite()
-	seq.EndWrite()
-}
-
-func TestSeqCountReadUncontended(t *testing.T) {
-	var seq SeqCount
-	epoch := seq.BeginRead()
-	if !seq.ReadOk(epoch) {
-		t.Errorf("ReadOk: got false, wanted true")
-	}
-}
-
-func TestSeqCountBeginReadAfterWrite(t *testing.T) {
-	var seq SeqCount
-	var data int32
-	const want = 1
-	seq.BeginWrite()
-	data = want
-	seq.EndWrite()
-	epoch := seq.BeginRead()
-	if data != want {
-		t.Errorf("Reader: got %v, wanted %v", data, want)
-	}
-	if !seq.ReadOk(epoch) {
-		t.Errorf("ReadOk: got false, wanted true")
-	}
-}
-
-func TestSeqCountBeginReadDuringWrite(t *testing.T) {
-	var seq SeqCount
-	var data int
-	const want = 1
-	seq.BeginWrite()
-	go func() {
-		time.Sleep(time.Second)
-		data = want
-		seq.EndWrite()
-	}()
-	epoch := seq.BeginRead()
-	if data != want {
-		t.Errorf("Reader: got %v, wanted %v", data, want)
-	}
-	if !seq.ReadOk(epoch) {
-		t.Errorf("ReadOk: got false, wanted true")
-	}
-}
-
-func TestSeqCountReadOkAfterWrite(t *testing.T) {
-	var seq SeqCount
-	epoch := seq.BeginRead()
-	seq.BeginWrite()
-	seq.EndWrite()
-	if seq.ReadOk(epoch) {
-		t.Errorf("ReadOk: got true, wanted false")
-	}
-}
-
-func TestSeqCountReadOkDuringWrite(t *testing.T) {
-	var seq SeqCount
-	epoch := seq.BeginRead()
-	seq.BeginWrite()
-	if seq.ReadOk(epoch) {
-		t.Errorf("ReadOk: got true, wanted false")
-	}
-	seq.EndWrite()
-}
-
-func BenchmarkSeqCountWriteUncontended(b *testing.B) {
-	var seq SeqCount
-	for i := 0; i < b.N; i++ {
-		seq.BeginWrite()
-		seq.EndWrite()
-	}
-}
-
-func BenchmarkSeqCountReadUncontended(b *testing.B) {
-	var seq SeqCount
-	b.RunParallel(func(pb *testing.PB) {
-		for pb.Next() {
-			epoch := seq.BeginRead()
-			if !seq.ReadOk(epoch) {
-				b.Fatalf("ReadOk: got false, wanted true")
-			}
-		}
-	})
-}
diff --git a/pkg/tcpip/buffer/buffer_state_autogen.go b/pkg/tcpip/buffer/buffer_state_autogen.go
new file mode 100644
index 0000000..51bfbff
--- /dev/null
+++ b/pkg/tcpip/buffer/buffer_state_autogen.go
@@ -0,0 +1,39 @@
+// automatically generated by stateify.
+
+package buffer
+
+import (
+	"gvisor.dev/gvisor/pkg/state"
+)
+
+func (vv *VectorisedView) StateTypeName() string {
+	return "pkg/tcpip/buffer.VectorisedView"
+}
+
+func (vv *VectorisedView) StateFields() []string {
+	return []string{
+		"views",
+		"size",
+	}
+}
+
+func (vv *VectorisedView) beforeSave() {}
+
+// +checklocksignore
+func (vv *VectorisedView) StateSave(stateSinkObject state.Sink) {
+	vv.beforeSave()
+	stateSinkObject.Save(0, &vv.views)
+	stateSinkObject.Save(1, &vv.size)
+}
+
+func (vv *VectorisedView) afterLoad() {}
+
+// +checklocksignore
+func (vv *VectorisedView) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &vv.views)
+	stateSourceObject.Load(1, &vv.size)
+}
+
+func init() {
+	state.Register((*VectorisedView)(nil))
+}
diff --git a/pkg/tcpip/buffer/buffer_unsafe_state_autogen.go b/pkg/tcpip/buffer/buffer_unsafe_state_autogen.go
new file mode 100644
index 0000000..5a5c407
--- /dev/null
+++ b/pkg/tcpip/buffer/buffer_unsafe_state_autogen.go
@@ -0,0 +1,3 @@
+// automatically generated by stateify.
+
+package buffer
diff --git a/pkg/tcpip/buffer/view_test.go b/pkg/tcpip/buffer/view_test.go
deleted file mode 100644
index d296d9c..0000000
--- a/pkg/tcpip/buffer/view_test.go
+++ /dev/null
@@ -1,629 +0,0 @@
-// 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 buffer_test contains tests for the buffer.VectorisedView type.
-package buffer_test
-
-import (
-	"bytes"
-	"io"
-	"reflect"
-	"testing"
-	"unsafe"
-
-	"gvisor.dev/gvisor/pkg/tcpip"
-	"gvisor.dev/gvisor/pkg/tcpip/buffer"
-)
-
-// copy returns a deep-copy of the vectorised view.
-func copyVV(vv buffer.VectorisedView) buffer.VectorisedView {
-	views := make([]buffer.View, 0, len(vv.Views()))
-	for _, v := range vv.Views() {
-		views = append(views, append(buffer.View(nil), v...))
-	}
-	return buffer.NewVectorisedView(vv.Size(), views)
-}
-
-// vv is an helper to build buffer.VectorisedView from different strings.
-func vv(size int, pieces ...string) buffer.VectorisedView {
-	views := make([]buffer.View, len(pieces))
-	for i, p := range pieces {
-		views[i] = []byte(p)
-	}
-
-	return buffer.NewVectorisedView(size, views)
-}
-
-// v returns a buffer.View containing piece.
-func v(piece string) buffer.View {
-	return buffer.View(piece)
-}
-
-var capLengthTestCases = []struct {
-	comment string
-	in      buffer.VectorisedView
-	length  int
-	want    buffer.VectorisedView
-}{
-	{
-		comment: "Simple case",
-		in:      vv(2, "12"),
-		length:  1,
-		want:    vv(1, "1"),
-	},
-	{
-		comment: "Case spanning across two Views",
-		in:      vv(4, "123", "4"),
-		length:  2,
-		want:    vv(2, "12"),
-	},
-	{
-		comment: "Corner case with negative length",
-		in:      vv(1, "1"),
-		length:  -1,
-		want:    vv(0),
-	},
-	{
-		comment: "Corner case with length = 0",
-		in:      vv(3, "12", "3"),
-		length:  0,
-		want:    vv(0),
-	},
-	{
-		comment: "Corner case with length = size",
-		in:      vv(1, "1"),
-		length:  1,
-		want:    vv(1, "1"),
-	},
-	{
-		comment: "Corner case with length > size",
-		in:      vv(1, "1"),
-		length:  2,
-		want:    vv(1, "1"),
-	},
-}
-
-func TestCapLength(t *testing.T) {
-	for _, c := range capLengthTestCases {
-		orig := copyVV(c.in)
-		c.in.CapLength(c.length)
-		if !reflect.DeepEqual(c.in, c.want) {
-			t.Errorf("Test \"%s\" failed when calling CapLength(%d) on %v. Got %v. Want %v",
-				c.comment, c.length, orig, c.in, c.want)
-		}
-	}
-}
-
-var trimFrontTestCases = []struct {
-	comment string
-	in      buffer.VectorisedView
-	count   int
-	want    buffer.VectorisedView
-}{
-	{
-		comment: "Simple case",
-		in:      vv(2, "12"),
-		count:   1,
-		want:    vv(1, "2"),
-	},
-	{
-		comment: "Case where we trim an entire View",
-		in:      vv(2, "1", "2"),
-		count:   1,
-		want:    vv(1, "2"),
-	},
-	{
-		comment: "Case spanning across two Views",
-		in:      vv(3, "1", "23"),
-		count:   2,
-		want:    vv(1, "3"),
-	},
-	{
-		comment: "Case with one empty Views",
-		in:      vv(3, "1", "", "23"),
-		count:   2,
-		want:    vv(1, "3"),
-	},
-	{
-		comment: "Corner case with negative count",
-		in:      vv(1, "1"),
-		count:   -1,
-		want:    vv(1, "1"),
-	},
-	{
-		comment: " Corner case with count = 0",
-		in:      vv(1, "1"),
-		count:   0,
-		want:    vv(1, "1"),
-	},
-	{
-		comment: "Corner case with count = size",
-		in:      vv(1, "1"),
-		count:   1,
-		want:    vv(0),
-	},
-	{
-		comment: "Corner case with count > size",
-		in:      vv(1, "1"),
-		count:   2,
-		want:    vv(0),
-	},
-}
-
-func TestTrimFront(t *testing.T) {
-	for _, c := range trimFrontTestCases {
-		orig := copyVV(c.in)
-		c.in.TrimFront(c.count)
-		if !reflect.DeepEqual(c.in, c.want) {
-			t.Errorf("Test \"%s\" failed when calling TrimFront(%d) on %v. Got %v. Want %v",
-				c.comment, c.count, orig, c.in, c.want)
-		}
-	}
-}
-
-var toViewCases = []struct {
-	comment string
-	in      buffer.VectorisedView
-	want    buffer.View
-}{
-	{
-		comment: "Simple case",
-		in:      vv(2, "12"),
-		want:    []byte("12"),
-	},
-	{
-		comment: "Case with multiple views",
-		in:      vv(2, "1", "2"),
-		want:    []byte("12"),
-	},
-	{
-		comment: "Empty case",
-		in:      vv(0),
-		want:    []byte(""),
-	},
-}
-
-func TestToView(t *testing.T) {
-	for _, c := range toViewCases {
-		got := c.in.ToView()
-		if !reflect.DeepEqual(got, c.want) {
-			t.Errorf("Test \"%s\" failed when calling ToView() on %v. Got %v. Want %v",
-				c.comment, c.in, got, c.want)
-		}
-	}
-}
-
-var toCloneCases = []struct {
-	comment  string
-	inView   buffer.VectorisedView
-	inBuffer []buffer.View
-}{
-	{
-		comment:  "Simple case",
-		inView:   vv(1, "1"),
-		inBuffer: make([]buffer.View, 1),
-	},
-	{
-		comment:  "Case with multiple views",
-		inView:   vv(2, "1", "2"),
-		inBuffer: make([]buffer.View, 2),
-	},
-	{
-		comment:  "Case with buffer too small",
-		inView:   vv(2, "1", "2"),
-		inBuffer: make([]buffer.View, 1),
-	},
-	{
-		comment:  "Case with buffer larger than needed",
-		inView:   vv(1, "1"),
-		inBuffer: make([]buffer.View, 2),
-	},
-	{
-		comment:  "Case with nil buffer",
-		inView:   vv(1, "1"),
-		inBuffer: nil,
-	},
-}
-
-func TestToClone(t *testing.T) {
-	for _, c := range toCloneCases {
-		t.Run(c.comment, func(t *testing.T) {
-			got := c.inView.Clone(c.inBuffer)
-			if !reflect.DeepEqual(got, c.inView) {
-				t.Fatalf("got (%+v).Clone(%+v) = %+v, want = %+v",
-					c.inView, c.inBuffer, got, c.inView)
-			}
-		})
-	}
-}
-
-type readToTestCases struct {
-	comment     string
-	vv          buffer.VectorisedView
-	bytesToRead int
-	wantBytes   string
-	leftVV      buffer.VectorisedView
-}
-
-func createReadToTestCases() []readToTestCases {
-	return []readToTestCases{
-		{
-			comment:     "large VV, short read",
-			vv:          vv(30, "012345678901234567890123456789"),
-			bytesToRead: 10,
-			wantBytes:   "0123456789",
-			leftVV:      vv(20, "01234567890123456789"),
-		},
-		{
-			comment:     "largeVV, multiple views, short read",
-			vv:          vv(13, "123", "345", "567", "8910"),
-			bytesToRead: 6,
-			wantBytes:   "123345",
-			leftVV:      vv(7, "567", "8910"),
-		},
-		{
-			comment:     "smallVV (multiple views), large read",
-			vv:          vv(3, "1", "2", "3"),
-			bytesToRead: 10,
-			wantBytes:   "123",
-			leftVV:      vv(0, ""),
-		},
-		{
-			comment:     "smallVV (single view), large read",
-			vv:          vv(1, "1"),
-			bytesToRead: 10,
-			wantBytes:   "1",
-			leftVV:      vv(0, ""),
-		},
-		{
-			comment:     "emptyVV, large read",
-			vv:          vv(0, ""),
-			bytesToRead: 10,
-			wantBytes:   "",
-			leftVV:      vv(0, ""),
-		},
-	}
-}
-
-func TestVVReadToVV(t *testing.T) {
-	for _, tc := range createReadToTestCases() {
-		t.Run(tc.comment, func(t *testing.T) {
-			var readTo buffer.VectorisedView
-			inSize := tc.vv.Size()
-			copied := tc.vv.ReadToVV(&readTo, tc.bytesToRead)
-			if got, want := copied, len(tc.wantBytes); got != want {
-				t.Errorf("incorrect number of bytes copied returned in ReadToVV got: %d, want: %d, tc: %+v", got, want, tc)
-			}
-			if got, want := string(readTo.ToView()), tc.wantBytes; got != want {
-				t.Errorf("unexpected content in readTo got: %s, want: %s", got, want)
-			}
-			if got, want := tc.vv.Size(), inSize-copied; got != want {
-				t.Errorf("test VV has incorrect size after reading got: %d, want: %d, tc.vv: %+v", got, want, tc.vv)
-			}
-			if got, want := string(tc.vv.ToView()), string(tc.leftVV.ToView()); got != want {
-				t.Errorf("unexpected data left in vv after read got: %+v, want: %+v", got, want)
-			}
-		})
-	}
-}
-
-func TestVVReadTo(t *testing.T) {
-	for _, tc := range createReadToTestCases() {
-		t.Run(tc.comment, func(t *testing.T) {
-			b := make([]byte, tc.bytesToRead)
-			dst := tcpip.SliceWriter(b)
-			origSize := tc.vv.Size()
-			copied, err := tc.vv.ReadTo(&dst, false /* peek */)
-			if err != nil && err != io.ErrShortWrite {
-				t.Errorf("got ReadTo(&dst, false) = (_, %s); want nil or io.ErrShortWrite", err)
-			}
-			if got, want := copied, len(tc.wantBytes); got != want {
-				t.Errorf("got ReadTo(&dst, false) = (%d, _); want %d", got, want)
-			}
-			if got, want := string(b[:copied]), tc.wantBytes; got != want {
-				t.Errorf("got dst = %q, want %q", got, want)
-			}
-			if got, want := tc.vv.Size(), origSize-copied; got != want {
-				t.Errorf("got after-read tc.vv.Size() = %d, want %d", got, want)
-			}
-			if got, want := string(tc.vv.ToView()), string(tc.leftVV.ToView()); got != want {
-				t.Errorf("got after-read data in tc.vv = %q, want %q", got, want)
-			}
-		})
-	}
-}
-
-func TestVVReadToPeek(t *testing.T) {
-	for _, tc := range createReadToTestCases() {
-		t.Run(tc.comment, func(t *testing.T) {
-			b := make([]byte, tc.bytesToRead)
-			dst := tcpip.SliceWriter(b)
-			origSize := tc.vv.Size()
-			origData := string(tc.vv.ToView())
-			copied, err := tc.vv.ReadTo(&dst, true /* peek */)
-			if err != nil && err != io.ErrShortWrite {
-				t.Errorf("got ReadTo(&dst, true) = (_, %s); want nil or io.ErrShortWrite", err)
-			}
-			if got, want := copied, len(tc.wantBytes); got != want {
-				t.Errorf("got ReadTo(&dst, true) = (%d, _); want %d", got, want)
-			}
-			if got, want := string(b[:copied]), tc.wantBytes; got != want {
-				t.Errorf("got dst = %q, want %q", got, want)
-			}
-			// Expect tc.vv is unchanged.
-			if got, want := tc.vv.Size(), origSize; got != want {
-				t.Errorf("got after-read tc.vv.Size() = %d, want %d", got, want)
-			}
-			if got, want := string(tc.vv.ToView()), origData; got != want {
-				t.Errorf("got after-read data in tc.vv = %q, want %q", got, want)
-			}
-		})
-	}
-}
-
-func TestVVRead(t *testing.T) {
-	testCases := []struct {
-		comment     string
-		vv          buffer.VectorisedView
-		bytesToRead int
-		readBytes   string
-		leftBytes   string
-		wantError   bool
-	}{
-		{
-			comment:     "large VV, short read",
-			vv:          vv(30, "012345678901234567890123456789"),
-			bytesToRead: 10,
-			readBytes:   "0123456789",
-			leftBytes:   "01234567890123456789",
-		},
-		{
-			comment:     "largeVV, multiple buffers, short read",
-			vv:          vv(13, "123", "345", "567", "8910"),
-			bytesToRead: 6,
-			readBytes:   "123345",
-			leftBytes:   "5678910",
-		},
-		{
-			comment:     "smallVV, large read",
-			vv:          vv(3, "1", "2", "3"),
-			bytesToRead: 10,
-			readBytes:   "123",
-			leftBytes:   "",
-		},
-		{
-			comment:     "smallVV, large read",
-			vv:          vv(1, "1"),
-			bytesToRead: 10,
-			readBytes:   "1",
-			leftBytes:   "",
-		},
-		{
-			comment:     "emptyVV, large read",
-			vv:          vv(0, ""),
-			bytesToRead: 10,
-			readBytes:   "",
-			wantError:   true,
-		},
-	}
-
-	for _, tc := range testCases {
-		t.Run(tc.comment, func(t *testing.T) {
-			readTo := buffer.NewView(tc.bytesToRead)
-			inSize := tc.vv.Size()
-			copied, err := tc.vv.Read(readTo)
-			if !tc.wantError && err != nil {
-				t.Fatalf("unexpected error in tc.vv.Read(..) = %s", err)
-			}
-			readTo = readTo[:copied]
-			if got, want := copied, len(tc.readBytes); got != want {
-				t.Errorf("incorrect number of bytes copied returned in ReadToVV got: %d, want: %d, tc.vv: %+v", got, want, tc.vv)
-			}
-			if got, want := string(readTo), tc.readBytes; got != want {
-				t.Errorf("unexpected data in readTo got: %s, want: %s", got, want)
-			}
-			if got, want := tc.vv.Size(), inSize-copied; got != want {
-				t.Errorf("test VV has incorrect size after reading got: %d, want: %d, tc.vv: %+v", got, want, tc.vv)
-			}
-			if got, want := string(tc.vv.ToView()), tc.leftBytes; got != want {
-				t.Errorf("vv has incorrect data after Read got: %s, want: %s", got, want)
-			}
-		})
-	}
-}
-
-var pullUpTestCases = []struct {
-	comment string
-	in      buffer.VectorisedView
-	count   int
-	want    []byte
-	result  buffer.VectorisedView
-	ok      bool
-}{
-	{
-		comment: "simple case",
-		in:      vv(2, "12"),
-		count:   1,
-		want:    []byte("1"),
-		result:  vv(2, "12"),
-		ok:      true,
-	},
-	{
-		comment: "entire View",
-		in:      vv(2, "1", "2"),
-		count:   1,
-		want:    []byte("1"),
-		result:  vv(2, "1", "2"),
-		ok:      true,
-	},
-	{
-		comment: "spanning across two Views",
-		in:      vv(3, "1", "23"),
-		count:   2,
-		want:    []byte("12"),
-		result:  vv(3, "12", "3"),
-		ok:      true,
-	},
-	{
-		comment: "spanning across all Views",
-		in:      vv(5, "1", "23", "45"),
-		count:   5,
-		want:    []byte("12345"),
-		result:  vv(5, "12345"),
-		ok:      true,
-	},
-	{
-		comment: "count = 0",
-		in:      vv(1, "1"),
-		count:   0,
-		want:    []byte{},
-		result:  vv(1, "1"),
-		ok:      true,
-	},
-	{
-		comment: "count = size",
-		in:      vv(1, "1"),
-		count:   1,
-		want:    []byte("1"),
-		result:  vv(1, "1"),
-		ok:      true,
-	},
-	{
-		comment: "count too large",
-		in:      vv(3, "1", "23"),
-		count:   4,
-		want:    nil,
-		result:  vv(3, "1", "23"),
-		ok:      false,
-	},
-	{
-		comment: "empty vv",
-		in:      vv(0, ""),
-		count:   1,
-		want:    nil,
-		result:  vv(0, ""),
-		ok:      false,
-	},
-	{
-		comment: "empty vv, count = 0",
-		in:      vv(0, ""),
-		count:   0,
-		want:    nil,
-		result:  vv(0, ""),
-		ok:      true,
-	},
-	{
-		comment: "empty views",
-		in:      vv(3, "", "1", "", "23"),
-		count:   2,
-		want:    []byte("12"),
-		result:  vv(3, "12", "3"),
-		ok:      true,
-	},
-}
-
-func TestPullUp(t *testing.T) {
-	for _, c := range pullUpTestCases {
-		got, ok := c.in.PullUp(c.count)
-
-		// Is the return value right?
-		if ok != c.ok {
-			t.Errorf("Test %q failed when calling PullUp(%d) on %v. Got an ok of %t. Want %t",
-				c.comment, c.count, c.in, ok, c.ok)
-		}
-		if bytes.Compare(got, buffer.View(c.want)) != 0 {
-			t.Errorf("Test %q failed when calling PullUp(%d) on %v. Got %v. Want %v",
-				c.comment, c.count, c.in, got, c.want)
-		}
-
-		// Is the underlying structure right?
-		if !reflect.DeepEqual(c.in, c.result) {
-			t.Errorf("Test %q failed when calling PullUp(%d). Got vv with structure %v. Wanted %v",
-				c.comment, c.count, c.in, c.result)
-		}
-	}
-}
-
-func TestToVectorisedView(t *testing.T) {
-	testCases := []struct {
-		in   buffer.View
-		want buffer.VectorisedView
-	}{
-		{nil, buffer.VectorisedView{}},
-		{buffer.View{}, buffer.VectorisedView{}},
-		{buffer.View{'a'}, buffer.NewVectorisedView(1, []buffer.View{{'a'}})},
-	}
-	for _, tc := range testCases {
-		if got, want := tc.in.ToVectorisedView(), tc.want; !reflect.DeepEqual(got, want) {
-			t.Errorf("(%v).ToVectorisedView failed got: %+v, want: %+v", tc.in, got, want)
-		}
-	}
-}
-
-func TestAppendView(t *testing.T) {
-	testCases := []struct {
-		vv   buffer.VectorisedView
-		in   buffer.View
-		want buffer.VectorisedView
-	}{
-		{vv(0), nil, vv(0)},
-		{vv(0), v(""), vv(0)},
-		{vv(4, "abcd"), nil, vv(4, "abcd")},
-		{vv(4, "abcd"), v(""), vv(4, "abcd")},
-		{vv(4, "abcd"), v("e"), vv(5, "abcd", "e")},
-	}
-	for _, tc := range testCases {
-		tc.vv.AppendView(tc.in)
-		if got, want := tc.vv, tc.want; !reflect.DeepEqual(got, want) {
-			t.Errorf("(%v).ToVectorisedView failed got: %+v, want: %+v", tc.in, got, want)
-		}
-	}
-}
-
-func TestAppendViews(t *testing.T) {
-	testCases := []struct {
-		vv   buffer.VectorisedView
-		in   []buffer.View
-		want buffer.VectorisedView
-	}{
-		{vv(0), nil, vv(0)},
-		{vv(0), []buffer.View{}, vv(0)},
-		{vv(0), []buffer.View{v("")}, vv(0, "")},
-		{vv(4, "abcd"), nil, vv(4, "abcd")},
-		{vv(4, "abcd"), []buffer.View{}, vv(4, "abcd")},
-		{vv(4, "abcd"), []buffer.View{v("")}, vv(4, "abcd", "")},
-		{vv(4, "abcd"), []buffer.View{v("")}, vv(4, "abcd", "")},
-		{vv(4, "abcd"), []buffer.View{v("e")}, vv(5, "abcd", "e")},
-		{vv(4, "abcd"), []buffer.View{v("e"), v("fg")}, vv(7, "abcd", "e", "fg")},
-		{vv(4, "abcd"), []buffer.View{v(""), v("fg")}, vv(6, "abcd", "", "fg")},
-	}
-	for _, tc := range testCases {
-		tc.vv.AppendViews(tc.in)
-		if got, want := tc.vv, tc.want; !reflect.DeepEqual(got, want) {
-			t.Errorf("(%v).ToVectorisedView failed got: %+v, want: %+v", tc.in, got, want)
-		}
-	}
-}
-
-func TestMemSize(t *testing.T) {
-	const perViewCap = 128
-	views := make([]buffer.View, 2, 32)
-	views[0] = make(buffer.View, 10, perViewCap)
-	views[1] = make(buffer.View, 20, perViewCap)
-	vv := buffer.NewVectorisedView(30, views)
-	want := int(unsafe.Sizeof(vv)) + cap(views)*int(unsafe.Sizeof(views)) + 2*perViewCap
-	if got := vv.MemSize(); got != want {
-		t.Errorf("vv.MemSize() = %d, want %d", got, want)
-	}
-}
diff --git a/pkg/tcpip/faketime/faketime_state_autogen.go b/pkg/tcpip/faketime/faketime_state_autogen.go
new file mode 100644
index 0000000..3de72f2
--- /dev/null
+++ b/pkg/tcpip/faketime/faketime_state_autogen.go
@@ -0,0 +1,3 @@
+// automatically generated by stateify.
+
+package faketime
diff --git a/pkg/tcpip/faketime/faketime_test.go b/pkg/tcpip/faketime/faketime_test.go
deleted file mode 100644
index c2704df..0000000
--- a/pkg/tcpip/faketime/faketime_test.go
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2020 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 faketime_test
-
-import (
-	"testing"
-	"time"
-
-	"gvisor.dev/gvisor/pkg/tcpip/faketime"
-)
-
-func TestManualClockAdvance(t *testing.T) {
-	const timeout = time.Millisecond
-	clock := faketime.NewManualClock()
-	start := clock.NowMonotonic()
-	clock.Advance(timeout)
-	if got, want := time.Duration(clock.NowMonotonic()-start)*time.Nanosecond, timeout; got != want {
-		t.Errorf("got = %d, want = %d", got, want)
-	}
-}
-
-func TestManualClockAfterFunc(t *testing.T) {
-	const (
-		timeout1 = time.Millisecond     // timeout for counter1
-		timeout2 = 2 * time.Millisecond // timeout for counter2
-	)
-	tests := []struct {
-		name         string
-		advance      time.Duration
-		wantCounter1 int
-		wantCounter2 int
-	}{
-		{
-			name:         "before timeout1",
-			advance:      timeout1 - 1,
-			wantCounter1: 0,
-			wantCounter2: 0,
-		},
-		{
-			name:         "timeout1",
-			advance:      timeout1,
-			wantCounter1: 1,
-			wantCounter2: 0,
-		},
-		{
-			name:         "timeout2",
-			advance:      timeout2,
-			wantCounter1: 1,
-			wantCounter2: 1,
-		},
-		{
-			name:         "after timeout2",
-			advance:      timeout2 + 1,
-			wantCounter1: 1,
-			wantCounter2: 1,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			clock := faketime.NewManualClock()
-			counter1 := 0
-			counter2 := 0
-			clock.AfterFunc(timeout1, func() {
-				counter1++
-			})
-			clock.AfterFunc(timeout2, func() {
-				counter2++
-			})
-			start := clock.NowMonotonic()
-			clock.Advance(test.advance)
-			if got, want := counter1, test.wantCounter1; got != want {
-				t.Errorf("got counter1 = %d, want = %d", got, want)
-			}
-			if got, want := counter2, test.wantCounter2; got != want {
-				t.Errorf("got counter2 = %d, want = %d", got, want)
-			}
-			if got, want := time.Duration(clock.NowMonotonic()-start)*time.Nanosecond, test.advance; got != want {
-				t.Errorf("got elapsed = %d, want = %d", got, want)
-			}
-		})
-	}
-}
diff --git a/pkg/tcpip/hash/jenkins/jenkins_state_autogen.go b/pkg/tcpip/hash/jenkins/jenkins_state_autogen.go
new file mode 100644
index 0000000..216cc5a
--- /dev/null
+++ b/pkg/tcpip/hash/jenkins/jenkins_state_autogen.go
@@ -0,0 +1,3 @@
+// automatically generated by stateify.
+
+package jenkins
diff --git a/pkg/tcpip/hash/jenkins/jenkins_test.go b/pkg/tcpip/hash/jenkins/jenkins_test.go
deleted file mode 100644
index 4c78b58..0000000
--- a/pkg/tcpip/hash/jenkins/jenkins_test.go
+++ /dev/null
@@ -1,176 +0,0 @@
-// 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 jenkins
-
-import (
-	"bytes"
-	"encoding/binary"
-	"hash"
-	"hash/fnv"
-	"math"
-	"testing"
-)
-
-func TestGolden32(t *testing.T) {
-	var golden32 = []struct {
-		out []byte
-		in  string
-	}{
-		{[]byte{0x00, 0x00, 0x00, 0x00}, ""},
-		{[]byte{0xca, 0x2e, 0x94, 0x42}, "a"},
-		{[]byte{0x45, 0xe6, 0x1e, 0x58}, "ab"},
-		{[]byte{0xed, 0x13, 0x1f, 0x5b}, "abc"},
-	}
-
-	hash := New32()
-
-	for _, g := range golden32 {
-		hash.Reset()
-		done, error := hash.Write([]byte(g.in))
-		if error != nil {
-			t.Fatalf("write error: %s", error)
-		}
-		if done != len(g.in) {
-			t.Fatalf("wrote only %d out of %d bytes", done, len(g.in))
-		}
-		if actual := hash.Sum(nil); !bytes.Equal(g.out, actual) {
-			t.Errorf("hash(%q) = 0x%x want 0x%x", g.in, actual, g.out)
-		}
-	}
-}
-
-func TestIntegrity32(t *testing.T) {
-	data := []byte{'1', '2', 3, 4, 5}
-
-	h := New32()
-	h.Write(data)
-	sum := h.Sum(nil)
-
-	if size := h.Size(); size != len(sum) {
-		t.Fatalf("Size()=%d but len(Sum())=%d", size, len(sum))
-	}
-
-	if a := h.Sum(nil); !bytes.Equal(sum, a) {
-		t.Fatalf("first Sum()=0x%x, second Sum()=0x%x", sum, a)
-	}
-
-	h.Reset()
-	h.Write(data)
-	if a := h.Sum(nil); !bytes.Equal(sum, a) {
-		t.Fatalf("Sum()=0x%x, but after Reset() Sum()=0x%x", sum, a)
-	}
-
-	h.Reset()
-	h.Write(data[:2])
-	h.Write(data[2:])
-	if a := h.Sum(nil); !bytes.Equal(sum, a) {
-		t.Fatalf("Sum()=0x%x, but with partial writes, Sum()=0x%x", sum, a)
-	}
-
-	sum32 := h.(hash.Hash32).Sum32()
-	if sum32 != binary.BigEndian.Uint32(sum) {
-		t.Fatalf("Sum()=0x%x, but Sum32()=0x%x", sum, sum32)
-	}
-}
-
-func BenchmarkJenkins32KB(b *testing.B) {
-	h := New32()
-
-	b.SetBytes(1024)
-	data := make([]byte, 1024)
-	for i := range data {
-		data[i] = byte(i)
-	}
-	in := make([]byte, 0, h.Size())
-
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		h.Reset()
-		h.Write(data)
-		h.Sum(in)
-	}
-}
-
-func BenchmarkFnv32(b *testing.B) {
-	arr := make([]int64, 1000)
-	for i := 0; i < b.N; i++ {
-		var payload [8]byte
-		binary.BigEndian.PutUint32(payload[:4], uint32(i))
-		binary.BigEndian.PutUint32(payload[4:], uint32(i))
-
-		h := fnv.New32()
-		h.Write(payload[:])
-		idx := int(h.Sum32()) % len(arr)
-		arr[idx]++
-	}
-	b.StopTimer()
-	c := 0
-	if b.N > 1000000 {
-		for i := 0; i < len(arr)-1; i++ {
-			if math.Abs(float64(arr[i]-arr[i+1]))/float64(arr[i]) > float64(0.1) {
-				if c == 0 {
-					b.Logf("i %d val[i] %d val[i+1] %d b.N %b\n", i, arr[i], arr[i+1], b.N)
-				}
-				c++
-			}
-		}
-		if c > 0 {
-			b.Logf("Unbalanced buckets: %d", c)
-		}
-	}
-}
-
-func BenchmarkSum32(b *testing.B) {
-	arr := make([]int64, 1000)
-	for i := 0; i < b.N; i++ {
-		var payload [8]byte
-		binary.BigEndian.PutUint32(payload[:4], uint32(i))
-		binary.BigEndian.PutUint32(payload[4:], uint32(i))
-		h := Sum32(0)
-		h.Write(payload[:])
-		idx := int(h.Sum32()) % len(arr)
-		arr[idx]++
-	}
-	b.StopTimer()
-	if b.N > 1000000 {
-		for i := 0; i < len(arr)-1; i++ {
-			if math.Abs(float64(arr[i]-arr[i+1]))/float64(arr[i]) > float64(0.1) {
-				b.Logf("val[%3d]=%8d\tval[%3d]=%8d\tb.N=%b\n", i, arr[i], i+1, arr[i+1], b.N)
-				break
-			}
-		}
-	}
-}
-
-func BenchmarkNew32(b *testing.B) {
-	arr := make([]int64, 1000)
-	for i := 0; i < b.N; i++ {
-		var payload [8]byte
-		binary.BigEndian.PutUint32(payload[:4], uint32(i))
-		binary.BigEndian.PutUint32(payload[4:], uint32(i))
-		h := New32()
-		h.Write(payload[:])
-		idx := int(h.Sum32()) % len(arr)
-		arr[idx]++
-	}
-	b.StopTimer()
-	if b.N > 1000000 {
-		for i := 0; i < len(arr)-1; i++ {
-			if math.Abs(float64(arr[i]-arr[i+1]))/float64(arr[i]) > float64(0.1) {
-				b.Logf("val[%3d]=%8d\tval[%3d]=%8d\tb.N=%b\n", i, arr[i], i+1, arr[i+1], b.N)
-				break
-			}
-		}
-	}
-}
diff --git a/pkg/tcpip/header/checksum_test.go b/pkg/tcpip/header/checksum_test.go
deleted file mode 100644
index d267dab..0000000
--- a/pkg/tcpip/header/checksum_test.go
+++ /dev/null
@@ -1,258 +0,0 @@
-// 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 header provides the implementation of the encoding and decoding of
-// network protocol headers.
-package header_test
-
-import (
-	"bytes"
-	"fmt"
-	"math/rand"
-	"sync"
-	"testing"
-
-	"gvisor.dev/gvisor/pkg/tcpip/buffer"
-	"gvisor.dev/gvisor/pkg/tcpip/header"
-)
-
-func TestChecksumer(t *testing.T) {
-	testCases := []struct {
-		name string
-		data [][]byte
-		want uint16
-	}{
-		{
-			name: "empty",
-			want: 0,
-		},
-		{
-			name: "OneOddView",
-			data: [][]byte{
-				[]byte{1, 9, 0, 5, 4},
-			},
-			want: 1294,
-		},
-		{
-			name: "TwoOddViews",
-			data: [][]byte{
-				[]byte{1, 9, 0, 5, 4},
-				[]byte{4, 3, 7, 1, 2, 123},
-			},
-			want: 33819,
-		},
-		{
-			name: "OneEvenView",
-			data: [][]byte{
-				[]byte{1, 9, 0, 5},
-			},
-			want: 270,
-		},
-		{
-			name: "TwoEvenViews",
-			data: [][]byte{
-				buffer.NewViewFromBytes([]byte{98, 1, 9, 0}),
-				buffer.NewViewFromBytes([]byte{9, 0, 5, 4}),
-			},
-			want: 30981,
-		},
-		{
-			name: "ThreeViews",
-			data: [][]byte{
-				[]byte{77, 11, 33, 0, 55, 44},
-				[]byte{98, 1, 9, 0, 5, 4},
-				[]byte{4, 3, 7, 1, 2, 123, 99},
-			},
-			want: 34236,
-		},
-	}
-	for _, tc := range testCases {
-		t.Run(tc.name, func(t *testing.T) {
-			var all bytes.Buffer
-			var c header.Checksumer
-			for _, b := range tc.data {
-				c.Add(b)
-				// Append to the buffer. We will check the checksum as a whole later.
-				if _, err := all.Write(b); err != nil {
-					t.Fatalf("all.Write(b) = _, %s; want _, nil", err)
-				}
-			}
-			if got, want := c.Checksum(), tc.want; got != want {
-				t.Errorf("c.Checksum() = %d, want %d", got, want)
-			}
-			if got, want := header.Checksum(all.Bytes(), 0 /* initial */), tc.want; got != want {
-				t.Errorf("Checksum(flatten tc.data) = %d, want %d", got, want)
-			}
-		})
-	}
-}
-
-func TestChecksum(t *testing.T) {
-	var bufSizes = []int{0, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64, 127, 128, 255, 256, 257, 1023, 1024}
-	type testCase struct {
-		buf      []byte
-		initial  uint16
-		csumOrig uint16
-		csumNew  uint16
-	}
-	testCases := make([]testCase, 100000)
-	// Ensure same buffer generation for test consistency.
-	rnd := rand.New(rand.NewSource(42))
-	for i := range testCases {
-		testCases[i].buf = make([]byte, bufSizes[i%len(bufSizes)])
-		testCases[i].initial = uint16(rnd.Intn(65536))
-		rnd.Read(testCases[i].buf)
-	}
-
-	for i := range testCases {
-		testCases[i].csumOrig = header.ChecksumOld(testCases[i].buf, testCases[i].initial)
-		testCases[i].csumNew = header.Checksum(testCases[i].buf, testCases[i].initial)
-		if got, want := testCases[i].csumNew, testCases[i].csumOrig; got != want {
-			t.Fatalf("new checksum for (buf = %x, initial = %d) does not match old got: %d, want: %d", testCases[i].buf, testCases[i].initial, got, want)
-		}
-	}
-}
-
-func BenchmarkChecksum(b *testing.B) {
-	var bufSizes = []int{64, 128, 256, 512, 1024, 1500, 2048, 4096, 8192, 16384, 32767, 32768, 65535, 65536}
-
-	checkSumImpls := []struct {
-		fn   func([]byte, uint16) uint16
-		name string
-	}{
-		{header.ChecksumOld, fmt.Sprintf("checksum_old")},
-		{header.Checksum, fmt.Sprintf("checksum")},
-	}
-
-	for _, csumImpl := range checkSumImpls {
-		// Ensure same buffer generation for test consistency.
-		rnd := rand.New(rand.NewSource(42))
-		for _, bufSz := range bufSizes {
-			b.Run(fmt.Sprintf("%s_%d", csumImpl.name, bufSz), func(b *testing.B) {
-				tc := struct {
-					buf     []byte
-					initial uint16
-					csum    uint16
-				}{
-					buf:     make([]byte, bufSz),
-					initial: uint16(rnd.Intn(65536)),
-				}
-				rnd.Read(tc.buf)
-				b.ResetTimer()
-				for i := 0; i < b.N; i++ {
-					tc.csum = csumImpl.fn(tc.buf, tc.initial)
-				}
-			})
-		}
-	}
-}
-
-func testICMPChecksum(t *testing.T, headerChecksum func() uint16, icmpChecksum func() uint16, want uint16, pktStr string) {
-	// icmpChecksum should not do any modifications of the header to
-	// calculate its checksum. Let's call it from a few go-routines and the
-	// race detector will trigger a warning if there are any concurrent
-	// read/write accesses.
-
-	const concurrency = 5
-	start := make(chan int)
-	ready := make(chan bool, concurrency)
-	var wg sync.WaitGroup
-	wg.Add(concurrency)
-	defer wg.Wait()
-
-	for i := 0; i < concurrency; i++ {
-		go func() {
-			defer wg.Done()
-
-			ready <- true
-			<-start
-
-			if got := headerChecksum(); want != got {
-				t.Errorf("new checksum for %s does not match old got: %x, want: %x", pktStr, got, want)
-			}
-			if got := icmpChecksum(); want != got {
-				t.Errorf("new checksum for %s does not match old got: %x, want: %x", pktStr, got, want)
-			}
-		}()
-	}
-	for i := 0; i < concurrency; i++ {
-		<-ready
-	}
-	close(start)
-}
-
-func TestICMPv4Checksum(t *testing.T) {
-	rnd := rand.New(rand.NewSource(42))
-
-	h := header.ICMPv4(make([]byte, header.ICMPv4MinimumSize))
-	if _, err := rnd.Read(h); err != nil {
-		t.Fatalf("rnd.Read failed: %v", err)
-	}
-	h.SetChecksum(0)
-
-	buf := make([]byte, 13)
-	if _, err := rnd.Read(buf); err != nil {
-		t.Fatalf("rnd.Read failed: %v", err)
-	}
-	vv := buffer.NewVectorisedView(len(buf), []buffer.View{
-		buffer.NewViewFromBytes(buf[:5]),
-		buffer.NewViewFromBytes(buf[5:]),
-	})
-
-	want := header.Checksum(vv.ToView(), 0)
-	want = ^header.Checksum(h, want)
-	h.SetChecksum(want)
-
-	testICMPChecksum(t, h.Checksum, func() uint16 {
-		return header.ICMPv4Checksum(h, header.ChecksumVV(vv, 0))
-	}, want, fmt.Sprintf("header: {% x} data {% x}", h, vv.ToView()))
-}
-
-func TestICMPv6Checksum(t *testing.T) {
-	rnd := rand.New(rand.NewSource(42))
-
-	h := header.ICMPv6(make([]byte, header.ICMPv6MinimumSize))
-	if _, err := rnd.Read(h); err != nil {
-		t.Fatalf("rnd.Read failed: %v", err)
-	}
-	h.SetChecksum(0)
-
-	buf := make([]byte, 13)
-	if _, err := rnd.Read(buf); err != nil {
-		t.Fatalf("rnd.Read failed: %v", err)
-	}
-	vv := buffer.NewVectorisedView(len(buf), []buffer.View{
-		buffer.NewViewFromBytes(buf[:7]),
-		buffer.NewViewFromBytes(buf[7:10]),
-		buffer.NewViewFromBytes(buf[10:]),
-	})
-
-	dst := header.IPv6Loopback
-	src := header.IPv6Loopback
-
-	want := header.PseudoHeaderChecksum(header.ICMPv6ProtocolNumber, src, dst, uint16(len(h)+vv.Size()))
-	want = header.Checksum(vv.ToView(), want)
-	want = ^header.Checksum(h, want)
-	h.SetChecksum(want)
-
-	testICMPChecksum(t, h.Checksum, func() uint16 {
-		return header.ICMPv6Checksum(header.ICMPv6ChecksumParams{
-			Header:      h,
-			Src:         src,
-			Dst:         dst,
-			PayloadCsum: header.ChecksumVV(vv, 0),
-			PayloadLen:  vv.Size(),
-		})
-	}, want, fmt.Sprintf("header: {% x} data {% x}", h, vv.ToView()))
-}
diff --git a/pkg/tcpip/header/eth_test.go b/pkg/tcpip/header/eth_test.go
deleted file mode 100644
index 3bc8b2b..0000000
--- a/pkg/tcpip/header/eth_test.go
+++ /dev/null
@@ -1,149 +0,0 @@
-// 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 header
-
-import (
-	"testing"
-
-	"gvisor.dev/gvisor/pkg/tcpip"
-)
-
-func TestIsValidUnicastEthernetAddress(t *testing.T) {
-	tests := []struct {
-		name     string
-		addr     tcpip.LinkAddress
-		expected bool
-	}{
-		{
-			"Nil",
-			tcpip.LinkAddress([]byte(nil)),
-			false,
-		},
-		{
-			"Empty",
-			tcpip.LinkAddress(""),
-			false,
-		},
-		{
-			"InvalidLength",
-			tcpip.LinkAddress("\x01\x02\x03"),
-			false,
-		},
-		{
-			"Unspecified",
-			unspecifiedEthernetAddress,
-			false,
-		},
-		{
-			"Multicast",
-			tcpip.LinkAddress("\x01\x02\x03\x04\x05\x06"),
-			false,
-		},
-		{
-			"Valid",
-			tcpip.LinkAddress("\x02\x02\x03\x04\x05\x06"),
-			true,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			if got := IsValidUnicastEthernetAddress(test.addr); got != test.expected {
-				t.Fatalf("got IsValidUnicastEthernetAddress = %t, want = %t", got, test.expected)
-			}
-		})
-	}
-}
-
-func TestIsMulticastEthernetAddress(t *testing.T) {
-	tests := []struct {
-		name     string
-		addr     tcpip.LinkAddress
-		expected bool
-	}{
-		{
-			"Nil",
-			tcpip.LinkAddress([]byte(nil)),
-			false,
-		},
-		{
-			"Empty",
-			tcpip.LinkAddress(""),
-			false,
-		},
-		{
-			"InvalidLength",
-			tcpip.LinkAddress("\x01\x02\x03"),
-			false,
-		},
-		{
-			"Unspecified",
-			unspecifiedEthernetAddress,
-			false,
-		},
-		{
-			"Multicast",
-			tcpip.LinkAddress("\x01\x02\x03\x04\x05\x06"),
-			true,
-		},
-		{
-			"Unicast",
-			tcpip.LinkAddress("\x02\x02\x03\x04\x05\x06"),
-			false,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			if got := IsMulticastEthernetAddress(test.addr); got != test.expected {
-				t.Fatalf("got IsMulticastEthernetAddress = %t, want = %t", got, test.expected)
-			}
-		})
-	}
-}
-
-func TestEthernetAddressFromMulticastIPv4Address(t *testing.T) {
-	tests := []struct {
-		name             string
-		addr             tcpip.Address
-		expectedLinkAddr tcpip.LinkAddress
-	}{
-		{
-			name:             "IPv4 Multicast without 24th bit set",
-			addr:             "\xe0\x7e\xdc\xba",
-			expectedLinkAddr: "\x01\x00\x5e\x7e\xdc\xba",
-		},
-		{
-			name:             "IPv4 Multicast with 24th bit set",
-			addr:             "\xe0\xfe\xdc\xba",
-			expectedLinkAddr: "\x01\x00\x5e\x7e\xdc\xba",
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			if got := EthernetAddressFromMulticastIPv4Address(test.addr); got != test.expectedLinkAddr {
-				t.Fatalf("got EthernetAddressFromMulticastIPv4Address(%s) = %s, want = %s", test.addr, got, test.expectedLinkAddr)
-			}
-		})
-	}
-}
-
-func TestEthernetAddressFromMulticastIPv6Address(t *testing.T) {
-	addr := tcpip.Address("\xff\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x1a")
-	if got, want := EthernetAddressFromMulticastIPv6Address(addr), tcpip.LinkAddress("\x33\x33\x0d\x0e\x0f\x1a"); got != want {
-		t.Fatalf("got EthernetAddressFromMulticastIPv6Address(%s) = %s, want = %s", addr, got, want)
-	}
-}
diff --git a/pkg/tcpip/header/header_state_autogen.go b/pkg/tcpip/header/header_state_autogen.go
new file mode 100644
index 0000000..d6dd588
--- /dev/null
+++ b/pkg/tcpip/header/header_state_autogen.go
@@ -0,0 +1,74 @@
+// automatically generated by stateify.
+
+package header
+
+import (
+	"gvisor.dev/gvisor/pkg/state"
+)
+
+func (r *SACKBlock) StateTypeName() string {
+	return "pkg/tcpip/header.SACKBlock"
+}
+
+func (r *SACKBlock) StateFields() []string {
+	return []string{
+		"Start",
+		"End",
+	}
+}
+
+func (r *SACKBlock) beforeSave() {}
+
+// +checklocksignore
+func (r *SACKBlock) StateSave(stateSinkObject state.Sink) {
+	r.beforeSave()
+	stateSinkObject.Save(0, &r.Start)
+	stateSinkObject.Save(1, &r.End)
+}
+
+func (r *SACKBlock) afterLoad() {}
+
+// +checklocksignore
+func (r *SACKBlock) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &r.Start)
+	stateSourceObject.Load(1, &r.End)
+}
+
+func (t *TCPOptions) StateTypeName() string {
+	return "pkg/tcpip/header.TCPOptions"
+}
+
+func (t *TCPOptions) StateFields() []string {
+	return []string{
+		"TS",
+		"TSVal",
+		"TSEcr",
+		"SACKBlocks",
+	}
+}
+
+func (t *TCPOptions) beforeSave() {}
+
+// +checklocksignore
+func (t *TCPOptions) StateSave(stateSinkObject state.Sink) {
+	t.beforeSave()
+	stateSinkObject.Save(0, &t.TS)
+	stateSinkObject.Save(1, &t.TSVal)
+	stateSinkObject.Save(2, &t.TSEcr)
+	stateSinkObject.Save(3, &t.SACKBlocks)
+}
+
+func (t *TCPOptions) afterLoad() {}
+
+// +checklocksignore
+func (t *TCPOptions) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &t.TS)
+	stateSourceObject.Load(1, &t.TSVal)
+	stateSourceObject.Load(2, &t.TSEcr)
+	stateSourceObject.Load(3, &t.SACKBlocks)
+}
+
+func init() {
+	state.Register((*SACKBlock)(nil))
+	state.Register((*TCPOptions)(nil))
+}
diff --git a/pkg/tcpip/header/igmp_test.go b/pkg/tcpip/header/igmp_test.go
deleted file mode 100644
index b6126d2..0000000
--- a/pkg/tcpip/header/igmp_test.go
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright 2020 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 header_test
-
-import (
-	"testing"
-	"time"
-
-	"gvisor.dev/gvisor/pkg/tcpip"
-	"gvisor.dev/gvisor/pkg/tcpip/header"
-)
-
-// TestIGMPHeader tests the functions within header.igmp
-func TestIGMPHeader(t *testing.T) {
-	const maxRespTimeTenthSec = 0xF0
-	b := []byte{
-		0x11,                // IGMP Type, Membership Query
-		maxRespTimeTenthSec, // Maximum Response Time
-		0xC0, 0xC0,          // Checksum
-		0x01, 0x02, 0x03, 0x04, // Group Address
-	}
-
-	igmpHeader := header.IGMP(b)
-
-	if got, want := igmpHeader.Type(), header.IGMPMembershipQuery; got != want {
-		t.Errorf("got igmpHeader.Type() = %x, want = %x", got, want)
-	}
-
-	if got, want := igmpHeader.MaxRespTime(), header.DecisecondToDuration(maxRespTimeTenthSec); got != want {
-		t.Errorf("got igmpHeader.MaxRespTime() = %s, want = %s", got, want)
-	}
-
-	if got, want := igmpHeader.Checksum(), uint16(0xC0C0); got != want {
-		t.Errorf("got igmpHeader.Checksum() = %x, want = %x", got, want)
-	}
-
-	if got, want := igmpHeader.GroupAddress(), tcpip.Address("\x01\x02\x03\x04"); got != want {
-		t.Errorf("got igmpHeader.GroupAddress() = %s, want = %s", got, want)
-	}
-
-	igmpType := header.IGMPv2MembershipReport
-	igmpHeader.SetType(igmpType)
-	if got := igmpHeader.Type(); got != igmpType {
-		t.Errorf("got igmpHeader.Type() = %x, want = %x", got, igmpType)
-	}
-	if got := header.IGMPType(b[0]); got != igmpType {
-		t.Errorf("got IGMPtype in backing buffer = %x, want %x", got, igmpType)
-	}
-
-	respTime := byte(0x02)
-	igmpHeader.SetMaxRespTime(respTime)
-	if got, want := igmpHeader.MaxRespTime(), header.DecisecondToDuration(respTime); got != want {
-		t.Errorf("got igmpHeader.MaxRespTime() = %s, want = %s", got, want)
-	}
-
-	checksum := uint16(0x0102)
-	igmpHeader.SetChecksum(checksum)
-	if got := igmpHeader.Checksum(); got != checksum {
-		t.Errorf("got igmpHeader.Checksum() = %x, want = %x", got, checksum)
-	}
-
-	groupAddress := tcpip.Address("\x04\x03\x02\x01")
-	igmpHeader.SetGroupAddress(groupAddress)
-	if got := igmpHeader.GroupAddress(); got != groupAddress {
-		t.Errorf("got igmpHeader.GroupAddress() = %s, want = %s", got, groupAddress)
-	}
-}
-
-// TestIGMPChecksum ensures that the checksum calculator produces the expected
-// checksum.
-func TestIGMPChecksum(t *testing.T) {
-	b := []byte{
-		0x11,       // IGMP Type, Membership Query
-		0xF0,       // Maximum Response Time
-		0xC0, 0xC0, // Checksum
-		0x01, 0x02, 0x03, 0x04, // Group Address
-	}
-
-	igmpHeader := header.IGMP(b)
-
-	// Calculate the initial checksum after setting the checksum temporarily to 0
-	// to avoid checksumming the checksum.
-	initialChecksum := igmpHeader.Checksum()
-	igmpHeader.SetChecksum(0)
-	checksum := ^header.Checksum(b, 0)
-	igmpHeader.SetChecksum(initialChecksum)
-
-	if got := header.IGMPCalculateChecksum(igmpHeader); got != checksum {
-		t.Errorf("got IGMPCalculateChecksum = %x, want %x", got, checksum)
-	}
-}
-
-func TestDecisecondToDuration(t *testing.T) {
-	const valueInDeciseconds = 5
-	if got, want := header.DecisecondToDuration(valueInDeciseconds), valueInDeciseconds*time.Second/10; got != want {
-		t.Fatalf("got header.DecisecondToDuration(%d) = %s, want = %s", valueInDeciseconds, got, want)
-	}
-}
diff --git a/pkg/tcpip/header/ipv4_test.go b/pkg/tcpip/header/ipv4_test.go
deleted file mode 100644
index 6475cd6..0000000
--- a/pkg/tcpip/header/ipv4_test.go
+++ /dev/null
@@ -1,179 +0,0 @@
-// Copyright 2020 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 header_test
-
-import (
-	"testing"
-
-	"github.com/google/go-cmp/cmp"
-	"gvisor.dev/gvisor/pkg/tcpip/buffer"
-	"gvisor.dev/gvisor/pkg/tcpip/header"
-)
-
-func TestIPv4OptionsSerializer(t *testing.T) {
-	optCases := []struct {
-		name   string
-		option []header.IPv4SerializableOption
-		expect []byte
-	}{
-		{
-			name: "NOP",
-			option: []header.IPv4SerializableOption{
-				&header.IPv4SerializableNOPOption{},
-			},
-			expect: []byte{1, 0, 0, 0},
-		},
-		{
-			name: "ListEnd",
-			option: []header.IPv4SerializableOption{
-				&header.IPv4SerializableListEndOption{},
-			},
-			expect: []byte{0, 0, 0, 0},
-		},
-		{
-			name: "RouterAlert",
-			option: []header.IPv4SerializableOption{
-				&header.IPv4SerializableRouterAlertOption{},
-			},
-			expect: []byte{148, 4, 0, 0},
-		}, {
-			name: "NOP and RouterAlert",
-			option: []header.IPv4SerializableOption{
-				&header.IPv4SerializableNOPOption{},
-				&header.IPv4SerializableRouterAlertOption{},
-			},
-			expect: []byte{1, 148, 4, 0, 0, 0, 0, 0},
-		},
-	}
-
-	for _, opt := range optCases {
-		t.Run(opt.name, func(t *testing.T) {
-			s := header.IPv4OptionsSerializer(opt.option)
-			l := s.Length()
-			if got := len(opt.expect); got != int(l) {
-				t.Fatalf("s.Length() = %d, want = %d", got, l)
-			}
-			b := make([]byte, l)
-			for i := range b {
-				// Fill the buffer with full bytes to ensure padding is being set
-				// correctly.
-				b[i] = 0xFF
-			}
-			if serializedLength := s.Serialize(b); serializedLength != l {
-				t.Fatalf("s.Serialize(_) = %d, want %d", serializedLength, l)
-			}
-			if diff := cmp.Diff(opt.expect, b); diff != "" {
-				t.Errorf("mismatched serialized option (-want +got):\n%s", diff)
-			}
-		})
-	}
-}
-
-// TestIPv4Encode checks that ipv4.Encode correctly fills out the requested
-// fields when options are supplied.
-func TestIPv4EncodeOptions(t *testing.T) {
-	tests := []struct {
-		name           string
-		numberOfNops   int
-		encodedOptions header.IPv4Options // reply should look like this
-		wantIHL        int
-	}{
-		{
-			name:    "valid no options",
-			wantIHL: header.IPv4MinimumSize,
-		},
-		{
-			name:           "one byte options",
-			numberOfNops:   1,
-			encodedOptions: header.IPv4Options{1, 0, 0, 0},
-			wantIHL:        header.IPv4MinimumSize + 4,
-		},
-		{
-			name:           "two byte options",
-			numberOfNops:   2,
-			encodedOptions: header.IPv4Options{1, 1, 0, 0},
-			wantIHL:        header.IPv4MinimumSize + 4,
-		},
-		{
-			name:           "three byte options",
-			numberOfNops:   3,
-			encodedOptions: header.IPv4Options{1, 1, 1, 0},
-			wantIHL:        header.IPv4MinimumSize + 4,
-		},
-		{
-			name:           "four byte options",
-			numberOfNops:   4,
-			encodedOptions: header.IPv4Options{1, 1, 1, 1},
-			wantIHL:        header.IPv4MinimumSize + 4,
-		},
-		{
-			name:           "five byte options",
-			numberOfNops:   5,
-			encodedOptions: header.IPv4Options{1, 1, 1, 1, 1, 0, 0, 0},
-			wantIHL:        header.IPv4MinimumSize + 8,
-		},
-		{
-			name:         "thirty nine byte options",
-			numberOfNops: 39,
-			encodedOptions: header.IPv4Options{
-				1, 1, 1, 1, 1, 1, 1, 1,
-				1, 1, 1, 1, 1, 1, 1, 1,
-				1, 1, 1, 1, 1, 1, 1, 1,
-				1, 1, 1, 1, 1, 1, 1, 1,
-				1, 1, 1, 1, 1, 1, 1, 0,
-			},
-			wantIHL: header.IPv4MinimumSize + 40,
-		},
-	}
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			serializeOpts := header.IPv4OptionsSerializer(make([]header.IPv4SerializableOption, test.numberOfNops))
-			for i := range serializeOpts {
-				serializeOpts[i] = &header.IPv4SerializableNOPOption{}
-			}
-			paddedOptionLength := serializeOpts.Length()
-			ipHeaderLength := int(header.IPv4MinimumSize + paddedOptionLength)
-			if ipHeaderLength > header.IPv4MaximumHeaderSize {
-				t.Fatalf("IP header length too large: got = %d, want <= %d ", ipHeaderLength, header.IPv4MaximumHeaderSize)
-			}
-			totalLen := uint16(ipHeaderLength)
-			hdr := buffer.NewPrependable(int(totalLen))
-			ip := header.IPv4(hdr.Prepend(ipHeaderLength))
-			// To check the padding works, poison the last byte of the options space.
-			if paddedOptionLength != serializeOpts.Length() {
-				ip.SetHeaderLength(uint8(ipHeaderLength))
-				ip.Options()[paddedOptionLength-1] = 0xff
-				ip.SetHeaderLength(0)
-			}
-			ip.Encode(&header.IPv4Fields{
-				Options: serializeOpts,
-			})
-			options := ip.Options()
-			wantOptions := test.encodedOptions
-			if got, want := int(ip.HeaderLength()), test.wantIHL; got != want {
-				t.Errorf("got IHL of %d, want %d", got, want)
-			}
-
-			// cmp.Diff does not consider nil slices equal to empty slices, but we do.
-			if len(wantOptions) == 0 && len(options) == 0 {
-				return
-			}
-
-			if diff := cmp.Diff(wantOptions, options); diff != "" {
-				t.Errorf("options mismatch (-want +got):\n%s", diff)
-			}
-		})
-	}
-}
diff --git a/pkg/tcpip/header/ipv6_extension_headers_test.go b/pkg/tcpip/header/ipv6_extension_headers_test.go
deleted file mode 100644
index 65adc62..0000000
--- a/pkg/tcpip/header/ipv6_extension_headers_test.go
+++ /dev/null
@@ -1,1346 +0,0 @@
-// Copyright 2020 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 header
-
-import (
-	"bytes"
-	"errors"
-	"io"
-	"testing"
-
-	"github.com/google/go-cmp/cmp"
-	"gvisor.dev/gvisor/pkg/tcpip"
-	"gvisor.dev/gvisor/pkg/tcpip/buffer"
-)
-
-// Equal returns true of a and b are equivalent.
-//
-// Note, Equal will return true if a and b hold the same Identifier value and
-// contain the same bytes in Buf, even if the bytes are split across views
-// differently.
-//
-// Needed to use cmp.Equal on IPv6RawPayloadHeader as it contains unexported
-// fields.
-func (a IPv6RawPayloadHeader) Equal(b IPv6RawPayloadHeader) bool {
-	return a.Identifier == b.Identifier && bytes.Equal(a.Buf.ToView(), b.Buf.ToView())
-}
-
-// Equal returns true of a and b are equivalent.
-//
-// Note, Equal will return true if a and b hold equivalent ipv6OptionsExtHdrs.
-//
-// Needed to use cmp.Equal on IPv6RawPayloadHeader as it contains unexported
-// fields.
-func (a IPv6HopByHopOptionsExtHdr) Equal(b IPv6HopByHopOptionsExtHdr) bool {
-	return bytes.Equal(a.ipv6OptionsExtHdr, b.ipv6OptionsExtHdr)
-}
-
-// Equal returns true of a and b are equivalent.
-//
-// Note, Equal will return true if a and b hold equivalent ipv6OptionsExtHdrs.
-//
-// Needed to use cmp.Equal on IPv6RawPayloadHeader as it contains unexported
-// fields.
-func (a IPv6DestinationOptionsExtHdr) Equal(b IPv6DestinationOptionsExtHdr) bool {
-	return bytes.Equal(a.ipv6OptionsExtHdr, b.ipv6OptionsExtHdr)
-}
-
-func TestIPv6UnknownExtHdrOption(t *testing.T) {
-	tests := []struct {
-		name                  string
-		identifier            IPv6ExtHdrOptionIdentifier
-		expectedUnknownAction IPv6OptionUnknownAction
-	}{
-		{
-			name:                  "Skip with zero LSBs",
-			identifier:            0,
-			expectedUnknownAction: IPv6OptionUnknownActionSkip,
-		},
-		{
-			name:                  "Discard with zero LSBs",
-			identifier:            64,
-			expectedUnknownAction: IPv6OptionUnknownActionDiscard,
-		},
-		{
-			name:                  "Discard and ICMP with zero LSBs",
-			identifier:            128,
-			expectedUnknownAction: IPv6OptionUnknownActionDiscardSendICMP,
-		},
-		{
-			name:                  "Discard and ICMP for non multicast destination with zero LSBs",
-			identifier:            192,
-			expectedUnknownAction: IPv6OptionUnknownActionDiscardSendICMPNoMulticastDest,
-		},
-		{
-			name:                  "Skip with non-zero LSBs",
-			identifier:            63,
-			expectedUnknownAction: IPv6OptionUnknownActionSkip,
-		},
-		{
-			name:                  "Discard with non-zero LSBs",
-			identifier:            127,
-			expectedUnknownAction: IPv6OptionUnknownActionDiscard,
-		},
-		{
-			name:                  "Discard and ICMP with non-zero LSBs",
-			identifier:            191,
-			expectedUnknownAction: IPv6OptionUnknownActionDiscardSendICMP,
-		},
-		{
-			name:                  "Discard and ICMP for non multicast destination with non-zero LSBs",
-			identifier:            255,
-			expectedUnknownAction: IPv6OptionUnknownActionDiscardSendICMPNoMulticastDest,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			opt := &IPv6UnknownExtHdrOption{Identifier: test.identifier, Data: []byte{1, 2, 3, 4}}
-			if a := opt.UnknownAction(); a != test.expectedUnknownAction {
-				t.Fatalf("got UnknownAction() = %d, want = %d", a, test.expectedUnknownAction)
-			}
-		})
-	}
-
-}
-
-func TestIPv6OptionsExtHdrIterErr(t *testing.T) {
-	tests := []struct {
-		name  string
-		bytes []byte
-		err   error
-	}{
-		{
-			name:  "Single unknown with zero length",
-			bytes: []byte{255, 0},
-		},
-		{
-			name:  "Single unknown with non-zero length",
-			bytes: []byte{255, 3, 1, 2, 3},
-		},
-		{
-			name: "Two options",
-			bytes: []byte{
-				255, 0,
-				254, 1, 1,
-			},
-		},
-		{
-			name: "Three options",
-			bytes: []byte{
-				255, 0,
-				254, 1, 1,
-				253, 4, 2, 3, 4, 5,
-			},
-		},
-		{
-			name:  "Single unknown only identifier",
-			bytes: []byte{255},
-			err:   io.ErrUnexpectedEOF,
-		},
-		{
-			name:  "Single unknown too small with length = 1",
-			bytes: []byte{255, 1},
-			err:   io.ErrUnexpectedEOF,
-		},
-		{
-			name:  "Single unknown too small with length = 2",
-			bytes: []byte{255, 2, 1},
-			err:   io.ErrUnexpectedEOF,
-		},
-		{
-			name: "Valid first with second unknown only identifier",
-			bytes: []byte{
-				255, 0,
-				254,
-			},
-			err: io.ErrUnexpectedEOF,
-		},
-		{
-			name: "Valid first with second unknown missing data",
-			bytes: []byte{
-				255, 0,
-				254, 1,
-			},
-			err: io.ErrUnexpectedEOF,
-		},
-		{
-			name: "Valid first with second unknown too small",
-			bytes: []byte{
-				255, 0,
-				254, 2, 1,
-			},
-			err: io.ErrUnexpectedEOF,
-		},
-		{
-			name:  "One Pad1",
-			bytes: []byte{0},
-		},
-		{
-			name:  "Multiple Pad1",
-			bytes: []byte{0, 0, 0},
-		},
-		{
-			name: "Multiple PadN",
-			bytes: []byte{
-				// Pad3
-				1, 1, 1,
-
-				// Pad5
-				1, 3, 1, 2, 3,
-			},
-		},
-		{
-			name:  "Pad5 too small middle of data buffer",
-			bytes: []byte{1, 3, 1, 2},
-			err:   io.ErrUnexpectedEOF,
-		},
-		{
-			name:  "Pad5 no data",
-			bytes: []byte{1, 3},
-			err:   io.ErrUnexpectedEOF,
-		},
-		{
-			name:  "Router alert without data",
-			bytes: []byte{byte(ipv6RouterAlertHopByHopOptionIdentifier), 0},
-			err:   ErrMalformedIPv6ExtHdrOption,
-		},
-		{
-			name:  "Router alert with partial data",
-			bytes: []byte{byte(ipv6RouterAlertHopByHopOptionIdentifier), 1, 1},
-			err:   ErrMalformedIPv6ExtHdrOption,
-		},
-		{
-			name:  "Router alert with partial data and Pad1",
-			bytes: []byte{byte(ipv6RouterAlertHopByHopOptionIdentifier), 1, 1, 0},
-			err:   ErrMalformedIPv6ExtHdrOption,
-		},
-		{
-			name:  "Router alert with extra data",
-			bytes: []byte{byte(ipv6RouterAlertHopByHopOptionIdentifier), 3, 1, 2, 3},
-			err:   ErrMalformedIPv6ExtHdrOption,
-		},
-		{
-			name:  "Router alert with missing data",
-			bytes: []byte{byte(ipv6RouterAlertHopByHopOptionIdentifier), 1},
-			err:   io.ErrUnexpectedEOF,
-		},
-	}
-
-	check := func(t *testing.T, it IPv6OptionsExtHdrOptionsIterator, expectedErr error) {
-		for i := 0; ; i++ {
-			_, done, err := it.Next()
-			if err != nil {
-				// If we encountered a non-nil error while iterating, make sure it is
-				// is the same error as expectedErr.
-				if !errors.Is(err, expectedErr) {
-					t.Fatalf("got %d-th Next() = %v, want = %v", i, err, expectedErr)
-				}
-
-				return
-			}
-			if done {
-				// If we are done (without an error), make sure that we did not expect
-				// an error.
-				if expectedErr != nil {
-					t.Fatalf("expected error when iterating; want = %s", expectedErr)
-				}
-
-				return
-			}
-		}
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			t.Run("Hop By Hop", func(t *testing.T) {
-				extHdr := IPv6HopByHopOptionsExtHdr{ipv6OptionsExtHdr: test.bytes}
-				check(t, extHdr.Iter(), test.err)
-			})
-
-			t.Run("Destination", func(t *testing.T) {
-				extHdr := IPv6DestinationOptionsExtHdr{ipv6OptionsExtHdr: test.bytes}
-				check(t, extHdr.Iter(), test.err)
-			})
-		})
-	}
-}
-
-func TestIPv6OptionsExtHdrIter(t *testing.T) {
-	tests := []struct {
-		name     string
-		bytes    []byte
-		expected []IPv6ExtHdrOption
-	}{
-		{
-			name:  "Single unknown with zero length",
-			bytes: []byte{255, 0},
-			expected: []IPv6ExtHdrOption{
-				&IPv6UnknownExtHdrOption{Identifier: 255, Data: []byte{}},
-			},
-		},
-		{
-			name:  "Single unknown with non-zero length",
-			bytes: []byte{255, 3, 1, 2, 3},
-			expected: []IPv6ExtHdrOption{
-				&IPv6UnknownExtHdrOption{Identifier: 255, Data: []byte{1, 2, 3}},
-			},
-		},
-		{
-			name:  "Single Pad1",
-			bytes: []byte{0},
-		},
-		{
-			name:  "Two Pad1",
-			bytes: []byte{0, 0},
-		},
-		{
-			name:  "Single Pad3",
-			bytes: []byte{1, 1, 1},
-		},
-		{
-			name:  "Single Pad5",
-			bytes: []byte{1, 3, 1, 2, 3},
-		},
-		{
-			name: "Multiple Pad",
-			bytes: []byte{
-				// Pad1
-				0,
-
-				// Pad2
-				1, 0,
-
-				// Pad3
-				1, 1, 1,
-
-				// Pad4
-				1, 2, 1, 2,
-
-				// Pad5
-				1, 3, 1, 2, 3,
-			},
-		},
-		{
-			name: "Multiple options",
-			bytes: []byte{
-				// Pad1
-				0,
-
-				// Unknown
-				255, 0,
-
-				// Pad2
-				1, 0,
-
-				// Unknown
-				254, 1, 1,
-
-				// Pad3
-				1, 1, 1,
-
-				// Unknown
-				253, 4, 2, 3, 4, 5,
-
-				// Pad4
-				1, 2, 1, 2,
-			},
-			expected: []IPv6ExtHdrOption{
-				&IPv6UnknownExtHdrOption{Identifier: 255, Data: []byte{}},
-				&IPv6UnknownExtHdrOption{Identifier: 254, Data: []byte{1}},
-				&IPv6UnknownExtHdrOption{Identifier: 253, Data: []byte{2, 3, 4, 5}},
-			},
-		},
-	}
-
-	checkIter := func(t *testing.T, it IPv6OptionsExtHdrOptionsIterator, expected []IPv6ExtHdrOption) {
-		for i, e := range expected {
-			opt, done, err := it.Next()
-			if err != nil {
-				t.Errorf("(i=%d) Next(): %s", i, err)
-			}
-			if done {
-				t.Errorf("(i=%d) unexpectedly done iterating", i)
-			}
-			if diff := cmp.Diff(e, opt); diff != "" {
-				t.Errorf("(i=%d) got option mismatch (-want +got):\n%s", i, diff)
-			}
-
-			if t.Failed() {
-				t.FailNow()
-			}
-		}
-
-		opt, done, err := it.Next()
-		if err != nil {
-			t.Errorf("(last) Next(): %s", err)
-		}
-		if !done {
-			t.Errorf("(last) iterator unexpectedly not done")
-		}
-		if opt != nil {
-			t.Errorf("(last) got Next() = %T, want = nil", opt)
-		}
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			t.Run("Hop By Hop", func(t *testing.T) {
-				extHdr := IPv6HopByHopOptionsExtHdr{ipv6OptionsExtHdr: test.bytes}
-				checkIter(t, extHdr.Iter(), test.expected)
-			})
-
-			t.Run("Destination", func(t *testing.T) {
-				extHdr := IPv6DestinationOptionsExtHdr{ipv6OptionsExtHdr: test.bytes}
-				checkIter(t, extHdr.Iter(), test.expected)
-			})
-		})
-	}
-}
-
-func TestIPv6RoutingExtHdr(t *testing.T) {
-	tests := []struct {
-		name         string
-		bytes        []byte
-		segmentsLeft uint8
-	}{
-		{
-			name:         "Zeroes",
-			bytes:        []byte{0, 0, 0, 0, 0, 0},
-			segmentsLeft: 0,
-		},
-		{
-			name:         "Ones",
-			bytes:        []byte{1, 1, 1, 1, 1, 1},
-			segmentsLeft: 1,
-		},
-		{
-			name:         "Mixed",
-			bytes:        []byte{1, 2, 3, 4, 5, 6},
-			segmentsLeft: 2,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			extHdr := IPv6RoutingExtHdr(test.bytes)
-			if got := extHdr.SegmentsLeft(); got != test.segmentsLeft {
-				t.Errorf("got SegmentsLeft() = %d, want = %d", got, test.segmentsLeft)
-			}
-		})
-	}
-}
-
-func TestIPv6FragmentExtHdr(t *testing.T) {
-	tests := []struct {
-		name           string
-		bytes          [6]byte
-		fragmentOffset uint16
-		more           bool
-		id             uint32
-	}{
-		{
-			name:           "Zeroes",
-			bytes:          [6]byte{0, 0, 0, 0, 0, 0},
-			fragmentOffset: 0,
-			more:           false,
-			id:             0,
-		},
-		{
-			name:           "Ones",
-			bytes:          [6]byte{0, 9, 0, 0, 0, 1},
-			fragmentOffset: 1,
-			more:           true,
-			id:             1,
-		},
-		{
-			name:           "Mixed",
-			bytes:          [6]byte{68, 9, 128, 4, 2, 1},
-			fragmentOffset: 2177,
-			more:           true,
-			id:             2147746305,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			extHdr := IPv6FragmentExtHdr(test.bytes)
-			if got := extHdr.FragmentOffset(); got != test.fragmentOffset {
-				t.Errorf("got FragmentOffset() = %d, want = %d", got, test.fragmentOffset)
-			}
-			if got := extHdr.More(); got != test.more {
-				t.Errorf("got More() = %t, want = %t", got, test.more)
-			}
-			if got := extHdr.ID(); got != test.id {
-				t.Errorf("got ID() = %d, want = %d", got, test.id)
-			}
-		})
-	}
-}
-
-func makeVectorisedViewFromByteBuffers(bs ...[]byte) buffer.VectorisedView {
-	size := 0
-	var vs []buffer.View
-
-	for _, b := range bs {
-		vs = append(vs, buffer.View(b))
-		size += len(b)
-	}
-
-	return buffer.NewVectorisedView(size, vs)
-}
-
-func TestIPv6ExtHdrIterErr(t *testing.T) {
-	tests := []struct {
-		name         string
-		firstNextHdr IPv6ExtensionHeaderIdentifier
-		payload      buffer.VectorisedView
-		err          error
-	}{
-		{
-			name:         "Upper layer only without data",
-			firstNextHdr: 255,
-		},
-		{
-			name:         "Upper layer only with data",
-			firstNextHdr: 255,
-			payload:      makeVectorisedViewFromByteBuffers([]byte{1, 2, 3, 4}),
-		},
-		{
-			name:         "No next header",
-			firstNextHdr: IPv6NoNextHeaderIdentifier,
-		},
-		{
-			name:         "No next header with data",
-			firstNextHdr: IPv6NoNextHeaderIdentifier,
-			payload:      makeVectorisedViewFromByteBuffers([]byte{1, 2, 3, 4}),
-		},
-		{
-			name:         "Valid single hop by hop",
-			firstNextHdr: IPv6HopByHopOptionsExtHdrIdentifier,
-			payload:      makeVectorisedViewFromByteBuffers([]byte{255, 0, 1, 4, 1, 2, 3, 4}),
-		},
-		{
-			name:         "Hop by hop too small",
-			firstNextHdr: IPv6HopByHopOptionsExtHdrIdentifier,
-			payload:      makeVectorisedViewFromByteBuffers([]byte{255, 0, 1, 4, 1, 2, 3}),
-			err:          io.ErrUnexpectedEOF,
-		},
-		{
-			name:         "Valid single fragment",
-			firstNextHdr: IPv6FragmentExtHdrIdentifier,
-			payload:      makeVectorisedViewFromByteBuffers([]byte{255, 0, 68, 9, 128, 4, 2, 1}),
-		},
-		{
-			name:         "Fragment too small",
-			firstNextHdr: IPv6FragmentExtHdrIdentifier,
-			payload:      makeVectorisedViewFromByteBuffers([]byte{255, 0, 68, 9, 128, 4, 2}),
-			err:          io.ErrUnexpectedEOF,
-		},
-		{
-			name:         "Valid single destination",
-			firstNextHdr: IPv6DestinationOptionsExtHdrIdentifier,
-			payload:      makeVectorisedViewFromByteBuffers([]byte{255, 0, 1, 4, 1, 2, 3, 4}),
-		},
-		{
-			name:         "Destination too small",
-			firstNextHdr: IPv6DestinationOptionsExtHdrIdentifier,
-			payload:      makeVectorisedViewFromByteBuffers([]byte{255, 0, 1, 4, 1, 2, 3}),
-			err:          io.ErrUnexpectedEOF,
-		},
-		{
-			name:         "Valid single routing",
-			firstNextHdr: IPv6RoutingExtHdrIdentifier,
-			payload:      makeVectorisedViewFromByteBuffers([]byte{255, 0, 1, 2, 3, 4, 5, 6}),
-		},
-		{
-			name:         "Valid single routing across views",
-			firstNextHdr: IPv6RoutingExtHdrIdentifier,
-			payload:      makeVectorisedViewFromByteBuffers([]byte{255, 0, 1, 2}, []byte{3, 4, 5, 6}),
-		},
-		{
-			name:         "Routing too small with zero length field",
-			firstNextHdr: IPv6RoutingExtHdrIdentifier,
-			payload:      makeVectorisedViewFromByteBuffers([]byte{255, 0, 1, 2, 3, 4, 5}),
-			err:          io.ErrUnexpectedEOF,
-		},
-		{
-			name:         "Valid routing with non-zero length field",
-			firstNextHdr: IPv6RoutingExtHdrIdentifier,
-			payload:      makeVectorisedViewFromByteBuffers([]byte{255, 1, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 7, 8}),
-		},
-		{
-			name:         "Valid routing with non-zero length field across views",
-			firstNextHdr: IPv6RoutingExtHdrIdentifier,
-			payload:      makeVectorisedViewFromByteBuffers([]byte{255, 1, 1, 2, 3, 4, 5, 6}, []byte{1, 2, 3, 4, 5, 6, 7, 8}),
-		},
-		{
-			name:         "Routing too small with non-zero length field",
-			firstNextHdr: IPv6RoutingExtHdrIdentifier,
-			payload:      makeVectorisedViewFromByteBuffers([]byte{255, 1, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 7}),
-			err:          io.ErrUnexpectedEOF,
-		},
-		{
-			name:         "Routing too small with non-zero length field across views",
-			firstNextHdr: IPv6RoutingExtHdrIdentifier,
-			payload:      makeVectorisedViewFromByteBuffers([]byte{255, 1, 1, 2, 3, 4, 5, 6}, []byte{1, 2, 3, 4, 5, 6, 7}),
-			err:          io.ErrUnexpectedEOF,
-		},
-		{
-			name:         "Mixed",
-			firstNextHdr: IPv6HopByHopOptionsExtHdrIdentifier,
-			payload: makeVectorisedViewFromByteBuffers([]byte{
-				// Hop By Hop Options extension header.
-				uint8(IPv6FragmentExtHdrIdentifier), 0, 1, 4, 1, 2, 3, 4,
-
-				// (Atomic) Fragment extension header.
-				//
-				// Reserved bits are 1 which should not affect anything.
-				uint8(IPv6RoutingExtHdrIdentifier), 255, 0, 6, 128, 4, 2, 1,
-
-				// Routing extension header.
-				uint8(IPv6DestinationOptionsExtHdrIdentifier), 0, 1, 2, 3, 4, 5, 6,
-
-				// Destination Options extension header.
-				255, 0, 255, 4, 1, 2, 3, 4,
-
-				// Upper layer data.
-				1, 2, 3, 4,
-			}),
-		},
-		{
-			name:         "Mixed without upper layer data",
-			firstNextHdr: IPv6HopByHopOptionsExtHdrIdentifier,
-			payload: makeVectorisedViewFromByteBuffers([]byte{
-				// Hop By Hop Options extension header.
-				uint8(IPv6FragmentExtHdrIdentifier), 0, 1, 4, 1, 2, 3, 4,
-
-				// (Atomic) Fragment extension header.
-				//
-				// Reserved bits are 1 which should not affect anything.
-				uint8(IPv6RoutingExtHdrIdentifier), 255, 0, 6, 128, 4, 2, 1,
-
-				// Routing extension header.
-				uint8(IPv6DestinationOptionsExtHdrIdentifier), 0, 1, 2, 3, 4, 5, 6,
-
-				// Destination Options extension header.
-				255, 0, 255, 4, 1, 2, 3, 4,
-			}),
-		},
-		{
-			name:         "Mixed without upper layer data but last ext hdr too small",
-			firstNextHdr: IPv6HopByHopOptionsExtHdrIdentifier,
-			payload: makeVectorisedViewFromByteBuffers([]byte{
-				// Hop By Hop Options extension header.
-				uint8(IPv6FragmentExtHdrIdentifier), 0, 1, 4, 1, 2, 3, 4,
-
-				// (Atomic) Fragment extension header.
-				//
-				// Reserved bits are 1 which should not affect anything.
-				uint8(IPv6RoutingExtHdrIdentifier), 255, 0, 6, 128, 4, 2, 1,
-
-				// Routing extension header.
-				uint8(IPv6DestinationOptionsExtHdrIdentifier), 0, 1, 2, 3, 4, 5, 6,
-
-				// Destination Options extension header.
-				255, 0, 255, 4, 1, 2, 3,
-			}),
-			err: io.ErrUnexpectedEOF,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			it := MakeIPv6PayloadIterator(test.firstNextHdr, test.payload)
-
-			for i := 0; ; i++ {
-				_, done, err := it.Next()
-				if err != nil {
-					// If we encountered a non-nil error while iterating, make sure it is
-					// is the same error as test.err.
-					if !errors.Is(err, test.err) {
-						t.Fatalf("got %d-th Next() = %v, want = %v", i, err, test.err)
-					}
-
-					return
-				}
-				if done {
-					// If we are done (without an error), make sure that we did not expect
-					// an error.
-					if test.err != nil {
-						t.Fatalf("expected error when iterating; want = %s", test.err)
-					}
-
-					return
-				}
-			}
-		})
-	}
-}
-
-func TestIPv6ExtHdrIter(t *testing.T) {
-	routingExtHdrWithUpperLayerData := buffer.View([]byte{255, 0, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4})
-	upperLayerData := buffer.View([]byte{1, 2, 3, 4})
-	tests := []struct {
-		name         string
-		firstNextHdr IPv6ExtensionHeaderIdentifier
-		payload      buffer.VectorisedView
-		expected     []IPv6PayloadHeader
-	}{
-		// With a non-atomic fragment that is not the first fragment, the payload
-		// after the fragment will not be parsed because the payload is expected to
-		// only hold upper layer data.
-		{
-			name:         "hopbyhop - fragment (not first) - routing - upper",
-			firstNextHdr: IPv6HopByHopOptionsExtHdrIdentifier,
-			payload: makeVectorisedViewFromByteBuffers([]byte{
-				// Hop By Hop extension header.
-				uint8(IPv6FragmentExtHdrIdentifier), 0, 1, 4, 1, 2, 3, 4,
-
-				// Fragment extension header.
-				//
-				// More = 1, Fragment Offset = 2117, ID = 2147746305
-				uint8(IPv6RoutingExtHdrIdentifier), 0, 68, 9, 128, 4, 2, 1,
-
-				// Routing extension header.
-				//
-				// Even though we have a routing ext header here, it should be
-				// be interpretted as raw bytes as only the first fragment is expected
-				// to hold headers.
-				255, 0, 1, 2, 3, 4, 5, 6,
-
-				// Upper layer data.
-				1, 2, 3, 4,
-			}),
-			expected: []IPv6PayloadHeader{
-				IPv6HopByHopOptionsExtHdr{ipv6OptionsExtHdr: []byte{1, 4, 1, 2, 3, 4}},
-				IPv6FragmentExtHdr([6]byte{68, 9, 128, 4, 2, 1}),
-				IPv6RawPayloadHeader{
-					Identifier: IPv6RoutingExtHdrIdentifier,
-					Buf:        routingExtHdrWithUpperLayerData.ToVectorisedView(),
-				},
-			},
-		},
-		{
-			name:         "hopbyhop - fragment (first) - routing - upper",
-			firstNextHdr: IPv6HopByHopOptionsExtHdrIdentifier,
-			payload: makeVectorisedViewFromByteBuffers([]byte{
-				// Hop By Hop extension header.
-				uint8(IPv6FragmentExtHdrIdentifier), 0, 1, 4, 1, 2, 3, 4,
-
-				// Fragment extension header.
-				//
-				// More = 1, Fragment Offset = 0, ID = 2147746305
-				uint8(IPv6RoutingExtHdrIdentifier), 0, 0, 1, 128, 4, 2, 1,
-
-				// Routing extension header.
-				255, 0, 1, 2, 3, 4, 5, 6,
-
-				// Upper layer data.
-				1, 2, 3, 4,
-			}),
-			expected: []IPv6PayloadHeader{
-				IPv6HopByHopOptionsExtHdr{ipv6OptionsExtHdr: []byte{1, 4, 1, 2, 3, 4}},
-				IPv6FragmentExtHdr([6]byte{0, 1, 128, 4, 2, 1}),
-				IPv6RoutingExtHdr([]byte{1, 2, 3, 4, 5, 6}),
-				IPv6RawPayloadHeader{
-					Identifier: 255,
-					Buf:        upperLayerData.ToVectorisedView(),
-				},
-			},
-		},
-		{
-			name:         "fragment - routing - upper (across views)",
-			firstNextHdr: IPv6FragmentExtHdrIdentifier,
-			payload: makeVectorisedViewFromByteBuffers([]byte{
-				// Fragment extension header.
-				uint8(IPv6RoutingExtHdrIdentifier), 0, 68, 9, 128, 4, 2, 1,
-
-				// Routing extension header.
-				255, 0, 1, 2}, []byte{3, 4, 5, 6,
-
-				// Upper layer data.
-				1, 2, 3, 4,
-			}),
-			expected: []IPv6PayloadHeader{
-				IPv6FragmentExtHdr([6]byte{68, 9, 128, 4, 2, 1}),
-				IPv6RawPayloadHeader{
-					Identifier: IPv6RoutingExtHdrIdentifier,
-					Buf:        routingExtHdrWithUpperLayerData.ToVectorisedView(),
-				},
-			},
-		},
-
-		// If we have an atomic fragment, the payload following the fragment
-		// extension header should be parsed normally.
-		{
-			name:         "atomic fragment - routing - destination - upper",
-			firstNextHdr: IPv6FragmentExtHdrIdentifier,
-			payload: makeVectorisedViewFromByteBuffers([]byte{
-				// Fragment extension header.
-				//
-				// Reserved bits are 1 which should not affect anything.
-				uint8(IPv6RoutingExtHdrIdentifier), 255, 0, 6, 128, 4, 2, 1,
-
-				// Routing extension header.
-				uint8(IPv6DestinationOptionsExtHdrIdentifier), 0, 1, 2, 3, 4, 5, 6,
-
-				// Destination Options extension header.
-				255, 0, 1, 4, 1, 2, 3, 4,
-
-				// Upper layer data.
-				1, 2, 3, 4,
-			}),
-			expected: []IPv6PayloadHeader{
-				IPv6FragmentExtHdr([6]byte{0, 6, 128, 4, 2, 1}),
-				IPv6RoutingExtHdr([]byte{1, 2, 3, 4, 5, 6}),
-				IPv6DestinationOptionsExtHdr{ipv6OptionsExtHdr: []byte{1, 4, 1, 2, 3, 4}},
-				IPv6RawPayloadHeader{
-					Identifier: 255,
-					Buf:        upperLayerData.ToVectorisedView(),
-				},
-			},
-		},
-		{
-			name:         "atomic fragment - routing - upper (across views)",
-			firstNextHdr: IPv6FragmentExtHdrIdentifier,
-			payload: makeVectorisedViewFromByteBuffers([]byte{
-				// Fragment extension header.
-				//
-				// Reserved bits are 1 which should not affect anything.
-				uint8(IPv6RoutingExtHdrIdentifier), 255, 0, 6}, []byte{128, 4, 2, 1,
-
-				// Routing extension header.
-				255, 0, 1, 2}, []byte{3, 4, 5, 6,
-
-				// Upper layer data.
-				1, 2}, []byte{3, 4}),
-			expected: []IPv6PayloadHeader{
-				IPv6FragmentExtHdr([6]byte{0, 6, 128, 4, 2, 1}),
-				IPv6RoutingExtHdr([]byte{1, 2, 3, 4, 5, 6}),
-				IPv6RawPayloadHeader{
-					Identifier: 255,
-					Buf:        makeVectorisedViewFromByteBuffers(upperLayerData[:2], upperLayerData[2:]),
-				},
-			},
-		},
-		{
-			name:         "atomic fragment - destination - no next header",
-			firstNextHdr: IPv6FragmentExtHdrIdentifier,
-			payload: makeVectorisedViewFromByteBuffers([]byte{
-				// Fragment extension header.
-				//
-				// Res (Reserved) bits are 1 which should not affect anything.
-				uint8(IPv6DestinationOptionsExtHdrIdentifier), 0, 0, 6, 128, 4, 2, 1,
-
-				// Destination Options extension header.
-				uint8(IPv6NoNextHeaderIdentifier), 0, 1, 4, 1, 2, 3, 4,
-
-				// Random data.
-				1, 2, 3, 4,
-			}),
-			expected: []IPv6PayloadHeader{
-				IPv6FragmentExtHdr([6]byte{0, 6, 128, 4, 2, 1}),
-				IPv6DestinationOptionsExtHdr{ipv6OptionsExtHdr: []byte{1, 4, 1, 2, 3, 4}},
-			},
-		},
-		{
-			name:         "routing - atomic fragment - no next header",
-			firstNextHdr: IPv6RoutingExtHdrIdentifier,
-			payload: makeVectorisedViewFromByteBuffers([]byte{
-				// Routing extension header.
-				uint8(IPv6FragmentExtHdrIdentifier), 0, 1, 2, 3, 4, 5, 6,
-
-				// Fragment extension header.
-				//
-				// Reserved bits are 1 which should not affect anything.
-				uint8(IPv6NoNextHeaderIdentifier), 0, 0, 6, 128, 4, 2, 1,
-
-				// Random data.
-				1, 2, 3, 4,
-			}),
-			expected: []IPv6PayloadHeader{
-				IPv6RoutingExtHdr([]byte{1, 2, 3, 4, 5, 6}),
-				IPv6FragmentExtHdr([6]byte{0, 6, 128, 4, 2, 1}),
-			},
-		},
-		{
-			name:         "routing - atomic fragment - no next header (across views)",
-			firstNextHdr: IPv6RoutingExtHdrIdentifier,
-			payload: makeVectorisedViewFromByteBuffers([]byte{
-				// Routing extension header.
-				uint8(IPv6FragmentExtHdrIdentifier), 0, 1, 2, 3, 4, 5, 6,
-
-				// Fragment extension header.
-				//
-				// Reserved bits are 1 which should not affect anything.
-				uint8(IPv6NoNextHeaderIdentifier), 255, 0, 6}, []byte{128, 4, 2, 1,
-
-				// Random data.
-				1, 2, 3, 4,
-			}),
-			expected: []IPv6PayloadHeader{
-				IPv6RoutingExtHdr([]byte{1, 2, 3, 4, 5, 6}),
-				IPv6FragmentExtHdr([6]byte{0, 6, 128, 4, 2, 1}),
-			},
-		},
-		{
-			name:         "hopbyhop - routing - fragment - no next header",
-			firstNextHdr: IPv6HopByHopOptionsExtHdrIdentifier,
-			payload: makeVectorisedViewFromByteBuffers([]byte{
-				// Hop By Hop Options extension header.
-				uint8(IPv6RoutingExtHdrIdentifier), 0, 1, 4, 1, 2, 3, 4,
-
-				// Routing extension header.
-				uint8(IPv6FragmentExtHdrIdentifier), 0, 1, 2, 3, 4, 5, 6,
-
-				// Fragment extension header.
-				//
-				// Fragment Offset = 32; Res = 6.
-				uint8(IPv6NoNextHeaderIdentifier), 0, 1, 6, 128, 4, 2, 1,
-
-				// Random data.
-				1, 2, 3, 4,
-			}),
-			expected: []IPv6PayloadHeader{
-				IPv6HopByHopOptionsExtHdr{ipv6OptionsExtHdr: []byte{1, 4, 1, 2, 3, 4}},
-				IPv6RoutingExtHdr([]byte{1, 2, 3, 4, 5, 6}),
-				IPv6FragmentExtHdr([6]byte{1, 6, 128, 4, 2, 1}),
-				IPv6RawPayloadHeader{
-					Identifier: IPv6NoNextHeaderIdentifier,
-					Buf:        upperLayerData.ToVectorisedView(),
-				},
-			},
-		},
-
-		// Test the raw payload for common transport layer protocol numbers.
-		{
-			name:         "TCP raw payload",
-			firstNextHdr: IPv6ExtensionHeaderIdentifier(TCPProtocolNumber),
-			payload:      makeVectorisedViewFromByteBuffers(upperLayerData),
-			expected: []IPv6PayloadHeader{IPv6RawPayloadHeader{
-				Identifier: IPv6ExtensionHeaderIdentifier(TCPProtocolNumber),
-				Buf:        upperLayerData.ToVectorisedView(),
-			}},
-		},
-		{
-			name:         "UDP raw payload",
-			firstNextHdr: IPv6ExtensionHeaderIdentifier(UDPProtocolNumber),
-			payload:      makeVectorisedViewFromByteBuffers(upperLayerData),
-			expected: []IPv6PayloadHeader{IPv6RawPayloadHeader{
-				Identifier: IPv6ExtensionHeaderIdentifier(UDPProtocolNumber),
-				Buf:        upperLayerData.ToVectorisedView(),
-			}},
-		},
-		{
-			name:         "ICMPv4 raw payload",
-			firstNextHdr: IPv6ExtensionHeaderIdentifier(ICMPv4ProtocolNumber),
-			payload:      makeVectorisedViewFromByteBuffers(upperLayerData),
-			expected: []IPv6PayloadHeader{IPv6RawPayloadHeader{
-				Identifier: IPv6ExtensionHeaderIdentifier(ICMPv4ProtocolNumber),
-				Buf:        upperLayerData.ToVectorisedView(),
-			}},
-		},
-		{
-			name:         "ICMPv6 raw payload",
-			firstNextHdr: IPv6ExtensionHeaderIdentifier(ICMPv6ProtocolNumber),
-			payload:      makeVectorisedViewFromByteBuffers(upperLayerData),
-			expected: []IPv6PayloadHeader{IPv6RawPayloadHeader{
-				Identifier: IPv6ExtensionHeaderIdentifier(ICMPv6ProtocolNumber),
-				Buf:        upperLayerData.ToVectorisedView(),
-			}},
-		},
-		{
-			name:         "Unknwon next header raw payload",
-			firstNextHdr: 255,
-			payload:      makeVectorisedViewFromByteBuffers(upperLayerData),
-			expected: []IPv6PayloadHeader{IPv6RawPayloadHeader{
-				Identifier: 255,
-				Buf:        upperLayerData.ToVectorisedView(),
-			}},
-		},
-		{
-			name:         "Unknwon next header raw payload (across views)",
-			firstNextHdr: 255,
-			payload:      makeVectorisedViewFromByteBuffers(upperLayerData[:2], upperLayerData[2:]),
-			expected: []IPv6PayloadHeader{IPv6RawPayloadHeader{
-				Identifier: 255,
-				Buf:        makeVectorisedViewFromByteBuffers(upperLayerData[:2], upperLayerData[2:]),
-			}},
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			it := MakeIPv6PayloadIterator(test.firstNextHdr, test.payload)
-
-			for i, e := range test.expected {
-				extHdr, done, err := it.Next()
-				if err != nil {
-					t.Errorf("(i=%d) Next(): %s", i, err)
-				}
-				if done {
-					t.Errorf("(i=%d) unexpectedly done iterating", i)
-				}
-				if diff := cmp.Diff(e, extHdr); diff != "" {
-					t.Errorf("(i=%d) got ext hdr mismatch (-want +got):\n%s", i, diff)
-				}
-
-				if t.Failed() {
-					t.FailNow()
-				}
-			}
-
-			extHdr, done, err := it.Next()
-			if err != nil {
-				t.Errorf("(last) Next(): %s", err)
-			}
-			if !done {
-				t.Errorf("(last) iterator unexpectedly not done")
-			}
-			if extHdr != nil {
-				t.Errorf("(last) got Next() = %T, want = nil", extHdr)
-			}
-		})
-	}
-}
-
-var _ IPv6SerializableHopByHopOption = (*dummyHbHOptionSerializer)(nil)
-
-// dummyHbHOptionSerializer provides a generic implementation of
-// IPv6SerializableHopByHopOption for use in tests.
-type dummyHbHOptionSerializer struct {
-	id          IPv6ExtHdrOptionIdentifier
-	payload     []byte
-	align       int
-	alignOffset int
-}
-
-// identifier implements IPv6SerializableHopByHopOption.
-func (s *dummyHbHOptionSerializer) identifier() IPv6ExtHdrOptionIdentifier {
-	return s.id
-}
-
-// length implements IPv6SerializableHopByHopOption.
-func (s *dummyHbHOptionSerializer) length() uint8 {
-	return uint8(len(s.payload))
-}
-
-// alignment implements IPv6SerializableHopByHopOption.
-func (s *dummyHbHOptionSerializer) alignment() (int, int) {
-	align := 1
-	if s.align != 0 {
-		align = s.align
-	}
-	return align, s.alignOffset
-}
-
-// serializeInto implements IPv6SerializableHopByHopOption.
-func (s *dummyHbHOptionSerializer) serializeInto(b []byte) uint8 {
-	return uint8(copy(b, s.payload))
-}
-
-func TestIPv6HopByHopSerializer(t *testing.T) {
-	validateDummies := func(t *testing.T, serializable IPv6SerializableHopByHopOption, deserialized IPv6ExtHdrOption) {
-		t.Helper()
-		dummy, ok := serializable.(*dummyHbHOptionSerializer)
-		if !ok {
-			t.Fatalf("got serializable = %T, want = *dummyHbHOptionSerializer", serializable)
-		}
-		unknown, ok := deserialized.(*IPv6UnknownExtHdrOption)
-		if !ok {
-			t.Fatalf("got deserialized = %T, want = %T", deserialized, &IPv6UnknownExtHdrOption{})
-		}
-		if dummy.id != unknown.Identifier {
-			t.Errorf("got deserialized identifier = %d, want = %d", unknown.Identifier, dummy.id)
-		}
-		if diff := cmp.Diff(dummy.payload, unknown.Data); diff != "" {
-			t.Errorf("option payload deserialization mismatch (-want +got):\n%s", diff)
-		}
-	}
-	tests := []struct {
-		name       string
-		nextHeader uint8
-		options    []IPv6SerializableHopByHopOption
-		expect     []byte
-		validate   func(*testing.T, IPv6SerializableHopByHopOption, IPv6ExtHdrOption)
-	}{
-		{
-			name:       "single option",
-			nextHeader: 13,
-			options: []IPv6SerializableHopByHopOption{
-				&dummyHbHOptionSerializer{
-					id:      15,
-					payload: []byte{9, 8, 7, 6},
-				},
-			},
-			expect:   []byte{13, 0, 15, 4, 9, 8, 7, 6},
-			validate: validateDummies,
-		},
-		{
-			name:       "short option padN zero",
-			nextHeader: 88,
-			options: []IPv6SerializableHopByHopOption{
-				&dummyHbHOptionSerializer{
-					id:      22,
-					payload: []byte{4, 5},
-				},
-			},
-			expect:   []byte{88, 0, 22, 2, 4, 5, 1, 0},
-			validate: validateDummies,
-		},
-		{
-			name:       "short option pad1",
-			nextHeader: 11,
-			options: []IPv6SerializableHopByHopOption{
-				&dummyHbHOptionSerializer{
-					id:      33,
-					payload: []byte{1, 2, 3},
-				},
-			},
-			expect:   []byte{11, 0, 33, 3, 1, 2, 3, 0},
-			validate: validateDummies,
-		},
-		{
-			name:       "long option padN",
-			nextHeader: 55,
-			options: []IPv6SerializableHopByHopOption{
-				&dummyHbHOptionSerializer{
-					id:      77,
-					payload: []byte{1, 2, 3, 4, 5, 6, 7, 8},
-				},
-			},
-			expect:   []byte{55, 1, 77, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 0, 0},
-			validate: validateDummies,
-		},
-		{
-			name:       "two options",
-			nextHeader: 33,
-			options: []IPv6SerializableHopByHopOption{
-				&dummyHbHOptionSerializer{
-					id:      11,
-					payload: []byte{1, 2, 3},
-				},
-				&dummyHbHOptionSerializer{
-					id:      22,
-					payload: []byte{4, 5, 6},
-				},
-			},
-			expect:   []byte{33, 1, 11, 3, 1, 2, 3, 22, 3, 4, 5, 6, 1, 2, 0, 0},
-			validate: validateDummies,
-		},
-		{
-			name:       "two options align 2n",
-			nextHeader: 33,
-			options: []IPv6SerializableHopByHopOption{
-				&dummyHbHOptionSerializer{
-					id:      11,
-					payload: []byte{1, 2, 3},
-				},
-				&dummyHbHOptionSerializer{
-					id:      22,
-					payload: []byte{4, 5, 6},
-					align:   2,
-				},
-			},
-			expect:   []byte{33, 1, 11, 3, 1, 2, 3, 0, 22, 3, 4, 5, 6, 1, 1, 0},
-			validate: validateDummies,
-		},
-		{
-			name:       "two options align 8n+1",
-			nextHeader: 33,
-			options: []IPv6SerializableHopByHopOption{
-				&dummyHbHOptionSerializer{
-					id:      11,
-					payload: []byte{1, 2},
-				},
-				&dummyHbHOptionSerializer{
-					id:          22,
-					payload:     []byte{4, 5, 6},
-					align:       8,
-					alignOffset: 1,
-				},
-			},
-			expect:   []byte{33, 1, 11, 2, 1, 2, 1, 1, 0, 22, 3, 4, 5, 6, 1, 0},
-			validate: validateDummies,
-		},
-		{
-			name:       "no options",
-			nextHeader: 33,
-			options:    []IPv6SerializableHopByHopOption{},
-			expect:     []byte{33, 0, 1, 4, 0, 0, 0, 0},
-		},
-		{
-			name:       "Router Alert",
-			nextHeader: 33,
-			options:    []IPv6SerializableHopByHopOption{&IPv6RouterAlertOption{Value: IPv6RouterAlertMLD}},
-			expect:     []byte{33, 0, 5, 2, 0, 0, 1, 0},
-			validate: func(t *testing.T, _ IPv6SerializableHopByHopOption, deserialized IPv6ExtHdrOption) {
-				t.Helper()
-				routerAlert, ok := deserialized.(*IPv6RouterAlertOption)
-				if !ok {
-					t.Fatalf("got deserialized = %T, want = *IPv6RouterAlertOption", deserialized)
-				}
-				if routerAlert.Value != IPv6RouterAlertMLD {
-					t.Errorf("got routerAlert.Value = %d, want = %d", routerAlert.Value, IPv6RouterAlertMLD)
-				}
-			},
-		},
-	}
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			s := IPv6SerializableHopByHopExtHdr(test.options)
-			length := s.length()
-			if length != len(test.expect) {
-				t.Fatalf("got s.length() = %d, want = %d", length, len(test.expect))
-			}
-			b := make([]byte, length)
-			for i := range b {
-				// Fill the buffer with ones to ensure all padding is correctly set.
-				b[i] = 0xFF
-			}
-			if got := s.serializeInto(test.nextHeader, b); got != length {
-				t.Fatalf("got s.serializeInto(..) = %d, want = %d", got, length)
-			}
-			if diff := cmp.Diff(test.expect, b); diff != "" {
-				t.Fatalf("serialization mismatch (-want +got):\n%s", diff)
-			}
-
-			// Deserialize the options and verify them.
-			optLen := (b[ipv6HopByHopExtHdrLengthOffset] + ipv6HopByHopExtHdrUnaccountedLenWords) * ipv6ExtHdrLenBytesPerUnit
-			iter := ipv6OptionsExtHdr(b[ipv6HopByHopExtHdrOptionsOffset:optLen]).Iter()
-			for _, testOpt := range test.options {
-				opt, done, err := iter.Next()
-				if err != nil {
-					t.Fatalf("iter.Next(): %s", err)
-				}
-				if done {
-					t.Fatalf("got iter.Next() = (%T, %t, _), want = (_, false, _)", opt, done)
-				}
-				test.validate(t, testOpt, opt)
-			}
-			opt, done, err := iter.Next()
-			if err != nil {
-				t.Fatalf("iter.Next(): %s", err)
-			}
-			if !done {
-				t.Fatalf("got iter.Next() = (%T, %t, _), want = (_, true, _)", opt, done)
-			}
-		})
-	}
-}
-
-var _ IPv6SerializableExtHdr = (*dummyIPv6ExtHdrSerializer)(nil)
-
-// dummyIPv6ExtHdrSerializer provides a generic implementation of
-// IPv6SerializableExtHdr for use in tests.
-//
-// The dummy header always carries the nextHeader value in the first byte.
-type dummyIPv6ExtHdrSerializer struct {
-	id             IPv6ExtensionHeaderIdentifier
-	headerContents []byte
-}
-
-// identifier implements IPv6SerializableExtHdr.
-func (s *dummyIPv6ExtHdrSerializer) identifier() IPv6ExtensionHeaderIdentifier {
-	return s.id
-}
-
-// length implements IPv6SerializableExtHdr.
-func (s *dummyIPv6ExtHdrSerializer) length() int {
-	return len(s.headerContents) + 1
-}
-
-// serializeInto implements IPv6SerializableExtHdr.
-func (s *dummyIPv6ExtHdrSerializer) serializeInto(nextHeader uint8, b []byte) int {
-	b[0] = nextHeader
-	return copy(b[1:], s.headerContents) + 1
-}
-
-func TestIPv6ExtHdrSerializer(t *testing.T) {
-	tests := []struct {
-		name             string
-		headers          []IPv6SerializableExtHdr
-		nextHeader       tcpip.TransportProtocolNumber
-		expectSerialized []byte
-		expectNextHeader uint8
-	}{
-		{
-			name: "one header",
-			headers: []IPv6SerializableExtHdr{
-				&dummyIPv6ExtHdrSerializer{
-					id:             15,
-					headerContents: []byte{1, 2, 3, 4},
-				},
-			},
-			nextHeader:       TCPProtocolNumber,
-			expectSerialized: []byte{byte(TCPProtocolNumber), 1, 2, 3, 4},
-			expectNextHeader: 15,
-		},
-		{
-			name: "two headers",
-			headers: []IPv6SerializableExtHdr{
-				&dummyIPv6ExtHdrSerializer{
-					id:             22,
-					headerContents: []byte{1, 2, 3},
-				},
-				&dummyIPv6ExtHdrSerializer{
-					id:             23,
-					headerContents: []byte{4, 5, 6},
-				},
-			},
-			nextHeader: ICMPv6ProtocolNumber,
-			expectSerialized: []byte{
-				23, 1, 2, 3,
-				byte(ICMPv6ProtocolNumber), 4, 5, 6,
-			},
-			expectNextHeader: 22,
-		},
-		{
-			name:             "no headers",
-			headers:          []IPv6SerializableExtHdr{},
-			nextHeader:       UDPProtocolNumber,
-			expectSerialized: []byte{},
-			expectNextHeader: byte(UDPProtocolNumber),
-		},
-	}
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			s := IPv6ExtHdrSerializer(test.headers)
-			l := s.Length()
-			if got, want := l, len(test.expectSerialized); got != want {
-				t.Fatalf("got serialized length = %d, want = %d", got, want)
-			}
-			b := make([]byte, l)
-			for i := range b {
-				// Fill the buffer with garbage to make sure we're writing to all bytes.
-				b[i] = 0xFF
-			}
-			nextHeader, serializedLen := s.Serialize(test.nextHeader, b)
-			if serializedLen != len(test.expectSerialized) || nextHeader != test.expectNextHeader {
-				t.Errorf(
-					"got s.Serialize(..) = (%d, %d), want = (%d, %d)",
-					nextHeader,
-					serializedLen,
-					test.expectNextHeader,
-					len(test.expectSerialized),
-				)
-			}
-			if diff := cmp.Diff(test.expectSerialized, b); diff != "" {
-				t.Errorf("serialization mismatch (-want +got):\n%s", diff)
-			}
-		})
-	}
-}
diff --git a/pkg/tcpip/header/ipv6_test.go b/pkg/tcpip/header/ipv6_test.go
deleted file mode 100644
index f10f446..0000000
--- a/pkg/tcpip/header/ipv6_test.go
+++ /dev/null
@@ -1,375 +0,0 @@
-// 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 header_test
-
-import (
-	"bytes"
-	"crypto/sha256"
-	"fmt"
-	"testing"
-
-	"github.com/google/go-cmp/cmp"
-	"gvisor.dev/gvisor/pkg/rand"
-	"gvisor.dev/gvisor/pkg/tcpip"
-	"gvisor.dev/gvisor/pkg/tcpip/header"
-)
-
-const (
-	linkAddr               = tcpip.LinkAddress("\x02\x02\x03\x04\x05\x06")
-	linkLocalAddr          = tcpip.Address("\xfe\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01")
-	linkLocalMulticastAddr = tcpip.Address("\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01")
-	uniqueLocalAddr1       = tcpip.Address("\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01")
-	uniqueLocalAddr2       = tcpip.Address("\xfd\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02")
-	globalAddr             = tcpip.Address("\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01")
-)
-
-func TestEthernetAdddressToModifiedEUI64(t *testing.T) {
-	expectedIID := [header.IIDSize]byte{0, 2, 3, 255, 254, 4, 5, 6}
-
-	if diff := cmp.Diff(expectedIID, header.EthernetAddressToModifiedEUI64(linkAddr)); diff != "" {
-		t.Errorf("EthernetAddressToModifiedEUI64(%s) mismatch (-want +got):\n%s", linkAddr, diff)
-	}
-
-	var buf [header.IIDSize]byte
-	header.EthernetAdddressToModifiedEUI64IntoBuf(linkAddr, buf[:])
-	if diff := cmp.Diff(expectedIID, buf); diff != "" {
-		t.Errorf("EthernetAddressToModifiedEUI64IntoBuf(%s, _) mismatch (-want +got):\n%s", linkAddr, diff)
-	}
-}
-
-func TestLinkLocalAddr(t *testing.T) {
-	if got, want := header.LinkLocalAddr(linkAddr), tcpip.Address("\xfe\x80\x00\x00\x00\x00\x00\x00\x00\x02\x03\xff\xfe\x04\x05\x06"); got != want {
-		t.Errorf("got LinkLocalAddr(%s) = %s, want = %s", linkAddr, got, want)
-	}
-}
-
-func TestAppendOpaqueInterfaceIdentifier(t *testing.T) {
-	var secretKeyBuf [header.OpaqueIIDSecretKeyMinBytes * 2]byte
-	if n, err := rand.Read(secretKeyBuf[:]); err != nil {
-		t.Fatalf("rand.Read(_): %s", err)
-	} else if want := header.OpaqueIIDSecretKeyMinBytes * 2; n != want {
-		t.Fatalf("expected rand.Read to read %d bytes, read %d bytes", want, n)
-	}
-
-	tests := []struct {
-		name       string
-		prefix     tcpip.Subnet
-		nicName    string
-		dadCounter uint8
-		secretKey  []byte
-	}{
-		{
-			name:       "SecretKey of minimum size",
-			prefix:     header.IPv6LinkLocalPrefix.Subnet(),
-			nicName:    "eth0",
-			dadCounter: 0,
-			secretKey:  secretKeyBuf[:header.OpaqueIIDSecretKeyMinBytes],
-		},
-		{
-			name: "SecretKey of less than minimum size",
-			prefix: func() tcpip.Subnet {
-				addrWithPrefix := tcpip.AddressWithPrefix{
-					Address:   "\x01\x02\x03\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
-					PrefixLen: header.IIDOffsetInIPv6Address * 8,
-				}
-				return addrWithPrefix.Subnet()
-			}(),
-			nicName:    "eth10",
-			dadCounter: 1,
-			secretKey:  secretKeyBuf[:header.OpaqueIIDSecretKeyMinBytes/2],
-		},
-		{
-			name: "SecretKey of more than minimum size",
-			prefix: func() tcpip.Subnet {
-				addrWithPrefix := tcpip.AddressWithPrefix{
-					Address:   "\x01\x02\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
-					PrefixLen: header.IIDOffsetInIPv6Address * 8,
-				}
-				return addrWithPrefix.Subnet()
-			}(),
-			nicName:    "eth11",
-			dadCounter: 2,
-			secretKey:  secretKeyBuf[:header.OpaqueIIDSecretKeyMinBytes*2],
-		},
-		{
-			name: "Nil SecretKey and empty nicName",
-			prefix: func() tcpip.Subnet {
-				addrWithPrefix := tcpip.AddressWithPrefix{
-					Address:   "\x01\x02\x03\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
-					PrefixLen: header.IIDOffsetInIPv6Address * 8,
-				}
-				return addrWithPrefix.Subnet()
-			}(),
-			nicName:    "",
-			dadCounter: 3,
-			secretKey:  nil,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			h := sha256.New()
-			h.Write([]byte(test.prefix.ID()[:header.IIDOffsetInIPv6Address]))
-			h.Write([]byte(test.nicName))
-			h.Write([]byte{test.dadCounter})
-			if k := test.secretKey; k != nil {
-				h.Write(k)
-			}
-			var hashSum [sha256.Size]byte
-			h.Sum(hashSum[:0])
-			want := hashSum[:header.IIDSize]
-
-			// Passing a nil buffer should result in a new buffer returned with the
-			// IID.
-			if got := header.AppendOpaqueInterfaceIdentifier(nil, test.prefix, test.nicName, test.dadCounter, test.secretKey); !bytes.Equal(got, want) {
-				t.Errorf("got AppendOpaqueInterfaceIdentifier(nil, %s, %s, %d, %x) = %x, want = %x", test.prefix, test.nicName, test.dadCounter, test.secretKey, got, want)
-			}
-
-			// Passing a buffer with sufficient capacity for the IID should populate
-			// the buffer provided.
-			var iidBuf [header.IIDSize]byte
-			if got := header.AppendOpaqueInterfaceIdentifier(iidBuf[:0], test.prefix, test.nicName, test.dadCounter, test.secretKey); !bytes.Equal(got, want) {
-				t.Errorf("got AppendOpaqueInterfaceIdentifier(iidBuf[:0], %s, %s, %d, %x) = %x, want = %x", test.prefix, test.nicName, test.dadCounter, test.secretKey, got, want)
-			}
-			if got := iidBuf[:]; !bytes.Equal(got, want) {
-				t.Errorf("got iidBuf = %x, want = %x", got, want)
-			}
-		})
-	}
-}
-
-func TestLinkLocalAddrWithOpaqueIID(t *testing.T) {
-	var secretKeyBuf [header.OpaqueIIDSecretKeyMinBytes * 2]byte
-	if n, err := rand.Read(secretKeyBuf[:]); err != nil {
-		t.Fatalf("rand.Read(_): %s", err)
-	} else if want := header.OpaqueIIDSecretKeyMinBytes * 2; n != want {
-		t.Fatalf("expected rand.Read to read %d bytes, read %d bytes", want, n)
-	}
-
-	prefix := header.IPv6LinkLocalPrefix.Subnet()
-
-	tests := []struct {
-		name       string
-		prefix     tcpip.Subnet
-		nicName    string
-		dadCounter uint8
-		secretKey  []byte
-	}{
-		{
-			name:       "SecretKey of minimum size",
-			nicName:    "eth0",
-			dadCounter: 0,
-			secretKey:  secretKeyBuf[:header.OpaqueIIDSecretKeyMinBytes],
-		},
-		{
-			name:       "SecretKey of less than minimum size",
-			nicName:    "eth10",
-			dadCounter: 1,
-			secretKey:  secretKeyBuf[:header.OpaqueIIDSecretKeyMinBytes/2],
-		},
-		{
-			name:       "SecretKey of more than minimum size",
-			nicName:    "eth11",
-			dadCounter: 2,
-			secretKey:  secretKeyBuf[:header.OpaqueIIDSecretKeyMinBytes*2],
-		},
-		{
-			name:       "Nil SecretKey and empty nicName",
-			nicName:    "",
-			dadCounter: 3,
-			secretKey:  nil,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			addrBytes := [header.IPv6AddressSize]byte{
-				0: 0xFE,
-				1: 0x80,
-			}
-
-			want := tcpip.Address(header.AppendOpaqueInterfaceIdentifier(
-				addrBytes[:header.IIDOffsetInIPv6Address],
-				prefix,
-				test.nicName,
-				test.dadCounter,
-				test.secretKey,
-			))
-
-			if got := header.LinkLocalAddrWithOpaqueIID(test.nicName, test.dadCounter, test.secretKey); got != want {
-				t.Errorf("got LinkLocalAddrWithOpaqueIID(%s, %d, %x) = %s, want = %s", test.nicName, test.dadCounter, test.secretKey, got, want)
-			}
-		})
-	}
-}
-
-func TestIsV6LinkLocalMulticastAddress(t *testing.T) {
-	tests := []struct {
-		name     string
-		addr     tcpip.Address
-		expected bool
-	}{
-		{
-			name:     "Valid Link Local Multicast",
-			addr:     linkLocalMulticastAddr,
-			expected: true,
-		},
-		{
-			name:     "Valid Link Local Multicast with flags",
-			addr:     "\xff\xf2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01",
-			expected: true,
-		},
-		{
-			name:     "Link Local Unicast",
-			addr:     linkLocalAddr,
-			expected: false,
-		},
-		{
-			name:     "IPv4 Multicast",
-			addr:     "\xe0\x00\x00\x01",
-			expected: false,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			if got := header.IsV6LinkLocalMulticastAddress(test.addr); got != test.expected {
-				t.Errorf("got header.IsV6LinkLocalMulticastAddress(%s) = %t, want = %t", test.addr, got, test.expected)
-			}
-		})
-	}
-}
-
-func TestIsV6LinkLocalAddress(t *testing.T) {
-	tests := []struct {
-		name     string
-		addr     tcpip.Address
-		expected bool
-	}{
-		{
-			name:     "Valid Link Local Unicast",
-			addr:     linkLocalAddr,
-			expected: true,
-		},
-		{
-			name:     "Link Local Multicast",
-			addr:     linkLocalMulticastAddr,
-			expected: false,
-		},
-		{
-			name:     "Unique Local",
-			addr:     uniqueLocalAddr1,
-			expected: false,
-		},
-		{
-			name:     "Global",
-			addr:     globalAddr,
-			expected: false,
-		},
-		{
-			name:     "IPv4 Link Local",
-			addr:     "\xa9\xfe\x00\x01",
-			expected: false,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			if got := header.IsV6LinkLocalAddress(test.addr); got != test.expected {
-				t.Errorf("got header.IsV6LinkLocalAddress(%s) = %t, want = %t", test.addr, got, test.expected)
-			}
-		})
-	}
-}
-
-func TestScopeForIPv6Address(t *testing.T) {
-	tests := []struct {
-		name  string
-		addr  tcpip.Address
-		scope header.IPv6AddressScope
-		err   tcpip.Error
-	}{
-		{
-			name:  "Unique Local",
-			addr:  uniqueLocalAddr1,
-			scope: header.GlobalScope,
-			err:   nil,
-		},
-		{
-			name:  "Link Local Unicast",
-			addr:  linkLocalAddr,
-			scope: header.LinkLocalScope,
-			err:   nil,
-		},
-		{
-			name:  "Link Local Multicast",
-			addr:  linkLocalMulticastAddr,
-			scope: header.LinkLocalScope,
-			err:   nil,
-		},
-		{
-			name:  "Global",
-			addr:  globalAddr,
-			scope: header.GlobalScope,
-			err:   nil,
-		},
-		{
-			name:  "IPv4",
-			addr:  "\x01\x02\x03\x04",
-			scope: header.GlobalScope,
-			err:   &tcpip.ErrBadAddress{},
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			got, err := header.ScopeForIPv6Address(test.addr)
-			if diff := cmp.Diff(test.err, err); diff != "" {
-				t.Errorf("unexpected error from header.IsV6UniqueLocalAddress(%s), (-want, +got):\n%s", test.addr, diff)
-			}
-			if got != test.scope {
-				t.Errorf("got header.IsV6UniqueLocalAddress(%s) = (%d, _), want = (%d, _)", test.addr, got, test.scope)
-			}
-		})
-	}
-}
-
-func TestSolicitedNodeAddr(t *testing.T) {
-	tests := []struct {
-		addr tcpip.Address
-		want tcpip.Address
-	}{
-		{
-			addr: "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\xa0",
-			want: "\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x0e\x0f\xa0",
-		},
-		{
-			addr: "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\xdd\x0e\x0f\xa0",
-			want: "\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x0e\x0f\xa0",
-		},
-		{
-			addr: "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\xdd\x01\x02\x03",
-			want: "\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x01\x02\x03",
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(fmt.Sprintf("%s", test.addr), func(t *testing.T) {
-			if got := header.SolicitedNodeAddr(test.addr); got != test.want {
-				t.Fatalf("got header.SolicitedNodeAddr(%s) = %s, want = %s", test.addr, got, test.want)
-			}
-		})
-	}
-}
diff --git a/pkg/tcpip/header/ipversion_test.go b/pkg/tcpip/header/ipversion_test.go
deleted file mode 100644
index b5540bf..0000000
--- a/pkg/tcpip/header/ipversion_test.go
+++ /dev/null
@@ -1,67 +0,0 @@
-// 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 header_test
-
-import (
-	"testing"
-
-	"gvisor.dev/gvisor/pkg/tcpip/header"
-)
-
-func TestIPv4(t *testing.T) {
-	b := header.IPv4(make([]byte, header.IPv4MinimumSize))
-	b.Encode(&header.IPv4Fields{})
-
-	const want = header.IPv4Version
-	if v := header.IPVersion(b); v != want {
-		t.Fatalf("Bad version, want %v, got %v", want, v)
-	}
-}
-
-func TestIPv6(t *testing.T) {
-	b := header.IPv6(make([]byte, header.IPv6MinimumSize))
-	b.Encode(&header.IPv6Fields{})
-
-	const want = header.IPv6Version
-	if v := header.IPVersion(b); v != want {
-		t.Fatalf("Bad version, want %v, got %v", want, v)
-	}
-}
-
-func TestOtherVersion(t *testing.T) {
-	const want = header.IPv4Version + header.IPv6Version
-	b := make([]byte, 1)
-	b[0] = want << 4
-
-	if v := header.IPVersion(b); v != want {
-		t.Fatalf("Bad version, want %v, got %v", want, v)
-	}
-}
-
-func TestTooShort(t *testing.T) {
-	b := make([]byte, 1)
-	b[0] = (header.IPv4Version + header.IPv6Version) << 4
-
-	// Get the version of a zero-length slice.
-	const want = -1
-	if v := header.IPVersion(b[:0]); v != want {
-		t.Fatalf("Bad version, want %v, got %v", want, v)
-	}
-
-	// Get the version of a nil slice.
-	if v := header.IPVersion(nil); v != want {
-		t.Fatalf("Bad version, want %v, got %v", want, v)
-	}
-}
diff --git a/pkg/tcpip/header/mld_test.go b/pkg/tcpip/header/mld_test.go
deleted file mode 100644
index 0cecf10..0000000
--- a/pkg/tcpip/header/mld_test.go
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2020 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 header
-
-import (
-	"encoding/binary"
-	"testing"
-	"time"
-
-	"gvisor.dev/gvisor/pkg/tcpip"
-)
-
-func TestMLD(t *testing.T) {
-	b := []byte{
-		// Maximum Response Delay
-		0, 0,
-
-		// Reserved
-		0, 0,
-
-		// MulticastAddress
-		1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6,
-	}
-
-	const maxRespDelay = 513
-	binary.BigEndian.PutUint16(b, maxRespDelay)
-
-	mld := MLD(b)
-
-	if got, want := mld.MaximumResponseDelay(), maxRespDelay*time.Millisecond; got != want {
-		t.Errorf("got mld.MaximumResponseDelay() = %s, want = %s", got, want)
-	}
-
-	const newMaxRespDelay = 1234
-	mld.SetMaximumResponseDelay(newMaxRespDelay)
-	if got, want := mld.MaximumResponseDelay(), newMaxRespDelay*time.Millisecond; got != want {
-		t.Errorf("got mld.MaximumResponseDelay() = %s, want = %s", got, want)
-	}
-
-	if got, want := mld.MulticastAddress(), tcpip.Address([]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6}); got != want {
-		t.Errorf("got mld.MulticastAddress() = %s, want = %s", got, want)
-	}
-
-	multicastAddress := tcpip.Address([]byte{15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0})
-	mld.SetMulticastAddress(multicastAddress)
-	if got := mld.MulticastAddress(); got != multicastAddress {
-		t.Errorf("got mld.MulticastAddress() = %s, want = %s", got, multicastAddress)
-	}
-}
diff --git a/pkg/tcpip/header/ndp_test.go b/pkg/tcpip/header/ndp_test.go
deleted file mode 100644
index d0a1a24..0000000
--- a/pkg/tcpip/header/ndp_test.go
+++ /dev/null
@@ -1,1452 +0,0 @@
-// 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 header
-
-import (
-	"bytes"
-	"encoding/binary"
-	"errors"
-	"fmt"
-	"io"
-	"regexp"
-	"testing"
-	"time"
-
-	"github.com/google/go-cmp/cmp"
-	"gvisor.dev/gvisor/pkg/tcpip"
-)
-
-// TestNDPNeighborSolicit tests the functions of NDPNeighborSolicit.
-func TestNDPNeighborSolicit(t *testing.T) {
-	b := []byte{
-		0, 0, 0, 0,
-		1, 2, 3, 4,
-		5, 6, 7, 8,
-		9, 10, 11, 12,
-		13, 14, 15, 16,
-	}
-
-	// Test getting the Target Address.
-	ns := NDPNeighborSolicit(b)
-	addr := tcpip.Address("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10")
-	if got := ns.TargetAddress(); got != addr {
-		t.Errorf("got ns.TargetAddress = %s, want %s", got, addr)
-	}
-
-	// Test updating the Target Address.
-	addr2 := tcpip.Address("\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x11")
-	ns.SetTargetAddress(addr2)
-	if got := ns.TargetAddress(); got != addr2 {
-		t.Errorf("got ns.TargetAddress = %s, want %s", got, addr2)
-	}
-	// Make sure the address got updated in the backing buffer.
-	if got := tcpip.Address(b[ndpNSTargetAddessOffset:][:IPv6AddressSize]); got != addr2 {
-		t.Errorf("got targetaddress buffer = %s, want %s", got, addr2)
-	}
-}
-
-// TestNDPNeighborAdvert tests the functions of NDPNeighborAdvert.
-func TestNDPNeighborAdvert(t *testing.T) {
-	b := []byte{
-		160, 0, 0, 0,
-		1, 2, 3, 4,
-		5, 6, 7, 8,
-		9, 10, 11, 12,
-		13, 14, 15, 16,
-	}
-
-	// Test getting the Target Address.
-	na := NDPNeighborAdvert(b)
-	addr := tcpip.Address("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10")
-	if got := na.TargetAddress(); got != addr {
-		t.Errorf("got TargetAddress = %s, want %s", got, addr)
-	}
-
-	// Test getting the Router Flag.
-	if got := na.RouterFlag(); !got {
-		t.Errorf("got RouterFlag = false, want = true")
-	}
-
-	// Test getting the Solicited Flag.
-	if got := na.SolicitedFlag(); got {
-		t.Errorf("got SolicitedFlag = true, want = false")
-	}
-
-	// Test getting the Override Flag.
-	if got := na.OverrideFlag(); !got {
-		t.Errorf("got OverrideFlag = false, want = true")
-	}
-
-	// Test updating the Target Address.
-	addr2 := tcpip.Address("\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x11")
-	na.SetTargetAddress(addr2)
-	if got := na.TargetAddress(); got != addr2 {
-		t.Errorf("got TargetAddress = %s, want %s", got, addr2)
-	}
-	// Make sure the address got updated in the backing buffer.
-	if got := tcpip.Address(b[ndpNATargetAddressOffset:][:IPv6AddressSize]); got != addr2 {
-		t.Errorf("got targetaddress buffer = %s, want %s", got, addr2)
-	}
-
-	// Test updating the Router Flag.
-	na.SetRouterFlag(false)
-	if got := na.RouterFlag(); got {
-		t.Errorf("got RouterFlag = true, want = false")
-	}
-
-	// Test updating the Solicited Flag.
-	na.SetSolicitedFlag(true)
-	if got := na.SolicitedFlag(); !got {
-		t.Errorf("got SolicitedFlag = false, want = true")
-	}
-
-	// Test updating the Override Flag.
-	na.SetOverrideFlag(false)
-	if got := na.OverrideFlag(); got {
-		t.Errorf("got OverrideFlag = true, want = false")
-	}
-
-	// Make sure flags got updated in the backing buffer.
-	if got := b[ndpNAFlagsOffset]; got != 64 {
-		t.Errorf("got flags byte = %d, want = 64", got)
-	}
-}
-
-func TestNDPRouterAdvert(t *testing.T) {
-	b := []byte{
-		64, 128, 1, 2,
-		3, 4, 5, 6,
-		7, 8, 9, 10,
-	}
-
-	ra := NDPRouterAdvert(b)
-
-	if got := ra.CurrHopLimit(); got != 64 {
-		t.Errorf("got ra.CurrHopLimit = %d, want = 64", got)
-	}
-
-	if got := ra.ManagedAddrConfFlag(); !got {
-		t.Errorf("got ManagedAddrConfFlag = false, want = true")
-	}
-
-	if got := ra.OtherConfFlag(); got {
-		t.Errorf("got OtherConfFlag = true, want = false")
-	}
-
-	if got, want := ra.RouterLifetime(), time.Second*258; got != want {
-		t.Errorf("got ra.RouterLifetime = %d, want = %d", got, want)
-	}
-
-	if got, want := ra.ReachableTime(), time.Millisecond*50595078; got != want {
-		t.Errorf("got ra.ReachableTime = %d, want = %d", got, want)
-	}
-
-	if got, want := ra.RetransTimer(), time.Millisecond*117967114; got != want {
-		t.Errorf("got ra.RetransTimer = %d, want = %d", got, want)
-	}
-}
-
-// TestNDPSourceLinkLayerAddressOptionEthernetAddress tests getting the
-// Ethernet address from an NDPSourceLinkLayerAddressOption.
-func TestNDPSourceLinkLayerAddressOptionEthernetAddress(t *testing.T) {
-	tests := []struct {
-		name     string
-		buf      []byte
-		expected tcpip.LinkAddress
-	}{
-		{
-			"ValidMAC",
-			[]byte{1, 2, 3, 4, 5, 6},
-			tcpip.LinkAddress("\x01\x02\x03\x04\x05\x06"),
-		},
-		{
-			"SLLBodyTooShort",
-			[]byte{1, 2, 3, 4, 5},
-			tcpip.LinkAddress([]byte(nil)),
-		},
-		{
-			"SLLBodyLargerThanNeeded",
-			[]byte{1, 2, 3, 4, 5, 6, 7, 8},
-			tcpip.LinkAddress("\x01\x02\x03\x04\x05\x06"),
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			sll := NDPSourceLinkLayerAddressOption(test.buf)
-			if got := sll.EthernetAddress(); got != test.expected {
-				t.Errorf("got sll.EthernetAddress = %s, want = %s", got, test.expected)
-			}
-		})
-	}
-}
-
-// TestNDPTargetLinkLayerAddressOptionEthernetAddress tests getting the
-// Ethernet address from an NDPTargetLinkLayerAddressOption.
-func TestNDPTargetLinkLayerAddressOptionEthernetAddress(t *testing.T) {
-	tests := []struct {
-		name     string
-		buf      []byte
-		expected tcpip.LinkAddress
-	}{
-		{
-			"ValidMAC",
-			[]byte{1, 2, 3, 4, 5, 6},
-			tcpip.LinkAddress("\x01\x02\x03\x04\x05\x06"),
-		},
-		{
-			"TLLBodyTooShort",
-			[]byte{1, 2, 3, 4, 5},
-			tcpip.LinkAddress([]byte(nil)),
-		},
-		{
-			"TLLBodyLargerThanNeeded",
-			[]byte{1, 2, 3, 4, 5, 6, 7, 8},
-			tcpip.LinkAddress("\x01\x02\x03\x04\x05\x06"),
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			tll := NDPTargetLinkLayerAddressOption(test.buf)
-			if got := tll.EthernetAddress(); got != test.expected {
-				t.Errorf("got tll.EthernetAddress = %s, want = %s", got, test.expected)
-			}
-		})
-	}
-}
-
-func TestOpts(t *testing.T) {
-	const optionHeaderLen = 2
-
-	checkNonce := func(expectedNonce []byte) func(*testing.T, NDPOption) {
-		return func(t *testing.T, opt NDPOption) {
-			if got := opt.kind(); got != ndpNonceOptionType {
-				t.Errorf("got kind() = %d, want = %d", got, ndpNonceOptionType)
-			}
-			nonce, ok := opt.(NDPNonceOption)
-			if !ok {
-				t.Fatalf("got nonce = %T, want = NDPNonceOption", opt)
-			}
-			if diff := cmp.Diff(expectedNonce, nonce.Nonce()); diff != "" {
-				t.Errorf("nonce mismatch (-want +got):\n%s", diff)
-			}
-		}
-	}
-
-	checkTLL := func(expectedAddr tcpip.LinkAddress) func(*testing.T, NDPOption) {
-		return func(t *testing.T, opt NDPOption) {
-			if got := opt.kind(); got != ndpTargetLinkLayerAddressOptionType {
-				t.Errorf("got kind() = %d, want = %d", got, ndpTargetLinkLayerAddressOptionType)
-			}
-			tll, ok := opt.(NDPTargetLinkLayerAddressOption)
-			if !ok {
-				t.Fatalf("got tll = %T, want = NDPTargetLinkLayerAddressOption", opt)
-			}
-			if got, want := tll.EthernetAddress(), expectedAddr; got != want {
-				t.Errorf("got tll.EthernetAddress = %s, want = %s", got, want)
-			}
-		}
-	}
-
-	checkSLL := func(expectedAddr tcpip.LinkAddress) func(*testing.T, NDPOption) {
-		return func(t *testing.T, opt NDPOption) {
-			if got := opt.kind(); got != ndpSourceLinkLayerAddressOptionType {
-				t.Errorf("got kind() = %d, want = %d", got, ndpSourceLinkLayerAddressOptionType)
-			}
-			sll, ok := opt.(NDPSourceLinkLayerAddressOption)
-			if !ok {
-				t.Fatalf("got sll = %T, want = NDPSourceLinkLayerAddressOption", opt)
-			}
-			if got, want := sll.EthernetAddress(), expectedAddr; got != want {
-				t.Errorf("got sll.EthernetAddress = %s, want = %s", got, want)
-			}
-		}
-	}
-
-	const validLifetimeSeconds = 16909060
-	const address = tcpip.Address("\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18")
-
-	expectedRDNSSBytes := [...]byte{
-		// Type, Length
-		25, 3,
-
-		// Reserved
-		0, 0,
-
-		// Lifetime
-		1, 2, 4, 8,
-
-		// Address
-		0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
-	}
-	binary.BigEndian.PutUint32(expectedRDNSSBytes[4:], validLifetimeSeconds)
-	if n := copy(expectedRDNSSBytes[8:], address); n != IPv6AddressSize {
-		t.Fatalf("got copy(...) = %d, want = %d", n, IPv6AddressSize)
-	}
-	// Update reserved fields to non zero values to make sure serializing sets
-	// them to zero.
-	rdnssBytes := expectedRDNSSBytes
-	rdnssBytes[1] = 1
-	rdnssBytes[2] = 2
-
-	const searchListPaddingBytes = 3
-	const domainName = "abc.abcd.e"
-	expectedSearchListBytes := [...]byte{
-		// Type, Length
-		31, 3,
-
-		// Reserved
-		0, 0,
-
-		// Lifetime
-		1, 0, 0, 0,
-
-		// Domain names
-		3, 'a', 'b', 'c',
-		4, 'a', 'b', 'c', 'd',
-		1, 'e',
-		0,
-		0, 0, 0, 0,
-	}
-	binary.BigEndian.PutUint32(expectedSearchListBytes[4:], validLifetimeSeconds)
-	// Update reserved fields to non zero values to make sure serializing sets
-	// them to zero.
-	searchListBytes := expectedSearchListBytes
-	searchListBytes[2] = 1
-	searchListBytes[3] = 2
-
-	const prefixLength = 43
-	const onLinkFlag = false
-	const slaacFlag = true
-	const preferredLifetimeSeconds = 84281096
-	const onLinkFlagBit = 7
-	const slaacFlagBit = 6
-	boolToByte := func(v bool) byte {
-		if v {
-			return 1
-		}
-		return 0
-	}
-	flags := boolToByte(onLinkFlag)<<onLinkFlagBit | boolToByte(slaacFlag)<<slaacFlagBit
-	expectedPrefixInformationBytes := [...]byte{
-		// Type, Length
-		3, 4,
-
-		prefixLength, flags,
-
-		// Valid Lifetime
-		1, 2, 3, 4,
-
-		// Preferred Lifetime
-		5, 6, 7, 8,
-
-		// Reserved2
-		0, 0, 0, 0,
-
-		// Address
-		9, 10, 11, 12,
-		13, 14, 15, 16,
-		17, 18, 19, 20,
-		21, 22, 23, 24,
-	}
-	binary.BigEndian.PutUint32(expectedPrefixInformationBytes[4:], validLifetimeSeconds)
-	binary.BigEndian.PutUint32(expectedPrefixInformationBytes[8:], preferredLifetimeSeconds)
-	if n := copy(expectedPrefixInformationBytes[16:], address); n != IPv6AddressSize {
-		t.Fatalf("got copy(...) = %d, want = %d", n, IPv6AddressSize)
-	}
-	// Update reserved fields to non zero values to make sure serializing sets
-	// them to zero.
-	prefixInformationBytes := expectedPrefixInformationBytes
-	prefixInformationBytes[3] |= (1 << slaacFlagBit) - 1
-	binary.BigEndian.PutUint32(prefixInformationBytes[12:], validLifetimeSeconds+1)
-	tests := []struct {
-		name        string
-		buf         []byte
-		opt         NDPOption
-		expectedBuf []byte
-		check       func(*testing.T, NDPOption)
-	}{
-		{
-			name:        "Nonce",
-			buf:         make([]byte, 8),
-			opt:         NDPNonceOption([]byte{1, 2, 3, 4, 5, 6}),
-			expectedBuf: []byte{14, 1, 1, 2, 3, 4, 5, 6},
-			check:       checkNonce([]byte{1, 2, 3, 4, 5, 6}),
-		},
-		{
-			name:        "Nonce with padding",
-			buf:         []byte{1, 1, 1, 1, 1, 1, 1, 1},
-			opt:         NDPNonceOption([]byte{1, 2, 3, 4, 5}),
-			expectedBuf: []byte{14, 1, 1, 2, 3, 4, 5, 0},
-			check:       checkNonce([]byte{1, 2, 3, 4, 5, 0}),
-		},
-
-		{
-			name:        "TLL Ethernet",
-			buf:         make([]byte, 8),
-			opt:         NDPTargetLinkLayerAddressOption("\x01\x02\x03\x04\x05\x06"),
-			expectedBuf: []byte{2, 1, 1, 2, 3, 4, 5, 6},
-			check:       checkTLL("\x01\x02\x03\x04\x05\x06"),
-		},
-		{
-			name:        "TLL Padding",
-			buf:         []byte{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
-			opt:         NDPTargetLinkLayerAddressOption("\x01\x02\x03\x04\x05\x06\x07\x08"),
-			expectedBuf: []byte{2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0},
-			check:       checkTLL("\x01\x02\x03\x04\x05\x06"),
-		},
-		{
-			name:        "TLL Empty",
-			buf:         nil,
-			opt:         NDPTargetLinkLayerAddressOption(""),
-			expectedBuf: nil,
-		},
-
-		{
-			name:        "SLL Ethernet",
-			buf:         make([]byte, 8),
-			opt:         NDPSourceLinkLayerAddressOption("\x01\x02\x03\x04\x05\x06"),
-			expectedBuf: []byte{1, 1, 1, 2, 3, 4, 5, 6},
-			check:       checkSLL("\x01\x02\x03\x04\x05\x06"),
-		},
-		{
-			name:        "SLL Padding",
-			buf:         []byte{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
-			opt:         NDPSourceLinkLayerAddressOption("\x01\x02\x03\x04\x05\x06\x07\x08"),
-			expectedBuf: []byte{1, 2, 1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0},
-			check:       checkSLL("\x01\x02\x03\x04\x05\x06"),
-		},
-		{
-			name:        "SLL Empty",
-			buf:         nil,
-			opt:         NDPSourceLinkLayerAddressOption(""),
-			expectedBuf: nil,
-		},
-
-		{
-			name: "RDNSS",
-			buf:  []byte{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
-			// NDPRecursiveDNSServer holds the option after the header bytes.
-			opt:         NDPRecursiveDNSServer(rdnssBytes[optionHeaderLen:]),
-			expectedBuf: expectedRDNSSBytes[:],
-			check: func(t *testing.T, opt NDPOption) {
-				if got := opt.kind(); got != ndpRecursiveDNSServerOptionType {
-					t.Errorf("got kind() = %d, want = %d", got, ndpRecursiveDNSServerOptionType)
-				}
-				rdnss, ok := opt.(NDPRecursiveDNSServer)
-				if !ok {
-					t.Fatalf("got opt = %T, want = NDPRecursiveDNSServer", opt)
-				}
-				if got, want := rdnss.length(), len(expectedRDNSSBytes[optionHeaderLen:]); got != want {
-					t.Errorf("got length() = %d, want = %d", got, want)
-				}
-				if got, want := rdnss.Lifetime(), validLifetimeSeconds*time.Second; got != want {
-					t.Errorf("got Lifetime() = %s, want = %s", got, want)
-				}
-				if addrs, err := rdnss.Addresses(); err != nil {
-					t.Errorf("Addresses(): %s", err)
-				} else if diff := cmp.Diff([]tcpip.Address{address}, addrs); diff != "" {
-					t.Errorf("mismatched addresses (-want +got):\n%s", diff)
-				}
-			},
-		},
-
-		{
-			name:        "Search list",
-			buf:         []byte{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
-			opt:         NDPDNSSearchList(searchListBytes[optionHeaderLen:]),
-			expectedBuf: expectedSearchListBytes[:],
-			check: func(t *testing.T, opt NDPOption) {
-				if got := opt.kind(); got != ndpDNSSearchListOptionType {
-					t.Errorf("got kind() = %d, want = %d", got, ndpDNSSearchListOptionType)
-				}
-
-				dnssl, ok := opt.(NDPDNSSearchList)
-				if !ok {
-					t.Fatalf("got opt = %T, want = NDPDNSSearchList", opt)
-				}
-				if got, want := dnssl.length(), len(expectedRDNSSBytes[optionHeaderLen:]); got != want {
-					t.Errorf("got length() = %d, want = %d", got, want)
-				}
-				if got, want := dnssl.Lifetime(), validLifetimeSeconds*time.Second; got != want {
-					t.Errorf("got Lifetime() = %s, want = %s", got, want)
-				}
-
-				if domainNames, err := dnssl.DomainNames(); err != nil {
-					t.Errorf("DomainNames(): %s", err)
-				} else if diff := cmp.Diff([]string{domainName}, domainNames); diff != "" {
-					t.Errorf("domain names mismatch (-want +got):\n%s", diff)
-				}
-			},
-		},
-
-		{
-			name: "Prefix Information",
-			buf:  []byte{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
-			// NDPPrefixInformation holds the option after the header bytes.
-			opt:         NDPPrefixInformation(prefixInformationBytes[optionHeaderLen:]),
-			expectedBuf: expectedPrefixInformationBytes[:],
-			check: func(t *testing.T, opt NDPOption) {
-				if got := opt.kind(); got != ndpPrefixInformationType {
-					t.Errorf("got kind() = %d, want = %d", got, ndpPrefixInformationType)
-				}
-
-				pi, ok := opt.(NDPPrefixInformation)
-				if !ok {
-					t.Fatalf("got opt = %T, want = NDPPrefixInformation", opt)
-				}
-
-				if got, want := pi.length(), len(expectedPrefixInformationBytes[optionHeaderLen:]); got != want {
-					t.Errorf("got length() = %d, want = %d", got, want)
-				}
-				if got := pi.PrefixLength(); got != prefixLength {
-					t.Errorf("got PrefixLength() = %d, want = %d", got, prefixLength)
-				}
-				if got := pi.OnLinkFlag(); got != onLinkFlag {
-					t.Errorf("got OnLinkFlag() = %t, want = %t", got, onLinkFlag)
-				}
-				if got := pi.AutonomousAddressConfigurationFlag(); got != slaacFlag {
-					t.Errorf("got AutonomousAddressConfigurationFlag() = %t, want = %t", got, slaacFlag)
-				}
-				if got, want := pi.ValidLifetime(), validLifetimeSeconds*time.Second; got != want {
-					t.Errorf("got ValidLifetime() = %s, want = %s", got, want)
-				}
-				if got, want := pi.PreferredLifetime(), preferredLifetimeSeconds*time.Second; got != want {
-					t.Errorf("got PreferredLifetime() = %s, want = %s", got, want)
-				}
-				if got := pi.Prefix(); got != address {
-					t.Errorf("got Prefix() = %s, want = %s", got, address)
-				}
-			},
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			opts := NDPOptions(test.buf)
-			serializer := NDPOptionsSerializer{
-				test.opt,
-			}
-			if got, want := int(serializer.Length()), len(test.expectedBuf); got != want {
-				t.Fatalf("got Length() = %d, want = %d", got, want)
-			}
-			opts.Serialize(serializer)
-			if diff := cmp.Diff(test.expectedBuf, test.buf); diff != "" {
-				t.Fatalf("serialized buffer mismatch (-want +got):\n%s", diff)
-			}
-
-			it, err := opts.Iter(true)
-			if err != nil {
-				t.Fatalf("got Iter(true) = (_, %s), want = (_, nil)", err)
-			}
-
-			if len(test.expectedBuf) > 0 {
-				next, done, err := it.Next()
-				if err != nil {
-					t.Fatalf("got Next() = (_, _, %s), want = (_, _, nil)", err)
-				}
-				if done {
-					t.Fatal("got Next() = (_, true, _), want = (_, false, _)")
-				}
-				test.check(t, next)
-			}
-
-			// Iterator should not return anything else.
-			next, done, err := it.Next()
-			if err != nil {
-				t.Errorf("got Next() = (_, _, %s), want = (_, _, nil)", err)
-			}
-			if !done {
-				t.Error("got Next() = (_, false, _), want = (_, true, _)")
-			}
-			if next != nil {
-				t.Errorf("got Next() = (%x, _, _), want = (nil, _, _)", next)
-			}
-		})
-	}
-}
-
-func TestNDPRecursiveDNSServerOption(t *testing.T) {
-	tests := []struct {
-		name     string
-		buf      []byte
-		lifetime time.Duration
-		addrs    []tcpip.Address
-	}{
-		{
-			"Valid1Addr",
-			[]byte{
-				25, 3, 0, 0,
-				0, 0, 0, 0,
-				0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
-			},
-			0,
-			[]tcpip.Address{
-				"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
-			},
-		},
-		{
-			"Valid2Addr",
-			[]byte{
-				25, 5, 0, 0,
-				0, 0, 0, 0,
-				0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
-				17, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16,
-			},
-			0,
-			[]tcpip.Address{
-				"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
-				"\x11\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x10",
-			},
-		},
-		{
-			"Valid3Addr",
-			[]byte{
-				25, 7, 0, 0,
-				0, 0, 0, 0,
-				0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
-				17, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16,
-				17, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 17,
-			},
-			0,
-			[]tcpip.Address{
-				"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
-				"\x11\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x10",
-				"\x11\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x11",
-			},
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			opts := NDPOptions(test.buf)
-			it, err := opts.Iter(true)
-			if err != nil {
-				t.Fatalf("got Iter = (_, %s), want = (_, nil)", err)
-			}
-
-			// Iterator should get our option.
-			next, done, err := it.Next()
-			if err != nil {
-				t.Fatalf("got Next = (_, _, %s), want = (_, _, nil)", err)
-			}
-			if done {
-				t.Fatal("got Next = (_, true, _), want = (_, false, _)")
-			}
-			if got := next.kind(); got != ndpRecursiveDNSServerOptionType {
-				t.Fatalf("got Type = %d, want = %d", got, ndpRecursiveDNSServerOptionType)
-			}
-
-			opt, ok := next.(NDPRecursiveDNSServer)
-			if !ok {
-				t.Fatalf("next (type = %T) cannot be casted to an NDPRecursiveDNSServer", next)
-			}
-			if got := opt.Lifetime(); got != test.lifetime {
-				t.Errorf("got Lifetime = %d, want = %d", got, test.lifetime)
-			}
-			addrs, err := opt.Addresses()
-			if err != nil {
-				t.Errorf("opt.Addresses() = %s", err)
-			}
-			if diff := cmp.Diff(addrs, test.addrs); diff != "" {
-				t.Errorf("mismatched addresses (-want +got):\n%s", diff)
-			}
-
-			// Iterator should not return anything else.
-			next, done, err = it.Next()
-			if err != nil {
-				t.Errorf("got Next = (_, _, %s), want = (_, _, nil)", err)
-			}
-			if !done {
-				t.Error("got Next = (_, false, _), want = (_, true, _)")
-			}
-			if next != nil {
-				t.Errorf("got Next = (%x, _, _), want = (nil, _, _)", next)
-			}
-		})
-	}
-}
-
-// TestNDPDNSSearchListOption tests the getters of NDPDNSSearchList.
-func TestNDPDNSSearchListOption(t *testing.T) {
-	tests := []struct {
-		name        string
-		buf         []byte
-		lifetime    time.Duration
-		domainNames []string
-		err         error
-	}{
-		{
-			name: "Valid1Label",
-			buf: []byte{
-				0, 0,
-				0, 0, 0, 1,
-				3, 'a', 'b', 'c',
-				0,
-				0, 0, 0,
-			},
-			lifetime: time.Second,
-			domainNames: []string{
-				"abc",
-			},
-			err: nil,
-		},
-		{
-			name: "Valid2Label",
-			buf: []byte{
-				0, 0,
-				0, 0, 0, 5,
-				3, 'a', 'b', 'c',
-				4, 'a', 'b', 'c', 'd',
-				0,
-				0, 0, 0, 0, 0, 0,
-			},
-			lifetime: 5 * time.Second,
-			domainNames: []string{
-				"abc.abcd",
-			},
-			err: nil,
-		},
-		{
-			name: "Valid3Label",
-			buf: []byte{
-				0, 0,
-				1, 0, 0, 0,
-				3, 'a', 'b', 'c',
-				4, 'a', 'b', 'c', 'd',
-				1, 'e',
-				0,
-				0, 0, 0, 0,
-			},
-			lifetime: 16777216 * time.Second,
-			domainNames: []string{
-				"abc.abcd.e",
-			},
-			err: nil,
-		},
-		{
-			name: "Valid2Domains",
-			buf: []byte{
-				0, 0,
-				1, 2, 3, 4,
-				3, 'a', 'b', 'c',
-				0,
-				2, 'd', 'e',
-				3, 'x', 'y', 'z',
-				0,
-				0, 0, 0,
-			},
-			lifetime: 16909060 * time.Second,
-			domainNames: []string{
-				"abc",
-				"de.xyz",
-			},
-			err: nil,
-		},
-		{
-			name: "Valid3DomainsMixedCase",
-			buf: []byte{
-				0, 0,
-				0, 0, 0, 0,
-				3, 'a', 'B', 'c',
-				0,
-				2, 'd', 'E',
-				3, 'X', 'y', 'z',
-				0,
-				1, 'J',
-				0,
-			},
-			lifetime: 0,
-			domainNames: []string{
-				"abc",
-				"de.xyz",
-				"j",
-			},
-			err: nil,
-		},
-		{
-			name: "ValidDomainAfterNULL",
-			buf: []byte{
-				0, 0,
-				0, 0, 0, 0,
-				3, 'a', 'B', 'c',
-				0, 0, 0, 0,
-				2, 'd', 'E',
-				3, 'X', 'y', 'z',
-				0,
-			},
-			lifetime: 0,
-			domainNames: []string{
-				"abc",
-				"de.xyz",
-			},
-			err: nil,
-		},
-		{
-			name: "Valid0Domains",
-			buf: []byte{
-				0, 0,
-				0, 0, 0, 0,
-				0,
-				0, 0, 0, 0, 0, 0, 0,
-			},
-			lifetime:    0,
-			domainNames: nil,
-			err:         nil,
-		},
-		{
-			name: "NoTrailingNull",
-			buf: []byte{
-				0, 0,
-				0, 0, 0, 0,
-				7, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
-			},
-			lifetime:    0,
-			domainNames: nil,
-			err:         io.ErrUnexpectedEOF,
-		},
-		{
-			name: "IncorrectLength",
-			buf: []byte{
-				0, 0,
-				0, 0, 0, 0,
-				8, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
-			},
-			lifetime:    0,
-			domainNames: nil,
-			err:         io.ErrUnexpectedEOF,
-		},
-		{
-			name: "IncorrectLengthWithNULL",
-			buf: []byte{
-				0, 0,
-				0, 0, 0, 0,
-				7, 'a', 'b', 'c', 'd', 'e', 'f',
-				0,
-			},
-			lifetime:    0,
-			domainNames: nil,
-			err:         ErrNDPOptMalformedBody,
-		},
-		{
-			name: "LabelOfLength63",
-			buf: []byte{
-				0, 0,
-				0, 0, 0, 0,
-				63, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
-				'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
-				'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
-				'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
-				'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k',
-				0,
-			},
-			lifetime: 0,
-			domainNames: []string{
-				"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk",
-			},
-			err: nil,
-		},
-		{
-			name: "LabelOfLength64",
-			buf: []byte{
-				0, 0,
-				0, 0, 0, 0,
-				64, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
-				'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
-				'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
-				'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
-				'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k', 'l',
-				0,
-			},
-			lifetime:    0,
-			domainNames: nil,
-			err:         ErrNDPOptMalformedBody,
-		},
-		{
-			name: "DomainNameOfLength255",
-			buf: []byte{
-				0, 0,
-				0, 0, 0, 0,
-				63, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
-				'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
-				'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
-				'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
-				'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k',
-				63, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
-				'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
-				'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
-				'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
-				'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k',
-				63, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
-				'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
-				'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
-				'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
-				'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k',
-				62, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
-				'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
-				'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
-				'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
-				'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j',
-				0,
-			},
-			lifetime: 0,
-			domainNames: []string{
-				"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghij",
-			},
-			err: nil,
-		},
-		{
-			name: "DomainNameOfLength256",
-			buf: []byte{
-				0, 0,
-				0, 0, 0, 0,
-				63, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
-				'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
-				'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
-				'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
-				'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k',
-				63, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
-				'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
-				'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
-				'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
-				'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k',
-				63, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
-				'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
-				'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
-				'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
-				'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k',
-				63, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
-				'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
-				'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
-				'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
-				'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k',
-				0,
-			},
-			lifetime:    0,
-			domainNames: nil,
-			err:         ErrNDPOptMalformedBody,
-		},
-		{
-			name: "StartingDigitForLabel",
-			buf: []byte{
-				0, 0,
-				0, 0, 0, 1,
-				3, '9', 'b', 'c',
-				0,
-				0, 0, 0,
-			},
-			lifetime:    time.Second,
-			domainNames: nil,
-			err:         ErrNDPOptMalformedBody,
-		},
-		{
-			name: "StartingHyphenForLabel",
-			buf: []byte{
-				0, 0,
-				0, 0, 0, 1,
-				3, '-', 'b', 'c',
-				0,
-				0, 0, 0,
-			},
-			lifetime:    time.Second,
-			domainNames: nil,
-			err:         ErrNDPOptMalformedBody,
-		},
-		{
-			name: "EndingHyphenForLabel",
-			buf: []byte{
-				0, 0,
-				0, 0, 0, 1,
-				3, 'a', 'b', '-',
-				0,
-				0, 0, 0,
-			},
-			lifetime:    time.Second,
-			domainNames: nil,
-			err:         ErrNDPOptMalformedBody,
-		},
-		{
-			name: "EndingDigitForLabel",
-			buf: []byte{
-				0, 0,
-				0, 0, 0, 1,
-				3, 'a', 'b', '9',
-				0,
-				0, 0, 0,
-			},
-			lifetime: time.Second,
-			domainNames: []string{
-				"ab9",
-			},
-			err: nil,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			opt := NDPDNSSearchList(test.buf)
-
-			if got := opt.Lifetime(); got != test.lifetime {
-				t.Errorf("got Lifetime = %d, want = %d", got, test.lifetime)
-			}
-			domainNames, err := opt.DomainNames()
-			if !errors.Is(err, test.err) {
-				t.Errorf("opt.DomainNames() = %s", err)
-			}
-			if diff := cmp.Diff(domainNames, test.domainNames); diff != "" {
-				t.Errorf("mismatched domain names (-want +got):\n%s", diff)
-			}
-		})
-	}
-}
-
-func TestNDPSearchListOptionDomainNameLabelInvalidSymbols(t *testing.T) {
-	for r := rune(0); r <= 255; r++ {
-		t.Run(fmt.Sprintf("RuneVal=%d", r), func(t *testing.T) {
-			buf := []byte{
-				0, 0,
-				0, 0, 0, 0,
-				3, 'a', 0 /* will be replaced */, 'c',
-				0,
-				0, 0, 0,
-			}
-			buf[8] = uint8(r)
-			opt := NDPDNSSearchList(buf)
-
-			// As per RFC 1035 section 2.3.1, the label must only include ASCII
-			// letters, digits and hyphens (a-z, A-Z, 0-9, -).
-			var expectedErr error
-			re := regexp.MustCompile(`[a-zA-Z0-9-]`)
-			if !re.Match([]byte{byte(r)}) {
-				expectedErr = ErrNDPOptMalformedBody
-			}
-
-			if domainNames, err := opt.DomainNames(); !errors.Is(err, expectedErr) {
-				t.Errorf("got opt.DomainNames() = (%s, %v), want = (_, %v)", domainNames, err, ErrNDPOptMalformedBody)
-			}
-		})
-	}
-}
-
-// TestNDPOptionsIterCheck tests that Iter will return false if the NDPOptions
-// the iterator was returned for is malformed.
-func TestNDPOptionsIterCheck(t *testing.T) {
-	tests := []struct {
-		name        string
-		buf         []byte
-		expectedErr error
-	}{
-		{
-			name:        "ZeroLengthField",
-			buf:         []byte{0, 0, 0, 0, 0, 0, 0, 0},
-			expectedErr: ErrNDPOptMalformedHeader,
-		},
-		{
-			name:        "ValidSourceLinkLayerAddressOption",
-			buf:         []byte{1, 1, 1, 2, 3, 4, 5, 6},
-			expectedErr: nil,
-		},
-		{
-			name:        "TooSmallSourceLinkLayerAddressOption",
-			buf:         []byte{1, 1, 1, 2, 3, 4, 5},
-			expectedErr: io.ErrUnexpectedEOF,
-		},
-		{
-			name:        "ValidTargetLinkLayerAddressOption",
-			buf:         []byte{2, 1, 1, 2, 3, 4, 5, 6},
-			expectedErr: nil,
-		},
-		{
-			name:        "TooSmallTargetLinkLayerAddressOption",
-			buf:         []byte{2, 1, 1, 2, 3, 4, 5},
-			expectedErr: io.ErrUnexpectedEOF,
-		},
-		{
-			name: "ValidPrefixInformation",
-			buf: []byte{
-				3, 4, 43, 64,
-				1, 2, 3, 4,
-				5, 6, 7, 8,
-				0, 0, 0, 0,
-				9, 10, 11, 12,
-				13, 14, 15, 16,
-				17, 18, 19, 20,
-				21, 22, 23, 24,
-			},
-			expectedErr: nil,
-		},
-		{
-			name: "TooSmallPrefixInformation",
-			buf: []byte{
-				3, 4, 43, 64,
-				1, 2, 3, 4,
-				5, 6, 7, 8,
-				0, 0, 0, 0,
-				9, 10, 11, 12,
-				13, 14, 15, 16,
-				17, 18, 19, 20,
-				21, 22, 23,
-			},
-			expectedErr: io.ErrUnexpectedEOF,
-		},
-		{
-			name: "InvalidPrefixInformationLength",
-			buf: []byte{
-				3, 3, 43, 64,
-				1, 2, 3, 4,
-				5, 6, 7, 8,
-				0, 0, 0, 0,
-				9, 10, 11, 12,
-				13, 14, 15, 16,
-			},
-			expectedErr: ErrNDPOptMalformedBody,
-		},
-		{
-			name: "ValidSourceAndTargetLinkLayerAddressWithPrefixInformation",
-			buf: []byte{
-				// Source Link-Layer Address.
-				1, 1, 1, 2, 3, 4, 5, 6,
-
-				// Target Link-Layer Address.
-				2, 1, 7, 8, 9, 10, 11, 12,
-
-				// Prefix information.
-				3, 4, 43, 64,
-				1, 2, 3, 4,
-				5, 6, 7, 8,
-				0, 0, 0, 0,
-				9, 10, 11, 12,
-				13, 14, 15, 16,
-				17, 18, 19, 20,
-				21, 22, 23, 24,
-			},
-			expectedErr: nil,
-		},
-		{
-			name: "ValidSourceAndTargetLinkLayerAddressWithPrefixInformationWithUnrecognized",
-			buf: []byte{
-				// Source Link-Layer Address.
-				1, 1, 1, 2, 3, 4, 5, 6,
-
-				// Target Link-Layer Address.
-				2, 1, 7, 8, 9, 10, 11, 12,
-
-				// 255 is an unrecognized type. If 255 ends up
-				// being the type for some recognized type,
-				// update 255 to some other unrecognized value.
-				255, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 7, 8,
-
-				// Prefix information.
-				3, 4, 43, 64,
-				1, 2, 3, 4,
-				5, 6, 7, 8,
-				0, 0, 0, 0,
-				9, 10, 11, 12,
-				13, 14, 15, 16,
-				17, 18, 19, 20,
-				21, 22, 23, 24,
-			},
-			expectedErr: nil,
-		},
-		{
-			name: "InvalidRecursiveDNSServerCutsOffAddress",
-			buf: []byte{
-				25, 4, 0, 0,
-				0, 0, 0, 0,
-				0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
-				0, 1, 2, 3, 4, 5, 6, 7,
-			},
-			expectedErr: ErrNDPOptMalformedBody,
-		},
-		{
-			name: "InvalidRecursiveDNSServerInvalidLengthField",
-			buf: []byte{
-				25, 2, 0, 0,
-				0, 0, 0, 0,
-				0, 1, 2, 3, 4, 5, 6, 7, 8,
-			},
-			expectedErr: io.ErrUnexpectedEOF,
-		},
-		{
-			name: "RecursiveDNSServerTooSmall",
-			buf: []byte{
-				25, 1, 0, 0,
-				0, 0, 0,
-			},
-			expectedErr: io.ErrUnexpectedEOF,
-		},
-		{
-			name: "RecursiveDNSServerMulticast",
-			buf: []byte{
-				25, 3, 0, 0,
-				0, 0, 0, 0,
-				255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
-			},
-			expectedErr: ErrNDPOptMalformedBody,
-		},
-		{
-			name: "RecursiveDNSServerUnspecified",
-			buf: []byte{
-				25, 3, 0, 0,
-				0, 0, 0, 0,
-				0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-			},
-			expectedErr: ErrNDPOptMalformedBody,
-		},
-		{
-			name: "DNSSearchListLargeCompliantRFC1035",
-			buf: []byte{
-				31, 33, 0, 0,
-				0, 0, 0, 0,
-				63, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
-				'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
-				'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
-				'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
-				'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k',
-				63, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
-				'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
-				'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
-				'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
-				'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k',
-				63, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
-				'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
-				'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
-				'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
-				'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k',
-				62, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
-				'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
-				'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
-				'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
-				'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j',
-				0,
-			},
-			expectedErr: nil,
-		},
-		{
-			name: "DNSSearchListNonCompliantRFC1035",
-			buf: []byte{
-				31, 33, 0, 0,
-				0, 0, 0, 0,
-				63, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
-				'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
-				'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
-				'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
-				'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k',
-				63, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
-				'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
-				'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
-				'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
-				'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k',
-				63, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
-				'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
-				'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
-				'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
-				'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k',
-				63, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
-				'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
-				'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
-				'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
-				'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-				'i', 'j', 'k',
-				0,
-				0, 0, 0, 0, 0, 0, 0, 0,
-			},
-			expectedErr: ErrNDPOptMalformedBody,
-		},
-		{
-			name: "DNSSearchListValidSmall",
-			buf: []byte{
-				31, 2, 0, 0,
-				0, 0, 0, 0,
-				6, 'a', 'b', 'c', 'd', 'e', 'f',
-				0,
-			},
-			expectedErr: nil,
-		},
-		{
-			name: "DNSSearchListTooSmall",
-			buf: []byte{
-				31, 1, 0, 0,
-				0, 0, 0,
-			},
-			expectedErr: io.ErrUnexpectedEOF,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			opts := NDPOptions(test.buf)
-
-			if _, err := opts.Iter(true); !errors.Is(err, test.expectedErr) {
-				t.Fatalf("got Iter(true) = (_, %v), want = (_, %v)", err, test.expectedErr)
-			}
-
-			// test.buf may be malformed but we chose not to check
-			// the iterator so it must return true.
-			if _, err := opts.Iter(false); err != nil {
-				t.Fatalf("got Iter(false) = (_, %s), want = (_, nil)", err)
-			}
-		})
-	}
-}
-
-// TestNDPOptionsIter tests that we can iterator over a valid NDPOptions. Note,
-// this test does not actually check any of the option's getters, it simply
-// checks the option Type and Body. We have other tests that tests the option
-// field gettings given an option body and don't need to duplicate those tests
-// here.
-func TestNDPOptionsIter(t *testing.T) {
-	buf := []byte{
-		// Source Link-Layer Address.
-		1, 1, 1, 2, 3, 4, 5, 6,
-
-		// Target Link-Layer Address.
-		2, 1, 7, 8, 9, 10, 11, 12,
-
-		// 255 is an unrecognized type. If 255 ends up being the type
-		// for some recognized type, update 255 to some other
-		// unrecognized value. Note, this option should be skipped when
-		// iterating.
-		255, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 7, 8,
-
-		// Prefix information.
-		3, 4, 43, 64,
-		1, 2, 3, 4,
-		5, 6, 7, 8,
-		0, 0, 0, 0,
-		9, 10, 11, 12,
-		13, 14, 15, 16,
-		17, 18, 19, 20,
-		21, 22, 23, 24,
-	}
-
-	opts := NDPOptions(buf)
-	it, err := opts.Iter(true)
-	if err != nil {
-		t.Fatalf("got Iter = (_, %s), want = (_, nil)", err)
-	}
-
-	// Test the first (Source Link-Layer) option.
-	next, done, err := it.Next()
-	if err != nil {
-		t.Fatalf("got Next = (_, _, %s), want = (_, _, nil)", err)
-	}
-	if done {
-		t.Fatal("got Next = (_, true, _), want = (_, false, _)")
-	}
-	if got, want := []byte(next.(NDPSourceLinkLayerAddressOption)), buf[2:][:6]; !bytes.Equal(got, want) {
-		t.Errorf("got Next = (%x, _, _), want = (%x, _, _)", got, want)
-	}
-	if got := next.kind(); got != ndpSourceLinkLayerAddressOptionType {
-		t.Errorf("got Type = %d, want = %d", got, ndpSourceLinkLayerAddressOptionType)
-	}
-
-	// Test the next (Target Link-Layer) option.
-	next, done, err = it.Next()
-	if err != nil {
-		t.Fatalf("got Next = (_, _, %s), want = (_, _, nil)", err)
-	}
-	if done {
-		t.Fatal("got Next = (_, true, _), want = (_, false, _)")
-	}
-	if got, want := []byte(next.(NDPTargetLinkLayerAddressOption)), buf[10:][:6]; !bytes.Equal(got, want) {
-		t.Errorf("got Next = (%x, _, _), want = (%x, _, _)", got, want)
-	}
-	if got := next.kind(); got != ndpTargetLinkLayerAddressOptionType {
-		t.Errorf("got Type = %d, want = %d", got, ndpTargetLinkLayerAddressOptionType)
-	}
-
-	// Test the next (Prefix Information) option.
-	// Note, the unrecognized option should be skipped.
-	next, done, err = it.Next()
-	if err != nil {
-		t.Fatalf("got Next = (_, _, %s), want = (_, _, nil)", err)
-	}
-	if done {
-		t.Fatal("got Next = (_, true, _), want = (_, false, _)")
-	}
-	if got, want := next.(NDPPrefixInformation), buf[34:][:30]; !bytes.Equal(got, want) {
-		t.Errorf("got Next = (%x, _, _), want = (%x, _, _)", got, want)
-	}
-	if got := next.kind(); got != ndpPrefixInformationType {
-		t.Errorf("got Type = %d, want = %d", got, ndpPrefixInformationType)
-	}
-
-	// Iterator should not return anything else.
-	next, done, err = it.Next()
-	if err != nil {
-		t.Errorf("got Next = (_, _, %s), want = (_, _, nil)", err)
-	}
-	if !done {
-		t.Error("got Next = (_, false, _), want = (_, true, _)")
-	}
-	if next != nil {
-		t.Errorf("got Next = (%x, _, _), want = (nil, _, _)", next)
-	}
-}
diff --git a/pkg/tcpip/header/parse/parse_state_autogen.go b/pkg/tcpip/header/parse/parse_state_autogen.go
new file mode 100644
index 0000000..ad047be
--- /dev/null
+++ b/pkg/tcpip/header/parse/parse_state_autogen.go
@@ -0,0 +1,3 @@
+// automatically generated by stateify.
+
+package parse
diff --git a/pkg/tcpip/header/tcp_test.go b/pkg/tcpip/header/tcp_test.go
deleted file mode 100644
index 96db846..0000000
--- a/pkg/tcpip/header/tcp_test.go
+++ /dev/null
@@ -1,168 +0,0 @@
-// 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 header_test
-
-import (
-	"reflect"
-	"testing"
-
-	"gvisor.dev/gvisor/pkg/tcpip/header"
-)
-
-func TestEncodeSACKBlocks(t *testing.T) {
-	testCases := []struct {
-		sackBlocks []header.SACKBlock
-		want       []header.SACKBlock
-		bufSize    int
-	}{
-		{
-			[]header.SACKBlock{{10, 20}, {22, 30}, {32, 40}, {42, 50}, {52, 60}, {62, 70}},
-			[]header.SACKBlock{{10, 20}, {22, 30}, {32, 40}, {42, 50}},
-			40,
-		},
-		{
-			[]header.SACKBlock{{10, 20}, {22, 30}, {32, 40}, {42, 50}, {52, 60}, {62, 70}},
-			[]header.SACKBlock{{10, 20}, {22, 30}, {32, 40}},
-			30,
-		},
-		{
-			[]header.SACKBlock{{10, 20}, {22, 30}, {32, 40}, {42, 50}, {52, 60}, {62, 70}},
-			[]header.SACKBlock{{10, 20}, {22, 30}},
-			20,
-		},
-		{
-			[]header.SACKBlock{{10, 20}, {22, 30}, {32, 40}, {42, 50}, {52, 60}, {62, 70}},
-			[]header.SACKBlock{{10, 20}},
-			10,
-		},
-		{
-			[]header.SACKBlock{{10, 20}, {22, 30}, {32, 40}, {42, 50}, {52, 60}, {62, 70}},
-			nil,
-			8,
-		},
-		{
-			[]header.SACKBlock{{10, 20}, {22, 30}, {32, 40}, {42, 50}, {52, 60}, {62, 70}},
-			[]header.SACKBlock{{10, 20}, {22, 30}, {32, 40}, {42, 50}},
-			60,
-		},
-	}
-	for _, tc := range testCases {
-		b := make([]byte, tc.bufSize)
-		t.Logf("testing: %v", tc)
-		header.EncodeSACKBlocks(tc.sackBlocks, b)
-		opts := header.ParseTCPOptions(b)
-		if got, want := opts.SACKBlocks, tc.want; !reflect.DeepEqual(got, want) {
-			t.Errorf("header.EncodeSACKBlocks(%v, %v), encoded blocks got: %v, want: %v", tc.sackBlocks, b, got, want)
-		}
-	}
-}
-
-func TestTCPParseOptions(t *testing.T) {
-	type tsOption struct {
-		tsVal uint32
-		tsEcr uint32
-	}
-
-	generateOptions := func(tsOpt *tsOption, sackBlocks []header.SACKBlock) []byte {
-		l := 0
-		if tsOpt != nil {
-			l += 10
-		}
-		if len(sackBlocks) != 0 {
-			l += len(sackBlocks)*8 + 2
-		}
-		b := make([]byte, l)
-		offset := 0
-		if tsOpt != nil {
-			offset = header.EncodeTSOption(tsOpt.tsVal, tsOpt.tsEcr, b)
-		}
-		header.EncodeSACKBlocks(sackBlocks, b[offset:])
-		return b
-	}
-
-	testCases := []struct {
-		b    []byte
-		want header.TCPOptions
-	}{
-		// Trivial cases.
-		{nil, header.TCPOptions{false, 0, 0, nil}},
-		{[]byte{header.TCPOptionNOP}, header.TCPOptions{false, 0, 0, nil}},
-		{[]byte{header.TCPOptionNOP, header.TCPOptionNOP}, header.TCPOptions{false, 0, 0, nil}},
-		{[]byte{header.TCPOptionEOL}, header.TCPOptions{false, 0, 0, nil}},
-		{[]byte{header.TCPOptionNOP, header.TCPOptionEOL, header.TCPOptionTS, 10, 1, 1}, header.TCPOptions{false, 0, 0, nil}},
-
-		// Test timestamp parsing.
-		{[]byte{header.TCPOptionNOP, header.TCPOptionTS, 10, 0, 0, 0, 1, 0, 0, 0, 1}, header.TCPOptions{true, 1, 1, nil}},
-		{[]byte{header.TCPOptionTS, 10, 0, 0, 0, 1, 0, 0, 0, 1}, header.TCPOptions{true, 1, 1, nil}},
-
-		// Test malformed timestamp option.
-		{[]byte{header.TCPOptionTS, 8, 1, 1}, header.TCPOptions{false, 0, 0, nil}},
-		{[]byte{header.TCPOptionNOP, header.TCPOptionTS, 8, 1, 1}, header.TCPOptions{false, 0, 0, nil}},
-		{[]byte{header.TCPOptionNOP, header.TCPOptionTS, 8, 0, 0, 0, 1, 0, 0, 0, 1}, header.TCPOptions{false, 0, 0, nil}},
-
-		// Test SACKBlock parsing.
-		{[]byte{header.TCPOptionSACK, 10, 0, 0, 0, 1, 0, 0, 0, 10}, header.TCPOptions{false, 0, 0, []header.SACKBlock{{1, 10}}}},
-		{[]byte{header.TCPOptionSACK, 18, 0, 0, 0, 1, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12}, header.TCPOptions{false, 0, 0, []header.SACKBlock{{1, 10}, {11, 12}}}},
-
-		// Test malformed SACK option.
-		{[]byte{header.TCPOptionSACK, 0}, header.TCPOptions{false, 0, 0, nil}},
-		{[]byte{header.TCPOptionSACK, 8, 0, 0, 0, 1, 0, 0, 0, 10}, header.TCPOptions{false, 0, 0, nil}},
-		{[]byte{header.TCPOptionSACK, 11, 0, 0, 0, 1, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12}, header.TCPOptions{false, 0, 0, nil}},
-		{[]byte{header.TCPOptionSACK, 17, 0, 0, 0, 1, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12}, header.TCPOptions{false, 0, 0, nil}},
-		{[]byte{header.TCPOptionSACK}, header.TCPOptions{false, 0, 0, nil}},
-		{[]byte{header.TCPOptionSACK, 10}, header.TCPOptions{false, 0, 0, nil}},
-		{[]byte{header.TCPOptionSACK, 10, 0, 0, 0, 1, 0, 0, 0}, header.TCPOptions{false, 0, 0, nil}},
-
-		// Test Timestamp + SACK block parsing.
-		{generateOptions(&tsOption{1, 1}, []header.SACKBlock{{1, 10}, {11, 12}}), header.TCPOptions{true, 1, 1, []header.SACKBlock{{1, 10}, {11, 12}}}},
-		{generateOptions(&tsOption{1, 2}, []header.SACKBlock{{1, 10}, {11, 12}}), header.TCPOptions{true, 1, 2, []header.SACKBlock{{1, 10}, {11, 12}}}},
-		{generateOptions(&tsOption{1, 3}, []header.SACKBlock{{1, 10}, {11, 12}, {13, 14}, {14, 15}, {15, 16}}), header.TCPOptions{true, 1, 3, []header.SACKBlock{{1, 10}, {11, 12}, {13, 14}, {14, 15}}}},
-
-		// Test valid timestamp + malformed SACK block parsing.
-		{[]byte{header.TCPOptionTS, 10, 0, 0, 0, 1, 0, 0, 0, 1, header.TCPOptionSACK}, header.TCPOptions{true, 1, 1, nil}},
-		{[]byte{header.TCPOptionTS, 10, 0, 0, 0, 1, 0, 0, 0, 1, header.TCPOptionSACK, 10}, header.TCPOptions{true, 1, 1, nil}},
-		{[]byte{header.TCPOptionTS, 10, 0, 0, 0, 1, 0, 0, 0, 1, header.TCPOptionSACK, 10, 0, 0, 0}, header.TCPOptions{true, 1, 1, nil}},
-		{[]byte{header.TCPOptionTS, 10, 0, 0, 0, 1, 0, 0, 0, 1, header.TCPOptionSACK, 11, 0, 0, 0, 1, 0, 0, 0, 1}, header.TCPOptions{true, 1, 1, nil}},
-		{[]byte{header.TCPOptionSACK, header.TCPOptionTS, 10, 0, 0, 0, 1, 0, 0, 0, 1}, header.TCPOptions{false, 0, 0, nil}},
-		{[]byte{header.TCPOptionSACK, 10, header.TCPOptionTS, 10, 0, 0, 0, 1, 0, 0, 0, 1}, header.TCPOptions{false, 0, 0, []header.SACKBlock{{134873088, 65536}}}},
-		{[]byte{header.TCPOptionSACK, 10, 0, 0, 0, header.TCPOptionTS, 10, 0, 0, 0, 1, 0, 0, 0, 1}, header.TCPOptions{false, 0, 0, []header.SACKBlock{{8, 167772160}}}},
-		{[]byte{header.TCPOptionSACK, 11, 0, 0, 0, 1, 0, 0, 0, 1, header.TCPOptionTS, 10, 0, 0, 0, 1, 0, 0, 0, 1}, header.TCPOptions{false, 0, 0, nil}},
-	}
-	for _, tc := range testCases {
-		if got, want := header.ParseTCPOptions(tc.b), tc.want; !reflect.DeepEqual(got, want) {
-			t.Errorf("ParseTCPOptions(%v) = %v, want: %v", tc.b, got, tc.want)
-		}
-	}
-}
-
-func TestTCPFlags(t *testing.T) {
-	for _, tt := range []struct {
-		flags header.TCPFlags
-		want  string
-	}{
-		{header.TCPFlagFin, "F     "},
-		{header.TCPFlagSyn, " S    "},
-		{header.TCPFlagRst, "  R   "},
-		{header.TCPFlagPsh, "   P  "},
-		{header.TCPFlagAck, "    A "},
-		{header.TCPFlagUrg, "     U"},
-		{header.TCPFlagSyn | header.TCPFlagAck, " S  A "},
-		{header.TCPFlagFin | header.TCPFlagAck, "F   A "},
-	} {
-		if got := tt.flags.String(); got != tt.want {
-			t.Errorf("got TCPFlags(%#b).String() = %s, want = %s", tt.flags, got, tt.want)
-		}
-	}
-}
diff --git a/pkg/tcpip/link/ethernet/ethernet_state_autogen.go b/pkg/tcpip/link/ethernet/ethernet_state_autogen.go
new file mode 100644
index 0000000..71d255c
--- /dev/null
+++ b/pkg/tcpip/link/ethernet/ethernet_state_autogen.go
@@ -0,0 +1,3 @@
+// automatically generated by stateify.
+
+package ethernet
diff --git a/pkg/tcpip/link/ethernet/ethernet_test.go b/pkg/tcpip/link/ethernet/ethernet_test.go
deleted file mode 100644
index 08a7f1c..0000000
--- a/pkg/tcpip/link/ethernet/ethernet_test.go
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2021 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 ethernet_test
-
-import (
-	"testing"
-
-	"gvisor.dev/gvisor/pkg/tcpip"
-	"gvisor.dev/gvisor/pkg/tcpip/buffer"
-	"gvisor.dev/gvisor/pkg/tcpip/header"
-	"gvisor.dev/gvisor/pkg/tcpip/link/channel"
-	"gvisor.dev/gvisor/pkg/tcpip/link/ethernet"
-	"gvisor.dev/gvisor/pkg/tcpip/stack"
-)
-
-var _ stack.NetworkDispatcher = (*testNetworkDispatcher)(nil)
-
-type testNetworkDispatcher struct {
-	networkPackets int
-}
-
-func (t *testNetworkDispatcher) DeliverNetworkPacket(_, _ tcpip.LinkAddress, _ tcpip.NetworkProtocolNumber, _ *stack.PacketBuffer) {
-	t.networkPackets++
-}
-
-func (*testNetworkDispatcher) DeliverOutboundPacket(_, _ tcpip.LinkAddress, _ tcpip.NetworkProtocolNumber, _ *stack.PacketBuffer) {
-}
-
-func TestDeliverNetworkPacket(t *testing.T) {
-	const (
-		linkAddr       = tcpip.LinkAddress("\x02\x02\x03\x04\x05\x06")
-		otherLinkAddr1 = tcpip.LinkAddress("\x02\x02\x03\x04\x05\x07")
-		otherLinkAddr2 = tcpip.LinkAddress("\x02\x02\x03\x04\x05\x08")
-	)
-
-	e := ethernet.New(channel.New(0, 0, linkAddr))
-	var networkDispatcher testNetworkDispatcher
-	e.Attach(&networkDispatcher)
-
-	if networkDispatcher.networkPackets != 0 {
-		t.Fatalf("got networkDispatcher.networkPackets = %d, want = 0", networkDispatcher.networkPackets)
-	}
-
-	// An ethernet frame with a destination link address that is not assigned to
-	// our ethernet link endpoint should still be delivered to the network
-	// dispatcher since the ethernet endpoint is not expected to filter frames.
-	eth := buffer.NewView(header.EthernetMinimumSize)
-	header.Ethernet(eth).Encode(&header.EthernetFields{
-		SrcAddr: otherLinkAddr1,
-		DstAddr: otherLinkAddr2,
-		Type:    header.IPv4ProtocolNumber,
-	})
-	e.DeliverNetworkPacket("", "", 0, stack.NewPacketBuffer(stack.PacketBufferOptions{
-		Data: eth.ToVectorisedView(),
-	}))
-	if networkDispatcher.networkPackets != 1 {
-		t.Fatalf("got networkDispatcher.networkPackets = %d, want = 1", networkDispatcher.networkPackets)
-	}
-}
diff --git a/pkg/tcpip/link/loopback/loopback_state_autogen.go b/pkg/tcpip/link/loopback/loopback_state_autogen.go
new file mode 100644
index 0000000..c00fd9f
--- /dev/null
+++ b/pkg/tcpip/link/loopback/loopback_state_autogen.go
@@ -0,0 +1,3 @@
+// automatically generated by stateify.
+
+package loopback
diff --git a/pkg/tcpip/link/nested/nested_state_autogen.go b/pkg/tcpip/link/nested/nested_state_autogen.go
new file mode 100644
index 0000000..9e1b5ca
--- /dev/null
+++ b/pkg/tcpip/link/nested/nested_state_autogen.go
@@ -0,0 +1,3 @@
+// automatically generated by stateify.
+
+package nested
diff --git a/pkg/tcpip/link/nested/nested_test.go b/pkg/tcpip/link/nested/nested_test.go
deleted file mode 100644
index c1f9d30..0000000
--- a/pkg/tcpip/link/nested/nested_test.go
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright 2020 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 nested_test
-
-import (
-	"testing"
-
-	"gvisor.dev/gvisor/pkg/tcpip"
-	"gvisor.dev/gvisor/pkg/tcpip/header"
-	"gvisor.dev/gvisor/pkg/tcpip/link/nested"
-	"gvisor.dev/gvisor/pkg/tcpip/stack"
-)
-
-type parentEndpoint struct {
-	nested.Endpoint
-}
-
-var _ stack.LinkEndpoint = (*parentEndpoint)(nil)
-var _ stack.NetworkDispatcher = (*parentEndpoint)(nil)
-
-type childEndpoint struct {
-	stack.LinkEndpoint
-	dispatcher stack.NetworkDispatcher
-}
-
-var _ stack.LinkEndpoint = (*childEndpoint)(nil)
-
-func (c *childEndpoint) Attach(dispatcher stack.NetworkDispatcher) {
-	c.dispatcher = dispatcher
-}
-
-func (c *childEndpoint) IsAttached() bool {
-	return c.dispatcher != nil
-}
-
-type counterDispatcher struct {
-	count int
-}
-
-var _ stack.NetworkDispatcher = (*counterDispatcher)(nil)
-
-func (d *counterDispatcher) DeliverNetworkPacket(tcpip.LinkAddress, tcpip.LinkAddress, tcpip.NetworkProtocolNumber, *stack.PacketBuffer) {
-	d.count++
-}
-
-func (d *counterDispatcher) DeliverOutboundPacket(tcpip.LinkAddress, tcpip.LinkAddress, tcpip.NetworkProtocolNumber, *stack.PacketBuffer) {
-	panic("unimplemented")
-}
-
-func TestNestedLinkEndpoint(t *testing.T) {
-	const emptyAddress = tcpip.LinkAddress("")
-
-	var (
-		childEP  childEndpoint
-		nestedEP parentEndpoint
-		disp     counterDispatcher
-	)
-	nestedEP.Endpoint.Init(&childEP, &nestedEP)
-
-	if childEP.IsAttached() {
-		t.Error("On init, childEP.IsAttached() = true, want = false")
-	}
-	if nestedEP.IsAttached() {
-		t.Error("On init, nestedEP.IsAttached() = true, want = false")
-	}
-
-	nestedEP.Attach(&disp)
-	if disp.count != 0 {
-		t.Fatalf("After attach, got disp.count = %d, want = 0", disp.count)
-	}
-	if !childEP.IsAttached() {
-		t.Error("After attach, childEP.IsAttached() = false, want = true")
-	}
-	if !nestedEP.IsAttached() {
-		t.Error("After attach, nestedEP.IsAttached() = false, want = true")
-	}
-
-	nestedEP.DeliverNetworkPacket(emptyAddress, emptyAddress, header.IPv4ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{}))
-	if disp.count != 1 {
-		t.Errorf("After first packet with dispatcher attached, got disp.count = %d, want = 1", disp.count)
-	}
-
-	nestedEP.Attach(nil)
-	if childEP.IsAttached() {
-		t.Error("After detach, childEP.IsAttached() = true, want = false")
-	}
-	if nestedEP.IsAttached() {
-		t.Error("After detach, nestedEP.IsAttached() = true, want = false")
-	}
-
-	disp.count = 0
-	nestedEP.DeliverNetworkPacket(emptyAddress, emptyAddress, header.IPv4ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{}))
-	if disp.count != 0 {
-		t.Errorf("After second packet with dispatcher detached, got disp.count = %d, want = 0", disp.count)
-	}
-
-}
diff --git a/pkg/tcpip/link/pipe/pipe_state_autogen.go b/pkg/tcpip/link/pipe/pipe_state_autogen.go
new file mode 100644
index 0000000..d3b40fe
--- /dev/null
+++ b/pkg/tcpip/link/pipe/pipe_state_autogen.go
@@ -0,0 +1,3 @@
+// automatically generated by stateify.
+
+package pipe
diff --git a/pkg/tcpip/link/sniffer/sniffer_state_autogen.go b/pkg/tcpip/link/sniffer/sniffer_state_autogen.go
new file mode 100644
index 0000000..8d79def
--- /dev/null
+++ b/pkg/tcpip/link/sniffer/sniffer_state_autogen.go
@@ -0,0 +1,3 @@
+// automatically generated by stateify.
+
+package sniffer
diff --git a/pkg/tcpip/network/arp/arp_state_autogen.go b/pkg/tcpip/network/arp/arp_state_autogen.go
new file mode 100644
index 0000000..5cd8535
--- /dev/null
+++ b/pkg/tcpip/network/arp/arp_state_autogen.go
@@ -0,0 +1,3 @@
+// automatically generated by stateify.
+
+package arp
diff --git a/pkg/tcpip/network/arp/arp_test.go b/pkg/tcpip/network/arp/arp_test.go
deleted file mode 100644
index 018d6a5..0000000
--- a/pkg/tcpip/network/arp/arp_test.go
+++ /dev/null
@@ -1,711 +0,0 @@
-// 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 arp_test
-
-import (
-	"context"
-	"fmt"
-	"testing"
-	"time"
-
-	"github.com/google/go-cmp/cmp"
-	"github.com/google/go-cmp/cmp/cmpopts"
-	"gvisor.dev/gvisor/pkg/tcpip"
-	"gvisor.dev/gvisor/pkg/tcpip/buffer"
-	"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/network/arp"
-	"gvisor.dev/gvisor/pkg/tcpip/network/ipv4"
-	"gvisor.dev/gvisor/pkg/tcpip/stack"
-	"gvisor.dev/gvisor/pkg/tcpip/transport/icmp"
-)
-
-const (
-	nicID = 1
-
-	stackAddr     = tcpip.Address("\x0a\x00\x00\x01")
-	stackLinkAddr = tcpip.LinkAddress("\x0a\x0a\x0b\x0b\x0c\x0c")
-
-	remoteAddr     = tcpip.Address("\x0a\x00\x00\x02")
-	remoteLinkAddr = tcpip.LinkAddress("\x01\x02\x03\x04\x05\x06")
-
-	unknownAddr = tcpip.Address("\x0a\x00\x00\x03")
-
-	defaultChannelSize = 1
-	defaultMTU         = 65536
-
-	// eventChanSize defines the size of event channels used by the neighbor
-	// cache's event dispatcher. The size chosen here needs to be sufficient to
-	// queue all the events received during tests before consumption.
-	// If eventChanSize is too small, the tests may deadlock.
-	eventChanSize = 32
-)
-
-type eventType uint8
-
-const (
-	entryAdded eventType = iota
-	entryChanged
-	entryRemoved
-)
-
-func (t eventType) String() string {
-	switch t {
-	case entryAdded:
-		return "add"
-	case entryChanged:
-		return "change"
-	case entryRemoved:
-		return "remove"
-	default:
-		return fmt.Sprintf("unknown (%d)", t)
-	}
-}
-
-type eventInfo struct {
-	eventType eventType
-	nicID     tcpip.NICID
-	entry     stack.NeighborEntry
-}
-
-func (e eventInfo) String() string {
-	return fmt.Sprintf("%s event for NIC #%d, %#v", e.eventType, e.nicID, e.entry)
-}
-
-// arpDispatcher implements NUDDispatcher to validate the dispatching of
-// events upon certain NUD state machine events.
-type arpDispatcher struct {
-	// C is where events are queued
-	C chan eventInfo
-}
-
-var _ stack.NUDDispatcher = (*arpDispatcher)(nil)
-
-func (d *arpDispatcher) OnNeighborAdded(nicID tcpip.NICID, entry stack.NeighborEntry) {
-	e := eventInfo{
-		eventType: entryAdded,
-		nicID:     nicID,
-		entry:     entry,
-	}
-	d.C <- e
-}
-
-func (d *arpDispatcher) OnNeighborChanged(nicID tcpip.NICID, entry stack.NeighborEntry) {
-	e := eventInfo{
-		eventType: entryChanged,
-		nicID:     nicID,
-		entry:     entry,
-	}
-	d.C <- e
-}
-
-func (d *arpDispatcher) OnNeighborRemoved(nicID tcpip.NICID, entry stack.NeighborEntry) {
-	e := eventInfo{
-		eventType: entryRemoved,
-		nicID:     nicID,
-		entry:     entry,
-	}
-	d.C <- e
-}
-
-func (d *arpDispatcher) waitForEvent(ctx context.Context, want eventInfo) error {
-	select {
-	case got := <-d.C:
-		if diff := cmp.Diff(want, got, cmp.AllowUnexported(got), cmpopts.IgnoreFields(stack.NeighborEntry{}, "UpdatedAtNanos")); diff != "" {
-			return fmt.Errorf("got invalid event (-want +got):\n%s", diff)
-		}
-	case <-ctx.Done():
-		return fmt.Errorf("%s for %s", ctx.Err(), want)
-	}
-	return nil
-}
-
-func (d *arpDispatcher) waitForEventWithTimeout(want eventInfo, timeout time.Duration) error {
-	ctx, cancel := context.WithTimeout(context.Background(), timeout)
-	defer cancel()
-	return d.waitForEvent(ctx, want)
-}
-
-func (d *arpDispatcher) nextEvent() (eventInfo, bool) {
-	select {
-	case event := <-d.C:
-		return event, true
-	default:
-		return eventInfo{}, false
-	}
-}
-
-type testContext struct {
-	s       *stack.Stack
-	linkEP  *channel.Endpoint
-	nudDisp *arpDispatcher
-}
-
-func newTestContext(t *testing.T) *testContext {
-	c := stack.DefaultNUDConfigurations()
-	// Transition from Reachable to Stale almost immediately to test if receiving
-	// probes refreshes positive reachability.
-	c.BaseReachableTime = time.Microsecond
-
-	d := arpDispatcher{
-		// Create an event channel large enough so the neighbor cache doesn't block
-		// while dispatching events. Blocking could interfere with the timing of
-		// NUD transitions.
-		C: make(chan eventInfo, eventChanSize),
-	}
-
-	s := stack.New(stack.Options{
-		NetworkProtocols:   []stack.NetworkProtocolFactory{ipv4.NewProtocol, arp.NewProtocol},
-		TransportProtocols: []stack.TransportProtocolFactory{icmp.NewProtocol4},
-		NUDConfigs:         c,
-		NUDDisp:            &d,
-	})
-
-	ep := channel.New(defaultChannelSize, defaultMTU, stackLinkAddr)
-	ep.LinkEPCapabilities |= stack.CapabilityResolutionRequired
-
-	wep := stack.LinkEndpoint(ep)
-
-	if testing.Verbose() {
-		wep = sniffer.New(ep)
-	}
-	if err := s.CreateNIC(nicID, wep); err != nil {
-		t.Fatalf("CreateNIC failed: %v", err)
-	}
-
-	if err := s.AddAddress(nicID, ipv4.ProtocolNumber, stackAddr); err != nil {
-		t.Fatalf("AddAddress for ipv4 failed: %v", err)
-	}
-
-	s.SetRouteTable([]tcpip.Route{{
-		Destination: header.IPv4EmptySubnet,
-		NIC:         nicID,
-	}})
-
-	return &testContext{
-		s:       s,
-		linkEP:  ep,
-		nudDisp: &d,
-	}
-}
-
-func (c *testContext) cleanup() {
-	c.linkEP.Close()
-}
-
-func TestMalformedPacket(t *testing.T) {
-	c := newTestContext(t)
-	defer c.cleanup()
-
-	v := make(buffer.View, header.ARPSize)
-	pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{
-		Data: v.ToVectorisedView(),
-	})
-
-	c.linkEP.InjectInbound(arp.ProtocolNumber, pkt)
-
-	if got := c.s.Stats().ARP.PacketsReceived.Value(); got != 1 {
-		t.Errorf("got c.s.Stats().ARP.PacketsReceived.Value() = %d, want = 1", got)
-	}
-	if got := c.s.Stats().ARP.MalformedPacketsReceived.Value(); got != 1 {
-		t.Errorf("got c.s.Stats().ARP.MalformedPacketsReceived.Value() = %d, want = 1", got)
-	}
-}
-
-func TestDisabledEndpoint(t *testing.T) {
-	c := newTestContext(t)
-	defer c.cleanup()
-
-	ep, err := c.s.GetNetworkEndpoint(nicID, header.ARPProtocolNumber)
-	if err != nil {
-		t.Fatalf("GetNetworkEndpoint(%d, header.ARPProtocolNumber) failed: %s", nicID, err)
-	}
-	ep.Disable()
-
-	v := make(buffer.View, header.ARPSize)
-	pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{
-		Data: v.ToVectorisedView(),
-	})
-
-	c.linkEP.InjectInbound(arp.ProtocolNumber, pkt)
-
-	if got := c.s.Stats().ARP.PacketsReceived.Value(); got != 1 {
-		t.Errorf("got c.s.Stats().ARP.PacketsReceived.Value() = %d, want = 1", got)
-	}
-	if got := c.s.Stats().ARP.DisabledPacketsReceived.Value(); got != 1 {
-		t.Errorf("got c.s.Stats().ARP.DisabledPacketsReceived.Value() = %d, want = 1", got)
-	}
-}
-
-func TestDirectReply(t *testing.T) {
-	c := newTestContext(t)
-	defer c.cleanup()
-
-	const senderMAC = "\x01\x02\x03\x04\x05\x06"
-	const senderIPv4 = "\x0a\x00\x00\x02"
-
-	v := make(buffer.View, header.ARPSize)
-	h := header.ARP(v)
-	h.SetIPv4OverEthernet()
-	h.SetOp(header.ARPReply)
-
-	copy(h.HardwareAddressSender(), senderMAC)
-	copy(h.ProtocolAddressSender(), senderIPv4)
-	copy(h.HardwareAddressTarget(), stackLinkAddr)
-	copy(h.ProtocolAddressTarget(), stackAddr)
-
-	pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{
-		Data: v.ToVectorisedView(),
-	})
-
-	c.linkEP.InjectInbound(arp.ProtocolNumber, pkt)
-
-	if got := c.s.Stats().ARP.PacketsReceived.Value(); got != 1 {
-		t.Errorf("got c.s.Stats().ARP.PacketsReceived.Value() = %d, want = 1", got)
-	}
-	if got := c.s.Stats().ARP.RepliesReceived.Value(); got != 1 {
-		t.Errorf("got c.s.Stats().ARP.PacketsReceived.Value() = %d, want = 1", got)
-	}
-}
-
-func TestDirectRequest(t *testing.T) {
-	c := newTestContext(t)
-	defer c.cleanup()
-
-	tests := []struct {
-		name           string
-		senderAddr     tcpip.Address
-		senderLinkAddr tcpip.LinkAddress
-		targetAddr     tcpip.Address
-		isValid        bool
-	}{
-		{
-			name:           "Loopback",
-			senderAddr:     stackAddr,
-			senderLinkAddr: stackLinkAddr,
-			targetAddr:     stackAddr,
-			isValid:        true,
-		},
-		{
-			name:           "Remote",
-			senderAddr:     remoteAddr,
-			senderLinkAddr: remoteLinkAddr,
-			targetAddr:     stackAddr,
-			isValid:        true,
-		},
-		{
-			name:           "RemoteInvalidTarget",
-			senderAddr:     remoteAddr,
-			senderLinkAddr: remoteLinkAddr,
-			targetAddr:     unknownAddr,
-			isValid:        false,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			packetsRecv := c.s.Stats().ARP.PacketsReceived.Value()
-			requestsRecv := c.s.Stats().ARP.RequestsReceived.Value()
-			requestsRecvUnknownAddr := c.s.Stats().ARP.RequestsReceivedUnknownTargetAddress.Value()
-			outgoingReplies := c.s.Stats().ARP.OutgoingRepliesSent.Value()
-
-			// Inject an incoming ARP request.
-			v := make(buffer.View, header.ARPSize)
-			h := header.ARP(v)
-			h.SetIPv4OverEthernet()
-			h.SetOp(header.ARPRequest)
-			copy(h.HardwareAddressSender(), test.senderLinkAddr)
-			copy(h.ProtocolAddressSender(), test.senderAddr)
-			copy(h.ProtocolAddressTarget(), test.targetAddr)
-			c.linkEP.InjectInbound(arp.ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
-				Data: v.ToVectorisedView(),
-			}))
-
-			if got, want := c.s.Stats().ARP.PacketsReceived.Value(), packetsRecv+1; got != want {
-				t.Errorf("got c.s.Stats().ARP.PacketsReceived.Value() = %d, want = %d", got, want)
-			}
-			if got, want := c.s.Stats().ARP.RequestsReceived.Value(), requestsRecv+1; got != want {
-				t.Errorf("got c.s.Stats().ARP.PacketsReceived.Value() = %d, want = %d", got, want)
-			}
-
-			if !test.isValid {
-				// No packets should be sent after receiving an invalid ARP request.
-				// There is no need to perform a blocking read here, since packets are
-				// sent in the same function that handles ARP requests.
-				if pkt, ok := c.linkEP.Read(); ok {
-					t.Errorf("unexpected packet sent with network protocol number %d", pkt.Proto)
-				}
-				if got, want := c.s.Stats().ARP.RequestsReceivedUnknownTargetAddress.Value(), requestsRecvUnknownAddr+1; got != want {
-					t.Errorf("got c.s.Stats().ARP.RequestsReceivedUnknownTargetAddress.Value() = %d, want = %d", got, want)
-				}
-				if got, want := c.s.Stats().ARP.OutgoingRepliesSent.Value(), outgoingReplies; got != want {
-					t.Errorf("got c.s.Stats().ARP.OutgoingRepliesSent.Value() = %d, want = %d", got, want)
-				}
-
-				return
-			}
-
-			if got, want := c.s.Stats().ARP.OutgoingRepliesSent.Value(), outgoingReplies+1; got != want {
-				t.Errorf("got c.s.Stats().ARP.OutgoingRepliesSent.Value() = %d, want = %d", got, want)
-			}
-
-			// Verify an ARP response was sent.
-			pi, ok := c.linkEP.Read()
-			if !ok {
-				t.Fatal("expected ARP response to be sent, got none")
-			}
-
-			if pi.Proto != arp.ProtocolNumber {
-				t.Fatalf("expected ARP response, got network protocol number %d", pi.Proto)
-			}
-			rep := header.ARP(pi.Pkt.NetworkHeader().View())
-			if !rep.IsValid() {
-				t.Fatalf("invalid ARP response: len = %d; response = %x", len(rep), rep)
-			}
-			if got, want := tcpip.LinkAddress(rep.HardwareAddressSender()), stackLinkAddr; got != want {
-				t.Errorf("got HardwareAddressSender() = %s, want = %s", got, want)
-			}
-			if got, want := tcpip.Address(rep.ProtocolAddressSender()), tcpip.Address(h.ProtocolAddressTarget()); got != want {
-				t.Errorf("got ProtocolAddressSender() = %s, want = %s", got, want)
-			}
-			if got, want := tcpip.LinkAddress(rep.HardwareAddressTarget()), tcpip.LinkAddress(h.HardwareAddressSender()); got != want {
-				t.Errorf("got HardwareAddressTarget() = %s, want = %s", got, want)
-			}
-			if got, want := tcpip.Address(rep.ProtocolAddressTarget()), tcpip.Address(h.ProtocolAddressSender()); got != want {
-				t.Errorf("got ProtocolAddressTarget() = %s, want = %s", got, want)
-			}
-
-			// Verify the sender was saved in the neighbor cache.
-			wantEvent := eventInfo{
-				eventType: entryAdded,
-				nicID:     nicID,
-				entry: stack.NeighborEntry{
-					Addr:     test.senderAddr,
-					LinkAddr: tcpip.LinkAddress(test.senderLinkAddr),
-					State:    stack.Stale,
-				},
-			}
-			if err := c.nudDisp.waitForEventWithTimeout(wantEvent, time.Second); err != nil {
-				t.Fatal(err)
-			}
-
-			neighbors, err := c.s.Neighbors(nicID, ipv4.ProtocolNumber)
-			if err != nil {
-				t.Fatalf("c.s.Neighbors(%d, %d): %s", nicID, ipv4.ProtocolNumber, err)
-			}
-
-			neighborByAddr := make(map[tcpip.Address]stack.NeighborEntry)
-			for _, n := range neighbors {
-				if existing, ok := neighborByAddr[n.Addr]; ok {
-					if diff := cmp.Diff(existing, n); diff != "" {
-						t.Fatalf("duplicate neighbor entry found (-existing +got):\n%s", diff)
-					}
-					t.Fatalf("exact neighbor entry duplicate found for addr=%s", n.Addr)
-				}
-				neighborByAddr[n.Addr] = n
-			}
-
-			neigh, ok := neighborByAddr[test.senderAddr]
-			if !ok {
-				t.Fatalf("expected neighbor entry with Addr = %s", test.senderAddr)
-			}
-			if got, want := neigh.LinkAddr, test.senderLinkAddr; got != want {
-				t.Errorf("got neighbor LinkAddr = %s, want = %s", got, want)
-			}
-			if got, want := neigh.State, stack.Stale; got != want {
-				t.Errorf("got neighbor State = %s, want = %s", got, want)
-			}
-
-			// No more events should be dispatched
-			for {
-				event, ok := c.nudDisp.nextEvent()
-				if !ok {
-					break
-				}
-				t.Errorf("unexpected %s", event)
-			}
-		})
-	}
-}
-
-var _ stack.LinkEndpoint = (*testLinkEndpoint)(nil)
-
-type testLinkEndpoint struct {
-	stack.LinkEndpoint
-
-	writeErr tcpip.Error
-}
-
-func (t *testLinkEndpoint) WritePacket(r stack.RouteInfo, gso *stack.GSO, protocol tcpip.NetworkProtocolNumber, pkt *stack.PacketBuffer) tcpip.Error {
-	if t.writeErr != nil {
-		return t.writeErr
-	}
-
-	return t.LinkEndpoint.WritePacket(r, gso, protocol, pkt)
-}
-
-func TestLinkAddressRequest(t *testing.T) {
-	const nicID = 1
-
-	testAddr := tcpip.Address([]byte{1, 2, 3, 4})
-
-	tests := []struct {
-		name                                            string
-		nicAddr                                         tcpip.Address
-		localAddr                                       tcpip.Address
-		remoteLinkAddr                                  tcpip.LinkAddress
-		linkErr                                         tcpip.Error
-		expectedErr                                     tcpip.Error
-		expectedLocalAddr                               tcpip.Address
-		expectedRemoteLinkAddr                          tcpip.LinkAddress
-		expectedRequestsSent                            uint64
-		expectedRequestBadLocalAddressErrors            uint64
-		expectedRequestInterfaceHasNoLocalAddressErrors uint64
-		expectedRequestDroppedErrors                    uint64
-	}{
-		{
-			name:                                 "Unicast",
-			nicAddr:                              stackAddr,
-			localAddr:                            stackAddr,
-			remoteLinkAddr:                       remoteLinkAddr,
-			expectedLocalAddr:                    stackAddr,
-			expectedRemoteLinkAddr:               remoteLinkAddr,
-			expectedRequestsSent:                 1,
-			expectedRequestBadLocalAddressErrors: 0,
-			expectedRequestInterfaceHasNoLocalAddressErrors: 0,
-			expectedRequestDroppedErrors:                    0,
-		},
-		{
-			name:                                 "Multicast",
-			nicAddr:                              stackAddr,
-			localAddr:                            stackAddr,
-			remoteLinkAddr:                       "",
-			expectedLocalAddr:                    stackAddr,
-			expectedRemoteLinkAddr:               header.EthernetBroadcastAddress,
-			expectedRequestsSent:                 1,
-			expectedRequestBadLocalAddressErrors: 0,
-			expectedRequestInterfaceHasNoLocalAddressErrors: 0,
-			expectedRequestDroppedErrors:                    0,
-		},
-		{
-			name:                                 "Unicast with unspecified source",
-			nicAddr:                              stackAddr,
-			localAddr:                            "",
-			remoteLinkAddr:                       remoteLinkAddr,
-			expectedLocalAddr:                    stackAddr,
-			expectedRemoteLinkAddr:               remoteLinkAddr,
-			expectedRequestsSent:                 1,
-			expectedRequestBadLocalAddressErrors: 0,
-			expectedRequestInterfaceHasNoLocalAddressErrors: 0,
-			expectedRequestDroppedErrors:                    0,
-		},
-		{
-			name:                                 "Multicast with unspecified source",
-			nicAddr:                              stackAddr,
-			localAddr:                            "",
-			remoteLinkAddr:                       "",
-			expectedLocalAddr:                    stackAddr,
-			expectedRemoteLinkAddr:               header.EthernetBroadcastAddress,
-			expectedRequestsSent:                 1,
-			expectedRequestBadLocalAddressErrors: 0,
-			expectedRequestInterfaceHasNoLocalAddressErrors: 0,
-			expectedRequestDroppedErrors:                    0,
-		},
-		{
-			name:                                 "Unicast with unassigned address",
-			nicAddr:                              stackAddr,
-			localAddr:                            testAddr,
-			remoteLinkAddr:                       remoteLinkAddr,
-			expectedErr:                          &tcpip.ErrBadLocalAddress{},
-			expectedRequestsSent:                 0,
-			expectedRequestBadLocalAddressErrors: 1,
-			expectedRequestInterfaceHasNoLocalAddressErrors: 0,
-			expectedRequestDroppedErrors:                    0,
-		},
-		{
-			name:                                 "Multicast with unassigned address",
-			nicAddr:                              stackAddr,
-			localAddr:                            testAddr,
-			remoteLinkAddr:                       "",
-			expectedErr:                          &tcpip.ErrBadLocalAddress{},
-			expectedRequestsSent:                 0,
-			expectedRequestBadLocalAddressErrors: 1,
-			expectedRequestInterfaceHasNoLocalAddressErrors: 0,
-			expectedRequestDroppedErrors:                    0,
-		},
-		{
-			name:                                 "Unicast with no local address available",
-			nicAddr:                              "",
-			localAddr:                            "",
-			remoteLinkAddr:                       remoteLinkAddr,
-			expectedErr:                          &tcpip.ErrNetworkUnreachable{},
-			expectedRequestsSent:                 0,
-			expectedRequestBadLocalAddressErrors: 0,
-			expectedRequestInterfaceHasNoLocalAddressErrors: 1,
-			expectedRequestDroppedErrors:                    0,
-		},
-		{
-			name:                                 "Multicast with no local address available",
-			nicAddr:                              "",
-			localAddr:                            "",
-			remoteLinkAddr:                       "",
-			expectedErr:                          &tcpip.ErrNetworkUnreachable{},
-			expectedRequestsSent:                 0,
-			expectedRequestBadLocalAddressErrors: 0,
-			expectedRequestInterfaceHasNoLocalAddressErrors: 1,
-			expectedRequestDroppedErrors:                    0,
-		},
-		{
-			name:                                 "Link error",
-			nicAddr:                              stackAddr,
-			localAddr:                            stackAddr,
-			remoteLinkAddr:                       remoteLinkAddr,
-			linkErr:                              &tcpip.ErrInvalidEndpointState{},
-			expectedErr:                          &tcpip.ErrInvalidEndpointState{},
-			expectedRequestsSent:                 0,
-			expectedRequestBadLocalAddressErrors: 0,
-			expectedRequestInterfaceHasNoLocalAddressErrors: 0,
-			expectedRequestDroppedErrors:                    1,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			s := stack.New(stack.Options{
-				NetworkProtocols: []stack.NetworkProtocolFactory{arp.NewProtocol, ipv4.NewProtocol},
-			})
-			linkEP := channel.New(defaultChannelSize, defaultMTU, stackLinkAddr)
-			if err := s.CreateNIC(nicID, &testLinkEndpoint{LinkEndpoint: linkEP, writeErr: test.linkErr}); err != nil {
-				t.Fatalf("s.CreateNIC(%d, _): %s", nicID, err)
-			}
-
-			ep, err := s.GetNetworkEndpoint(nicID, arp.ProtocolNumber)
-			if err != nil {
-				t.Fatalf("s.GetNetworkEndpoint(%d, %d): %s", nicID, arp.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, ipv4.ProtocolNumber, test.nicAddr); err != nil {
-					t.Fatalf("s.AddAddress(%d, %d, %s): %s", nicID, ipv4.ProtocolNumber, test.nicAddr, err)
-				}
-			}
-
-			{
-				err := linkRes.LinkAddressRequest(remoteAddr, 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", remoteAddr, test.localAddr, test.remoteLinkAddr, diff)
-				}
-			}
-
-			if got := s.Stats().ARP.OutgoingRequestsSent.Value(); got != test.expectedRequestsSent {
-				t.Errorf("got s.Stats().ARP.OutgoingRequestsSent.Value() = %d, want = %d", got, test.expectedRequestsSent)
-			}
-			if got := s.Stats().ARP.OutgoingRequestInterfaceHasNoLocalAddressErrors.Value(); got != test.expectedRequestInterfaceHasNoLocalAddressErrors {
-				t.Errorf("got s.Stats().ARP.OutgoingRequestInterfaceHasNoLocalAddressErrors.Value() = %d, want = %d", got, test.expectedRequestInterfaceHasNoLocalAddressErrors)
-			}
-			if got := s.Stats().ARP.OutgoingRequestBadLocalAddressErrors.Value(); got != test.expectedRequestBadLocalAddressErrors {
-				t.Errorf("got s.Stats().ARP.OutgoingRequestBadLocalAddressErrors.Value() = %d, want = %d", got, test.expectedRequestBadLocalAddressErrors)
-			}
-			if got := s.Stats().ARP.OutgoingRequestsDropped.Value(); got != test.expectedRequestDroppedErrors {
-				t.Errorf("got s.Stats().ARP.OutgoingRequestsDropped.Value() = %d, want = %d", got, test.expectedRequestDroppedErrors)
-			}
-
-			if test.expectedErr != nil {
-				return
-			}
-
-			pkt, ok := linkEP.Read()
-			if !ok {
-				t.Fatal("expected to send a link address request")
-			}
-
-			if pkt.Route.RemoteLinkAddress != test.expectedRemoteLinkAddr {
-				t.Errorf("got pkt.Route.RemoteLinkAddress = %s, want = %s", pkt.Route.RemoteLinkAddress, test.expectedRemoteLinkAddr)
-			}
-
-			rep := header.ARP(stack.PayloadSince(pkt.Pkt.NetworkHeader()))
-			if got := rep.Op(); got != header.ARPRequest {
-				t.Errorf("got Op = %d, want = %d", got, header.ARPRequest)
-			}
-			if got := tcpip.LinkAddress(rep.HardwareAddressSender()); got != stackLinkAddr {
-				t.Errorf("got HardwareAddressSender = %s, want = %s", got, stackLinkAddr)
-			}
-			if got := tcpip.Address(rep.ProtocolAddressSender()); got != test.expectedLocalAddr {
-				t.Errorf("got ProtocolAddressSender = %s, want = %s", got, test.expectedLocalAddr)
-			}
-			if got, want := tcpip.LinkAddress(rep.HardwareAddressTarget()), tcpip.LinkAddress("\x00\x00\x00\x00\x00\x00"); got != want {
-				t.Errorf("got HardwareAddressTarget = %s, want = %s", got, want)
-			}
-			if got := tcpip.Address(rep.ProtocolAddressTarget()); got != remoteAddr {
-				t.Errorf("got ProtocolAddressTarget = %s, want = %s", got, remoteAddr)
-			}
-		})
-	}
-}
-
-func TestDADARPRequestPacket(t *testing.T) {
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocolFactory{arp.NewProtocolWithOptions(arp.Options{
-			DADConfigs: stack.DADConfigurations{
-				DupAddrDetectTransmits: 1,
-				RetransmitTimer:        time.Second,
-			},
-		}), ipv4.NewProtocol},
-	})
-	e := channel.New(1, defaultMTU, stackLinkAddr)
-	if err := s.CreateNIC(nicID, e); err != nil {
-		t.Fatalf("s.CreateNIC(%d, _): %s", nicID, err)
-	}
-
-	if res, err := s.CheckDuplicateAddress(nicID, header.IPv4ProtocolNumber, remoteAddr, func(stack.DADResult) {}); err != nil {
-		t.Fatalf("s.CheckDuplicateAddress(%d, %d, %s, _): %s", nicID, header.IPv4ProtocolNumber, remoteAddr, err)
-	} else if res != stack.DADStarting {
-		t.Fatalf("got s.CheckDuplicateAddress(%d, %d, %s, _) = %d, want = %d", nicID, header.IPv4ProtocolNumber, remoteAddr, res, stack.DADStarting)
-	}
-
-	pkt, ok := e.ReadContext(context.Background())
-	if !ok {
-		t.Fatal("expected to send an ARP request")
-	}
-
-	if pkt.Route.RemoteLinkAddress != header.EthernetBroadcastAddress {
-		t.Errorf("got pkt.Route.RemoteLinkAddress = %s, want = %s", pkt.Route.RemoteLinkAddress, header.EthernetBroadcastAddress)
-	}
-
-	req := header.ARP(stack.PayloadSince(pkt.Pkt.NetworkHeader()))
-	if !req.IsValid() {
-		t.Errorf("got req.IsValid() = false, want = true")
-	}
-	if got := req.Op(); got != header.ARPRequest {
-		t.Errorf("got req.Op() = %d, want = %d", got, header.ARPRequest)
-	}
-	if got := tcpip.LinkAddress(req.HardwareAddressSender()); got != stackLinkAddr {
-		t.Errorf("got req.HardwareAddressSender() = %s, want = %s", got, stackLinkAddr)
-	}
-	if got := tcpip.Address(req.ProtocolAddressSender()); got != header.IPv4Any {
-		t.Errorf("got req.ProtocolAddressSender() = %s, want = %s", got, header.IPv4Any)
-	}
-	if got, want := tcpip.LinkAddress(req.HardwareAddressTarget()), tcpip.LinkAddress("\x00\x00\x00\x00\x00\x00"); got != want {
-		t.Errorf("got req.HardwareAddressTarget() = %s, want = %s", got, want)
-	}
-	if got := tcpip.Address(req.ProtocolAddressTarget()); got != remoteAddr {
-		t.Errorf("got req.ProtocolAddressTarget() = %s, want = %s", got, remoteAddr)
-	}
-}
diff --git a/pkg/tcpip/network/arp/stats_test.go b/pkg/tcpip/network/arp/stats_test.go
deleted file mode 100644
index e867b3c..0000000
--- a/pkg/tcpip/network/arp/stats_test.go
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2021 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 arp
-
-import (
-	"reflect"
-	"testing"
-
-	"gvisor.dev/gvisor/pkg/tcpip"
-	"gvisor.dev/gvisor/pkg/tcpip/network/internal/testutil"
-	"gvisor.dev/gvisor/pkg/tcpip/stack"
-)
-
-var _ stack.NetworkInterface = (*testInterface)(nil)
-
-type testInterface struct {
-	stack.NetworkInterface
-	nicID tcpip.NICID
-}
-
-func (t *testInterface) ID() tcpip.NICID {
-	return t.nicID
-}
-
-func TestMultiCounterStatsInitialization(t *testing.T) {
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocolFactory{NewProtocol},
-	})
-	proto := s.NetworkProtocolInstance(ProtocolNumber).(*protocol)
-	var nic testInterface
-	ep := proto.NewEndpoint(&nic, nil).(*endpoint)
-	// At this point, the Stack's stats and the NetworkEndpoint's stats are
-	// expected to be bound by a MultiCounterStat.
-	refStack := s.Stats()
-	refEP := ep.stats.localStats
-	if err := testutil.ValidateMultiCounterStats(reflect.ValueOf(&ep.stats.arp).Elem(), []reflect.Value{reflect.ValueOf(&refEP.ARP).Elem(), reflect.ValueOf(&refStack.ARP).Elem()}); err != nil {
-		t.Error(err)
-	}
-}
diff --git a/pkg/tcpip/network/hash/hash_state_autogen.go b/pkg/tcpip/network/hash/hash_state_autogen.go
new file mode 100644
index 0000000..9467fe2
--- /dev/null
+++ b/pkg/tcpip/network/hash/hash_state_autogen.go
@@ -0,0 +1,3 @@
+// automatically generated by stateify.
+
+package hash
diff --git a/pkg/tcpip/network/internal/fragmentation/fragmentation_state_autogen.go b/pkg/tcpip/network/internal/fragmentation/fragmentation_state_autogen.go
new file mode 100644
index 0000000..21c5774
--- /dev/null
+++ b/pkg/tcpip/network/internal/fragmentation/fragmentation_state_autogen.go
@@ -0,0 +1,68 @@
+// automatically generated by stateify.
+
+package fragmentation
+
+import (
+	"gvisor.dev/gvisor/pkg/state"
+)
+
+func (l *reassemblerList) StateTypeName() string {
+	return "pkg/tcpip/network/internal/fragmentation.reassemblerList"
+}
+
+func (l *reassemblerList) StateFields() []string {
+	return []string{
+		"head",
+		"tail",
+	}
+}
+
+func (l *reassemblerList) beforeSave() {}
+
+// +checklocksignore
+func (l *reassemblerList) StateSave(stateSinkObject state.Sink) {
+	l.beforeSave()
+	stateSinkObject.Save(0, &l.head)
+	stateSinkObject.Save(1, &l.tail)
+}
+
+func (l *reassemblerList) afterLoad() {}
+
+// +checklocksignore
+func (l *reassemblerList) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &l.head)
+	stateSourceObject.Load(1, &l.tail)
+}
+
+func (e *reassemblerEntry) StateTypeName() string {
+	return "pkg/tcpip/network/internal/fragmentation.reassemblerEntry"
+}
+
+func (e *reassemblerEntry) StateFields() []string {
+	return []string{
+		"next",
+		"prev",
+	}
+}
+
+func (e *reassemblerEntry) beforeSave() {}
+
+// +checklocksignore
+func (e *reassemblerEntry) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+	stateSinkObject.Save(0, &e.next)
+	stateSinkObject.Save(1, &e.prev)
+}
+
+func (e *reassemblerEntry) afterLoad() {}
+
+// +checklocksignore
+func (e *reassemblerEntry) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &e.next)
+	stateSourceObject.Load(1, &e.prev)
+}
+
+func init() {
+	state.Register((*reassemblerList)(nil))
+	state.Register((*reassemblerEntry)(nil))
+}
diff --git a/pkg/tcpip/network/internal/fragmentation/fragmentation_test.go b/pkg/tcpip/network/internal/fragmentation/fragmentation_test.go
deleted file mode 100644
index 7daf64b..0000000
--- a/pkg/tcpip/network/internal/fragmentation/fragmentation_test.go
+++ /dev/null
@@ -1,636 +0,0 @@
-// 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 fragmentation
-
-import (
-	"errors"
-	"testing"
-	"time"
-
-	"github.com/google/go-cmp/cmp"
-	"gvisor.dev/gvisor/pkg/tcpip/buffer"
-	"gvisor.dev/gvisor/pkg/tcpip/faketime"
-	"gvisor.dev/gvisor/pkg/tcpip/network/internal/testutil"
-	"gvisor.dev/gvisor/pkg/tcpip/stack"
-)
-
-// reassembleTimeout is dummy timeout used for testing, where the clock never
-// advances.
-const reassembleTimeout = 1
-
-// vv is a helper to build VectorisedView from different strings.
-func vv(size int, pieces ...string) buffer.VectorisedView {
-	views := make([]buffer.View, len(pieces))
-	for i, p := range pieces {
-		views[i] = []byte(p)
-	}
-
-	return buffer.NewVectorisedView(size, views)
-}
-
-func pkt(size int, pieces ...string) *stack.PacketBuffer {
-	return stack.NewPacketBuffer(stack.PacketBufferOptions{
-		Data: vv(size, pieces...),
-	})
-}
-
-type processInput struct {
-	id    FragmentID
-	first uint16
-	last  uint16
-	more  bool
-	proto uint8
-	pkt   *stack.PacketBuffer
-}
-
-type processOutput struct {
-	vv    buffer.VectorisedView
-	proto uint8
-	done  bool
-}
-
-var processTestCases = []struct {
-	comment string
-	in      []processInput
-	out     []processOutput
-}{
-	{
-		comment: "One ID",
-		in: []processInput{
-			{id: FragmentID{ID: 0}, first: 0, last: 1, more: true, pkt: pkt(2, "01")},
-			{id: FragmentID{ID: 0}, first: 2, last: 3, more: false, pkt: pkt(2, "23")},
-		},
-		out: []processOutput{
-			{vv: buffer.VectorisedView{}, done: false},
-			{vv: vv(4, "01", "23"), done: true},
-		},
-	},
-	{
-		comment: "Next Header protocol mismatch",
-		in: []processInput{
-			{id: FragmentID{ID: 0}, first: 0, last: 1, more: true, proto: 6, pkt: pkt(2, "01")},
-			{id: FragmentID{ID: 0}, first: 2, last: 3, more: false, proto: 17, pkt: pkt(2, "23")},
-		},
-		out: []processOutput{
-			{vv: buffer.VectorisedView{}, done: false},
-			{vv: vv(4, "01", "23"), proto: 6, done: true},
-		},
-	},
-	{
-		comment: "Two IDs",
-		in: []processInput{
-			{id: FragmentID{ID: 0}, first: 0, last: 1, more: true, pkt: pkt(2, "01")},
-			{id: FragmentID{ID: 1}, first: 0, last: 1, more: true, pkt: pkt(2, "ab")},
-			{id: FragmentID{ID: 1}, first: 2, last: 3, more: false, pkt: pkt(2, "cd")},
-			{id: FragmentID{ID: 0}, first: 2, last: 3, more: false, pkt: pkt(2, "23")},
-		},
-		out: []processOutput{
-			{vv: buffer.VectorisedView{}, done: false},
-			{vv: buffer.VectorisedView{}, done: false},
-			{vv: vv(4, "ab", "cd"), done: true},
-			{vv: vv(4, "01", "23"), done: true},
-		},
-	},
-}
-
-func TestFragmentationProcess(t *testing.T) {
-	for _, c := range processTestCases {
-		t.Run(c.comment, func(t *testing.T) {
-			f := NewFragmentation(minBlockSize, 1024, 512, reassembleTimeout, &faketime.NullClock{}, nil)
-			firstFragmentProto := c.in[0].proto
-			for i, in := range c.in {
-				resPkt, proto, done, err := f.Process(in.id, in.first, in.last, in.more, in.proto, in.pkt)
-				if err != nil {
-					t.Fatalf("f.Process(%+v, %d, %d, %t, %d, %#v) failed: %s",
-						in.id, in.first, in.last, in.more, in.proto, in.pkt, err)
-				}
-				if done != c.out[i].done {
-					t.Errorf("got Process(%+v, %d, %d, %t, %d, _) = (_, _, %t, _), want = (_, _, %t, _)",
-						in.id, in.first, in.last, in.more, in.proto, done, c.out[i].done)
-				}
-				if c.out[i].done {
-					if diff := cmp.Diff(c.out[i].vv.ToOwnedView(), resPkt.Data().AsRange().ToOwnedView()); diff != "" {
-						t.Errorf("got Process(%+v, %d, %d, %t, %d, %#v) result mismatch (-want, +got):\n%s",
-							in.id, in.first, in.last, in.more, in.proto, in.pkt, diff)
-					}
-					if firstFragmentProto != proto {
-						t.Errorf("got Process(%+v, %d, %d, %t, %d, _) = (_, %d, _, _), want = (_, %d, _, _)",
-							in.id, in.first, in.last, in.more, in.proto, proto, firstFragmentProto)
-					}
-					if _, ok := f.reassemblers[in.id]; ok {
-						t.Errorf("Process(%d) did not remove buffer from reassemblers", i)
-					}
-					for n := f.rList.Front(); n != nil; n = n.Next() {
-						if n.id == in.id {
-							t.Errorf("Process(%d) did not remove buffer from rList", i)
-						}
-					}
-				}
-			}
-		})
-	}
-}
-
-func TestReassemblingTimeout(t *testing.T) {
-	const (
-		reassemblyTimeout = time.Millisecond
-		protocol          = 0xff
-	)
-
-	type fragment struct {
-		first uint16
-		last  uint16
-		more  bool
-		data  string
-	}
-
-	type event struct {
-		// name is a nickname of this event.
-		name string
-
-		// clockAdvance is a duration to advance the clock. The clock advances
-		// before a fragment specified in the fragment field is processed.
-		clockAdvance time.Duration
-
-		// fragment is a fragment to process. This can be nil if there is no
-		// fragment to process.
-		fragment *fragment
-
-		// expectDone is true if the fragmentation instance should report the
-		// reassembly is done after the fragment is processd.
-		expectDone bool
-
-		// memSizeAfterEvent is the expected memory size of the fragmentation
-		// instance after the event.
-		memSizeAfterEvent int
-	}
-
-	memSizeOfFrags := func(frags ...*fragment) int {
-		var size int
-		for _, frag := range frags {
-			size += pkt(len(frag.data), frag.data).MemSize()
-		}
-		return size
-	}
-
-	half1 := &fragment{first: 0, last: 0, more: true, data: "0"}
-	half2 := &fragment{first: 1, last: 1, more: false, data: "1"}
-
-	tests := []struct {
-		name   string
-		events []event
-	}{
-		{
-			name: "half1 and half2 are reassembled successfully",
-			events: []event{
-				{
-					name:              "half1",
-					fragment:          half1,
-					expectDone:        false,
-					memSizeAfterEvent: memSizeOfFrags(half1),
-				},
-				{
-					name:              "half2",
-					fragment:          half2,
-					expectDone:        true,
-					memSizeAfterEvent: 0,
-				},
-			},
-		},
-		{
-			name: "half1 timeout, half2 timeout",
-			events: []event{
-				{
-					name:              "half1",
-					fragment:          half1,
-					expectDone:        false,
-					memSizeAfterEvent: memSizeOfFrags(half1),
-				},
-				{
-					name:              "half1 just before reassembly timeout",
-					clockAdvance:      reassemblyTimeout - 1,
-					memSizeAfterEvent: memSizeOfFrags(half1),
-				},
-				{
-					name:              "half1 reassembly timeout",
-					clockAdvance:      1,
-					memSizeAfterEvent: 0,
-				},
-				{
-					name:              "half2",
-					fragment:          half2,
-					expectDone:        false,
-					memSizeAfterEvent: memSizeOfFrags(half2),
-				},
-				{
-					name:              "half2 just before reassembly timeout",
-					clockAdvance:      reassemblyTimeout - 1,
-					memSizeAfterEvent: memSizeOfFrags(half2),
-				},
-				{
-					name:              "half2 reassembly timeout",
-					clockAdvance:      1,
-					memSizeAfterEvent: 0,
-				},
-			},
-		},
-	}
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			clock := faketime.NewManualClock()
-			f := NewFragmentation(minBlockSize, HighFragThreshold, LowFragThreshold, reassemblyTimeout, clock, nil)
-			for _, event := range test.events {
-				clock.Advance(event.clockAdvance)
-				if frag := event.fragment; frag != nil {
-					_, _, done, err := f.Process(FragmentID{}, frag.first, frag.last, frag.more, protocol, pkt(len(frag.data), frag.data))
-					if err != nil {
-						t.Fatalf("%s: f.Process failed: %s", event.name, err)
-					}
-					if done != event.expectDone {
-						t.Fatalf("%s: got done = %t, want = %t", event.name, done, event.expectDone)
-					}
-				}
-				if got, want := f.memSize, event.memSizeAfterEvent; got != want {
-					t.Errorf("%s: got f.memSize = %d, want = %d", event.name, got, want)
-				}
-			}
-		})
-	}
-}
-
-func TestMemoryLimits(t *testing.T) {
-	lowLimit := pkt(1, "0").MemSize()
-	highLimit := 3 * lowLimit // Allow at most 3 such packets.
-	f := NewFragmentation(minBlockSize, highLimit, lowLimit, reassembleTimeout, &faketime.NullClock{}, nil)
-	// Send first fragment with id = 0.
-	f.Process(FragmentID{ID: 0}, 0, 0, true, 0xFF, pkt(1, "0"))
-	// Send first fragment with id = 1.
-	f.Process(FragmentID{ID: 1}, 0, 0, true, 0xFF, pkt(1, "1"))
-	// Send first fragment with id = 2.
-	f.Process(FragmentID{ID: 2}, 0, 0, true, 0xFF, pkt(1, "2"))
-
-	// Send first fragment with id = 3. This should caused id = 0 and id = 1 to be
-	// evicted.
-	f.Process(FragmentID{ID: 3}, 0, 0, true, 0xFF, pkt(1, "3"))
-
-	if _, ok := f.reassemblers[FragmentID{ID: 0}]; ok {
-		t.Errorf("Memory limits are not respected: id=0 has not been evicted.")
-	}
-	if _, ok := f.reassemblers[FragmentID{ID: 1}]; ok {
-		t.Errorf("Memory limits are not respected: id=1 has not been evicted.")
-	}
-	if _, ok := f.reassemblers[FragmentID{ID: 3}]; !ok {
-		t.Errorf("Implementation of memory limits is wrong: id=3 is not present.")
-	}
-}
-
-func TestMemoryLimitsIgnoresDuplicates(t *testing.T) {
-	memSize := pkt(1, "0").MemSize()
-	f := NewFragmentation(minBlockSize, memSize, 0, reassembleTimeout, &faketime.NullClock{}, nil)
-	// Send first fragment with id = 0.
-	f.Process(FragmentID{}, 0, 0, true, 0xFF, pkt(1, "0"))
-	// Send the same packet again.
-	f.Process(FragmentID{}, 0, 0, true, 0xFF, pkt(1, "0"))
-
-	if got, want := f.memSize, memSize; got != want {
-		t.Errorf("Wrong size, duplicates are not handled correctly: got=%d, want=%d.", got, want)
-	}
-}
-
-func TestErrors(t *testing.T) {
-	tests := []struct {
-		name      string
-		blockSize uint16
-		first     uint16
-		last      uint16
-		more      bool
-		data      string
-		err       error
-	}{
-		{
-			name:      "exact block size without more",
-			blockSize: 2,
-			first:     2,
-			last:      3,
-			more:      false,
-			data:      "01",
-		},
-		{
-			name:      "exact block size with more",
-			blockSize: 2,
-			first:     2,
-			last:      3,
-			more:      true,
-			data:      "01",
-		},
-		{
-			name:      "exact block size with more and extra data",
-			blockSize: 2,
-			first:     2,
-			last:      3,
-			more:      true,
-			data:      "012",
-			err:       ErrInvalidArgs,
-		},
-		{
-			name:      "exact block size with more and too little data",
-			blockSize: 2,
-			first:     2,
-			last:      3,
-			more:      true,
-			data:      "0",
-			err:       ErrInvalidArgs,
-		},
-		{
-			name:      "not exact block size with more",
-			blockSize: 2,
-			first:     2,
-			last:      2,
-			more:      true,
-			data:      "0",
-			err:       ErrInvalidArgs,
-		},
-		{
-			name:      "not exact block size without more",
-			blockSize: 2,
-			first:     2,
-			last:      2,
-			more:      false,
-			data:      "0",
-		},
-		{
-			name:      "first not a multiple of block size",
-			blockSize: 2,
-			first:     3,
-			last:      4,
-			more:      true,
-			data:      "01",
-			err:       ErrInvalidArgs,
-		},
-		{
-			name:      "first more than last",
-			blockSize: 2,
-			first:     4,
-			last:      3,
-			more:      true,
-			data:      "01",
-			err:       ErrInvalidArgs,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			f := NewFragmentation(test.blockSize, HighFragThreshold, LowFragThreshold, reassembleTimeout, &faketime.NullClock{}, nil)
-			_, _, done, err := f.Process(FragmentID{}, test.first, test.last, test.more, 0, pkt(len(test.data), test.data))
-			if !errors.Is(err, test.err) {
-				t.Errorf("got Process(_, %d, %d, %t, _, %q) = (_, _, _, %v), want = (_, _, _, %v)", test.first, test.last, test.more, test.data, err, test.err)
-			}
-			if done {
-				t.Errorf("got Process(_, %d, %d, %t, _, %q) = (_, _, true, _), want = (_, _, false, _)", test.first, test.last, test.more, test.data)
-			}
-		})
-	}
-}
-
-type fragmentInfo struct {
-	remaining int
-	copied    int
-	offset    int
-	more      bool
-}
-
-func TestPacketFragmenter(t *testing.T) {
-	const (
-		reserve = 60
-		proto   = 0
-	)
-
-	tests := []struct {
-		name               string
-		fragmentPayloadLen uint32
-		transportHeaderLen int
-		payloadSize        int
-		wantFragments      []fragmentInfo
-	}{
-		{
-			name:               "Packet exactly fits in MTU",
-			fragmentPayloadLen: 1280,
-			transportHeaderLen: 0,
-			payloadSize:        1280,
-			wantFragments: []fragmentInfo{
-				{remaining: 0, copied: 1280, offset: 0, more: false},
-			},
-		},
-		{
-			name:               "Packet exactly does not fit in MTU",
-			fragmentPayloadLen: 1000,
-			transportHeaderLen: 0,
-			payloadSize:        1001,
-			wantFragments: []fragmentInfo{
-				{remaining: 1, copied: 1000, offset: 0, more: true},
-				{remaining: 0, copied: 1, offset: 1000, more: false},
-			},
-		},
-		{
-			name:               "Packet has a transport header",
-			fragmentPayloadLen: 560,
-			transportHeaderLen: 40,
-			payloadSize:        560,
-			wantFragments: []fragmentInfo{
-				{remaining: 1, copied: 560, offset: 0, more: true},
-				{remaining: 0, copied: 40, offset: 560, more: false},
-			},
-		},
-		{
-			name:               "Packet has a huge transport header",
-			fragmentPayloadLen: 500,
-			transportHeaderLen: 1300,
-			payloadSize:        500,
-			wantFragments: []fragmentInfo{
-				{remaining: 3, copied: 500, offset: 0, more: true},
-				{remaining: 2, copied: 500, offset: 500, more: true},
-				{remaining: 1, copied: 500, offset: 1000, more: true},
-				{remaining: 0, copied: 300, offset: 1500, more: false},
-			},
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			pkt := testutil.MakeRandPkt(test.transportHeaderLen, reserve, []int{test.payloadSize}, proto)
-			originalPayload := stack.PayloadSince(pkt.TransportHeader())
-			var reassembledPayload buffer.VectorisedView
-			pf := MakePacketFragmenter(pkt, test.fragmentPayloadLen, reserve)
-			for i := 0; ; i++ {
-				fragPkt, offset, copied, more := pf.BuildNextFragment()
-				wantFragment := test.wantFragments[i]
-				if got := pf.RemainingFragmentCount(); got != wantFragment.remaining {
-					t.Errorf("(fragment #%d) got pf.RemainingFragmentCount() = %d, want = %d", i, got, wantFragment.remaining)
-				}
-				if copied != wantFragment.copied {
-					t.Errorf("(fragment #%d) got copied = %d, want = %d", i, copied, wantFragment.copied)
-				}
-				if offset != wantFragment.offset {
-					t.Errorf("(fragment #%d) got offset = %d, want = %d", i, offset, wantFragment.offset)
-				}
-				if more != wantFragment.more {
-					t.Errorf("(fragment #%d) got more = %t, want = %t", i, more, wantFragment.more)
-				}
-				if got := uint32(fragPkt.Size()); got > test.fragmentPayloadLen {
-					t.Errorf("(fragment #%d) got fragPkt.Size() = %d, want <= %d", i, got, test.fragmentPayloadLen)
-				}
-				if got := fragPkt.AvailableHeaderBytes(); got != reserve {
-					t.Errorf("(fragment #%d) got fragPkt.AvailableHeaderBytes() = %d, want = %d", i, got, reserve)
-				}
-				if got := fragPkt.TransportHeader().View().Size(); got != 0 {
-					t.Errorf("(fragment #%d) got fragPkt.TransportHeader().View().Size() = %d, want = 0", i, got)
-				}
-				reassembledPayload.AppendViews(fragPkt.Data().Views())
-				if !more {
-					if i != len(test.wantFragments)-1 {
-						t.Errorf("got fragment count = %d, want = %d", i, len(test.wantFragments)-1)
-					}
-					break
-				}
-			}
-			if diff := cmp.Diff(reassembledPayload.ToView(), originalPayload); diff != "" {
-				t.Errorf("reassembledPayload mismatch (-want +got):\n%s", diff)
-			}
-		})
-	}
-}
-
-type testTimeoutHandler struct {
-	pkt *stack.PacketBuffer
-}
-
-func (h *testTimeoutHandler) OnReassemblyTimeout(pkt *stack.PacketBuffer) {
-	h.pkt = pkt
-}
-
-func TestTimeoutHandler(t *testing.T) {
-	const (
-		proto = 99
-	)
-
-	pk1 := pkt(1, "1")
-	pk2 := pkt(1, "2")
-
-	type processParam struct {
-		first uint16
-		last  uint16
-		more  bool
-		pkt   *stack.PacketBuffer
-	}
-
-	tests := []struct {
-		name      string
-		params    []processParam
-		wantError bool
-		wantPkt   *stack.PacketBuffer
-	}{
-		{
-			name: "onTimeout runs",
-			params: []processParam{
-				{
-					first: 0,
-					last:  0,
-					more:  true,
-					pkt:   pk1,
-				},
-			},
-			wantError: false,
-			wantPkt:   pk1,
-		},
-		{
-			name: "no first fragment",
-			params: []processParam{
-				{
-					first: 1,
-					last:  1,
-					more:  true,
-					pkt:   pk1,
-				},
-			},
-			wantError: false,
-			wantPkt:   nil,
-		},
-		{
-			name: "second pkt is ignored",
-			params: []processParam{
-				{
-					first: 0,
-					last:  0,
-					more:  true,
-					pkt:   pk1,
-				},
-				{
-					first: 0,
-					last:  0,
-					more:  true,
-					pkt:   pk2,
-				},
-			},
-			wantError: false,
-			wantPkt:   pk1,
-		},
-		{
-			name: "invalid args - first is greater than last",
-			params: []processParam{
-				{
-					first: 1,
-					last:  0,
-					more:  true,
-					pkt:   pk1,
-				},
-			},
-			wantError: true,
-			wantPkt:   nil,
-		},
-	}
-
-	id := FragmentID{ID: 0}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			handler := &testTimeoutHandler{pkt: nil}
-
-			f := NewFragmentation(minBlockSize, HighFragThreshold, LowFragThreshold, reassembleTimeout, &faketime.NullClock{}, handler)
-
-			for _, p := range test.params {
-				if _, _, _, err := f.Process(id, p.first, p.last, p.more, proto, p.pkt); err != nil && !test.wantError {
-					t.Errorf("f.Process error = %s", err)
-				}
-			}
-			if !test.wantError {
-				r, ok := f.reassemblers[id]
-				if !ok {
-					t.Fatal("Reassembler not found")
-				}
-				f.release(r, true)
-			}
-			switch {
-			case handler.pkt != nil && test.wantPkt == nil:
-				t.Errorf("got handler.pkt = not nil (pkt.Data = %x), want = nil", handler.pkt.Data().AsRange().ToOwnedView())
-			case handler.pkt == nil && test.wantPkt != nil:
-				t.Errorf("got handler.pkt = nil, want = not nil (pkt.Data = %x)", test.wantPkt.Data().AsRange().ToOwnedView())
-			case handler.pkt != nil && test.wantPkt != nil:
-				if diff := cmp.Diff(test.wantPkt.Data().AsRange().ToOwnedView(), handler.pkt.Data().AsRange().ToOwnedView()); diff != "" {
-					t.Errorf("pkt.Data mismatch (-want, +got):\n%s", diff)
-				}
-			}
-		})
-	}
-}
diff --git a/pkg/tcpip/network/internal/fragmentation/reassembler_list.go b/pkg/tcpip/network/internal/fragmentation/reassembler_list.go
new file mode 100644
index 0000000..673bb11
--- /dev/null
+++ b/pkg/tcpip/network/internal/fragmentation/reassembler_list.go
@@ -0,0 +1,221 @@
+package fragmentation
+
+// ElementMapper provides an identity mapping by default.
+//
+// This can be replaced to provide a struct that maps elements to linker
+// objects, if they are not the same. An ElementMapper is not typically
+// required if: Linker is left as is, Element is left as is, or Linker and
+// Element are the same type.
+type reassemblerElementMapper struct{}
+
+// linkerFor maps an Element to a Linker.
+//
+// This default implementation should be inlined.
+//
+//go:nosplit
+func (reassemblerElementMapper) linkerFor(elem *reassembler) *reassembler { return elem }
+
+// List is an intrusive list. Entries can be added to or removed from the list
+// in O(1) time and with no additional memory allocations.
+//
+// The zero value for List is an empty list ready to use.
+//
+// To iterate over a list (where l is a List):
+//      for e := l.Front(); e != nil; e = e.Next() {
+// 		// do something with e.
+//      }
+//
+// +stateify savable
+type reassemblerList struct {
+	head *reassembler
+	tail *reassembler
+}
+
+// Reset resets list l to the empty state.
+func (l *reassemblerList) Reset() {
+	l.head = nil
+	l.tail = nil
+}
+
+// Empty returns true iff the list is empty.
+//
+//go:nosplit
+func (l *reassemblerList) Empty() bool {
+	return l.head == nil
+}
+
+// Front returns the first element of list l or nil.
+//
+//go:nosplit
+func (l *reassemblerList) Front() *reassembler {
+	return l.head
+}
+
+// Back returns the last element of list l or nil.
+//
+//go:nosplit
+func (l *reassemblerList) Back() *reassembler {
+	return l.tail
+}
+
+// Len returns the number of elements in the list.
+//
+// NOTE: This is an O(n) operation.
+//
+//go:nosplit
+func (l *reassemblerList) Len() (count int) {
+	for e := l.Front(); e != nil; e = (reassemblerElementMapper{}.linkerFor(e)).Next() {
+		count++
+	}
+	return count
+}
+
+// PushFront inserts the element e at the front of list l.
+//
+//go:nosplit
+func (l *reassemblerList) PushFront(e *reassembler) {
+	linker := reassemblerElementMapper{}.linkerFor(e)
+	linker.SetNext(l.head)
+	linker.SetPrev(nil)
+	if l.head != nil {
+		reassemblerElementMapper{}.linkerFor(l.head).SetPrev(e)
+	} else {
+		l.tail = e
+	}
+
+	l.head = e
+}
+
+// PushBack inserts the element e at the back of list l.
+//
+//go:nosplit
+func (l *reassemblerList) PushBack(e *reassembler) {
+	linker := reassemblerElementMapper{}.linkerFor(e)
+	linker.SetNext(nil)
+	linker.SetPrev(l.tail)
+	if l.tail != nil {
+		reassemblerElementMapper{}.linkerFor(l.tail).SetNext(e)
+	} else {
+		l.head = e
+	}
+
+	l.tail = e
+}
+
+// PushBackList inserts list m at the end of list l, emptying m.
+//
+//go:nosplit
+func (l *reassemblerList) PushBackList(m *reassemblerList) {
+	if l.head == nil {
+		l.head = m.head
+		l.tail = m.tail
+	} else if m.head != nil {
+		reassemblerElementMapper{}.linkerFor(l.tail).SetNext(m.head)
+		reassemblerElementMapper{}.linkerFor(m.head).SetPrev(l.tail)
+
+		l.tail = m.tail
+	}
+	m.head = nil
+	m.tail = nil
+}
+
+// InsertAfter inserts e after b.
+//
+//go:nosplit
+func (l *reassemblerList) InsertAfter(b, e *reassembler) {
+	bLinker := reassemblerElementMapper{}.linkerFor(b)
+	eLinker := reassemblerElementMapper{}.linkerFor(e)
+
+	a := bLinker.Next()
+
+	eLinker.SetNext(a)
+	eLinker.SetPrev(b)
+	bLinker.SetNext(e)
+
+	if a != nil {
+		reassemblerElementMapper{}.linkerFor(a).SetPrev(e)
+	} else {
+		l.tail = e
+	}
+}
+
+// InsertBefore inserts e before a.
+//
+//go:nosplit
+func (l *reassemblerList) InsertBefore(a, e *reassembler) {
+	aLinker := reassemblerElementMapper{}.linkerFor(a)
+	eLinker := reassemblerElementMapper{}.linkerFor(e)
+
+	b := aLinker.Prev()
+	eLinker.SetNext(a)
+	eLinker.SetPrev(b)
+	aLinker.SetPrev(e)
+
+	if b != nil {
+		reassemblerElementMapper{}.linkerFor(b).SetNext(e)
+	} else {
+		l.head = e
+	}
+}
+
+// Remove removes e from l.
+//
+//go:nosplit
+func (l *reassemblerList) Remove(e *reassembler) {
+	linker := reassemblerElementMapper{}.linkerFor(e)
+	prev := linker.Prev()
+	next := linker.Next()
+
+	if prev != nil {
+		reassemblerElementMapper{}.linkerFor(prev).SetNext(next)
+	} else if l.head == e {
+		l.head = next
+	}
+
+	if next != nil {
+		reassemblerElementMapper{}.linkerFor(next).SetPrev(prev)
+	} else if l.tail == e {
+		l.tail = prev
+	}
+
+	linker.SetNext(nil)
+	linker.SetPrev(nil)
+}
+
+// Entry is a default implementation of Linker. Users can add anonymous fields
+// of this type to their structs to make them automatically implement the
+// methods needed by List.
+//
+// +stateify savable
+type reassemblerEntry struct {
+	next *reassembler
+	prev *reassembler
+}
+
+// Next returns the entry that follows e in the list.
+//
+//go:nosplit
+func (e *reassemblerEntry) Next() *reassembler {
+	return e.next
+}
+
+// Prev returns the entry that precedes e in the list.
+//
+//go:nosplit
+func (e *reassemblerEntry) Prev() *reassembler {
+	return e.prev
+}
+
+// SetNext assigns 'entry' as the entry that follows e in the list.
+//
+//go:nosplit
+func (e *reassemblerEntry) SetNext(elem *reassembler) {
+	e.next = elem
+}
+
+// SetPrev assigns 'entry' as the entry that precedes e in the list.
+//
+//go:nosplit
+func (e *reassemblerEntry) SetPrev(elem *reassembler) {
+	e.prev = elem
+}
diff --git a/pkg/tcpip/network/internal/fragmentation/reassembler_test.go b/pkg/tcpip/network/internal/fragmentation/reassembler_test.go
deleted file mode 100644
index cfd9f00..0000000
--- a/pkg/tcpip/network/internal/fragmentation/reassembler_test.go
+++ /dev/null
@@ -1,233 +0,0 @@
-// 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 fragmentation
-
-import (
-	"bytes"
-	"math"
-	"testing"
-
-	"github.com/google/go-cmp/cmp"
-	"gvisor.dev/gvisor/pkg/tcpip/buffer"
-	"gvisor.dev/gvisor/pkg/tcpip/faketime"
-	"gvisor.dev/gvisor/pkg/tcpip/stack"
-)
-
-type processParams struct {
-	first     uint16
-	last      uint16
-	more      bool
-	pkt       *stack.PacketBuffer
-	wantDone  bool
-	wantError error
-}
-
-func TestReassemblerProcess(t *testing.T) {
-	const proto = 99
-
-	v := func(size int) buffer.View {
-		payload := buffer.NewView(size)
-		for i := 1; i < size; i++ {
-			payload[i] = uint8(i) * 3
-		}
-		return payload
-	}
-
-	pkt := func(sizes ...int) *stack.PacketBuffer {
-		var vv buffer.VectorisedView
-		for _, size := range sizes {
-			vv.AppendView(v(size))
-		}
-		return stack.NewPacketBuffer(stack.PacketBufferOptions{
-			Data: vv,
-		})
-	}
-
-	var tests = []struct {
-		name    string
-		params  []processParams
-		want    []hole
-		wantPkt *stack.PacketBuffer
-	}{
-		{
-			name:   "No fragments",
-			params: nil,
-			want:   []hole{{first: 0, last: math.MaxUint16, filled: false, final: true}},
-		},
-		{
-			name:   "One fragment at beginning",
-			params: []processParams{{first: 0, last: 1, more: true, pkt: pkt(2), wantDone: false, wantError: nil}},
-			want: []hole{
-				{first: 0, last: 1, filled: true, final: false, pkt: pkt(2)},
-				{first: 2, last: math.MaxUint16, filled: false, final: true},
-			},
-		},
-		{
-			name:   "One fragment in the middle",
-			params: []processParams{{first: 1, last: 2, more: true, pkt: pkt(2), wantDone: false, wantError: nil}},
-			want: []hole{
-				{first: 1, last: 2, filled: true, final: false, pkt: pkt(2)},
-				{first: 0, last: 0, filled: false, final: false},
-				{first: 3, last: math.MaxUint16, filled: false, final: true},
-			},
-		},
-		{
-			name:   "One fragment at the end",
-			params: []processParams{{first: 1, last: 2, more: false, pkt: pkt(2), wantDone: false, wantError: nil}},
-			want: []hole{
-				{first: 1, last: 2, filled: true, final: true, pkt: pkt(2)},
-				{first: 0, last: 0, filled: false},
-			},
-		},
-		{
-			name:   "One fragment completing a packet",
-			params: []processParams{{first: 0, last: 1, more: false, pkt: pkt(2), wantDone: true, wantError: nil}},
-			want: []hole{
-				{first: 0, last: 1, filled: true, final: true},
-			},
-			wantPkt: pkt(2),
-		},
-		{
-			name: "Two fragments completing a packet",
-			params: []processParams{
-				{first: 0, last: 1, more: true, pkt: pkt(2), wantDone: false, wantError: nil},
-				{first: 2, last: 3, more: false, pkt: pkt(2), wantDone: true, wantError: nil},
-			},
-			want: []hole{
-				{first: 0, last: 1, filled: true, final: false},
-				{first: 2, last: 3, filled: true, final: true},
-			},
-			wantPkt: pkt(2, 2),
-		},
-		{
-			name: "Two fragments completing a packet with a duplicate",
-			params: []processParams{
-				{first: 0, last: 1, more: true, pkt: pkt(2), wantDone: false, wantError: nil},
-				{first: 0, last: 1, more: true, pkt: pkt(2), wantDone: false, wantError: nil},
-				{first: 2, last: 3, more: false, pkt: pkt(2), wantDone: true, wantError: nil},
-			},
-			want: []hole{
-				{first: 0, last: 1, filled: true, final: false},
-				{first: 2, last: 3, filled: true, final: true},
-			},
-			wantPkt: pkt(2, 2),
-		},
-		{
-			name: "Two fragments completing a packet with a partial duplicate",
-			params: []processParams{
-				{first: 0, last: 3, more: true, pkt: pkt(4), wantDone: false, wantError: nil},
-				{first: 1, last: 2, more: true, pkt: pkt(2), wantDone: false, wantError: nil},
-				{first: 4, last: 5, more: false, pkt: pkt(2), wantDone: true, wantError: nil},
-			},
-			want: []hole{
-				{first: 0, last: 3, filled: true, final: false},
-				{first: 4, last: 5, filled: true, final: true},
-			},
-			wantPkt: pkt(4, 2),
-		},
-		{
-			name: "Two overlapping fragments",
-			params: []processParams{
-				{first: 0, last: 10, more: true, pkt: pkt(11), wantDone: false, wantError: nil},
-				{first: 5, last: 15, more: false, pkt: pkt(11), wantDone: false, wantError: ErrFragmentOverlap},
-			},
-			want: []hole{
-				{first: 0, last: 10, filled: true, final: false, pkt: pkt(11)},
-				{first: 11, last: math.MaxUint16, filled: false, final: true},
-			},
-		},
-		{
-			name: "Two final fragments with different ends",
-			params: []processParams{
-				{first: 10, last: 14, more: false, pkt: pkt(5), wantDone: false, wantError: nil},
-				{first: 0, last: 9, more: false, pkt: pkt(10), wantDone: false, wantError: ErrFragmentConflict},
-			},
-			want: []hole{
-				{first: 10, last: 14, filled: true, final: true, pkt: pkt(5)},
-				{first: 0, last: 9, filled: false, final: false},
-			},
-		},
-		{
-			name: "Two final fragments - duplicate",
-			params: []processParams{
-				{first: 5, last: 14, more: false, pkt: pkt(10), wantDone: false, wantError: nil},
-				{first: 10, last: 14, more: false, pkt: pkt(5), wantDone: false, wantError: nil},
-			},
-			want: []hole{
-				{first: 5, last: 14, filled: true, final: true, pkt: pkt(10)},
-				{first: 0, last: 4, filled: false, final: false},
-			},
-		},
-		{
-			name: "Two final fragments - duplicate, with different ends",
-			params: []processParams{
-				{first: 5, last: 14, more: false, pkt: pkt(10), wantDone: false, wantError: nil},
-				{first: 10, last: 13, more: false, pkt: pkt(4), wantDone: false, wantError: ErrFragmentConflict},
-			},
-			want: []hole{
-				{first: 5, last: 14, filled: true, final: true, pkt: pkt(10)},
-				{first: 0, last: 4, filled: false, final: false},
-			},
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			r := newReassembler(FragmentID{}, &faketime.NullClock{})
-			var resPkt *stack.PacketBuffer
-			var isDone bool
-			for _, param := range test.params {
-				pkt, _, done, _, err := r.process(param.first, param.last, param.more, proto, param.pkt)
-				if done != param.wantDone || err != param.wantError {
-					t.Errorf("got r.process(%d, %d, %t, %d, _) = (_, _, %t, _, %v), want = (%t, %v)", param.first, param.last, param.more, proto, done, err, param.wantDone, param.wantError)
-				}
-				if done {
-					resPkt = pkt
-					isDone = true
-				}
-			}
-
-			ignorePkt := func(a, b *stack.PacketBuffer) bool { return true }
-			cmpPktData := func(a, b *stack.PacketBuffer) bool {
-				if a == nil || b == nil {
-					return a == b
-				}
-				return bytes.Equal(a.Data().AsRange().ToOwnedView(), b.Data().AsRange().ToOwnedView())
-			}
-
-			if isDone {
-				if diff := cmp.Diff(
-					test.want, r.holes,
-					cmp.AllowUnexported(hole{}),
-					// Do not compare pkt in hole. Data will be altered.
-					cmp.Comparer(ignorePkt),
-				); diff != "" {
-					t.Errorf("r.holes mismatch (-want +got):\n%s", diff)
-				}
-				if diff := cmp.Diff(test.wantPkt, resPkt, cmp.Comparer(cmpPktData)); diff != "" {
-					t.Errorf("Reassembled pkt mismatch (-want +got):\n%s", diff)
-				}
-			} else {
-				if diff := cmp.Diff(
-					test.want, r.holes,
-					cmp.AllowUnexported(hole{}),
-					cmp.Comparer(cmpPktData),
-				); diff != "" {
-					t.Errorf("r.holes mismatch (-want +got):\n%s", diff)
-				}
-			}
-		})
-	}
-}
diff --git a/pkg/tcpip/network/internal/ip/duplicate_address_detection_test.go b/pkg/tcpip/network/internal/ip/duplicate_address_detection_test.go
deleted file mode 100644
index a22b712..0000000
--- a/pkg/tcpip/network/internal/ip/duplicate_address_detection_test.go
+++ /dev/null
@@ -1,381 +0,0 @@
-// Copyright 2021 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 ip_test
-
-import (
-	"bytes"
-	"testing"
-	"time"
-
-	"github.com/google/go-cmp/cmp"
-	"gvisor.dev/gvisor/pkg/sync"
-	"gvisor.dev/gvisor/pkg/tcpip"
-	"gvisor.dev/gvisor/pkg/tcpip/faketime"
-	"gvisor.dev/gvisor/pkg/tcpip/network/internal/ip"
-	"gvisor.dev/gvisor/pkg/tcpip/stack"
-)
-
-type mockDADProtocol struct {
-	t *testing.T
-
-	mu struct {
-		sync.Mutex
-
-		dad        ip.DAD
-		sentNonces map[tcpip.Address][][]byte
-	}
-}
-
-func (m *mockDADProtocol) init(t *testing.T, c stack.DADConfigurations, opts ip.DADOptions) {
-	m.mu.Lock()
-	defer m.mu.Unlock()
-
-	m.t = t
-	opts.Protocol = m
-	m.mu.dad.Init(&m.mu, c, opts)
-	m.initLocked()
-}
-
-func (m *mockDADProtocol) initLocked() {
-	m.mu.sentNonces = make(map[tcpip.Address][][]byte)
-}
-
-func (m *mockDADProtocol) SendDADMessage(addr tcpip.Address, nonce []byte) tcpip.Error {
-	m.mu.Lock()
-	defer m.mu.Unlock()
-	m.mu.sentNonces[addr] = append(m.mu.sentNonces[addr], nonce)
-	return nil
-}
-
-func (m *mockDADProtocol) check(addrs []tcpip.Address) string {
-	sentNonces := make(map[tcpip.Address][][]byte)
-	for _, a := range addrs {
-		sentNonces[a] = append(sentNonces[a], nil)
-	}
-
-	return m.checkWithNonce(sentNonces)
-}
-
-func (m *mockDADProtocol) checkWithNonce(expectedSentNonces map[tcpip.Address][][]byte) string {
-	m.mu.Lock()
-	defer m.mu.Unlock()
-
-	diff := cmp.Diff(expectedSentNonces, m.mu.sentNonces)
-	m.initLocked()
-	return diff
-}
-
-func (m *mockDADProtocol) checkDuplicateAddress(addr tcpip.Address, h stack.DADCompletionHandler) stack.DADCheckAddressDisposition {
-	m.mu.Lock()
-	defer m.mu.Unlock()
-	return m.mu.dad.CheckDuplicateAddressLocked(addr, h)
-}
-
-func (m *mockDADProtocol) stop(addr tcpip.Address, reason stack.DADResult) {
-	m.mu.Lock()
-	defer m.mu.Unlock()
-	m.mu.dad.StopLocked(addr, reason)
-}
-
-func (m *mockDADProtocol) extendIfNonceEqual(addr tcpip.Address, nonce []byte) ip.ExtendIfNonceEqualLockedDisposition {
-	m.mu.Lock()
-	defer m.mu.Unlock()
-	return m.mu.dad.ExtendIfNonceEqualLocked(addr, nonce)
-}
-
-func (m *mockDADProtocol) setConfigs(c stack.DADConfigurations) {
-	m.mu.Lock()
-	defer m.mu.Unlock()
-	m.mu.dad.SetConfigsLocked(c)
-}
-
-const (
-	addr1 = tcpip.Address("\x01")
-	addr2 = tcpip.Address("\x02")
-	addr3 = tcpip.Address("\x03")
-	addr4 = tcpip.Address("\x04")
-)
-
-type dadResult struct {
-	Addr tcpip.Address
-	R    stack.DADResult
-}
-
-func handler(ch chan<- dadResult, a tcpip.Address) func(stack.DADResult) {
-	return func(r stack.DADResult) {
-		ch <- dadResult{Addr: a, R: r}
-	}
-}
-
-func TestDADCheckDuplicateAddress(t *testing.T) {
-	var dad mockDADProtocol
-	clock := faketime.NewManualClock()
-	dad.init(t, stack.DADConfigurations{}, ip.DADOptions{
-		Clock: clock,
-	})
-
-	ch := make(chan dadResult, 2)
-
-	// DAD should initially be disabled.
-	if res := dad.checkDuplicateAddress(addr1, handler(nil, "")); res != stack.DADDisabled {
-		t.Errorf("got dad.checkDuplicateAddress(%s, _) = %d, want = %d", addr1, res, stack.DADDisabled)
-	}
-	// Wait for any initially fired timers to complete.
-	clock.Advance(0)
-	if diff := dad.check(nil); diff != "" {
-		t.Errorf("dad check mismatch (-want +got):\n%s", diff)
-	}
-
-	// Enable and request DAD.
-	dadConfigs1 := stack.DADConfigurations{
-		DupAddrDetectTransmits: 1,
-		RetransmitTimer:        time.Second,
-	}
-	dad.setConfigs(dadConfigs1)
-	if res := dad.checkDuplicateAddress(addr1, handler(ch, addr1)); res != stack.DADStarting {
-		t.Errorf("got dad.checkDuplicateAddress(%s, _) = %d, want = %d", addr1, res, stack.DADStarting)
-	}
-	clock.Advance(0)
-	if diff := dad.check([]tcpip.Address{addr1}); diff != "" {
-		t.Errorf("dad check mismatch (-want +got):\n%s", diff)
-	}
-	// The second request for DAD on the same address should use the original
-	// request since it has not completed yet.
-	if res := dad.checkDuplicateAddress(addr1, handler(ch, addr1)); res != stack.DADAlreadyRunning {
-		t.Errorf("got dad.checkDuplicateAddress(%s, _) = %d, want = %d", addr1, res, stack.DADAlreadyRunning)
-	}
-	clock.Advance(0)
-	if diff := dad.check(nil); diff != "" {
-		t.Errorf("dad check mismatch (-want +got):\n%s", diff)
-	}
-
-	dadConfigs2 := stack.DADConfigurations{
-		DupAddrDetectTransmits: 2,
-		RetransmitTimer:        time.Second,
-	}
-	dad.setConfigs(dadConfigs2)
-	// A new address should start a new DAD process.
-	if res := dad.checkDuplicateAddress(addr2, handler(ch, addr2)); res != stack.DADStarting {
-		t.Errorf("got dad.checkDuplicateAddress(%s, _) = %d, want = %d", addr2, res, stack.DADStarting)
-	}
-	clock.Advance(0)
-	if diff := dad.check([]tcpip.Address{addr2}); diff != "" {
-		t.Errorf("dad check mismatch (-want +got):\n%s", diff)
-	}
-
-	// Make sure DAD for addr1 only resolves after the expected timeout.
-	const delta = time.Nanosecond
-	dadConfig1Duration := time.Duration(dadConfigs1.DupAddrDetectTransmits) * dadConfigs1.RetransmitTimer
-	clock.Advance(dadConfig1Duration - delta)
-	select {
-	case r := <-ch:
-		t.Fatalf("unexpectedly got a DAD result before the expected timeout of %s; r = %#v", dadConfig1Duration, r)
-	default:
-	}
-	clock.Advance(delta)
-	for i := 0; i < 2; i++ {
-		if diff := cmp.Diff(dadResult{Addr: addr1, R: &stack.DADSucceeded{}}, <-ch); diff != "" {
-			t.Errorf("(i=%d) dad result mismatch (-want +got):\n%s", i, diff)
-		}
-	}
-
-	// Make sure DAD for addr2 only resolves after the expected timeout.
-	dadConfig2Duration := time.Duration(dadConfigs2.DupAddrDetectTransmits) * dadConfigs2.RetransmitTimer
-	clock.Advance(dadConfig2Duration - dadConfig1Duration - delta)
-	select {
-	case r := <-ch:
-		t.Fatalf("unexpectedly got a DAD result before the expected timeout of %s; r = %#v", dadConfig2Duration, r)
-	default:
-	}
-	clock.Advance(delta)
-	if diff := cmp.Diff(dadResult{Addr: addr2, R: &stack.DADSucceeded{}}, <-ch); diff != "" {
-		t.Errorf("dad result mismatch (-want +got):\n%s", diff)
-	}
-
-	// Should be able to restart DAD for addr2 after it resolved.
-	if res := dad.checkDuplicateAddress(addr2, handler(ch, addr2)); res != stack.DADStarting {
-		t.Errorf("got dad.checkDuplicateAddress(%s, _) = %d, want = %d", addr2, res, stack.DADStarting)
-	}
-	clock.Advance(0)
-	if diff := dad.check([]tcpip.Address{addr2, addr2}); diff != "" {
-		t.Errorf("dad check mismatch (-want +got):\n%s", diff)
-	}
-	clock.Advance(dadConfig2Duration)
-	if diff := cmp.Diff(dadResult{Addr: addr2, R: &stack.DADSucceeded{}}, <-ch); diff != "" {
-		t.Errorf("dad result mismatch (-want +got):\n%s", diff)
-	}
-
-	// Should not have anymore results.
-	select {
-	case r := <-ch:
-		t.Fatalf("unexpectedly got an extra DAD result; r = %#v", r)
-	default:
-	}
-}
-
-func TestDADStop(t *testing.T) {
-	var dad mockDADProtocol
-	clock := faketime.NewManualClock()
-	dadConfigs := stack.DADConfigurations{
-		DupAddrDetectTransmits: 1,
-		RetransmitTimer:        time.Second,
-	}
-	dad.init(t, dadConfigs, ip.DADOptions{
-		Clock: clock,
-	})
-
-	ch := make(chan dadResult, 1)
-
-	if res := dad.checkDuplicateAddress(addr1, handler(ch, addr1)); res != stack.DADStarting {
-		t.Errorf("got dad.checkDuplicateAddress(%s, _) = %d, want = %d", addr1, res, stack.DADStarting)
-	}
-	if res := dad.checkDuplicateAddress(addr2, handler(ch, addr2)); res != stack.DADStarting {
-		t.Errorf("got dad.checkDuplicateAddress(%s, _) = %d, want = %d", addr2, res, stack.DADStarting)
-	}
-	if res := dad.checkDuplicateAddress(addr3, handler(ch, addr3)); res != stack.DADStarting {
-		t.Errorf("got dad.checkDuplicateAddress(%s, _) = %d, want = %d", addr2, res, stack.DADStarting)
-	}
-	clock.Advance(0)
-	if diff := dad.check([]tcpip.Address{addr1, addr2, addr3}); diff != "" {
-		t.Errorf("dad check mismatch (-want +got):\n%s", diff)
-	}
-
-	dad.stop(addr1, &stack.DADAborted{})
-	if diff := cmp.Diff(dadResult{Addr: addr1, R: &stack.DADAborted{}}, <-ch); diff != "" {
-		t.Errorf("dad result mismatch (-want +got):\n%s", diff)
-	}
-
-	dad.stop(addr2, &stack.DADDupAddrDetected{})
-	if diff := cmp.Diff(dadResult{Addr: addr2, R: &stack.DADDupAddrDetected{}}, <-ch); diff != "" {
-		t.Errorf("dad result mismatch (-want +got):\n%s", diff)
-	}
-
-	dadResolutionDuration := time.Duration(dadConfigs.DupAddrDetectTransmits) * dadConfigs.RetransmitTimer
-	clock.Advance(dadResolutionDuration)
-	if diff := cmp.Diff(dadResult{Addr: addr3, R: &stack.DADSucceeded{}}, <-ch); diff != "" {
-		t.Errorf("dad result mismatch (-want +got):\n%s", diff)
-	}
-
-	// Should be able to restart DAD for an address we stopped DAD on.
-	if res := dad.checkDuplicateAddress(addr1, handler(ch, addr1)); res != stack.DADStarting {
-		t.Errorf("got dad.checkDuplicateAddress(%s, _) = %d, want = %d", addr1, res, stack.DADStarting)
-	}
-	clock.Advance(0)
-	if diff := dad.check([]tcpip.Address{addr1}); diff != "" {
-		t.Errorf("dad check mismatch (-want +got):\n%s", diff)
-	}
-	clock.Advance(dadResolutionDuration)
-	if diff := cmp.Diff(dadResult{Addr: addr1, R: &stack.DADSucceeded{}}, <-ch); diff != "" {
-		t.Errorf("dad result mismatch (-want +got):\n%s", diff)
-	}
-
-	// Should not have anymore updates.
-	select {
-	case r := <-ch:
-		t.Fatalf("unexpectedly got an extra DAD result; r = %#v", r)
-	default:
-	}
-}
-
-func TestNonce(t *testing.T) {
-	const (
-		nonceSize = 2
-
-		extendRequestAttempts = 2
-
-		dupAddrDetectTransmits = 2
-		extendTransmits        = 5
-	)
-
-	var secureRNGBytes [nonceSize * (dupAddrDetectTransmits + extendTransmits)]byte
-	for i := range secureRNGBytes {
-		secureRNGBytes[i] = byte(i)
-	}
-
-	tests := []struct {
-		name                string
-		mockedReceivedNonce []byte
-		expectedResults     [extendRequestAttempts]ip.ExtendIfNonceEqualLockedDisposition
-		expectedTransmits   int
-	}{
-		{
-			name:                "not matching",
-			mockedReceivedNonce: []byte{0, 0},
-			expectedResults:     [extendRequestAttempts]ip.ExtendIfNonceEqualLockedDisposition{ip.NonceNotEqual, ip.NonceNotEqual},
-			expectedTransmits:   dupAddrDetectTransmits,
-		},
-		{
-			name:                "matching nonce",
-			mockedReceivedNonce: secureRNGBytes[:nonceSize],
-			expectedResults:     [extendRequestAttempts]ip.ExtendIfNonceEqualLockedDisposition{ip.Extended, ip.AlreadyExtended},
-			expectedTransmits:   dupAddrDetectTransmits + extendTransmits,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			var dad mockDADProtocol
-			clock := faketime.NewManualClock()
-			dadConfigs := stack.DADConfigurations{
-				DupAddrDetectTransmits: dupAddrDetectTransmits,
-				RetransmitTimer:        time.Second,
-			}
-
-			var secureRNG bytes.Reader
-			secureRNG.Reset(secureRNGBytes[:])
-			dad.init(t, dadConfigs, ip.DADOptions{
-				Clock:              clock,
-				SecureRNG:          &secureRNG,
-				NonceSize:          nonceSize,
-				ExtendDADTransmits: extendTransmits,
-			})
-
-			ch := make(chan dadResult, 1)
-			if res := dad.checkDuplicateAddress(addr1, handler(ch, addr1)); res != stack.DADStarting {
-				t.Errorf("got dad.checkDuplicateAddress(%s, _) = %d, want = %d", addr1, res, stack.DADStarting)
-			}
-
-			clock.Advance(0)
-			for i, want := range test.expectedResults {
-				if got := dad.extendIfNonceEqual(addr1, test.mockedReceivedNonce); got != want {
-					t.Errorf("(i=%d) got dad.extendIfNonceEqual(%s, _) = %d, want = %d", i, addr1, got, want)
-				}
-			}
-
-			for i := 0; i < test.expectedTransmits; i++ {
-				if diff := dad.checkWithNonce(map[tcpip.Address][][]byte{
-					addr1: {
-						secureRNGBytes[nonceSize*i:][:nonceSize],
-					},
-				}); diff != "" {
-					t.Errorf("(i=%d) dad check mismatch (-want +got):\n%s", i, diff)
-				}
-
-				clock.Advance(dadConfigs.RetransmitTimer)
-			}
-
-			if diff := cmp.Diff(dadResult{Addr: addr1, R: &stack.DADSucceeded{}}, <-ch); diff != "" {
-				t.Errorf("dad result mismatch (-want +got):\n%s", diff)
-			}
-
-			// Should not have anymore updates.
-			select {
-			case r := <-ch:
-				t.Fatalf("unexpectedly got an extra DAD result; r = %#v", r)
-			default:
-			}
-		})
-	}
-}
diff --git a/pkg/tcpip/network/internal/ip/generic_multicast_protocol_test.go b/pkg/tcpip/network/internal/ip/generic_multicast_protocol_test.go
deleted file mode 100644
index 381460c..0000000
--- a/pkg/tcpip/network/internal/ip/generic_multicast_protocol_test.go
+++ /dev/null
@@ -1,805 +0,0 @@
-// Copyright 2020 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 ip_test
-
-import (
-	"math/rand"
-	"testing"
-	"time"
-
-	"github.com/google/go-cmp/cmp"
-	"gvisor.dev/gvisor/pkg/sync"
-	"gvisor.dev/gvisor/pkg/tcpip"
-	"gvisor.dev/gvisor/pkg/tcpip/faketime"
-	"gvisor.dev/gvisor/pkg/tcpip/network/internal/ip"
-)
-
-const maxUnsolicitedReportDelay = time.Second
-
-var _ ip.MulticastGroupProtocol = (*mockMulticastGroupProtocol)(nil)
-
-type mockMulticastGroupProtocolProtectedFields struct {
-	sync.RWMutex
-
-	genericMulticastGroup    ip.GenericMulticastProtocolState
-	sendReportGroupAddrCount map[tcpip.Address]int
-	sendLeaveGroupAddrCount  map[tcpip.Address]int
-	makeQueuePackets         bool
-	disabled                 bool
-}
-
-type mockMulticastGroupProtocol struct {
-	t *testing.T
-
-	mu mockMulticastGroupProtocolProtectedFields
-}
-
-func (m *mockMulticastGroupProtocol) init(opts ip.GenericMulticastProtocolOptions) {
-	m.mu.Lock()
-	defer m.mu.Unlock()
-	m.initLocked()
-	opts.Protocol = m
-	m.mu.genericMulticastGroup.Init(&m.mu.RWMutex, opts)
-}
-
-func (m *mockMulticastGroupProtocol) initLocked() {
-	m.mu.sendReportGroupAddrCount = make(map[tcpip.Address]int)
-	m.mu.sendLeaveGroupAddrCount = make(map[tcpip.Address]int)
-}
-
-func (m *mockMulticastGroupProtocol) setEnabled(v bool) {
-	m.mu.Lock()
-	defer m.mu.Unlock()
-	m.mu.disabled = !v
-}
-
-func (m *mockMulticastGroupProtocol) setQueuePackets(v bool) {
-	m.mu.Lock()
-	defer m.mu.Unlock()
-	m.mu.makeQueuePackets = v
-}
-
-func (m *mockMulticastGroupProtocol) joinGroup(addr tcpip.Address) {
-	m.mu.Lock()
-	defer m.mu.Unlock()
-	m.mu.genericMulticastGroup.JoinGroupLocked(addr)
-}
-
-func (m *mockMulticastGroupProtocol) leaveGroup(addr tcpip.Address) bool {
-	m.mu.Lock()
-	defer m.mu.Unlock()
-	return m.mu.genericMulticastGroup.LeaveGroupLocked(addr)
-}
-
-func (m *mockMulticastGroupProtocol) handleReport(addr tcpip.Address) {
-	m.mu.Lock()
-	defer m.mu.Unlock()
-	m.mu.genericMulticastGroup.HandleReportLocked(addr)
-}
-
-func (m *mockMulticastGroupProtocol) handleQuery(addr tcpip.Address, maxRespTime time.Duration) {
-	m.mu.Lock()
-	defer m.mu.Unlock()
-	m.mu.genericMulticastGroup.HandleQueryLocked(addr, maxRespTime)
-}
-
-func (m *mockMulticastGroupProtocol) isLocallyJoined(addr tcpip.Address) bool {
-	m.mu.RLock()
-	defer m.mu.RUnlock()
-	return m.mu.genericMulticastGroup.IsLocallyJoinedRLocked(addr)
-}
-
-func (m *mockMulticastGroupProtocol) makeAllNonMember() {
-	m.mu.Lock()
-	defer m.mu.Unlock()
-	m.mu.genericMulticastGroup.MakeAllNonMemberLocked()
-}
-
-func (m *mockMulticastGroupProtocol) initializeGroups() {
-	m.mu.Lock()
-	defer m.mu.Unlock()
-	m.mu.genericMulticastGroup.InitializeGroupsLocked()
-}
-
-func (m *mockMulticastGroupProtocol) sendQueuedReports() {
-	m.mu.Lock()
-	defer m.mu.Unlock()
-	m.mu.genericMulticastGroup.SendQueuedReportsLocked()
-}
-
-// Enabled implements ip.MulticastGroupProtocol.
-//
-// Precondition: m.mu must be read locked.
-func (m *mockMulticastGroupProtocol) Enabled() bool {
-	if m.mu.TryLock() {
-		m.mu.Unlock()
-		m.t.Fatal("got write lock, expected to not take the lock; generic multicast protocol must take the read or write lock before calling Enabled")
-	}
-
-	return !m.mu.disabled
-}
-
-// SendReport implements ip.MulticastGroupProtocol.
-//
-// Precondition: m.mu must be locked.
-func (m *mockMulticastGroupProtocol) SendReport(groupAddress tcpip.Address) (bool, tcpip.Error) {
-	if m.mu.TryLock() {
-		m.mu.Unlock()
-		m.t.Fatalf("got write lock, expected to not take the lock; generic multicast protocol must take the write lock before sending report for %s", groupAddress)
-	}
-	if m.mu.TryRLock() {
-		m.mu.RUnlock()
-		m.t.Fatalf("got read lock, expected to not take the lock; generic multicast protocol must take the write lock before sending report for %s", groupAddress)
-	}
-
-	m.mu.sendReportGroupAddrCount[groupAddress]++
-	return !m.mu.makeQueuePackets, nil
-}
-
-// SendLeave implements ip.MulticastGroupProtocol.
-//
-// Precondition: m.mu must be locked.
-func (m *mockMulticastGroupProtocol) SendLeave(groupAddress tcpip.Address) tcpip.Error {
-	if m.mu.TryLock() {
-		m.mu.Unlock()
-		m.t.Fatalf("got write lock, expected to not take the lock; generic multicast protocol must take the write lock before sending leave for %s", groupAddress)
-	}
-	if m.mu.TryRLock() {
-		m.mu.RUnlock()
-		m.t.Fatalf("got read lock, expected to not take the lock; generic multicast protocol must take the write lock before sending leave for %s", groupAddress)
-	}
-
-	m.mu.sendLeaveGroupAddrCount[groupAddress]++
-	return nil
-}
-
-func (m *mockMulticastGroupProtocol) check(sendReportGroupAddresses []tcpip.Address, sendLeaveGroupAddresses []tcpip.Address) string {
-	m.mu.Lock()
-	defer m.mu.Unlock()
-
-	sendReportGroupAddrCount := make(map[tcpip.Address]int)
-	for _, a := range sendReportGroupAddresses {
-		sendReportGroupAddrCount[a] = 1
-	}
-
-	sendLeaveGroupAddrCount := make(map[tcpip.Address]int)
-	for _, a := range sendLeaveGroupAddresses {
-		sendLeaveGroupAddrCount[a] = 1
-	}
-
-	diff := cmp.Diff(
-		&mockMulticastGroupProtocol{
-			mu: mockMulticastGroupProtocolProtectedFields{
-				sendReportGroupAddrCount: sendReportGroupAddrCount,
-				sendLeaveGroupAddrCount:  sendLeaveGroupAddrCount,
-			},
-		},
-		m,
-		cmp.AllowUnexported(mockMulticastGroupProtocol{}),
-		cmp.AllowUnexported(mockMulticastGroupProtocolProtectedFields{}),
-		// ignore mockMulticastGroupProtocol.mu and mockMulticastGroupProtocol.t
-		cmp.FilterPath(
-			func(p cmp.Path) bool {
-				switch p.Last().String() {
-				case ".RWMutex", ".t", ".makeQueuePackets", ".disabled", ".genericMulticastGroup":
-					return true
-				}
-				return false
-			},
-			cmp.Ignore(),
-		),
-	)
-	m.initLocked()
-	return diff
-}
-
-func TestJoinGroup(t *testing.T) {
-	tests := []struct {
-		name              string
-		addr              tcpip.Address
-		shouldSendReports bool
-	}{
-		{
-			name:              "Normal group",
-			addr:              addr1,
-			shouldSendReports: true,
-		},
-		{
-			name:              "All-nodes group",
-			addr:              addr2,
-			shouldSendReports: false,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			mgp := mockMulticastGroupProtocol{t: t}
-			clock := faketime.NewManualClock()
-
-			mgp.init(ip.GenericMulticastProtocolOptions{
-				Rand:                      rand.New(rand.NewSource(0)),
-				Clock:                     clock,
-				MaxUnsolicitedReportDelay: maxUnsolicitedReportDelay,
-				AllNodesAddress:           addr2,
-			})
-
-			// Joining a group should send a report immediately and another after
-			// a random interval between 0 and the maximum unsolicited report delay.
-			mgp.joinGroup(test.addr)
-			if test.shouldSendReports {
-				if diff := mgp.check([]tcpip.Address{test.addr} /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-					t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-				}
-
-				// Generic multicast protocol timers are expected to take the job mutex.
-				clock.Advance(maxUnsolicitedReportDelay)
-				if diff := mgp.check([]tcpip.Address{test.addr} /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-					t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-				}
-			}
-
-			// Should have no more messages to send.
-			clock.Advance(time.Hour)
-			if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-				t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-			}
-		})
-	}
-}
-
-func TestLeaveGroup(t *testing.T) {
-	tests := []struct {
-		name               string
-		addr               tcpip.Address
-		shouldSendMessages bool
-	}{
-		{
-			name:               "Normal group",
-			addr:               addr1,
-			shouldSendMessages: true,
-		},
-		{
-			name:               "All-nodes group",
-			addr:               addr2,
-			shouldSendMessages: false,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			mgp := mockMulticastGroupProtocol{t: t}
-			clock := faketime.NewManualClock()
-
-			mgp.init(ip.GenericMulticastProtocolOptions{
-				Rand:                      rand.New(rand.NewSource(1)),
-				Clock:                     clock,
-				MaxUnsolicitedReportDelay: maxUnsolicitedReportDelay,
-				AllNodesAddress:           addr2,
-			})
-
-			mgp.joinGroup(test.addr)
-			if test.shouldSendMessages {
-				if diff := mgp.check([]tcpip.Address{test.addr} /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-					t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-				}
-			}
-
-			// Leaving a group should send a leave report immediately and cancel any
-			// delayed reports.
-			{
-
-				if !mgp.leaveGroup(test.addr) {
-					t.Fatalf("got mgp.leaveGroup(%s) = false, want = true", test.addr)
-				}
-			}
-			if test.shouldSendMessages {
-				if diff := mgp.check(nil /* sendReportGroupAddresses */, []tcpip.Address{test.addr} /* sendLeaveGroupAddresses */); diff != "" {
-					t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-				}
-			}
-
-			// Should have no more messages to send.
-			//
-			// Generic multicast protocol timers are expected to take the job mutex.
-			clock.Advance(time.Hour)
-			if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-				t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-			}
-		})
-	}
-}
-
-func TestHandleReport(t *testing.T) {
-	tests := []struct {
-		name             string
-		reportAddr       tcpip.Address
-		expectReportsFor []tcpip.Address
-	}{
-		{
-			name:             "Unpecified empty",
-			reportAddr:       "",
-			expectReportsFor: []tcpip.Address{addr1, addr2},
-		},
-		{
-			name:             "Unpecified any",
-			reportAddr:       "\x00",
-			expectReportsFor: []tcpip.Address{addr1, addr2},
-		},
-		{
-			name:             "Specified",
-			reportAddr:       addr1,
-			expectReportsFor: []tcpip.Address{addr2},
-		},
-		{
-			name:             "Specified all-nodes",
-			reportAddr:       addr3,
-			expectReportsFor: []tcpip.Address{addr1, addr2},
-		},
-		{
-			name:             "Specified other",
-			reportAddr:       addr4,
-			expectReportsFor: []tcpip.Address{addr1, addr2},
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			mgp := mockMulticastGroupProtocol{t: t}
-			clock := faketime.NewManualClock()
-
-			mgp.init(ip.GenericMulticastProtocolOptions{
-				Rand:                      rand.New(rand.NewSource(2)),
-				Clock:                     clock,
-				MaxUnsolicitedReportDelay: maxUnsolicitedReportDelay,
-				AllNodesAddress:           addr3,
-			})
-
-			mgp.joinGroup(addr1)
-			if diff := mgp.check([]tcpip.Address{addr1} /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-				t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-			}
-			mgp.joinGroup(addr2)
-			if diff := mgp.check([]tcpip.Address{addr2} /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-				t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-			}
-			mgp.joinGroup(addr3)
-			if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-				t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-			}
-
-			// Receiving a report for a group we have a timer scheduled for should
-			// cancel our delayed report timer for the group.
-			mgp.handleReport(test.reportAddr)
-			if len(test.expectReportsFor) != 0 {
-				// Generic multicast protocol timers are expected to take the job mutex.
-				clock.Advance(maxUnsolicitedReportDelay)
-				if diff := mgp.check(test.expectReportsFor /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-					t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-				}
-			}
-
-			// Should have no more messages to send.
-			clock.Advance(time.Hour)
-			if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-				t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-			}
-		})
-	}
-}
-
-func TestHandleQuery(t *testing.T) {
-	tests := []struct {
-		name                    string
-		queryAddr               tcpip.Address
-		maxDelay                time.Duration
-		expectQueriedReportsFor []tcpip.Address
-		expectDelayedReportsFor []tcpip.Address
-	}{
-		{
-			name:                    "Unpecified empty",
-			queryAddr:               "",
-			maxDelay:                0,
-			expectQueriedReportsFor: []tcpip.Address{addr1, addr2},
-			expectDelayedReportsFor: nil,
-		},
-		{
-			name:                    "Unpecified any",
-			queryAddr:               "\x00",
-			maxDelay:                1,
-			expectQueriedReportsFor: []tcpip.Address{addr1, addr2},
-			expectDelayedReportsFor: nil,
-		},
-		{
-			name:                    "Specified",
-			queryAddr:               addr1,
-			maxDelay:                2,
-			expectQueriedReportsFor: []tcpip.Address{addr1},
-			expectDelayedReportsFor: []tcpip.Address{addr2},
-		},
-		{
-			name:                    "Specified all-nodes",
-			queryAddr:               addr3,
-			maxDelay:                3,
-			expectQueriedReportsFor: nil,
-			expectDelayedReportsFor: []tcpip.Address{addr1, addr2},
-		},
-		{
-			name:                    "Specified other",
-			queryAddr:               addr4,
-			maxDelay:                4,
-			expectQueriedReportsFor: nil,
-			expectDelayedReportsFor: []tcpip.Address{addr1, addr2},
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			mgp := mockMulticastGroupProtocol{t: t}
-			clock := faketime.NewManualClock()
-
-			mgp.init(ip.GenericMulticastProtocolOptions{
-				Rand:                      rand.New(rand.NewSource(3)),
-				Clock:                     clock,
-				MaxUnsolicitedReportDelay: maxUnsolicitedReportDelay,
-				AllNodesAddress:           addr3,
-			})
-
-			mgp.joinGroup(addr1)
-			if diff := mgp.check([]tcpip.Address{addr1} /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-				t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-			}
-			mgp.joinGroup(addr2)
-			if diff := mgp.check([]tcpip.Address{addr2} /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-				t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-			}
-			mgp.joinGroup(addr3)
-			if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-				t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-			}
-
-			// Receiving a query should make us reschedule our delayed report timer
-			// to some time within the new max response delay.
-			mgp.handleQuery(test.queryAddr, test.maxDelay)
-			clock.Advance(test.maxDelay)
-			if diff := mgp.check(test.expectQueriedReportsFor /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-				t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-			}
-
-			// The groups that were not affected by the query should still send a
-			// report after the max unsolicited report delay.
-			clock.Advance(maxUnsolicitedReportDelay)
-			if diff := mgp.check(test.expectDelayedReportsFor /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-				t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-			}
-
-			// Should have no more messages to send.
-			clock.Advance(time.Hour)
-			if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-				t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-			}
-		})
-	}
-}
-
-func TestJoinCount(t *testing.T) {
-	mgp := mockMulticastGroupProtocol{t: t}
-	clock := faketime.NewManualClock()
-
-	mgp.init(ip.GenericMulticastProtocolOptions{
-		Rand:                      rand.New(rand.NewSource(4)),
-		Clock:                     clock,
-		MaxUnsolicitedReportDelay: time.Second,
-	})
-
-	// Set the join count to 2 for a group.
-	mgp.joinGroup(addr1)
-	if !mgp.isLocallyJoined(addr1) {
-		t.Fatalf("got mgp.isLocallyJoined(%s) = false, want = true", addr1)
-	}
-	// Only the first join should trigger a report to be sent.
-	if diff := mgp.check([]tcpip.Address{addr1} /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-		t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-	}
-	mgp.joinGroup(addr1)
-	if !mgp.isLocallyJoined(addr1) {
-		t.Errorf("got mgp.isLocallyJoined(%s) = false, want = true", addr1)
-	}
-	if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-		t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-	}
-	if t.Failed() {
-		t.FailNow()
-	}
-
-	// Group should still be considered joined after leaving once.
-	if !mgp.leaveGroup(addr1) {
-		t.Errorf("got mgp.leaveGroup(%s) = false, want = true", addr1)
-	}
-	if !mgp.isLocallyJoined(addr1) {
-		t.Errorf("got mgp.isLocallyJoined(%s) = false, want = true", addr1)
-	}
-	// A leave report should only be sent once the join count reaches 0.
-	if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-		t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-	}
-	if t.Failed() {
-		t.FailNow()
-	}
-
-	// Leaving once more should actually remove us from the group.
-	if !mgp.leaveGroup(addr1) {
-		t.Errorf("got mgp.leaveGroup(%s) = false, want = true", addr1)
-	}
-	if mgp.isLocallyJoined(addr1) {
-		t.Errorf("got mgp.isLocallyJoined(%s) = true, want = false", addr1)
-	}
-	if diff := mgp.check(nil /* sendReportGroupAddresses */, []tcpip.Address{addr1} /* sendLeaveGroupAddresses */); diff != "" {
-		t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-	}
-	if t.Failed() {
-		t.FailNow()
-	}
-
-	// Group should no longer be joined so we should not have anything to
-	// leave.
-	if mgp.leaveGroup(addr1) {
-		t.Errorf("got mgp.leaveGroup(%s) = true, want = false", addr1)
-	}
-	if mgp.isLocallyJoined(addr1) {
-		t.Errorf("got mgp.isLocallyJoined(%s) = true, want = false", addr1)
-	}
-	if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-		t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-	}
-
-	// Should have no more messages to send.
-	//
-	// Generic multicast protocol timers are expected to take the job mutex.
-	clock.Advance(time.Hour)
-	if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-		t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-	}
-}
-
-func TestMakeAllNonMemberAndInitialize(t *testing.T) {
-	mgp := mockMulticastGroupProtocol{t: t}
-	clock := faketime.NewManualClock()
-
-	mgp.init(ip.GenericMulticastProtocolOptions{
-		Rand:                      rand.New(rand.NewSource(3)),
-		Clock:                     clock,
-		MaxUnsolicitedReportDelay: maxUnsolicitedReportDelay,
-		AllNodesAddress:           addr3,
-	})
-
-	mgp.joinGroup(addr1)
-	if diff := mgp.check([]tcpip.Address{addr1} /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-		t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-	}
-	mgp.joinGroup(addr2)
-	if diff := mgp.check([]tcpip.Address{addr2} /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-		t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-	}
-	mgp.joinGroup(addr3)
-	if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-		t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-	}
-
-	// Should send the leave reports for each but still consider them locally
-	// joined.
-	mgp.makeAllNonMember()
-	if diff := mgp.check(nil /* sendReportGroupAddresses */, []tcpip.Address{addr1, addr2} /* sendLeaveGroupAddresses */); diff != "" {
-		t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-	}
-	// Generic multicast protocol timers are expected to take the job mutex.
-	clock.Advance(time.Hour)
-	if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-		t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-	}
-	for _, group := range []tcpip.Address{addr1, addr2, addr3} {
-		if !mgp.isLocallyJoined(group) {
-			t.Fatalf("got mgp.isLocallyJoined(%s) = false, want = true", group)
-		}
-	}
-
-	// Should send the initial set of unsolcited reports.
-	mgp.initializeGroups()
-	if diff := mgp.check([]tcpip.Address{addr1, addr2} /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-		t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-	}
-	clock.Advance(maxUnsolicitedReportDelay)
-	if diff := mgp.check([]tcpip.Address{addr1, addr2} /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-		t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-	}
-
-	// Should have no more messages to send.
-	clock.Advance(time.Hour)
-	if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-		t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-	}
-}
-
-// TestGroupStateNonMember tests that groups do not send packets when in the
-// non-member state, but are still considered locally joined.
-func TestGroupStateNonMember(t *testing.T) {
-	mgp := mockMulticastGroupProtocol{t: t}
-	clock := faketime.NewManualClock()
-
-	mgp.init(ip.GenericMulticastProtocolOptions{
-		Rand:                      rand.New(rand.NewSource(3)),
-		Clock:                     clock,
-		MaxUnsolicitedReportDelay: maxUnsolicitedReportDelay,
-	})
-	mgp.setEnabled(false)
-
-	// Joining groups should not send any reports.
-	mgp.joinGroup(addr1)
-	if !mgp.isLocallyJoined(addr1) {
-		t.Fatalf("got mgp.isLocallyJoined(%s) = false, want = true", addr1)
-	}
-	if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-		t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-	}
-	mgp.joinGroup(addr2)
-	if !mgp.isLocallyJoined(addr1) {
-		t.Fatalf("got mgp.isLocallyJoined(%s) = false, want = true", addr2)
-	}
-	if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-		t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-	}
-
-	// Receiving a query should not send any reports.
-	mgp.handleQuery(addr1, time.Nanosecond)
-	// Generic multicast protocol timers are expected to take the job mutex.
-	clock.Advance(time.Nanosecond)
-	if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-		t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-	}
-
-	// Leaving groups should not send any leave messages.
-	if !mgp.leaveGroup(addr1) {
-		t.Errorf("got mgp.leaveGroup(%s) = false, want = true", addr2)
-	}
-	if mgp.isLocallyJoined(addr1) {
-		t.Errorf("got mgp.isLocallyJoined(%s) = true, want = false", addr2)
-	}
-	if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-		t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-	}
-
-	clock.Advance(time.Hour)
-	if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-		t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-	}
-}
-
-func TestQueuedPackets(t *testing.T) {
-	clock := faketime.NewManualClock()
-	mgp := mockMulticastGroupProtocol{t: t}
-	mgp.init(ip.GenericMulticastProtocolOptions{
-		Rand:                      rand.New(rand.NewSource(4)),
-		Clock:                     clock,
-		MaxUnsolicitedReportDelay: maxUnsolicitedReportDelay,
-	})
-
-	// Joining should trigger a SendReport, but mgp should report that we did not
-	// send the packet.
-	mgp.setQueuePackets(true)
-	mgp.joinGroup(addr1)
-	if diff := mgp.check([]tcpip.Address{addr1} /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-		t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-	}
-
-	// The delayed report timer should have been cancelled since we did not send
-	// the initial report earlier.
-	clock.Advance(time.Hour)
-	if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-		t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-	}
-
-	// Mock being able to successfully send the report.
-	mgp.setQueuePackets(false)
-	mgp.sendQueuedReports()
-	if diff := mgp.check([]tcpip.Address{addr1} /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-		t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-	}
-
-	// The delayed report (sent after the initial report) should now be sent.
-	clock.Advance(maxUnsolicitedReportDelay)
-	if diff := mgp.check([]tcpip.Address{addr1} /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-		t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-	}
-
-	// Should not have anything else to send (we should be idle).
-	mgp.sendQueuedReports()
-	clock.Advance(time.Hour)
-	if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-		t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-	}
-
-	// Receive a query but mock being unable to send reports again.
-	mgp.setQueuePackets(true)
-	mgp.handleQuery(addr1, time.Nanosecond)
-	clock.Advance(time.Nanosecond)
-	if diff := mgp.check([]tcpip.Address{addr1} /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-		t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-	}
-
-	// Mock being able to send reports again - we should have a packet queued to
-	// send.
-	mgp.setQueuePackets(false)
-	mgp.sendQueuedReports()
-	if diff := mgp.check([]tcpip.Address{addr1} /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-		t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-	}
-
-	// Should not have anything else to send.
-	mgp.sendQueuedReports()
-	clock.Advance(time.Hour)
-	if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-		t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-	}
-
-	// Receive a query again, but mock being unable to send reports.
-	mgp.setQueuePackets(true)
-	mgp.handleQuery(addr1, time.Nanosecond)
-	clock.Advance(time.Nanosecond)
-	if diff := mgp.check([]tcpip.Address{addr1} /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-		t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-	}
-
-	// Receiving a report should should transition us into the idle member state,
-	// even if we had a packet queued. We should no longer have any packets to
-	// send.
-	mgp.handleReport(addr1)
-	mgp.sendQueuedReports()
-	clock.Advance(time.Hour)
-	if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-		t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-	}
-
-	// When we fail to send the initial set of reports, incoming reports should
-	// not affect a newly joined group's reports from being sent.
-	mgp.setQueuePackets(true)
-	mgp.joinGroup(addr2)
-	if diff := mgp.check([]tcpip.Address{addr2} /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-		t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-	}
-	mgp.handleReport(addr2)
-	// Attempting to send queued reports while still unable to send reports should
-	// not change the host state.
-	mgp.sendQueuedReports()
-	if diff := mgp.check([]tcpip.Address{addr2} /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-		t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-	}
-	// Mock being able to successfully send the report.
-	mgp.setQueuePackets(false)
-	mgp.sendQueuedReports()
-	if diff := mgp.check([]tcpip.Address{addr2} /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-		t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-	}
-	// The delayed report (sent after the initial report) should now be sent.
-	clock.Advance(maxUnsolicitedReportDelay)
-	if diff := mgp.check([]tcpip.Address{addr2} /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-		t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-	}
-
-	// Should not have anything else to send.
-	mgp.sendQueuedReports()
-	clock.Advance(time.Hour)
-	if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
-		t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
-	}
-}
diff --git a/pkg/tcpip/network/internal/ip/ip_state_autogen.go b/pkg/tcpip/network/internal/ip/ip_state_autogen.go
new file mode 100644
index 0000000..aee7704
--- /dev/null
+++ b/pkg/tcpip/network/internal/ip/ip_state_autogen.go
@@ -0,0 +1,3 @@
+// automatically generated by stateify.
+
+package ip
diff --git a/pkg/tcpip/network/ipv4/igmp_test.go b/pkg/tcpip/network/ipv4/igmp_test.go
deleted file mode 100644
index e5e1b89..0000000
--- a/pkg/tcpip/network/ipv4/igmp_test.go
+++ /dev/null
@@ -1,383 +0,0 @@
-// Copyright 2020 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 ipv4_test
-
-import (
-	"testing"
-	"time"
-
-	"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/network/ipv4"
-	"gvisor.dev/gvisor/pkg/tcpip/stack"
-)
-
-const (
-	linkAddr            = tcpip.LinkAddress("\x02\x02\x03\x04\x05\x06")
-	stackAddr           = tcpip.Address("\x0a\x00\x00\x01")
-	remoteAddr          = tcpip.Address("\x0a\x00\x00\x02")
-	multicastAddr       = tcpip.Address("\xe0\x00\x00\x03")
-	nicID               = 1
-	defaultTTL          = 1
-	defaultPrefixLength = 24
-)
-
-// validateIgmpPacket checks that a passed PacketInfo is an IPv4 IGMP packet
-// sent to the provided address with the passed fields set. Raises a t.Error if
-// any field does not match.
-func validateIgmpPacket(t *testing.T, p channel.PacketInfo, igmpType header.IGMPType, maxRespTime byte, srcAddr, dstAddr, groupAddress tcpip.Address) {
-	t.Helper()
-
-	payload := header.IPv4(stack.PayloadSince(p.Pkt.NetworkHeader()))
-	checker.IPv4(t, payload,
-		checker.SrcAddr(srcAddr),
-		checker.DstAddr(dstAddr),
-		// TTL for an IGMP message must be 1 as per RFC 2236 section 2.
-		checker.TTL(1),
-		checker.IPv4RouterAlert(),
-		checker.IGMP(
-			checker.IGMPType(igmpType),
-			checker.IGMPMaxRespTime(header.DecisecondToDuration(maxRespTime)),
-			checker.IGMPGroupAddress(groupAddress),
-		),
-	)
-}
-
-func createStack(t *testing.T, igmpEnabled bool) (*channel.Endpoint, *stack.Stack, *faketime.ManualClock) {
-	t.Helper()
-
-	// Create an endpoint of queue size 1, since no more than 1 packets are ever
-	// queued in the tests in this file.
-	e := channel.New(1, 1280, linkAddr)
-	clock := faketime.NewManualClock()
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocolWithOptions(ipv4.Options{
-			IGMP: ipv4.IGMPOptions{
-				Enabled: igmpEnabled,
-			},
-		})},
-		Clock: clock,
-	})
-	if err := s.CreateNIC(nicID, e); err != nil {
-		t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
-	}
-	return e, s, clock
-}
-
-func createAndInjectIGMPPacket(e *channel.Endpoint, igmpType header.IGMPType, maxRespTime byte, ttl uint8, srcAddr, dstAddr, groupAddress tcpip.Address, hasRouterAlertOption bool) {
-	var options header.IPv4OptionsSerializer
-	if hasRouterAlertOption {
-		options = header.IPv4OptionsSerializer{
-			&header.IPv4SerializableRouterAlertOption{},
-		}
-	}
-	buf := buffer.NewView(header.IPv4MinimumSize + int(options.Length()) + header.IGMPQueryMinimumSize)
-
-	ip := header.IPv4(buf)
-	ip.Encode(&header.IPv4Fields{
-		TotalLength: uint16(len(buf)),
-		TTL:         ttl,
-		Protocol:    uint8(header.IGMPProtocolNumber),
-		SrcAddr:     srcAddr,
-		DstAddr:     dstAddr,
-		Options:     options,
-	})
-	ip.SetChecksum(^ip.CalculateChecksum())
-
-	igmp := header.IGMP(ip.Payload())
-	igmp.SetType(igmpType)
-	igmp.SetMaxRespTime(maxRespTime)
-	igmp.SetGroupAddress(groupAddress)
-	igmp.SetChecksum(header.IGMPCalculateChecksum(igmp))
-
-	e.InjectInbound(ipv4.ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
-		Data: buf.ToVectorisedView(),
-	}))
-}
-
-// TestIGMPV1Present tests the node's ability to fallback to V1 when a V1
-// router is detected. V1 present status is expected to be reset when the NIC
-// cycles.
-func TestIGMPV1Present(t *testing.T) {
-	e, s, clock := createStack(t, true)
-	addr := tcpip.AddressWithPrefix{Address: stackAddr, PrefixLen: defaultPrefixLength}
-	if err := s.AddAddressWithPrefix(nicID, ipv4.ProtocolNumber, addr); err != nil {
-		t.Fatalf("AddAddressWithPrefix(%d, %d, %s): %s", nicID, ipv4.ProtocolNumber, addr, err)
-	}
-
-	if err := s.JoinGroup(ipv4.ProtocolNumber, nicID, multicastAddr); err != nil {
-		t.Fatalf("JoinGroup(ipv4, nic, %s) = %s", multicastAddr, err)
-	}
-
-	// This NIC will send an IGMPv2 report immediately, before this test can get
-	// the IGMPv1 General Membership Query in.
-	{
-		p, ok := e.Read()
-		if !ok {
-			t.Fatal("unable to Read IGMP packet, expected V2MembershipReport")
-		}
-		if got := s.Stats().IGMP.PacketsSent.V2MembershipReport.Value(); got != 1 {
-			t.Fatalf("got V2MembershipReport messages sent = %d, want = 1", got)
-		}
-		validateIgmpPacket(t, p, header.IGMPv2MembershipReport, 0, stackAddr, multicastAddr, multicastAddr)
-	}
-	if t.Failed() {
-		t.FailNow()
-	}
-
-	// Inject an IGMPv1 General Membership Query which is identical to a standard
-	// membership query except the Max Response Time is set to 0, which will tell
-	// the stack that this is a router using IGMPv1. Send it to the all systems
-	// group which is the only group this host belongs to.
-	createAndInjectIGMPPacket(e, header.IGMPMembershipQuery, 0, defaultTTL, remoteAddr, stackAddr, header.IPv4AllSystems, true /* hasRouterAlertOption */)
-	if got := s.Stats().IGMP.PacketsReceived.MembershipQuery.Value(); got != 1 {
-		t.Fatalf("got Membership Queries received = %d, want = 1", got)
-	}
-
-	// Before advancing the clock, verify that this host has not sent a
-	// V1MembershipReport yet.
-	if got := s.Stats().IGMP.PacketsSent.V1MembershipReport.Value(); got != 0 {
-		t.Fatalf("got V1MembershipReport messages sent = %d, want = 0", got)
-	}
-
-	// Verify the solicited Membership Report is sent. Now that this NIC has seen
-	// an IGMPv1 query, it should send an IGMPv1 Membership Report.
-	if p, ok := e.Read(); ok {
-		t.Fatalf("sent unexpected packet, expected V1MembershipReport only after advancing the clock = %+v", p.Pkt)
-	}
-	clock.Advance(ipv4.UnsolicitedReportIntervalMax)
-	{
-		p, ok := e.Read()
-		if !ok {
-			t.Fatal("unable to Read IGMP packet, expected V1MembershipReport")
-		}
-		if got := s.Stats().IGMP.PacketsSent.V1MembershipReport.Value(); got != 1 {
-			t.Fatalf("got V1MembershipReport messages sent = %d, want = 1", got)
-		}
-		validateIgmpPacket(t, p, header.IGMPv1MembershipReport, 0, stackAddr, multicastAddr, multicastAddr)
-	}
-
-	// Cycling the interface should reset the V1 present flag.
-	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)
-	}
-	{
-		p, ok := e.Read()
-		if !ok {
-			t.Fatal("unable to Read IGMP packet, expected V2MembershipReport")
-		}
-		if got := s.Stats().IGMP.PacketsSent.V2MembershipReport.Value(); got != 2 {
-			t.Fatalf("got V2MembershipReport messages sent = %d, want = 2", got)
-		}
-		validateIgmpPacket(t, p, header.IGMPv2MembershipReport, 0, stackAddr, multicastAddr, multicastAddr)
-	}
-}
-
-func TestSendQueuedIGMPReports(t *testing.T) {
-	e, s, clock := createStack(t, true)
-
-	// Joining a group without an assigned address should queue IGMP packets; none
-	// should be sent without an assigned address.
-	if err := s.JoinGroup(ipv4.ProtocolNumber, nicID, multicastAddr); err != nil {
-		t.Fatalf("JoinGroup(%d, %d, %s): %s", ipv4.ProtocolNumber, nicID, multicastAddr, err)
-	}
-	reportStat := s.Stats().IGMP.PacketsSent.V2MembershipReport
-	if got := reportStat.Value(); got != 0 {
-		t.Errorf("got reportStat.Value() = %d, want = 0", got)
-	}
-	clock.Advance(time.Hour)
-	if p, ok := e.Read(); ok {
-		t.Fatalf("got unexpected packet = %#v", p)
-	}
-
-	// The initial set of IGMP reports that were queued should be sent once an
-	// address is assigned.
-	if err := s.AddAddress(nicID, ipv4.ProtocolNumber, stackAddr); err != nil {
-		t.Fatalf("AddAddress(%d, %d, %s): %s", nicID, ipv4.ProtocolNumber, stackAddr, err)
-	}
-	if got := reportStat.Value(); got != 1 {
-		t.Errorf("got reportStat.Value() = %d, want = 1", got)
-	}
-	if p, ok := e.Read(); !ok {
-		t.Error("expected to send an IGMP membership report")
-	} else {
-		validateIgmpPacket(t, p, header.IGMPv2MembershipReport, 0, stackAddr, multicastAddr, multicastAddr)
-	}
-	if t.Failed() {
-		t.FailNow()
-	}
-	clock.Advance(ipv4.UnsolicitedReportIntervalMax)
-	if got := reportStat.Value(); got != 2 {
-		t.Errorf("got reportStat.Value() = %d, want = 2", got)
-	}
-	if p, ok := e.Read(); !ok {
-		t.Error("expected to send an IGMP membership report")
-	} else {
-		validateIgmpPacket(t, p, header.IGMPv2MembershipReport, 0, stackAddr, multicastAddr, multicastAddr)
-	}
-	if t.Failed() {
-		t.FailNow()
-	}
-
-	// Should have no more packets to send after the initial set of unsolicited
-	// reports.
-	clock.Advance(time.Hour)
-	if p, ok := e.Read(); ok {
-		t.Fatalf("got unexpected packet = %#v", p)
-	}
-}
-
-func TestIGMPPacketValidation(t *testing.T) {
-	tests := []struct {
-		name                     string
-		messageType              header.IGMPType
-		stackAddresses           []tcpip.AddressWithPrefix
-		srcAddr                  tcpip.Address
-		includeRouterAlertOption bool
-		ttl                      uint8
-		expectValidIGMP          bool
-		getMessageTypeStatValue  func(tcpip.Stats) uint64
-	}{
-		{
-			name:                     "valid",
-			messageType:              header.IGMPLeaveGroup,
-			includeRouterAlertOption: true,
-			stackAddresses:           []tcpip.AddressWithPrefix{{Address: stackAddr, PrefixLen: 24}},
-			srcAddr:                  remoteAddr,
-			ttl:                      1,
-			expectValidIGMP:          true,
-			getMessageTypeStatValue:  func(stats tcpip.Stats) uint64 { return stats.IGMP.PacketsReceived.LeaveGroup.Value() },
-		},
-		{
-			name:                     "bad ttl",
-			messageType:              header.IGMPv1MembershipReport,
-			includeRouterAlertOption: true,
-			stackAddresses:           []tcpip.AddressWithPrefix{{Address: stackAddr, PrefixLen: 24}},
-			srcAddr:                  remoteAddr,
-			ttl:                      2,
-			expectValidIGMP:          false,
-			getMessageTypeStatValue:  func(stats tcpip.Stats) uint64 { return stats.IGMP.PacketsReceived.V1MembershipReport.Value() },
-		},
-		{
-			name:                     "missing router alert ip option",
-			messageType:              header.IGMPv2MembershipReport,
-			includeRouterAlertOption: false,
-			stackAddresses:           []tcpip.AddressWithPrefix{{Address: stackAddr, PrefixLen: 24}},
-			srcAddr:                  remoteAddr,
-			ttl:                      1,
-			expectValidIGMP:          false,
-			getMessageTypeStatValue:  func(stats tcpip.Stats) uint64 { return stats.IGMP.PacketsReceived.V2MembershipReport.Value() },
-		},
-		{
-			name:                     "igmp leave group and src ip does not belong to nic subnet",
-			messageType:              header.IGMPLeaveGroup,
-			includeRouterAlertOption: true,
-			stackAddresses:           []tcpip.AddressWithPrefix{{Address: stackAddr, PrefixLen: 24}},
-			srcAddr:                  tcpip.Address("\x0a\x00\x01\x02"),
-			ttl:                      1,
-			expectValidIGMP:          false,
-			getMessageTypeStatValue:  func(stats tcpip.Stats) uint64 { return stats.IGMP.PacketsReceived.LeaveGroup.Value() },
-		},
-		{
-			name:                     "igmp query and src ip does not belong to nic subnet",
-			messageType:              header.IGMPMembershipQuery,
-			includeRouterAlertOption: true,
-			stackAddresses:           []tcpip.AddressWithPrefix{{Address: stackAddr, PrefixLen: 24}},
-			srcAddr:                  tcpip.Address("\x0a\x00\x01\x02"),
-			ttl:                      1,
-			expectValidIGMP:          true,
-			getMessageTypeStatValue:  func(stats tcpip.Stats) uint64 { return stats.IGMP.PacketsReceived.MembershipQuery.Value() },
-		},
-		{
-			name:                     "igmp report v1 and src ip does not belong to nic subnet",
-			messageType:              header.IGMPv1MembershipReport,
-			includeRouterAlertOption: true,
-			stackAddresses:           []tcpip.AddressWithPrefix{{Address: stackAddr, PrefixLen: 24}},
-			srcAddr:                  tcpip.Address("\x0a\x00\x01\x02"),
-			ttl:                      1,
-			expectValidIGMP:          false,
-			getMessageTypeStatValue:  func(stats tcpip.Stats) uint64 { return stats.IGMP.PacketsReceived.V1MembershipReport.Value() },
-		},
-		{
-			name:                     "igmp report v2 and src ip does not belong to nic subnet",
-			messageType:              header.IGMPv2MembershipReport,
-			includeRouterAlertOption: true,
-			stackAddresses:           []tcpip.AddressWithPrefix{{Address: stackAddr, PrefixLen: 24}},
-			srcAddr:                  tcpip.Address("\x0a\x00\x01\x02"),
-			ttl:                      1,
-			expectValidIGMP:          false,
-			getMessageTypeStatValue:  func(stats tcpip.Stats) uint64 { return stats.IGMP.PacketsReceived.V2MembershipReport.Value() },
-		},
-		{
-			name:                     "src ip belongs to the subnet of the nic's second address",
-			messageType:              header.IGMPv2MembershipReport,
-			includeRouterAlertOption: true,
-			stackAddresses: []tcpip.AddressWithPrefix{
-				{Address: tcpip.Address("\x0a\x00\x0f\x01"), PrefixLen: 24},
-				{Address: stackAddr, PrefixLen: 24},
-			},
-			srcAddr:                 remoteAddr,
-			ttl:                     1,
-			expectValidIGMP:         true,
-			getMessageTypeStatValue: func(stats tcpip.Stats) uint64 { return stats.IGMP.PacketsReceived.V2MembershipReport.Value() },
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			e, s, _ := createStack(t, true)
-			for _, address := range test.stackAddresses {
-				if err := s.AddAddressWithPrefix(nicID, ipv4.ProtocolNumber, address); err != nil {
-					t.Fatalf("AddAddressWithPrefix(%d, %d, %s): %s", nicID, ipv4.ProtocolNumber, address, err)
-				}
-			}
-			stats := s.Stats()
-			// Verify that every relevant stats is zero'd before we send a packet.
-			if got := test.getMessageTypeStatValue(s.Stats()); got != 0 {
-				t.Errorf("got test.getMessageTypeStatValue(s.Stats()) = %d, want = 0", got)
-			}
-			if got := stats.IGMP.PacketsReceived.Invalid.Value(); got != 0 {
-				t.Errorf("got stats.IGMP.PacketsReceived.Invalid.Value() = %d, want = 0", got)
-			}
-			if got := stats.IP.PacketsDelivered.Value(); got != 0 {
-				t.Fatalf("got stats.IP.PacketsDelivered.Value() = %d, want = 0", got)
-			}
-			createAndInjectIGMPPacket(e, test.messageType, 0, test.ttl, test.srcAddr, header.IPv4AllSystems, header.IPv4AllSystems, test.includeRouterAlertOption)
-			// We always expect the packet to pass IP validation.
-			if got := stats.IP.PacketsDelivered.Value(); got != 1 {
-				t.Fatalf("got stats.IP.PacketsDelivered.Value() = %d, want = 1", got)
-			}
-			// Even when the IGMP-specific validation checks fail, we expect the
-			// corresponding IGMP counter to be incremented.
-			if got := test.getMessageTypeStatValue(s.Stats()); got != 1 {
-				t.Errorf("got test.getMessageTypeStatValue(s.Stats()) = %d, want = 1", got)
-			}
-			var expectedInvalidCount uint64
-			if !test.expectValidIGMP {
-				expectedInvalidCount = 1
-			}
-			if got := stats.IGMP.PacketsReceived.Invalid.Value(); got != expectedInvalidCount {
-				t.Errorf("got stats.IGMP.PacketsReceived.Invalid.Value() = %d, want = %d", got, expectedInvalidCount)
-			}
-		})
-	}
-}
diff --git a/pkg/tcpip/network/ipv4/ipv4_state_autogen.go b/pkg/tcpip/network/ipv4/ipv4_state_autogen.go
new file mode 100644
index 0000000..19b6722
--- /dev/null
+++ b/pkg/tcpip/network/ipv4/ipv4_state_autogen.go
@@ -0,0 +1,113 @@
+// automatically generated by stateify.
+
+package ipv4
+
+import (
+	"gvisor.dev/gvisor/pkg/state"
+)
+
+func (i *icmpv4DestinationUnreachableSockError) StateTypeName() string {
+	return "pkg/tcpip/network/ipv4.icmpv4DestinationUnreachableSockError"
+}
+
+func (i *icmpv4DestinationUnreachableSockError) StateFields() []string {
+	return []string{}
+}
+
+func (i *icmpv4DestinationUnreachableSockError) beforeSave() {}
+
+// +checklocksignore
+func (i *icmpv4DestinationUnreachableSockError) StateSave(stateSinkObject state.Sink) {
+	i.beforeSave()
+}
+
+func (i *icmpv4DestinationUnreachableSockError) afterLoad() {}
+
+// +checklocksignore
+func (i *icmpv4DestinationUnreachableSockError) StateLoad(stateSourceObject state.Source) {
+}
+
+func (i *icmpv4DestinationHostUnreachableSockError) StateTypeName() string {
+	return "pkg/tcpip/network/ipv4.icmpv4DestinationHostUnreachableSockError"
+}
+
+func (i *icmpv4DestinationHostUnreachableSockError) StateFields() []string {
+	return []string{
+		"icmpv4DestinationUnreachableSockError",
+	}
+}
+
+func (i *icmpv4DestinationHostUnreachableSockError) beforeSave() {}
+
+// +checklocksignore
+func (i *icmpv4DestinationHostUnreachableSockError) StateSave(stateSinkObject state.Sink) {
+	i.beforeSave()
+	stateSinkObject.Save(0, &i.icmpv4DestinationUnreachableSockError)
+}
+
+func (i *icmpv4DestinationHostUnreachableSockError) afterLoad() {}
+
+// +checklocksignore
+func (i *icmpv4DestinationHostUnreachableSockError) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &i.icmpv4DestinationUnreachableSockError)
+}
+
+func (i *icmpv4DestinationPortUnreachableSockError) StateTypeName() string {
+	return "pkg/tcpip/network/ipv4.icmpv4DestinationPortUnreachableSockError"
+}
+
+func (i *icmpv4DestinationPortUnreachableSockError) StateFields() []string {
+	return []string{
+		"icmpv4DestinationUnreachableSockError",
+	}
+}
+
+func (i *icmpv4DestinationPortUnreachableSockError) beforeSave() {}
+
+// +checklocksignore
+func (i *icmpv4DestinationPortUnreachableSockError) StateSave(stateSinkObject state.Sink) {
+	i.beforeSave()
+	stateSinkObject.Save(0, &i.icmpv4DestinationUnreachableSockError)
+}
+
+func (i *icmpv4DestinationPortUnreachableSockError) afterLoad() {}
+
+// +checklocksignore
+func (i *icmpv4DestinationPortUnreachableSockError) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &i.icmpv4DestinationUnreachableSockError)
+}
+
+func (e *icmpv4FragmentationNeededSockError) StateTypeName() string {
+	return "pkg/tcpip/network/ipv4.icmpv4FragmentationNeededSockError"
+}
+
+func (e *icmpv4FragmentationNeededSockError) StateFields() []string {
+	return []string{
+		"icmpv4DestinationUnreachableSockError",
+		"mtu",
+	}
+}
+
+func (e *icmpv4FragmentationNeededSockError) beforeSave() {}
+
+// +checklocksignore
+func (e *icmpv4FragmentationNeededSockError) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+	stateSinkObject.Save(0, &e.icmpv4DestinationUnreachableSockError)
+	stateSinkObject.Save(1, &e.mtu)
+}
+
+func (e *icmpv4FragmentationNeededSockError) afterLoad() {}
+
+// +checklocksignore
+func (e *icmpv4FragmentationNeededSockError) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &e.icmpv4DestinationUnreachableSockError)
+	stateSourceObject.Load(1, &e.mtu)
+}
+
+func init() {
+	state.Register((*icmpv4DestinationUnreachableSockError)(nil))
+	state.Register((*icmpv4DestinationHostUnreachableSockError)(nil))
+	state.Register((*icmpv4DestinationPortUnreachableSockError)(nil))
+	state.Register((*icmpv4FragmentationNeededSockError)(nil))
+}
diff --git a/pkg/tcpip/network/ipv4/ipv4_test.go b/pkg/tcpip/network/ipv4/ipv4_test.go
deleted file mode 100644
index cfed241..0000000
--- a/pkg/tcpip/network/ipv4/ipv4_test.go
+++ /dev/null
@@ -1,3106 +0,0 @@
-// Copyright 2021 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 ipv4_test
-
-import (
-	"bytes"
-	"context"
-	"encoding/hex"
-	"fmt"
-	"io/ioutil"
-	"math"
-	"net"
-	"testing"
-	"time"
-
-	"github.com/google/go-cmp/cmp"
-	"gvisor.dev/gvisor/pkg/sync"
-	"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/link/sniffer"
-	"gvisor.dev/gvisor/pkg/tcpip/network/arp"
-	"gvisor.dev/gvisor/pkg/tcpip/network/internal/testutil"
-	"gvisor.dev/gvisor/pkg/tcpip/network/ipv4"
-	"gvisor.dev/gvisor/pkg/tcpip/stack"
-	"gvisor.dev/gvisor/pkg/tcpip/transport/icmp"
-	"gvisor.dev/gvisor/pkg/tcpip/transport/raw"
-	"gvisor.dev/gvisor/pkg/tcpip/transport/tcp"
-	"gvisor.dev/gvisor/pkg/tcpip/transport/udp"
-	"gvisor.dev/gvisor/pkg/waiter"
-)
-
-const (
-	extraHeaderReserve = 50
-	defaultMTU         = 65536
-)
-
-func TestExcludeBroadcast(t *testing.T) {
-	s := stack.New(stack.Options{
-		NetworkProtocols:   []stack.NetworkProtocolFactory{ipv4.NewProtocol},
-		TransportProtocols: []stack.TransportProtocolFactory{udp.NewProtocol},
-	})
-
-	ep := stack.LinkEndpoint(channel.New(256, defaultMTU, ""))
-	if testing.Verbose() {
-		ep = sniffer.New(ep)
-	}
-	if err := s.CreateNIC(1, ep); err != nil {
-		t.Fatalf("CreateNIC failed: %v", err)
-	}
-
-	s.SetRouteTable([]tcpip.Route{{
-		Destination: header.IPv4EmptySubnet,
-		NIC:         1,
-	}})
-
-	randomAddr := tcpip.FullAddress{NIC: 1, Addr: "\x0a\x00\x00\x01", Port: 53}
-
-	var wq waiter.Queue
-	t.Run("WithoutPrimaryAddress", func(t *testing.T) {
-		ep, err := s.NewEndpoint(udp.ProtocolNumber, ipv4.ProtocolNumber, &wq)
-		if err != nil {
-			t.Fatal(err)
-		}
-		defer ep.Close()
-
-		// Cannot connect using a broadcast address as the source.
-		{
-			err := ep.Connect(randomAddr)
-			if _, ok := err.(*tcpip.ErrNoRoute); !ok {
-				t.Errorf("got ep.Connect(...) = %v, want = %v", err, &tcpip.ErrNoRoute{})
-			}
-		}
-
-		// However, we can bind to a broadcast address to listen.
-		if err := ep.Bind(tcpip.FullAddress{Addr: header.IPv4Broadcast, Port: 53, NIC: 1}); err != nil {
-			t.Errorf("Bind failed: %v", err)
-		}
-	})
-
-	t.Run("WithPrimaryAddress", func(t *testing.T) {
-		ep, err := s.NewEndpoint(udp.ProtocolNumber, ipv4.ProtocolNumber, &wq)
-		if err != nil {
-			t.Fatal(err)
-		}
-		defer ep.Close()
-
-		// Add a valid primary endpoint address, now we can connect.
-		if err := s.AddAddress(1, ipv4.ProtocolNumber, "\x0a\x00\x00\x02"); err != nil {
-			t.Fatalf("AddAddress failed: %v", err)
-		}
-		if err := ep.Connect(randomAddr); err != nil {
-			t.Errorf("Connect failed: %v", err)
-		}
-	})
-}
-
-func TestForwarding(t *testing.T) {
-	const (
-		nicID1           = 1
-		nicID2           = 2
-		randomSequence   = 123
-		randomIdent      = 42
-		randomTimeOffset = 0x10203040
-	)
-
-	ipv4Addr1 := tcpip.AddressWithPrefix{
-		Address:   tcpip.Address(net.ParseIP("10.0.0.1").To4()),
-		PrefixLen: 8,
-	}
-	ipv4Addr2 := tcpip.AddressWithPrefix{
-		Address:   tcpip.Address(net.ParseIP("11.0.0.1").To4()),
-		PrefixLen: 8,
-	}
-	remoteIPv4Addr1 := tcpip.Address(net.ParseIP("10.0.0.2").To4())
-	remoteIPv4Addr2 := tcpip.Address(net.ParseIP("11.0.0.2").To4())
-
-	tests := []struct {
-		name             string
-		TTL              uint8
-		expectErrorICMP  bool
-		options          header.IPv4Options
-		forwardedOptions header.IPv4Options
-		icmpType         header.ICMPv4Type
-		icmpCode         header.ICMPv4Code
-	}{
-		{
-			name:            "TTL of zero",
-			TTL:             0,
-			expectErrorICMP: true,
-			icmpType:        header.ICMPv4TimeExceeded,
-			icmpCode:        header.ICMPv4TTLExceeded,
-		},
-		{
-			name:            "TTL of one",
-			TTL:             1,
-			expectErrorICMP: false,
-		},
-		{
-			name:            "TTL of two",
-			TTL:             2,
-			expectErrorICMP: false,
-		},
-		{
-			name:            "Max TTL",
-			TTL:             math.MaxUint8,
-			expectErrorICMP: false,
-		},
-		{
-			name:             "four EOL options",
-			TTL:              2,
-			expectErrorICMP:  false,
-			options:          header.IPv4Options{0, 0, 0, 0},
-			forwardedOptions: header.IPv4Options{0, 0, 0, 0},
-		},
-		{
-			name: "TS type 1 full",
-			TTL:  2,
-			options: header.IPv4Options{
-				68, 12, 13, 0xF1,
-				192, 168, 1, 12,
-				1, 2, 3, 4,
-			},
-			expectErrorICMP: true,
-			icmpType:        header.ICMPv4ParamProblem,
-			icmpCode:        header.ICMPv4UnusedCode,
-		},
-		{
-			name: "TS type 0",
-			TTL:  2,
-			options: header.IPv4Options{
-				68, 24, 21, 0x00,
-				1, 2, 3, 4,
-				5, 6, 7, 8,
-				9, 10, 11, 12,
-				13, 14, 15, 16,
-				0, 0, 0, 0,
-			},
-			forwardedOptions: header.IPv4Options{
-				68, 24, 25, 0x00,
-				1, 2, 3, 4,
-				5, 6, 7, 8,
-				9, 10, 11, 12,
-				13, 14, 15, 16,
-				0x00, 0xad, 0x1c, 0x40, // time we expect from fakeclock
-			},
-		},
-		{
-			name: "end of options list",
-			TTL:  2,
-			options: header.IPv4Options{
-				68, 12, 13, 0x11,
-				192, 168, 1, 12,
-				1, 2, 3, 4,
-				0, 10, 3, 99, // EOL followed by junk
-				1, 2, 3, 4,
-			},
-			forwardedOptions: header.IPv4Options{
-				68, 12, 13, 0x21,
-				192, 168, 1, 12,
-				1, 2, 3, 4,
-				0,       // End of Options hides following bytes.
-				0, 0, 0, // 7 bytes unknown option removed.
-				0, 0, 0, 0,
-			},
-		},
-	}
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			clock := faketime.NewManualClock()
-			s := stack.New(stack.Options{
-				NetworkProtocols:   []stack.NetworkProtocolFactory{ipv4.NewProtocol},
-				TransportProtocols: []stack.TransportProtocolFactory{icmp.NewProtocol4},
-				Clock:              clock,
-			})
-
-			// Advance the clock by some unimportant amount to make
-			// it give a more recognisable signature than 00,00,00,00.
-			clock.Advance(time.Millisecond * randomTimeOffset)
-
-			// We expect at most a single packet in response to our ICMP Echo Request.
-			e1 := channel.New(1, ipv4.MaxTotalSize, "")
-			if err := s.CreateNIC(nicID1, e1); err != nil {
-				t.Fatalf("CreateNIC(%d, _): %s", nicID1, err)
-			}
-			ipv4ProtoAddr1 := tcpip.ProtocolAddress{Protocol: header.IPv4ProtocolNumber, AddressWithPrefix: ipv4Addr1}
-			if err := s.AddProtocolAddress(nicID1, ipv4ProtoAddr1); err != nil {
-				t.Fatalf("AddProtocolAddress(%d, %#v): %s", nicID1, ipv4ProtoAddr1, err)
-			}
-
-			e2 := channel.New(1, ipv4.MaxTotalSize, "")
-			if err := s.CreateNIC(nicID2, e2); err != nil {
-				t.Fatalf("CreateNIC(%d, _): %s", nicID2, err)
-			}
-			ipv4ProtoAddr2 := tcpip.ProtocolAddress{Protocol: header.IPv4ProtocolNumber, AddressWithPrefix: ipv4Addr2}
-			if err := s.AddProtocolAddress(nicID2, ipv4ProtoAddr2); err != nil {
-				t.Fatalf("AddProtocolAddress(%d, %#v): %s", nicID2, ipv4ProtoAddr2, err)
-			}
-
-			s.SetRouteTable([]tcpip.Route{
-				{
-					Destination: ipv4Addr1.Subnet(),
-					NIC:         nicID1,
-				},
-				{
-					Destination: ipv4Addr2.Subnet(),
-					NIC:         nicID2,
-				},
-			})
-
-			if err := s.SetForwarding(header.IPv4ProtocolNumber, true); err != nil {
-				t.Fatalf("SetForwarding(%d, true): %s", header.IPv4ProtocolNumber, err)
-			}
-
-			ipHeaderLength := header.IPv4MinimumSize + len(test.options)
-			if ipHeaderLength > header.IPv4MaximumHeaderSize {
-				t.Fatalf("got ipHeaderLength = %d, want <= %d ", ipHeaderLength, header.IPv4MaximumHeaderSize)
-			}
-			totalLen := uint16(ipHeaderLength + header.ICMPv4MinimumSize)
-			hdr := buffer.NewPrependable(int(totalLen))
-			icmp := header.ICMPv4(hdr.Prepend(header.ICMPv4MinimumSize))
-			icmp.SetIdent(randomIdent)
-			icmp.SetSequence(randomSequence)
-			icmp.SetType(header.ICMPv4Echo)
-			icmp.SetCode(header.ICMPv4UnusedCode)
-			icmp.SetChecksum(0)
-			icmp.SetChecksum(^header.Checksum(icmp, 0))
-			ip := header.IPv4(hdr.Prepend(ipHeaderLength))
-			ip.Encode(&header.IPv4Fields{
-				TotalLength: totalLen,
-				Protocol:    uint8(header.ICMPv4ProtocolNumber),
-				TTL:         test.TTL,
-				SrcAddr:     remoteIPv4Addr1,
-				DstAddr:     remoteIPv4Addr2,
-			})
-			if len(test.options) != 0 {
-				ip.SetHeaderLength(uint8(ipHeaderLength))
-				// Copy options manually. We do not use Encode for options so we can
-				// verify malformed options with handcrafted payloads.
-				if want, got := copy(ip.Options(), test.options), len(test.options); want != got {
-					t.Fatalf("got copy(ip.Options(), test.options) = %d, want = %d", got, want)
-				}
-			}
-			ip.SetChecksum(0)
-			ip.SetChecksum(^ip.CalculateChecksum())
-			requestPkt := stack.NewPacketBuffer(stack.PacketBufferOptions{
-				Data: hdr.View().ToVectorisedView(),
-			})
-			e1.InjectInbound(header.IPv4ProtocolNumber, requestPkt)
-
-			if test.expectErrorICMP {
-				reply, ok := e1.Read()
-				if !ok {
-					t.Fatalf("expected ICMP packet type %d through incoming NIC", test.icmpType)
-				}
-
-				checker.IPv4(t, header.IPv4(stack.PayloadSince(reply.Pkt.NetworkHeader())),
-					checker.SrcAddr(ipv4Addr1.Address),
-					checker.DstAddr(remoteIPv4Addr1),
-					checker.TTL(ipv4.DefaultTTL),
-					checker.ICMPv4(
-						checker.ICMPv4Checksum(),
-						checker.ICMPv4Type(test.icmpType),
-						checker.ICMPv4Code(test.icmpCode),
-						checker.ICMPv4Payload([]byte(hdr.View())),
-					),
-				)
-
-				if n := e2.Drain(); n != 0 {
-					t.Fatalf("got e2.Drain() = %d, want = 0", n)
-				}
-			} else {
-				reply, ok := e2.Read()
-				if !ok {
-					t.Fatal("expected ICMP Echo packet through outgoing NIC")
-				}
-
-				checker.IPv4(t, header.IPv4(stack.PayloadSince(reply.Pkt.NetworkHeader())),
-					checker.SrcAddr(remoteIPv4Addr1),
-					checker.DstAddr(remoteIPv4Addr2),
-					checker.TTL(test.TTL-1),
-					checker.IPv4Options(test.forwardedOptions),
-					checker.ICMPv4(
-						checker.ICMPv4Checksum(),
-						checker.ICMPv4Type(header.ICMPv4Echo),
-						checker.ICMPv4Code(header.ICMPv4UnusedCode),
-						checker.ICMPv4Payload(nil),
-					),
-				)
-
-				if n := e1.Drain(); n != 0 {
-					t.Fatalf("got e1.Drain() = %d, want = 0", n)
-				}
-			}
-		})
-	}
-}
-
-// TestIPv4Sanity sends IP/ICMP packets with various problems to the stack and
-// checks the response.
-func TestIPv4Sanity(t *testing.T) {
-	const (
-		ttl            = 255
-		nicID          = 1
-		randomSequence = 123
-		randomIdent    = 42
-		// In some cases Linux sets the error pointer to the start of the option
-		// (offset 0) instead of the actual wrong value, which is the length byte
-		// (offset 1). For compatibility we must do the same. Use this constant
-		// to indicate where this happens.
-		pointerOffsetForInvalidLength = 0
-		randomTimeOffset              = 0x10203040
-	)
-	var (
-		ipv4Addr = tcpip.AddressWithPrefix{
-			Address:   tcpip.Address(net.ParseIP("192.168.1.58").To4()),
-			PrefixLen: 24,
-		}
-		remoteIPv4Addr = tcpip.Address(net.ParseIP("10.0.0.1").To4())
-	)
-
-	tests := []struct {
-		name                string
-		headerLength        uint8 // value of 0 means "use correct size"
-		badHeaderChecksum   bool
-		maxTotalLength      uint16
-		transportProtocol   uint8
-		TTL                 uint8
-		options             header.IPv4Options
-		replyOptions        header.IPv4Options // reply should look like this
-		shouldFail          bool
-		expectErrorICMP     bool
-		ICMPType            header.ICMPv4Type
-		ICMPCode            header.ICMPv4Code
-		paramProblemPointer uint8
-	}{
-		{
-			name:              "valid no options",
-			maxTotalLength:    ipv4.MaxTotalSize,
-			transportProtocol: uint8(header.ICMPv4ProtocolNumber),
-			TTL:               ttl,
-		},
-		{
-			name:              "bad header checksum",
-			maxTotalLength:    ipv4.MaxTotalSize,
-			transportProtocol: uint8(header.ICMPv4ProtocolNumber),
-			TTL:               ttl,
-			badHeaderChecksum: true,
-			shouldFail:        true,
-		},
-		// The TTL tests check that we are not rejecting an incoming packet
-		// with a zero or one TTL, which has been a point of confusion in the
-		// past as RFC 791 says: "If this field contains the value zero, then the
-		// datagram must be destroyed". However RFC 1122 section 3.2.1.7 clarifies
-		// for the case of the destination host, stating as follows.
-		//
-		//      A host MUST NOT send a datagram with a Time-to-Live (TTL)
-		//      value of zero.
-		//
-		//      A host MUST NOT discard a datagram just because it was
-		//      received with TTL less than 2.
-		{
-			name:              "zero TTL",
-			maxTotalLength:    ipv4.MaxTotalSize,
-			transportProtocol: uint8(header.ICMPv4ProtocolNumber),
-			TTL:               0,
-		},
-		{
-			name:              "one TTL",
-			maxTotalLength:    ipv4.MaxTotalSize,
-			transportProtocol: uint8(header.ICMPv4ProtocolNumber),
-			TTL:               1,
-		},
-		{
-			name:              "End options",
-			maxTotalLength:    ipv4.MaxTotalSize,
-			transportProtocol: uint8(header.ICMPv4ProtocolNumber),
-			TTL:               ttl,
-			options:           header.IPv4Options{0, 0, 0, 0},
-			replyOptions:      header.IPv4Options{0, 0, 0, 0},
-		},
-		{
-			name:              "NOP options",
-			maxTotalLength:    ipv4.MaxTotalSize,
-			transportProtocol: uint8(header.ICMPv4ProtocolNumber),
-			TTL:               ttl,
-			options:           header.IPv4Options{1, 1, 1, 1},
-			replyOptions:      header.IPv4Options{1, 1, 1, 1},
-		},
-		{
-			name:              "NOP and End options",
-			maxTotalLength:    ipv4.MaxTotalSize,
-			transportProtocol: uint8(header.ICMPv4ProtocolNumber),
-			TTL:               ttl,
-			options:           header.IPv4Options{1, 1, 0, 0},
-			replyOptions:      header.IPv4Options{1, 1, 0, 0},
-		},
-		{
-			name:              "bad header length",
-			headerLength:      header.IPv4MinimumSize - 1,
-			maxTotalLength:    ipv4.MaxTotalSize,
-			transportProtocol: uint8(header.ICMPv4ProtocolNumber),
-			TTL:               ttl,
-			shouldFail:        true,
-		},
-		{
-			name:              "bad total length (0)",
-			maxTotalLength:    0,
-			transportProtocol: uint8(header.ICMPv4ProtocolNumber),
-			TTL:               ttl,
-			shouldFail:        true,
-		},
-		{
-			name:              "bad total length (ip - 1)",
-			maxTotalLength:    uint16(header.IPv4MinimumSize - 1),
-			transportProtocol: uint8(header.ICMPv4ProtocolNumber),
-			TTL:               ttl,
-			shouldFail:        true,
-		},
-		{
-			name:              "bad total length (ip + icmp - 1)",
-			maxTotalLength:    uint16(header.IPv4MinimumSize + header.ICMPv4MinimumSize - 1),
-			transportProtocol: uint8(header.ICMPv4ProtocolNumber),
-			TTL:               ttl,
-			shouldFail:        true,
-		},
-		{
-			name:              "bad protocol",
-			maxTotalLength:    ipv4.MaxTotalSize,
-			transportProtocol: 99,
-			TTL:               ttl,
-			shouldFail:        true,
-			expectErrorICMP:   true,
-			ICMPType:          header.ICMPv4DstUnreachable,
-			ICMPCode:          header.ICMPv4ProtoUnreachable,
-		},
-		{
-			name:              "timestamp option overflow",
-			maxTotalLength:    ipv4.MaxTotalSize,
-			transportProtocol: uint8(header.ICMPv4ProtocolNumber),
-			TTL:               ttl,
-			options: header.IPv4Options{
-				68, 12, 13, 0x11,
-				192, 168, 1, 12,
-				1, 2, 3, 4,
-			},
-			replyOptions: header.IPv4Options{
-				68, 12, 13, 0x21,
-				192, 168, 1, 12,
-				1, 2, 3, 4,
-			},
-		},
-		{
-			name:              "timestamp option overflow full",
-			maxTotalLength:    ipv4.MaxTotalSize,
-			transportProtocol: uint8(header.ICMPv4ProtocolNumber),
-			TTL:               ttl,
-			options: header.IPv4Options{
-				68, 12, 13, 0xF1,
-				//            ^   Counter full (15/0xF)
-				192, 168, 1, 12,
-				1, 2, 3, 4,
-			},
-			shouldFail:          true,
-			expectErrorICMP:     true,
-			ICMPType:            header.ICMPv4ParamProblem,
-			ICMPCode:            header.ICMPv4UnusedCode,
-			paramProblemPointer: header.IPv4MinimumSize + 3,
-			replyOptions:        header.IPv4Options{},
-		},
-		{
-			name:              "unknown option",
-			maxTotalLength:    ipv4.MaxTotalSize,
-			transportProtocol: uint8(header.ICMPv4ProtocolNumber),
-			TTL:               ttl,
-			options:           header.IPv4Options{10, 4, 9, 0},
-			//                        ^^
-			// The unknown option should be stripped out of the reply.
-			replyOptions: header.IPv4Options{},
-		},
-		{
-			name:              "bad option - no length",
-			maxTotalLength:    ipv4.MaxTotalSize,
-			transportProtocol: uint8(header.ICMPv4ProtocolNumber),
-			TTL:               ttl,
-			options: header.IPv4Options{
-				1, 1, 1, 68,
-				//        ^-start of timestamp.. but no length..
-			},
-			shouldFail:          true,
-			expectErrorICMP:     true,
-			ICMPType:            header.ICMPv4ParamProblem,
-			ICMPCode:            header.ICMPv4UnusedCode,
-			paramProblemPointer: header.IPv4MinimumSize + 3,
-		},
-		{
-			name:              "bad option - length 0",
-			maxTotalLength:    ipv4.MaxTotalSize,
-			transportProtocol: uint8(header.ICMPv4ProtocolNumber),
-			TTL:               ttl,
-			options: header.IPv4Options{
-				68, 0, 9, 0,
-				//  ^
-				1, 2, 3, 4,
-			},
-			shouldFail:          true,
-			expectErrorICMP:     true,
-			ICMPType:            header.ICMPv4ParamProblem,
-			ICMPCode:            header.ICMPv4UnusedCode,
-			paramProblemPointer: header.IPv4MinimumSize + pointerOffsetForInvalidLength,
-		},
-		{
-			name:              "bad option - length 1",
-			maxTotalLength:    ipv4.MaxTotalSize,
-			transportProtocol: uint8(header.ICMPv4ProtocolNumber),
-			TTL:               ttl,
-			options: header.IPv4Options{
-				68, 1, 9, 0,
-				//  ^
-				1, 2, 3, 4,
-			},
-			shouldFail:          true,
-			expectErrorICMP:     true,
-			ICMPType:            header.ICMPv4ParamProblem,
-			ICMPCode:            header.ICMPv4UnusedCode,
-			paramProblemPointer: header.IPv4MinimumSize + pointerOffsetForInvalidLength,
-		},
-		{
-			name:              "bad option - length big",
-			maxTotalLength:    ipv4.MaxTotalSize,
-			transportProtocol: uint8(header.ICMPv4ProtocolNumber),
-			TTL:               ttl,
-			options: header.IPv4Options{
-				68, 9, 9, 0,
-				//  ^
-				// There are only 8 bytes allocated to options so 9 bytes of timestamp
-				// space is not possible. (Second byte)
-				1, 2, 3, 4,
-			},
-			shouldFail:          true,
-			expectErrorICMP:     true,
-			ICMPType:            header.ICMPv4ParamProblem,
-			ICMPCode:            header.ICMPv4UnusedCode,
-			paramProblemPointer: header.IPv4MinimumSize + pointerOffsetForInvalidLength,
-		},
-		{
-			// This tests for some linux compatible behaviour.
-			// The ICMP pointer returned is 22 for Linux but the
-			// error is actually in spot 21.
-			name:              "bad option - length bad",
-			maxTotalLength:    ipv4.MaxTotalSize,
-			transportProtocol: uint8(header.ICMPv4ProtocolNumber),
-			TTL:               ttl,
-			// Timestamps are in multiples of 4 or 8 but never 7.
-			// The option space should be padded out.
-			options: header.IPv4Options{
-				68, 7, 5, 0,
-				//  ^  ^ Linux points here which is wrong.
-				//  | Not a multiple of 4
-				1, 2, 3, 0,
-			},
-			shouldFail:          true,
-			expectErrorICMP:     true,
-			ICMPType:            header.ICMPv4ParamProblem,
-			ICMPCode:            header.ICMPv4UnusedCode,
-			paramProblemPointer: header.IPv4MinimumSize + header.IPv4OptTSPointerOffset,
-		},
-		{
-			name:              "multiple type 0 with room",
-			maxTotalLength:    ipv4.MaxTotalSize,
-			transportProtocol: uint8(header.ICMPv4ProtocolNumber),
-			TTL:               ttl,
-			options: header.IPv4Options{
-				68, 24, 21, 0x00,
-				1, 2, 3, 4,
-				5, 6, 7, 8,
-				9, 10, 11, 12,
-				13, 14, 15, 16,
-				0, 0, 0, 0,
-			},
-			replyOptions: header.IPv4Options{
-				68, 24, 25, 0x00,
-				1, 2, 3, 4,
-				5, 6, 7, 8,
-				9, 10, 11, 12,
-				13, 14, 15, 16,
-				0x00, 0xad, 0x1c, 0x40, // time we expect from fakeclock
-			},
-		},
-		{
-			// The timestamp area is full so add to the overflow count.
-			name:              "multiple type 1 timestamps",
-			maxTotalLength:    ipv4.MaxTotalSize,
-			transportProtocol: uint8(header.ICMPv4ProtocolNumber),
-			TTL:               ttl,
-			options: header.IPv4Options{
-				68, 20, 21, 0x11,
-				//            ^
-				192, 168, 1, 12,
-				1, 2, 3, 4,
-				192, 168, 1, 13,
-				5, 6, 7, 8,
-			},
-			// Overflow count is the top nibble of the 4th byte.
-			replyOptions: header.IPv4Options{
-				68, 20, 21, 0x21,
-				//            ^
-				192, 168, 1, 12,
-				1, 2, 3, 4,
-				192, 168, 1, 13,
-				5, 6, 7, 8,
-			},
-		},
-		{
-			name:              "multiple type 1 timestamps with room",
-			maxTotalLength:    ipv4.MaxTotalSize,
-			transportProtocol: uint8(header.ICMPv4ProtocolNumber),
-			TTL:               ttl,
-			options: header.IPv4Options{
-				68, 28, 21, 0x01,
-				192, 168, 1, 12,
-				1, 2, 3, 4,
-				192, 168, 1, 13,
-				5, 6, 7, 8,
-				0, 0, 0, 0,
-				0, 0, 0, 0,
-			},
-			replyOptions: header.IPv4Options{
-				68, 28, 29, 0x01,
-				192, 168, 1, 12,
-				1, 2, 3, 4,
-				192, 168, 1, 13,
-				5, 6, 7, 8,
-				192, 168, 1, 58, // New IP Address.
-				0x00, 0xad, 0x1c, 0x40, // time we expect from fakeclock
-			},
-		},
-		{
-			// Timestamp pointer uses one based counting so 0 is invalid.
-			name:              "timestamp pointer invalid",
-			maxTotalLength:    ipv4.MaxTotalSize,
-			transportProtocol: uint8(header.ICMPv4ProtocolNumber),
-			TTL:               ttl,
-			options: header.IPv4Options{
-				68, 8, 0, 0x00,
-				//      ^ 0 instead of 5 or more.
-				0, 0, 0, 0,
-			},
-			shouldFail:          true,
-			expectErrorICMP:     true,
-			ICMPType:            header.ICMPv4ParamProblem,
-			ICMPCode:            header.ICMPv4UnusedCode,
-			paramProblemPointer: header.IPv4MinimumSize + 2,
-		},
-		{
-			// Timestamp pointer cannot be less than 5. It must point past the header
-			// which is 4 bytes. (1 based counting)
-			name:              "timestamp pointer too small by 1",
-			maxTotalLength:    ipv4.MaxTotalSize,
-			transportProtocol: uint8(header.ICMPv4ProtocolNumber),
-			TTL:               ttl,
-			options: header.IPv4Options{
-				68, 8, header.IPv4OptionTimestampHdrLength, 0x00,
-				//          ^ header is 4 bytes, so 4 should fail.
-				0, 0, 0, 0,
-			},
-			shouldFail:          true,
-			expectErrorICMP:     true,
-			ICMPType:            header.ICMPv4ParamProblem,
-			ICMPCode:            header.ICMPv4UnusedCode,
-			paramProblemPointer: header.IPv4MinimumSize + header.IPv4OptTSPointerOffset,
-		},
-		{
-			name:              "valid timestamp pointer",
-			maxTotalLength:    ipv4.MaxTotalSize,
-			transportProtocol: uint8(header.ICMPv4ProtocolNumber),
-			TTL:               ttl,
-			options: header.IPv4Options{
-				68, 8, header.IPv4OptionTimestampHdrLength + 1, 0x00,
-				//          ^ header is 4 bytes, so 5 should succeed.
-				0, 0, 0, 0,
-			},
-			replyOptions: header.IPv4Options{
-				68, 8, 9, 0x00,
-				0x00, 0xad, 0x1c, 0x40, // time we expect from fakeclock
-			},
-		},
-		{
-			// Needs 8 bytes for a type 1 timestamp but there are only 4 free.
-			name:              "bad timer element alignment",
-			maxTotalLength:    ipv4.MaxTotalSize,
-			transportProtocol: uint8(header.ICMPv4ProtocolNumber),
-			TTL:               ttl,
-			options: header.IPv4Options{
-				68, 20, 17, 0x01,
-				//  ^^  ^^   20 byte area, next free spot at 17.
-				192, 168, 1, 12,
-				1, 2, 3, 4,
-				0, 0, 0, 0,
-				0, 0, 0, 0,
-			},
-			shouldFail:          true,
-			expectErrorICMP:     true,
-			ICMPType:            header.ICMPv4ParamProblem,
-			ICMPCode:            header.ICMPv4UnusedCode,
-			paramProblemPointer: header.IPv4MinimumSize + header.IPv4OptTSPointerOffset,
-		},
-		// End of option list with illegal option after it, which should be ignored.
-		{
-			name:              "end of options list",
-			maxTotalLength:    ipv4.MaxTotalSize,
-			transportProtocol: uint8(header.ICMPv4ProtocolNumber),
-			TTL:               ttl,
-			options: header.IPv4Options{
-				68, 12, 13, 0x11,
-				192, 168, 1, 12,
-				1, 2, 3, 4,
-				0, 10, 3, 99, // EOL followed by junk
-			},
-			replyOptions: header.IPv4Options{
-				68, 12, 13, 0x21,
-				192, 168, 1, 12,
-				1, 2, 3, 4,
-				0,       // End of Options hides following bytes.
-				0, 0, 0, // 3 bytes unknown option removed.
-			},
-		},
-		{
-			// Timestamp with a size much too small.
-			name:              "timestamp truncated",
-			maxTotalLength:    ipv4.MaxTotalSize,
-			transportProtocol: uint8(header.ICMPv4ProtocolNumber),
-			TTL:               ttl,
-			options: header.IPv4Options{
-				68, 1, 0, 0,
-				//  ^ Smallest possible is 8. Linux points at the 68.
-			},
-			shouldFail:          true,
-			expectErrorICMP:     true,
-			ICMPType:            header.ICMPv4ParamProblem,
-			ICMPCode:            header.ICMPv4UnusedCode,
-			paramProblemPointer: header.IPv4MinimumSize + pointerOffsetForInvalidLength,
-		},
-		{
-			name:              "single record route with room",
-			maxTotalLength:    ipv4.MaxTotalSize,
-			transportProtocol: uint8(header.ICMPv4ProtocolNumber),
-			TTL:               ttl,
-			options: header.IPv4Options{
-				7, 7, 4, //  3 byte header
-				0, 0, 0, 0,
-				0,
-			},
-			replyOptions: header.IPv4Options{
-				7, 7, 8, // 3 byte header
-				192, 168, 1, 58, // New IP Address.
-				0, // padding to multiple of 4 bytes.
-			},
-		},
-		{
-			name:              "multiple record route with room",
-			maxTotalLength:    ipv4.MaxTotalSize,
-			transportProtocol: uint8(header.ICMPv4ProtocolNumber),
-			TTL:               ttl,
-			options: header.IPv4Options{
-				7, 23, 20, //  3 byte header
-				1, 2, 3, 4,
-				5, 6, 7, 8,
-				9, 10, 11, 12,
-				13, 14, 15, 16,
-				0, 0, 0, 0,
-				0,
-			},
-			replyOptions: header.IPv4Options{
-				7, 23, 24,
-				1, 2, 3, 4,
-				5, 6, 7, 8,
-				9, 10, 11, 12,
-				13, 14, 15, 16,
-				192, 168, 1, 58, // New IP Address.
-				0, // padding to multiple of 4 bytes.
-			},
-		},
-		{
-			name:              "single record route with no room",
-			maxTotalLength:    ipv4.MaxTotalSize,
-			transportProtocol: uint8(header.ICMPv4ProtocolNumber),
-			TTL:               ttl,
-			options: header.IPv4Options{
-				7, 7, 8, // 3 byte header
-				1, 2, 3, 4,
-				0,
-			},
-			replyOptions: header.IPv4Options{
-				7, 7, 8, // 3 byte header
-				1, 2, 3, 4,
-				0, // padding to multiple of 4 bytes.
-			},
-		},
-		{
-			// Unlike timestamp, this should just succeed.
-			name:              "multiple record route with no room",
-			maxTotalLength:    ipv4.MaxTotalSize,
-			transportProtocol: uint8(header.ICMPv4ProtocolNumber),
-			TTL:               ttl,
-			options: header.IPv4Options{
-				7, 23, 24, // 3 byte header
-				1, 2, 3, 4,
-				5, 6, 7, 8,
-				9, 10, 11, 12,
-				13, 14, 15, 16,
-				17, 18, 19, 20,
-				0,
-			},
-			replyOptions: header.IPv4Options{
-				7, 23, 24,
-				1, 2, 3, 4,
-				5, 6, 7, 8,
-				9, 10, 11, 12,
-				13, 14, 15, 16,
-				17, 18, 19, 20,
-				0, // padding to multiple of 4 bytes.
-			},
-		},
-		{
-			// Pointer uses one based counting so 0 is invalid.
-			name:              "record route pointer zero",
-			maxTotalLength:    ipv4.MaxTotalSize,
-			transportProtocol: uint8(header.ICMPv4ProtocolNumber),
-			TTL:               ttl,
-			options: header.IPv4Options{
-				7, 8, 0, // 3 byte header
-				0, 0, 0, 0,
-				0,
-			},
-			shouldFail:          true,
-			expectErrorICMP:     true,
-			ICMPType:            header.ICMPv4ParamProblem,
-			ICMPCode:            header.ICMPv4UnusedCode,
-			paramProblemPointer: header.IPv4MinimumSize + header.IPv4OptRRPointerOffset,
-		},
-		{
-			// Pointer must be 4 or more as it must point past the 3 byte header
-			// using 1 based counting. 3 should fail.
-			name:              "record route pointer too small by 1",
-			maxTotalLength:    ipv4.MaxTotalSize,
-			transportProtocol: uint8(header.ICMPv4ProtocolNumber),
-			TTL:               ttl,
-			options: header.IPv4Options{
-				7, 8, header.IPv4OptionRecordRouteHdrLength, // 3 byte header
-				0, 0, 0, 0,
-				0,
-			},
-			shouldFail:          true,
-			expectErrorICMP:     true,
-			ICMPType:            header.ICMPv4ParamProblem,
-			ICMPCode:            header.ICMPv4UnusedCode,
-			paramProblemPointer: header.IPv4MinimumSize + header.IPv4OptRRPointerOffset,
-		},
-		{
-			// Pointer must be 4 or more as it must point past the 3 byte header
-			// using 1 based counting. Check 4 passes. (Duplicates "single
-			// record route with room")
-			name:              "valid record route pointer",
-			maxTotalLength:    ipv4.MaxTotalSize,
-			transportProtocol: uint8(header.ICMPv4ProtocolNumber),
-			TTL:               ttl,
-			options: header.IPv4Options{
-				7, 7, header.IPv4OptionRecordRouteHdrLength + 1, // 3 byte header
-				0, 0, 0, 0,
-				0,
-			},
-			replyOptions: header.IPv4Options{
-				7, 7, 8, // 3 byte header
-				192, 168, 1, 58, // New IP Address.
-				0, // padding to multiple of 4 bytes.
-			},
-		},
-		{
-			// Confirm Linux bug for bug compatibility.
-			// Linux returns slot 22 but the error is in slot 21.
-			name:              "multiple record route with not enough room",
-			maxTotalLength:    ipv4.MaxTotalSize,
-			transportProtocol: uint8(header.ICMPv4ProtocolNumber),
-			TTL:               ttl,
-			options: header.IPv4Options{
-				7, 8, 8, // 3 byte header
-				// ^  ^ Linux points here. We must too.
-				// | Not enough room. 1 byte free, need 4.
-				1, 2, 3, 4,
-				0,
-			},
-			shouldFail:          true,
-			expectErrorICMP:     true,
-			ICMPType:            header.ICMPv4ParamProblem,
-			ICMPCode:            header.ICMPv4UnusedCode,
-			paramProblemPointer: header.IPv4MinimumSize + header.IPv4OptRRPointerOffset,
-		},
-		{
-			name:              "duplicate record route",
-			maxTotalLength:    ipv4.MaxTotalSize,
-			transportProtocol: uint8(header.ICMPv4ProtocolNumber),
-			TTL:               ttl,
-			options: header.IPv4Options{
-				7, 7, 8, // 3 byte header
-				1, 2, 3, 4,
-				7, 7, 8, // 3 byte header
-				1, 2, 3, 4,
-				0, 0, // pad
-			},
-			shouldFail:          true,
-			expectErrorICMP:     true,
-			ICMPType:            header.ICMPv4ParamProblem,
-			ICMPCode:            header.ICMPv4UnusedCode,
-			paramProblemPointer: header.IPv4MinimumSize + 7,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			clock := faketime.NewManualClock()
-			s := stack.New(stack.Options{
-				NetworkProtocols:   []stack.NetworkProtocolFactory{ipv4.NewProtocol},
-				TransportProtocols: []stack.TransportProtocolFactory{icmp.NewProtocol4},
-				Clock:              clock,
-			})
-			// Advance the clock by some unimportant amount to make
-			// it give a more recognisable signature than 00,00,00,00.
-			clock.Advance(time.Millisecond * randomTimeOffset)
-
-			// We expect at most a single packet in response to our ICMP Echo Request.
-			e := channel.New(1, ipv4.MaxTotalSize, "")
-			if err := s.CreateNIC(nicID, e); err != nil {
-				t.Fatalf("CreateNIC(%d, _): %s", nicID, err)
-			}
-			ipv4ProtoAddr := tcpip.ProtocolAddress{Protocol: header.IPv4ProtocolNumber, AddressWithPrefix: ipv4Addr}
-			if err := s.AddProtocolAddress(nicID, ipv4ProtoAddr); err != nil {
-				t.Fatalf("AddProtocolAddress(%d, %#v): %s", nicID, ipv4ProtoAddr, err)
-			}
-
-			// Default routes for IPv4 so ICMP can find a route to the remote
-			// node when attempting to send the ICMP Echo Reply.
-			s.SetRouteTable([]tcpip.Route{
-				{
-					Destination: header.IPv4EmptySubnet,
-					NIC:         nicID,
-				},
-			})
-
-			if len(test.options)%4 != 0 {
-				t.Fatalf("options must be aligned to 32 bits, invalid test options: %x (len=%d)", test.options, len(test.options))
-			}
-			ipHeaderLength := header.IPv4MinimumSize + len(test.options)
-			if ipHeaderLength > header.IPv4MaximumHeaderSize {
-				t.Fatalf("IP header length too large: got = %d, want <= %d ", ipHeaderLength, header.IPv4MaximumHeaderSize)
-			}
-			totalLen := uint16(ipHeaderLength + header.ICMPv4MinimumSize)
-			hdr := buffer.NewPrependable(int(totalLen))
-			icmp := header.ICMPv4(hdr.Prepend(header.ICMPv4MinimumSize))
-
-			// Specify ident/seq to make sure we get the same in the response.
-			icmp.SetIdent(randomIdent)
-			icmp.SetSequence(randomSequence)
-			icmp.SetType(header.ICMPv4Echo)
-			icmp.SetCode(header.ICMPv4UnusedCode)
-			icmp.SetChecksum(0)
-			icmp.SetChecksum(^header.Checksum(icmp, 0))
-			ip := header.IPv4(hdr.Prepend(ipHeaderLength))
-			if test.maxTotalLength < totalLen {
-				totalLen = test.maxTotalLength
-			}
-			ip.Encode(&header.IPv4Fields{
-				TotalLength: totalLen,
-				Protocol:    test.transportProtocol,
-				TTL:         test.TTL,
-				SrcAddr:     remoteIPv4Addr,
-				DstAddr:     ipv4Addr.Address,
-			})
-			if test.headerLength != 0 {
-				ip.SetHeaderLength(test.headerLength)
-			} else {
-				// Set the calculated header length, since we may manually add options.
-				ip.SetHeaderLength(uint8(ipHeaderLength))
-			}
-			if len(test.options) != 0 {
-				// Copy options manually. We do not use Encode for options so we can
-				// verify malformed options with handcrafted payloads.
-				if want, got := copy(ip.Options(), test.options), len(test.options); want != got {
-					t.Fatalf("got copy(ip.Options(), test.options) = %d, want = %d", got, want)
-				}
-			}
-			ip.SetChecksum(0)
-			ipHeaderChecksum := ip.CalculateChecksum()
-			if test.badHeaderChecksum {
-				ipHeaderChecksum += 42
-			}
-			ip.SetChecksum(^ipHeaderChecksum)
-			requestPkt := stack.NewPacketBuffer(stack.PacketBufferOptions{
-				Data: hdr.View().ToVectorisedView(),
-			})
-			e.InjectInbound(header.IPv4ProtocolNumber, requestPkt)
-			reply, ok := e.Read()
-			if !ok {
-				if test.shouldFail {
-					if test.expectErrorICMP {
-						t.Fatalf("ICMP error response (type %d, code %d) missing", test.ICMPType, test.ICMPCode)
-					}
-					return // Expected silent failure.
-				}
-				t.Fatal("expected ICMP echo reply missing")
-			}
-
-			// We didn't expect a packet. Register our surprise but carry on to
-			// provide more information about what we got.
-			if test.shouldFail && !test.expectErrorICMP {
-				t.Error("unexpected packet response")
-			}
-
-			// Check the route that brought the packet to us.
-			if reply.Route.LocalAddress != ipv4Addr.Address {
-				t.Errorf("got pkt.Route.LocalAddress = %s, want = %s", reply.Route.LocalAddress, ipv4Addr.Address)
-			}
-			if reply.Route.RemoteAddress != remoteIPv4Addr {
-				t.Errorf("got pkt.Route.RemoteAddress = %s, want = %s", reply.Route.RemoteAddress, remoteIPv4Addr)
-			}
-
-			// Make sure it's all in one buffer for checker.
-			replyIPHeader := header.IPv4(stack.PayloadSince(reply.Pkt.NetworkHeader()))
-
-			// At this stage we only know it's probably an IP+ICMP header so verify
-			// that much.
-			checker.IPv4(t, replyIPHeader,
-				checker.SrcAddr(ipv4Addr.Address),
-				checker.DstAddr(remoteIPv4Addr),
-				checker.ICMPv4(
-					checker.ICMPv4Checksum(),
-				),
-			)
-
-			// Don't proceed any further if the checker found problems.
-			if t.Failed() {
-				t.FailNow()
-			}
-
-			// OK it's ICMP. We can safely look at the type now.
-			replyICMPHeader := header.ICMPv4(replyIPHeader.Payload())
-			switch replyICMPHeader.Type() {
-			case header.ICMPv4ParamProblem:
-				if !test.shouldFail {
-					t.Fatalf("got Parameter Problem with pointer %d, wanted Echo Reply", replyICMPHeader.Pointer())
-				}
-				if !test.expectErrorICMP {
-					t.Fatalf("got Parameter Problem with pointer %d, wanted no response", replyICMPHeader.Pointer())
-				}
-				checker.IPv4(t, replyIPHeader,
-					checker.IPFullLength(uint16(header.IPv4MinimumSize+header.ICMPv4MinimumSize+requestPkt.Size())),
-					checker.IPv4HeaderLength(header.IPv4MinimumSize),
-					checker.ICMPv4(
-						checker.ICMPv4Type(test.ICMPType),
-						checker.ICMPv4Code(test.ICMPCode),
-						checker.ICMPv4Pointer(test.paramProblemPointer),
-						checker.ICMPv4Payload([]byte(hdr.View())),
-					),
-				)
-				return
-			case header.ICMPv4DstUnreachable:
-				if !test.shouldFail {
-					t.Fatalf("got ICMP error packet type %d, code %d, wanted Echo Reply",
-						header.ICMPv4DstUnreachable, replyICMPHeader.Code())
-				}
-				if !test.expectErrorICMP {
-					t.Fatalf("got ICMP error packet type %d, code %d, wanted no response",
-						header.ICMPv4DstUnreachable, replyICMPHeader.Code())
-				}
-				checker.IPv4(t, replyIPHeader,
-					checker.IPFullLength(uint16(header.IPv4MinimumSize+header.ICMPv4MinimumSize+requestPkt.Size())),
-					checker.IPv4HeaderLength(header.IPv4MinimumSize),
-					checker.ICMPv4(
-						checker.ICMPv4Type(test.ICMPType),
-						checker.ICMPv4Code(test.ICMPCode),
-						checker.ICMPv4Payload([]byte(hdr.View())),
-					),
-				)
-				return
-			case header.ICMPv4EchoReply:
-				if test.shouldFail {
-					if !test.expectErrorICMP {
-						t.Error("got Echo Reply packet, want no response")
-					} else {
-						t.Errorf("got Echo Reply, want ICMP error type %d, code %d", test.ICMPType, test.ICMPCode)
-					}
-				}
-				// If the IP options change size then the packet will change size, so
-				// some IP header fields will need to be adjusted for the checks.
-				sizeChange := len(test.replyOptions) - len(test.options)
-
-				checker.IPv4(t, replyIPHeader,
-					checker.IPv4HeaderLength(ipHeaderLength+sizeChange),
-					checker.IPv4Options(test.replyOptions),
-					checker.IPFullLength(uint16(requestPkt.Size()+sizeChange)),
-					checker.ICMPv4(
-						checker.ICMPv4Checksum(),
-						checker.ICMPv4Code(header.ICMPv4UnusedCode),
-						checker.ICMPv4Seq(randomSequence),
-						checker.ICMPv4Ident(randomIdent),
-					),
-				)
-			default:
-				t.Fatalf("unexpected ICMP response, got type %d, want = %d, %d or %d",
-					replyICMPHeader.Type(), header.ICMPv4EchoReply, header.ICMPv4DstUnreachable, header.ICMPv4ParamProblem)
-			}
-		})
-	}
-}
-
-// comparePayloads compared the contents of all the packets against the contents
-// of the source packet.
-func compareFragments(packets []*stack.PacketBuffer, sourcePacket *stack.PacketBuffer, mtu uint32, wantFragments []fragmentInfo, proto tcpip.TransportProtocolNumber) error {
-	// Make a complete array of the sourcePacket packet.
-	source := header.IPv4(packets[0].NetworkHeader().View())
-	vv := buffer.NewVectorisedView(sourcePacket.Size(), sourcePacket.Views())
-	source = append(source, vv.ToView()...)
-
-	// Make a copy of the IP header, which will be modified in some fields to make
-	// an expected header.
-	sourceCopy := header.IPv4(append(buffer.View(nil), source[:source.HeaderLength()]...))
-	sourceCopy.SetChecksum(0)
-	sourceCopy.SetFlagsFragmentOffset(0, 0)
-	sourceCopy.SetTotalLength(0)
-	// Build up an array of the bytes sent.
-	var reassembledPayload buffer.VectorisedView
-	for i, packet := range packets {
-		// Confirm that the packet is valid.
-		allBytes := buffer.NewVectorisedView(packet.Size(), packet.Views())
-		fragmentIPHeader := header.IPv4(allBytes.ToView())
-		if !fragmentIPHeader.IsValid(len(fragmentIPHeader)) {
-			return fmt.Errorf("fragment #%d: IP packet is invalid:\n%s", i, hex.Dump(fragmentIPHeader))
-		}
-		if got := len(fragmentIPHeader); got > int(mtu) {
-			return fmt.Errorf("fragment #%d: got len(fragmentIPHeader) = %d, want <= %d", i, got, mtu)
-		}
-		if got := fragmentIPHeader.TransportProtocol(); got != proto {
-			return fmt.Errorf("fragment #%d: got fragmentIPHeader.TransportProtocol() = %d, want = %d", i, got, uint8(proto))
-		}
-		if got := packet.AvailableHeaderBytes(); got != extraHeaderReserve {
-			return fmt.Errorf("fragment #%d: got packet.AvailableHeaderBytes() = %d, want = %d", i, got, extraHeaderReserve)
-		}
-		if got, want := packet.NetworkProtocolNumber, sourcePacket.NetworkProtocolNumber; got != want {
-			return fmt.Errorf("fragment #%d: got fragment.NetworkProtocolNumber = %d, want = %d", i, got, want)
-		}
-		if got, want := fragmentIPHeader.CalculateChecksum(), uint16(0xffff); got != want {
-			return fmt.Errorf("fragment #%d: got ip.CalculateChecksum() = %#x, want = %#x", i, got, want)
-		}
-		if wantFragments[i].more {
-			sourceCopy.SetFlagsFragmentOffset(sourceCopy.Flags()|header.IPv4FlagMoreFragments, wantFragments[i].offset)
-		} else {
-			sourceCopy.SetFlagsFragmentOffset(sourceCopy.Flags()&^header.IPv4FlagMoreFragments, wantFragments[i].offset)
-		}
-		reassembledPayload.AppendView(packet.TransportHeader().View())
-		reassembledPayload.AppendView(packet.Data().AsRange().ToOwnedView())
-		// Clear out the checksum and length from the ip because we can't compare
-		// it.
-		sourceCopy.SetTotalLength(wantFragments[i].payloadSize + header.IPv4MinimumSize)
-		sourceCopy.SetChecksum(0)
-		sourceCopy.SetChecksum(^sourceCopy.CalculateChecksum())
-		if diff := cmp.Diff(fragmentIPHeader[:fragmentIPHeader.HeaderLength()], sourceCopy[:sourceCopy.HeaderLength()]); diff != "" {
-			return fmt.Errorf("fragment #%d: fragmentIPHeader mismatch (-want +got):\n%s", i, diff)
-		}
-	}
-
-	expected := buffer.View(source[source.HeaderLength():])
-	if diff := cmp.Diff(expected, reassembledPayload.ToView()); diff != "" {
-		return fmt.Errorf("reassembledPayload mismatch (-want +got):\n%s", diff)
-	}
-
-	return nil
-}
-
-type fragmentInfo struct {
-	offset      uint16
-	more        bool
-	payloadSize uint16
-}
-
-var fragmentationTests = []struct {
-	description           string
-	mtu                   uint32
-	gso                   *stack.GSO
-	transportHeaderLength int
-	payloadSize           int
-	wantFragments         []fragmentInfo
-}{
-	{
-		description:           "No fragmentation",
-		mtu:                   1280,
-		gso:                   nil,
-		transportHeaderLength: 0,
-		payloadSize:           1000,
-		wantFragments: []fragmentInfo{
-			{offset: 0, payloadSize: 1000, more: false},
-		},
-	},
-	{
-		description:           "Fragmented",
-		mtu:                   1280,
-		gso:                   nil,
-		transportHeaderLength: 0,
-		payloadSize:           2000,
-		wantFragments: []fragmentInfo{
-			{offset: 0, payloadSize: 1256, more: true},
-			{offset: 1256, payloadSize: 744, more: false},
-		},
-	},
-	{
-		description:           "Fragmented with the minimum mtu",
-		mtu:                   header.IPv4MinimumMTU,
-		gso:                   nil,
-		transportHeaderLength: 0,
-		payloadSize:           100,
-		wantFragments: []fragmentInfo{
-			{offset: 0, payloadSize: 48, more: true},
-			{offset: 48, payloadSize: 48, more: true},
-			{offset: 96, payloadSize: 4, more: false},
-		},
-	},
-	{
-		description:           "Fragmented with mtu not a multiple of 8",
-		mtu:                   header.IPv4MinimumMTU + 1,
-		gso:                   nil,
-		transportHeaderLength: 0,
-		payloadSize:           100,
-		wantFragments: []fragmentInfo{
-			{offset: 0, payloadSize: 48, more: true},
-			{offset: 48, payloadSize: 48, more: true},
-			{offset: 96, payloadSize: 4, more: false},
-		},
-	},
-	{
-		description:           "No fragmentation with big header",
-		mtu:                   2000,
-		gso:                   nil,
-		transportHeaderLength: 100,
-		payloadSize:           1000,
-		wantFragments: []fragmentInfo{
-			{offset: 0, payloadSize: 1100, more: false},
-		},
-	},
-	{
-		description:           "Fragmented with gso none",
-		mtu:                   1280,
-		gso:                   &stack.GSO{Type: stack.GSONone},
-		transportHeaderLength: 0,
-		payloadSize:           1400,
-		wantFragments: []fragmentInfo{
-			{offset: 0, payloadSize: 1256, more: true},
-			{offset: 1256, payloadSize: 144, more: false},
-		},
-	},
-	{
-		description:           "Fragmented with big header",
-		mtu:                   1280,
-		gso:                   nil,
-		transportHeaderLength: 100,
-		payloadSize:           1200,
-		wantFragments: []fragmentInfo{
-			{offset: 0, payloadSize: 1256, more: true},
-			{offset: 1256, payloadSize: 44, more: false},
-		},
-	},
-	{
-		description:           "Fragmented with MTU smaller than header",
-		mtu:                   300,
-		gso:                   nil,
-		transportHeaderLength: 1000,
-		payloadSize:           500,
-		wantFragments: []fragmentInfo{
-			{offset: 0, payloadSize: 280, more: true},
-			{offset: 280, payloadSize: 280, more: true},
-			{offset: 560, payloadSize: 280, more: true},
-			{offset: 840, payloadSize: 280, more: true},
-			{offset: 1120, payloadSize: 280, more: true},
-			{offset: 1400, payloadSize: 100, more: false},
-		},
-	},
-}
-
-func TestFragmentationWritePacket(t *testing.T) {
-	const ttl = 42
-
-	for _, ft := range fragmentationTests {
-		t.Run(ft.description, func(t *testing.T) {
-			ep := testutil.NewMockLinkEndpoint(ft.mtu, nil, math.MaxInt32)
-			r := buildRoute(t, ep)
-			pkt := testutil.MakeRandPkt(ft.transportHeaderLength, extraHeaderReserve+header.IPv4MinimumSize, []int{ft.payloadSize}, header.IPv4ProtocolNumber)
-			source := pkt.Clone()
-			err := r.WritePacket(ft.gso, stack.NetworkHeaderParams{
-				Protocol: tcp.ProtocolNumber,
-				TTL:      ttl,
-				TOS:      stack.DefaultTOS,
-			}, pkt)
-			if err != nil {
-				t.Fatalf("r.WritePacket(_, _, _) = %s", err)
-			}
-			if got := len(ep.WrittenPackets); got != len(ft.wantFragments) {
-				t.Errorf("got len(ep.WrittenPackets) = %d, want = %d", got, len(ft.wantFragments))
-			}
-			if got := int(r.Stats().IP.PacketsSent.Value()); got != len(ft.wantFragments) {
-				t.Errorf("got c.Route.Stats().IP.PacketsSent.Value() = %d, want = %d", got, len(ft.wantFragments))
-			}
-			if got := r.Stats().IP.OutgoingPacketErrors.Value(); got != 0 {
-				t.Errorf("got r.Stats().IP.OutgoingPacketErrors.Value() = %d, want = 0", got)
-			}
-			if err := compareFragments(ep.WrittenPackets, source, ft.mtu, ft.wantFragments, tcp.ProtocolNumber); err != nil {
-				t.Error(err)
-			}
-		})
-	}
-}
-
-func TestFragmentationWritePackets(t *testing.T) {
-	const ttl = 42
-	writePacketsTests := []struct {
-		description  string
-		insertBefore int
-		insertAfter  int
-	}{
-		{
-			description:  "Single packet",
-			insertBefore: 0,
-			insertAfter:  0,
-		},
-		{
-			description:  "With packet before",
-			insertBefore: 1,
-			insertAfter:  0,
-		},
-		{
-			description:  "With packet after",
-			insertBefore: 0,
-			insertAfter:  1,
-		},
-		{
-			description:  "With packet before and after",
-			insertBefore: 1,
-			insertAfter:  1,
-		},
-	}
-	tinyPacket := testutil.MakeRandPkt(header.TCPMinimumSize, extraHeaderReserve+header.IPv4MinimumSize, []int{1}, header.IPv4ProtocolNumber)
-
-	for _, test := range writePacketsTests {
-		t.Run(test.description, func(t *testing.T) {
-			for _, ft := range fragmentationTests {
-				t.Run(ft.description, func(t *testing.T) {
-					var pkts stack.PacketBufferList
-					for i := 0; i < test.insertBefore; i++ {
-						pkts.PushBack(tinyPacket.Clone())
-					}
-					pkt := testutil.MakeRandPkt(ft.transportHeaderLength, extraHeaderReserve+header.IPv4MinimumSize, []int{ft.payloadSize}, header.IPv4ProtocolNumber)
-					pkts.PushBack(pkt.Clone())
-					for i := 0; i < test.insertAfter; i++ {
-						pkts.PushBack(tinyPacket.Clone())
-					}
-
-					ep := testutil.NewMockLinkEndpoint(ft.mtu, nil, math.MaxInt32)
-					r := buildRoute(t, ep)
-
-					wantTotalPackets := len(ft.wantFragments) + test.insertBefore + test.insertAfter
-					n, err := r.WritePackets(ft.gso, pkts, stack.NetworkHeaderParams{
-						Protocol: tcp.ProtocolNumber,
-						TTL:      ttl,
-						TOS:      stack.DefaultTOS,
-					})
-					if err != nil {
-						t.Errorf("got WritePackets(_, _, _) = (_, %s), want = (_, nil)", err)
-					}
-					if n != wantTotalPackets {
-						t.Errorf("got WritePackets(_, _, _) = (%d, _), want = (%d, _)", n, wantTotalPackets)
-					}
-					if got := len(ep.WrittenPackets); got != wantTotalPackets {
-						t.Errorf("got len(ep.WrittenPackets) = %d, want = %d", got, wantTotalPackets)
-					}
-					if got := int(r.Stats().IP.PacketsSent.Value()); got != wantTotalPackets {
-						t.Errorf("got c.Route.Stats().IP.PacketsSent.Value() = %d, want = %d", got, wantTotalPackets)
-					}
-					if got := int(r.Stats().IP.OutgoingPacketErrors.Value()); got != 0 {
-						t.Errorf("got r.Stats().IP.OutgoingPacketErrors.Value() = %d, want = 0", got)
-					}
-
-					if wantTotalPackets == 0 {
-						return
-					}
-
-					fragments := ep.WrittenPackets[test.insertBefore : len(ft.wantFragments)+test.insertBefore]
-					if err := compareFragments(fragments, pkt, ft.mtu, ft.wantFragments, tcp.ProtocolNumber); err != nil {
-						t.Error(err)
-					}
-				})
-			}
-		})
-	}
-}
-
-// TestFragmentationErrors checks that errors are returned from WritePacket
-// correctly.
-func TestFragmentationErrors(t *testing.T) {
-	const ttl = 42
-
-	tests := []struct {
-		description           string
-		mtu                   uint32
-		transportHeaderLength int
-		payloadSize           int
-		allowPackets          int
-		outgoingErrors        int
-		mockError             tcpip.Error
-		wantError             tcpip.Error
-	}{
-		{
-			description:           "No frag",
-			mtu:                   2000,
-			payloadSize:           1000,
-			transportHeaderLength: 0,
-			allowPackets:          0,
-			outgoingErrors:        1,
-			mockError:             &tcpip.ErrAborted{},
-			wantError:             &tcpip.ErrAborted{},
-		},
-		{
-			description:           "Error on first frag",
-			mtu:                   500,
-			payloadSize:           1000,
-			transportHeaderLength: 0,
-			allowPackets:          0,
-			outgoingErrors:        3,
-			mockError:             &tcpip.ErrAborted{},
-			wantError:             &tcpip.ErrAborted{},
-		},
-		{
-			description:           "Error on second frag",
-			mtu:                   500,
-			payloadSize:           1000,
-			transportHeaderLength: 0,
-			allowPackets:          1,
-			outgoingErrors:        2,
-			mockError:             &tcpip.ErrAborted{},
-			wantError:             &tcpip.ErrAborted{},
-		},
-		{
-			description:           "Error on first frag MTU smaller than header",
-			mtu:                   500,
-			transportHeaderLength: 1000,
-			payloadSize:           500,
-			allowPackets:          0,
-			outgoingErrors:        4,
-			mockError:             &tcpip.ErrAborted{},
-			wantError:             &tcpip.ErrAborted{},
-		},
-		{
-			description:           "Error when MTU is smaller than IPv4 minimum MTU",
-			mtu:                   header.IPv4MinimumMTU - 1,
-			transportHeaderLength: 0,
-			payloadSize:           500,
-			allowPackets:          0,
-			outgoingErrors:        1,
-			mockError:             nil,
-			wantError:             &tcpip.ErrInvalidEndpointState{},
-		},
-	}
-
-	for _, ft := range tests {
-		t.Run(ft.description, func(t *testing.T) {
-			pkt := testutil.MakeRandPkt(ft.transportHeaderLength, extraHeaderReserve+header.IPv4MinimumSize, []int{ft.payloadSize}, header.IPv4ProtocolNumber)
-			ep := testutil.NewMockLinkEndpoint(ft.mtu, ft.mockError, ft.allowPackets)
-			r := buildRoute(t, ep)
-			err := r.WritePacket(&stack.GSO{}, stack.NetworkHeaderParams{
-				Protocol: tcp.ProtocolNumber,
-				TTL:      ttl,
-				TOS:      stack.DefaultTOS,
-			}, pkt)
-			if diff := cmp.Diff(ft.wantError, err); diff != "" {
-				t.Fatalf("unexpected error from r.WritePacket(_, _, _), (-want, +got):\n%s", diff)
-			}
-			if got := int(r.Stats().IP.PacketsSent.Value()); got != ft.allowPackets {
-				t.Errorf("got r.Stats().IP.PacketsSent.Value() = %d, want = %d", got, ft.allowPackets)
-			}
-			if got := int(r.Stats().IP.OutgoingPacketErrors.Value()); got != ft.outgoingErrors {
-				t.Errorf("got r.Stats().IP.OutgoingPacketErrors.Value() = %d, want = %d", got, ft.outgoingErrors)
-			}
-		})
-	}
-}
-
-func TestInvalidFragments(t *testing.T) {
-	const (
-		nicID    = 1
-		linkAddr = tcpip.LinkAddress("\x0a\x0b\x0c\x0d\x0e\x0e")
-		addr1    = "\x0a\x00\x00\x01"
-		addr2    = "\x0a\x00\x00\x02"
-		tos      = 0
-		ident    = 1
-		ttl      = 48
-		protocol = 6
-	)
-
-	payloadGen := func(payloadLen int) []byte {
-		payload := make([]byte, payloadLen)
-		for i := 0; i < len(payload); i++ {
-			payload[i] = 0x30
-		}
-		return payload
-	}
-
-	type fragmentData struct {
-		ipv4fields header.IPv4Fields
-		// 0 means insert the correct IHL. Non 0 means override the correct IHL.
-		overrideIHL  int // For 0 use 1 as it is an int and will be divided by 4.
-		payload      []byte
-		autoChecksum bool // If true, the Checksum field will be overwritten.
-	}
-
-	tests := []struct {
-		name                   string
-		fragments              []fragmentData
-		wantMalformedIPPackets uint64
-		wantMalformedFragments uint64
-	}{
-		{
-			name: "IHL and TotalLength zero, FragmentOffset non-zero",
-			fragments: []fragmentData{
-				{
-					ipv4fields: header.IPv4Fields{
-						TOS:            tos,
-						TotalLength:    0,
-						ID:             ident,
-						Flags:          header.IPv4FlagDontFragment | header.IPv4FlagMoreFragments,
-						FragmentOffset: 59776,
-						TTL:            ttl,
-						Protocol:       protocol,
-						SrcAddr:        addr1,
-						DstAddr:        addr2,
-					},
-					overrideIHL:  1, // See note above.
-					payload:      payloadGen(12),
-					autoChecksum: true,
-				},
-			},
-			wantMalformedIPPackets: 1,
-			wantMalformedFragments: 0,
-		},
-		{
-			name: "IHL and TotalLength zero, FragmentOffset zero",
-			fragments: []fragmentData{
-				{
-					ipv4fields: header.IPv4Fields{
-						TOS:            tos,
-						TotalLength:    0,
-						ID:             ident,
-						Flags:          header.IPv4FlagMoreFragments,
-						FragmentOffset: 0,
-						TTL:            ttl,
-						Protocol:       protocol,
-						SrcAddr:        addr1,
-						DstAddr:        addr2,
-					},
-					overrideIHL:  1, // See note above.
-					payload:      payloadGen(12),
-					autoChecksum: true,
-				},
-			},
-			wantMalformedIPPackets: 1,
-			wantMalformedFragments: 0,
-		},
-		{
-			// Payload 17 octets and Fragment offset 65520
-			// Leading to the fragment end to be past 65536.
-			name: "fragment ends past 65536",
-			fragments: []fragmentData{
-				{
-					ipv4fields: header.IPv4Fields{
-						TOS:            tos,
-						TotalLength:    header.IPv4MinimumSize + 17,
-						ID:             ident,
-						Flags:          0,
-						FragmentOffset: 65520,
-						TTL:            ttl,
-						Protocol:       protocol,
-						SrcAddr:        addr1,
-						DstAddr:        addr2,
-					},
-					payload:      payloadGen(17),
-					autoChecksum: true,
-				},
-			},
-			wantMalformedIPPackets: 1,
-			wantMalformedFragments: 1,
-		},
-		{
-			// Payload 16 octets and fragment offset 65520
-			// Leading to the fragment end to be exactly 65536.
-			name: "fragment ends exactly at 65536",
-			fragments: []fragmentData{
-				{
-					ipv4fields: header.IPv4Fields{
-						TOS:            tos,
-						TotalLength:    header.IPv4MinimumSize + 16,
-						ID:             ident,
-						Flags:          0,
-						FragmentOffset: 65520,
-						TTL:            ttl,
-						Protocol:       protocol,
-						SrcAddr:        addr1,
-						DstAddr:        addr2,
-					},
-					payload:      payloadGen(16),
-					autoChecksum: true,
-				},
-			},
-			wantMalformedIPPackets: 0,
-			wantMalformedFragments: 0,
-		},
-		{
-			name: "IHL less than IPv4 minimum size",
-			fragments: []fragmentData{
-				{
-					ipv4fields: header.IPv4Fields{
-						TOS:            tos,
-						TotalLength:    header.IPv4MinimumSize + 28,
-						ID:             ident,
-						Flags:          0,
-						FragmentOffset: 1944,
-						TTL:            ttl,
-						Protocol:       protocol,
-						SrcAddr:        addr1,
-						DstAddr:        addr2,
-					},
-					payload:      payloadGen(28),
-					overrideIHL:  header.IPv4MinimumSize - 12,
-					autoChecksum: true,
-				},
-				{
-					ipv4fields: header.IPv4Fields{
-						TOS:            tos,
-						TotalLength:    header.IPv4MinimumSize - 12,
-						ID:             ident,
-						Flags:          header.IPv4FlagMoreFragments,
-						FragmentOffset: 0,
-						TTL:            ttl,
-						Protocol:       protocol,
-						SrcAddr:        addr1,
-						DstAddr:        addr2,
-					},
-					payload:      payloadGen(28),
-					overrideIHL:  header.IPv4MinimumSize - 12,
-					autoChecksum: true,
-				},
-			},
-			wantMalformedIPPackets: 2,
-			wantMalformedFragments: 0,
-		},
-		{
-			name: "fragment with short TotalLength and extra payload",
-			fragments: []fragmentData{
-				{
-					ipv4fields: header.IPv4Fields{
-						TOS:            tos,
-						TotalLength:    header.IPv4MinimumSize + 28,
-						ID:             ident,
-						Flags:          0,
-						FragmentOffset: 28816,
-						TTL:            ttl,
-						Protocol:       protocol,
-						SrcAddr:        addr1,
-						DstAddr:        addr2,
-					},
-					payload:      payloadGen(28),
-					overrideIHL:  header.IPv4MinimumSize + 4,
-					autoChecksum: true,
-				},
-				{
-					ipv4fields: header.IPv4Fields{
-						TOS:            tos,
-						TotalLength:    header.IPv4MinimumSize + 4,
-						ID:             ident,
-						Flags:          header.IPv4FlagMoreFragments,
-						FragmentOffset: 0,
-						TTL:            ttl,
-						Protocol:       protocol,
-						SrcAddr:        addr1,
-						DstAddr:        addr2,
-					},
-					payload:      payloadGen(28),
-					overrideIHL:  header.IPv4MinimumSize + 4,
-					autoChecksum: true,
-				},
-			},
-			wantMalformedIPPackets: 1,
-			wantMalformedFragments: 1,
-		},
-		{
-			name: "multiple fragments with More Fragments flag set to false",
-			fragments: []fragmentData{
-				{
-					ipv4fields: header.IPv4Fields{
-						TOS:            tos,
-						TotalLength:    header.IPv4MinimumSize + 8,
-						ID:             ident,
-						Flags:          0,
-						FragmentOffset: 128,
-						TTL:            ttl,
-						Protocol:       protocol,
-						SrcAddr:        addr1,
-						DstAddr:        addr2,
-					},
-					payload:      payloadGen(8),
-					autoChecksum: true,
-				},
-				{
-					ipv4fields: header.IPv4Fields{
-						TOS:            tos,
-						TotalLength:    header.IPv4MinimumSize + 8,
-						ID:             ident,
-						Flags:          0,
-						FragmentOffset: 8,
-						TTL:            ttl,
-						Protocol:       protocol,
-						SrcAddr:        addr1,
-						DstAddr:        addr2,
-					},
-					payload:      payloadGen(8),
-					autoChecksum: true,
-				},
-				{
-					ipv4fields: header.IPv4Fields{
-						TOS:            tos,
-						TotalLength:    header.IPv4MinimumSize + 8,
-						ID:             ident,
-						Flags:          header.IPv4FlagMoreFragments,
-						FragmentOffset: 0,
-						TTL:            ttl,
-						Protocol:       protocol,
-						SrcAddr:        addr1,
-						DstAddr:        addr2,
-					},
-					payload:      payloadGen(8),
-					autoChecksum: true,
-				},
-			},
-			wantMalformedIPPackets: 1,
-			wantMalformedFragments: 1,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			s := stack.New(stack.Options{
-				NetworkProtocols: []stack.NetworkProtocolFactory{
-					ipv4.NewProtocol,
-				},
-			})
-			e := channel.New(0, 1500, linkAddr)
-			if err := s.CreateNIC(nicID, e); err != nil {
-				t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
-			}
-			if err := s.AddAddress(nicID, ipv4.ProtocolNumber, addr2); err != nil {
-				t.Fatalf("AddAddress(%d, %d, %s) = %s", nicID, header.IPv4ProtocolNumber, addr2, err)
-			}
-
-			for _, f := range test.fragments {
-				pktSize := header.IPv4MinimumSize + len(f.payload)
-				hdr := buffer.NewPrependable(pktSize)
-
-				ip := header.IPv4(hdr.Prepend(pktSize))
-				ip.Encode(&f.ipv4fields)
-				if want, got := len(f.payload), copy(ip[header.IPv4MinimumSize:], f.payload); want != got {
-					t.Fatalf("copied %d bytes, expected %d bytes.", got, want)
-				}
-				// Encode sets this up correctly. If we want a different value for
-				// testing then we need to overwrite the good value.
-				if f.overrideIHL != 0 {
-					ip.SetHeaderLength(uint8(f.overrideIHL))
-					// If we are asked to add options (type not specified) then pad
-					// with 0 (EOL). RFC 791 page 23 says "The padding is zero".
-					for i := header.IPv4MinimumSize; i < f.overrideIHL; i++ {
-						ip[i] = byte(header.IPv4OptionListEndType)
-					}
-				}
-
-				if f.autoChecksum {
-					ip.SetChecksum(0)
-					ip.SetChecksum(^ip.CalculateChecksum())
-				}
-
-				vv := hdr.View().ToVectorisedView()
-				e.InjectInbound(header.IPv4ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
-					Data: vv,
-				}))
-			}
-
-			if got, want := s.Stats().IP.MalformedPacketsReceived.Value(), test.wantMalformedIPPackets; got != want {
-				t.Errorf("incorrect Stats.IP.MalformedPacketsReceived, got: %d, want: %d", got, want)
-			}
-			if got, want := s.Stats().IP.MalformedFragmentsReceived.Value(), test.wantMalformedFragments; got != want {
-				t.Errorf("incorrect Stats.IP.MalformedFragmentsReceived, got: %d, want: %d", got, want)
-			}
-		})
-	}
-}
-
-func TestFragmentReassemblyTimeout(t *testing.T) {
-	const (
-		nicID    = 1
-		linkAddr = tcpip.LinkAddress("\x0a\x0b\x0c\x0d\x0e\x0e")
-		addr1    = "\x0a\x00\x00\x01"
-		addr2    = "\x0a\x00\x00\x02"
-		tos      = 0
-		ident    = 1
-		ttl      = 48
-		protocol = 99
-		data     = "TEST_FRAGMENT_REASSEMBLY_TIMEOUT"
-	)
-
-	type fragmentData struct {
-		ipv4fields header.IPv4Fields
-		payload    []byte
-	}
-
-	tests := []struct {
-		name       string
-		fragments  []fragmentData
-		expectICMP bool
-	}{
-		{
-			name: "first fragment only",
-			fragments: []fragmentData{
-				{
-					ipv4fields: header.IPv4Fields{
-						TOS:            tos,
-						TotalLength:    header.IPv4MinimumSize + 16,
-						ID:             ident,
-						Flags:          header.IPv4FlagMoreFragments,
-						FragmentOffset: 0,
-						TTL:            ttl,
-						Protocol:       protocol,
-						SrcAddr:        addr1,
-						DstAddr:        addr2,
-					},
-					payload: []byte(data)[:16],
-				},
-			},
-			expectICMP: true,
-		},
-		{
-			name: "two first fragments",
-			fragments: []fragmentData{
-				{
-					ipv4fields: header.IPv4Fields{
-						TOS:            tos,
-						TotalLength:    header.IPv4MinimumSize + 16,
-						ID:             ident,
-						Flags:          header.IPv4FlagMoreFragments,
-						FragmentOffset: 0,
-						TTL:            ttl,
-						Protocol:       protocol,
-						SrcAddr:        addr1,
-						DstAddr:        addr2,
-					},
-					payload: []byte(data)[:16],
-				},
-				{
-					ipv4fields: header.IPv4Fields{
-						TOS:            tos,
-						TotalLength:    header.IPv4MinimumSize + 16,
-						ID:             ident,
-						Flags:          header.IPv4FlagMoreFragments,
-						FragmentOffset: 0,
-						TTL:            ttl,
-						Protocol:       protocol,
-						SrcAddr:        addr1,
-						DstAddr:        addr2,
-					},
-					payload: []byte(data)[:16],
-				},
-			},
-			expectICMP: true,
-		},
-		{
-			name: "second fragment only",
-			fragments: []fragmentData{
-				{
-					ipv4fields: header.IPv4Fields{
-						TOS:            tos,
-						TotalLength:    uint16(header.IPv4MinimumSize + len(data) - 16),
-						ID:             ident,
-						Flags:          0,
-						FragmentOffset: 8,
-						TTL:            ttl,
-						Protocol:       protocol,
-						SrcAddr:        addr1,
-						DstAddr:        addr2,
-					},
-					payload: []byte(data)[16:],
-				},
-			},
-			expectICMP: false,
-		},
-		{
-			name: "two fragments with a gap",
-			fragments: []fragmentData{
-				{
-					ipv4fields: header.IPv4Fields{
-						TOS:            tos,
-						TotalLength:    header.IPv4MinimumSize + 8,
-						ID:             ident,
-						Flags:          header.IPv4FlagMoreFragments,
-						FragmentOffset: 0,
-						TTL:            ttl,
-						Protocol:       protocol,
-						SrcAddr:        addr1,
-						DstAddr:        addr2,
-					},
-					payload: []byte(data)[:8],
-				},
-				{
-					ipv4fields: header.IPv4Fields{
-						TOS:            tos,
-						TotalLength:    uint16(header.IPv4MinimumSize + len(data) - 16),
-						ID:             ident,
-						Flags:          0,
-						FragmentOffset: 16,
-						TTL:            ttl,
-						Protocol:       protocol,
-						SrcAddr:        addr1,
-						DstAddr:        addr2,
-					},
-					payload: []byte(data)[16:],
-				},
-			},
-			expectICMP: true,
-		},
-		{
-			name: "two fragments with a gap in reverse order",
-			fragments: []fragmentData{
-				{
-					ipv4fields: header.IPv4Fields{
-						TOS:            tos,
-						TotalLength:    uint16(header.IPv4MinimumSize + len(data) - 16),
-						ID:             ident,
-						Flags:          0,
-						FragmentOffset: 16,
-						TTL:            ttl,
-						Protocol:       protocol,
-						SrcAddr:        addr1,
-						DstAddr:        addr2,
-					},
-					payload: []byte(data)[16:],
-				},
-				{
-					ipv4fields: header.IPv4Fields{
-						TOS:            tos,
-						TotalLength:    header.IPv4MinimumSize + 8,
-						ID:             ident,
-						Flags:          header.IPv4FlagMoreFragments,
-						FragmentOffset: 0,
-						TTL:            ttl,
-						Protocol:       protocol,
-						SrcAddr:        addr1,
-						DstAddr:        addr2,
-					},
-					payload: []byte(data)[:8],
-				},
-			},
-			expectICMP: true,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			clock := faketime.NewManualClock()
-			s := stack.New(stack.Options{
-				NetworkProtocols: []stack.NetworkProtocolFactory{
-					ipv4.NewProtocol,
-				},
-				Clock: clock,
-			})
-			e := channel.New(1, 1500, linkAddr)
-			if err := s.CreateNIC(nicID, e); err != nil {
-				t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
-			}
-			if err := s.AddAddress(nicID, ipv4.ProtocolNumber, addr2); err != nil {
-				t.Fatalf("AddAddress(%d, %d, %s) = %s", nicID, header.IPv4ProtocolNumber, addr2, err)
-			}
-			s.SetRouteTable([]tcpip.Route{{
-				Destination: header.IPv4EmptySubnet,
-				NIC:         nicID,
-			}})
-
-			var firstFragmentSent buffer.View
-			for _, f := range test.fragments {
-				pktSize := header.IPv4MinimumSize
-				hdr := buffer.NewPrependable(pktSize)
-
-				ip := header.IPv4(hdr.Prepend(pktSize))
-				ip.Encode(&f.ipv4fields)
-
-				ip.SetChecksum(0)
-				ip.SetChecksum(^ip.CalculateChecksum())
-
-				vv := hdr.View().ToVectorisedView()
-				vv.AppendView(f.payload)
-
-				pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{
-					Data: vv,
-				})
-
-				if firstFragmentSent == nil && ip.FragmentOffset() == 0 {
-					firstFragmentSent = stack.PayloadSince(pkt.NetworkHeader())
-				}
-
-				e.InjectInbound(header.IPv4ProtocolNumber, pkt)
-			}
-
-			clock.Advance(ipv4.ReassembleTimeout)
-
-			reply, ok := e.Read()
-			if !test.expectICMP {
-				if ok {
-					t.Fatalf("unexpected ICMP error message received: %#v", reply)
-				}
-				return
-			}
-			if !ok {
-				t.Fatal("expected ICMP error message missing")
-			}
-			if firstFragmentSent == nil {
-				t.Fatalf("unexpected ICMP error message received: %#v", reply)
-			}
-
-			checker.IPv4(t, stack.PayloadSince(reply.Pkt.NetworkHeader()),
-				checker.SrcAddr(addr2),
-				checker.DstAddr(addr1),
-				checker.IPFullLength(uint16(header.IPv4MinimumSize+header.ICMPv4MinimumSize+firstFragmentSent.Size())),
-				checker.IPv4HeaderLength(header.IPv4MinimumSize),
-				checker.ICMPv4(
-					checker.ICMPv4Type(header.ICMPv4TimeExceeded),
-					checker.ICMPv4Code(header.ICMPv4ReassemblyTimeout),
-					checker.ICMPv4Checksum(),
-					checker.ICMPv4Payload([]byte(firstFragmentSent)),
-				),
-			)
-		})
-	}
-}
-
-// TestReceiveFragments feeds fragments in through the incoming packet path to
-// test reassembly
-func TestReceiveFragments(t *testing.T) {
-	const (
-		nicID = 1
-
-		addr1 = "\x0c\xa8\x00\x01" // 192.168.0.1
-		addr2 = "\x0c\xa8\x00\x02" // 192.168.0.2
-		addr3 = "\x0c\xa8\x00\x03" // 192.168.0.3
-	)
-
-	// Build and return a UDP header containing payload.
-	udpGen := func(payloadLen int, multiplier uint8, src, dst tcpip.Address) buffer.View {
-		payload := buffer.NewView(payloadLen)
-		for i := 0; i < len(payload); i++ {
-			payload[i] = uint8(i) * multiplier
-		}
-
-		udpLength := header.UDPMinimumSize + len(payload)
-
-		hdr := buffer.NewPrependable(udpLength)
-		u := header.UDP(hdr.Prepend(udpLength))
-		u.Encode(&header.UDPFields{
-			SrcPort: 5555,
-			DstPort: 80,
-			Length:  uint16(udpLength),
-		})
-		copy(u.Payload(), payload)
-		sum := header.PseudoHeaderChecksum(udp.ProtocolNumber, src, dst, uint16(udpLength))
-		sum = header.Checksum(payload, sum)
-		u.SetChecksum(^u.CalculateChecksum(sum))
-		return hdr.View()
-	}
-
-	// UDP header plus a payload of 0..256
-	ipv4Payload1Addr1ToAddr2 := udpGen(256, 1, addr1, addr2)
-	udpPayload1Addr1ToAddr2 := ipv4Payload1Addr1ToAddr2[header.UDPMinimumSize:]
-	ipv4Payload1Addr3ToAddr2 := udpGen(256, 1, addr3, addr2)
-	udpPayload1Addr3ToAddr2 := ipv4Payload1Addr3ToAddr2[header.UDPMinimumSize:]
-	// UDP header plus a payload of 0..256 in increments of 2.
-	ipv4Payload2Addr1ToAddr2 := udpGen(128, 2, addr1, addr2)
-	udpPayload2Addr1ToAddr2 := ipv4Payload2Addr1ToAddr2[header.UDPMinimumSize:]
-	// UDP header plus a payload of 0..256 in increments of 3.
-	// Used to test cases where the fragment blocks are not a multiple of
-	// the fragment block size of 8 (RFC 791 section 3.1 page 14).
-	ipv4Payload3Addr1ToAddr2 := udpGen(127, 3, addr1, addr2)
-	udpPayload3Addr1ToAddr2 := ipv4Payload3Addr1ToAddr2[header.UDPMinimumSize:]
-	// Used to test the max reassembled IPv4 payload length.
-	ipv4Payload4Addr1ToAddr2 := udpGen(header.UDPMaximumSize-header.UDPMinimumSize, 4, addr1, addr2)
-	udpPayload4Addr1ToAddr2 := ipv4Payload4Addr1ToAddr2[header.UDPMinimumSize:]
-
-	type fragmentData struct {
-		srcAddr        tcpip.Address
-		dstAddr        tcpip.Address
-		id             uint16
-		flags          uint8
-		fragmentOffset uint16
-		payload        buffer.View
-	}
-
-	tests := []struct {
-		name             string
-		fragments        []fragmentData
-		expectedPayloads [][]byte
-	}{
-		{
-			name: "No fragmentation",
-			fragments: []fragmentData{
-				{
-					srcAddr:        addr1,
-					dstAddr:        addr2,
-					id:             1,
-					flags:          0,
-					fragmentOffset: 0,
-					payload:        ipv4Payload1Addr1ToAddr2,
-				},
-			},
-			expectedPayloads: [][]byte{udpPayload1Addr1ToAddr2},
-		},
-		{
-			name: "No fragmentation with size not a multiple of fragment block size",
-			fragments: []fragmentData{
-				{
-					srcAddr:        addr1,
-					dstAddr:        addr2,
-					id:             1,
-					flags:          0,
-					fragmentOffset: 0,
-					payload:        ipv4Payload3Addr1ToAddr2,
-				},
-			},
-			expectedPayloads: [][]byte{udpPayload3Addr1ToAddr2},
-		},
-		{
-			name: "More fragments without payload",
-			fragments: []fragmentData{
-				{
-					srcAddr:        addr1,
-					dstAddr:        addr2,
-					id:             1,
-					flags:          header.IPv4FlagMoreFragments,
-					fragmentOffset: 0,
-					payload:        ipv4Payload1Addr1ToAddr2,
-				},
-			},
-			expectedPayloads: nil,
-		},
-		{
-			name: "Non-zero fragment offset without payload",
-			fragments: []fragmentData{
-				{
-					srcAddr:        addr1,
-					dstAddr:        addr2,
-					id:             1,
-					flags:          0,
-					fragmentOffset: 8,
-					payload:        ipv4Payload1Addr1ToAddr2,
-				},
-			},
-			expectedPayloads: nil,
-		},
-		{
-			name: "Two fragments",
-			fragments: []fragmentData{
-				{
-					srcAddr:        addr1,
-					dstAddr:        addr2,
-					id:             1,
-					flags:          header.IPv4FlagMoreFragments,
-					fragmentOffset: 0,
-					payload:        ipv4Payload1Addr1ToAddr2[:64],
-				},
-				{
-					srcAddr:        addr1,
-					dstAddr:        addr2,
-					id:             1,
-					flags:          0,
-					fragmentOffset: 64,
-					payload:        ipv4Payload1Addr1ToAddr2[64:],
-				},
-			},
-			expectedPayloads: [][]byte{udpPayload1Addr1ToAddr2},
-		},
-		{
-			name: "Two fragments out of order",
-			fragments: []fragmentData{
-				{
-					srcAddr:        addr1,
-					dstAddr:        addr2,
-					id:             1,
-					flags:          0,
-					fragmentOffset: 64,
-					payload:        ipv4Payload1Addr1ToAddr2[64:],
-				},
-				{
-					srcAddr:        addr1,
-					dstAddr:        addr2,
-					id:             1,
-					flags:          header.IPv4FlagMoreFragments,
-					fragmentOffset: 0,
-					payload:        ipv4Payload1Addr1ToAddr2[:64],
-				},
-			},
-			expectedPayloads: [][]byte{udpPayload1Addr1ToAddr2},
-		},
-		{
-			name: "Two fragments with last fragment size not a multiple of fragment block size",
-			fragments: []fragmentData{
-				{
-					srcAddr:        addr1,
-					dstAddr:        addr2,
-					id:             1,
-					flags:          header.IPv4FlagMoreFragments,
-					fragmentOffset: 0,
-					payload:        ipv4Payload3Addr1ToAddr2[:64],
-				},
-				{
-					srcAddr:        addr1,
-					dstAddr:        addr2,
-					id:             1,
-					flags:          0,
-					fragmentOffset: 64,
-					payload:        ipv4Payload3Addr1ToAddr2[64:],
-				},
-			},
-			expectedPayloads: [][]byte{udpPayload3Addr1ToAddr2},
-		},
-		{
-			name: "Two fragments with first fragment size not a multiple of fragment block size",
-			fragments: []fragmentData{
-				{
-					srcAddr:        addr1,
-					dstAddr:        addr2,
-					id:             1,
-					flags:          header.IPv4FlagMoreFragments,
-					fragmentOffset: 0,
-					payload:        ipv4Payload3Addr1ToAddr2[:63],
-				},
-				{
-					srcAddr:        addr1,
-					dstAddr:        addr2,
-					id:             1,
-					flags:          0,
-					fragmentOffset: 63,
-					payload:        ipv4Payload3Addr1ToAddr2[63:],
-				},
-			},
-			expectedPayloads: nil,
-		},
-		{
-			name: "Second fragment has MoreFlags set",
-			fragments: []fragmentData{
-				{
-					srcAddr:        addr1,
-					dstAddr:        addr2,
-					id:             1,
-					flags:          header.IPv4FlagMoreFragments,
-					fragmentOffset: 0,
-					payload:        ipv4Payload1Addr1ToAddr2[:64],
-				},
-				{
-					srcAddr:        addr1,
-					dstAddr:        addr2,
-					id:             1,
-					flags:          header.IPv4FlagMoreFragments,
-					fragmentOffset: 64,
-					payload:        ipv4Payload1Addr1ToAddr2[64:],
-				},
-			},
-			expectedPayloads: nil,
-		},
-		{
-			name: "Two fragments with different IDs",
-			fragments: []fragmentData{
-				{
-					srcAddr:        addr1,
-					dstAddr:        addr2,
-					id:             1,
-					flags:          header.IPv4FlagMoreFragments,
-					fragmentOffset: 0,
-					payload:        ipv4Payload1Addr1ToAddr2[:64],
-				},
-				{
-					srcAddr:        addr1,
-					dstAddr:        addr2,
-					id:             2,
-					flags:          0,
-					fragmentOffset: 64,
-					payload:        ipv4Payload1Addr1ToAddr2[64:],
-				},
-			},
-			expectedPayloads: nil,
-		},
-		{
-			name: "Two interleaved fragmented packets",
-			fragments: []fragmentData{
-				{
-					srcAddr:        addr1,
-					dstAddr:        addr2,
-					id:             1,
-					flags:          header.IPv4FlagMoreFragments,
-					fragmentOffset: 0,
-					payload:        ipv4Payload1Addr1ToAddr2[:64],
-				},
-				{
-					srcAddr:        addr1,
-					dstAddr:        addr2,
-					id:             2,
-					flags:          header.IPv4FlagMoreFragments,
-					fragmentOffset: 0,
-					payload:        ipv4Payload2Addr1ToAddr2[:64],
-				},
-				{
-					srcAddr:        addr1,
-					dstAddr:        addr2,
-					id:             1,
-					flags:          0,
-					fragmentOffset: 64,
-					payload:        ipv4Payload1Addr1ToAddr2[64:],
-				},
-				{
-					srcAddr:        addr1,
-					dstAddr:        addr2,
-					id:             2,
-					flags:          0,
-					fragmentOffset: 64,
-					payload:        ipv4Payload2Addr1ToAddr2[64:],
-				},
-			},
-			expectedPayloads: [][]byte{udpPayload1Addr1ToAddr2, udpPayload2Addr1ToAddr2},
-		},
-		{
-			name: "Two interleaved fragmented packets from different sources but with same ID",
-			fragments: []fragmentData{
-				{
-					srcAddr:        addr1,
-					dstAddr:        addr2,
-					id:             1,
-					flags:          header.IPv4FlagMoreFragments,
-					fragmentOffset: 0,
-					payload:        ipv4Payload1Addr1ToAddr2[:64],
-				},
-				{
-					srcAddr:        addr3,
-					dstAddr:        addr2,
-					id:             1,
-					flags:          header.IPv4FlagMoreFragments,
-					fragmentOffset: 0,
-					payload:        ipv4Payload1Addr3ToAddr2[:32],
-				},
-				{
-					srcAddr:        addr1,
-					dstAddr:        addr2,
-					id:             1,
-					flags:          0,
-					fragmentOffset: 64,
-					payload:        ipv4Payload1Addr1ToAddr2[64:],
-				},
-				{
-					srcAddr:        addr3,
-					dstAddr:        addr2,
-					id:             1,
-					flags:          0,
-					fragmentOffset: 32,
-					payload:        ipv4Payload1Addr3ToAddr2[32:],
-				},
-			},
-			expectedPayloads: [][]byte{udpPayload1Addr1ToAddr2, udpPayload1Addr3ToAddr2},
-		},
-		{
-			name: "Fragment without followup",
-			fragments: []fragmentData{
-				{
-					srcAddr:        addr1,
-					dstAddr:        addr2,
-					id:             1,
-					flags:          header.IPv4FlagMoreFragments,
-					fragmentOffset: 0,
-					payload:        ipv4Payload1Addr1ToAddr2[:64],
-				},
-			},
-			expectedPayloads: nil,
-		},
-		{
-			name: "Two fragments reassembled into a maximum UDP packet",
-			fragments: []fragmentData{
-				{
-					srcAddr:        addr1,
-					dstAddr:        addr2,
-					id:             1,
-					flags:          header.IPv4FlagMoreFragments,
-					fragmentOffset: 0,
-					payload:        ipv4Payload4Addr1ToAddr2[:65512],
-				},
-				{
-					srcAddr:        addr1,
-					dstAddr:        addr2,
-					id:             1,
-					flags:          0,
-					fragmentOffset: 65512,
-					payload:        ipv4Payload4Addr1ToAddr2[65512:],
-				},
-			},
-			expectedPayloads: [][]byte{udpPayload4Addr1ToAddr2},
-		},
-		{
-			name: "Two fragments with MF flag reassembled into a maximum UDP packet",
-			fragments: []fragmentData{
-				{
-					srcAddr:        addr1,
-					dstAddr:        addr2,
-					id:             1,
-					flags:          header.IPv4FlagMoreFragments,
-					fragmentOffset: 0,
-					payload:        ipv4Payload4Addr1ToAddr2[:65512],
-				},
-				{
-					srcAddr:        addr1,
-					dstAddr:        addr2,
-					id:             1,
-					flags:          header.IPv4FlagMoreFragments,
-					fragmentOffset: 65512,
-					payload:        ipv4Payload4Addr1ToAddr2[65512:],
-				},
-			},
-			expectedPayloads: nil,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			// Setup a stack and endpoint.
-			s := stack.New(stack.Options{
-				NetworkProtocols:   []stack.NetworkProtocolFactory{ipv4.NewProtocol},
-				TransportProtocols: []stack.TransportProtocolFactory{udp.NewProtocol},
-				RawFactory:         raw.EndpointFactory{},
-			})
-			e := channel.New(0, 1280, tcpip.LinkAddress("\xf0\x00"))
-			if err := s.CreateNIC(nicID, e); err != nil {
-				t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
-			}
-			if err := s.AddAddress(nicID, header.IPv4ProtocolNumber, addr2); err != nil {
-				t.Fatalf("AddAddress(%d, %d, %s) = %s", nicID, header.IPv4ProtocolNumber, addr2, 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(udp.ProtocolNumber, header.IPv4ProtocolNumber, &wq)
-			if err != nil {
-				t.Fatalf("NewEndpoint(%d, %d, _): %s", udp.ProtocolNumber, header.IPv4ProtocolNumber, err)
-			}
-			defer ep.Close()
-
-			bindAddr := tcpip.FullAddress{Addr: addr2, Port: 80}
-			if err := ep.Bind(bindAddr); err != nil {
-				t.Fatalf("Bind(%+v): %s", bindAddr, err)
-			}
-
-			// Bring up a raw endpoint so we can examine network headers.
-			epRaw, err := s.NewRawEndpoint(udp.ProtocolNumber, header.IPv4ProtocolNumber, &wq, true /* associated */)
-			if err != nil {
-				t.Fatalf("NewRawEndpoint(%d, %d, _, true): %s", udp.ProtocolNumber, header.IPv4ProtocolNumber, err)
-			}
-			defer epRaw.Close()
-
-			// Prepare and send the fragments.
-			for _, frag := range test.fragments {
-				hdr := buffer.NewPrependable(header.IPv4MinimumSize)
-
-				// Serialize IPv4 fixed header.
-				ip := header.IPv4(hdr.Prepend(header.IPv4MinimumSize))
-				ip.Encode(&header.IPv4Fields{
-					TotalLength:    header.IPv4MinimumSize + uint16(len(frag.payload)),
-					ID:             frag.id,
-					Flags:          frag.flags,
-					FragmentOffset: frag.fragmentOffset,
-					TTL:            64,
-					Protocol:       uint8(header.UDPProtocolNumber),
-					SrcAddr:        frag.srcAddr,
-					DstAddr:        frag.dstAddr,
-				})
-				ip.SetChecksum(^ip.CalculateChecksum())
-
-				vv := hdr.View().ToVectorisedView()
-				vv.AppendView(frag.payload)
-
-				e.InjectInbound(header.IPv4ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
-					Data: vv,
-				}))
-			}
-
-			if got, want := s.Stats().UDP.PacketsReceived.Value(), uint64(len(test.expectedPayloads)); got != want {
-				t.Errorf("got UDP Rx Packets = %d, want = %d", got, want)
-			}
-
-			for i, expectedPayload := range test.expectedPayloads {
-				// Check UDP payload delivered by UDP endpoint.
-				var buf bytes.Buffer
-				result, err := ep.Read(&buf, tcpip.ReadOptions{})
-				if err != nil {
-					t.Fatalf("(i=%d) ep.Read: %s", i, err)
-				}
-				if diff := cmp.Diff(tcpip.ReadResult{
-					Count: len(expectedPayload),
-					Total: len(expectedPayload),
-				}, result, checker.IgnoreCmpPath("ControlMessages")); diff != "" {
-					t.Errorf("(i=%d) ep.Read: unexpected result (-want +got):\n%s", i, diff)
-				}
-				if diff := cmp.Diff(expectedPayload, buf.Bytes()); diff != "" {
-					t.Errorf("(i=%d) ep.Read: UDP payload mismatch (-want +got):\n%s", i, diff)
-				}
-
-				// Check IPv4 header in packet delivered by raw endpoint.
-				buf.Reset()
-				result, err = epRaw.Read(&buf, tcpip.ReadOptions{})
-				if err != nil {
-					t.Fatalf("(i=%d) epRaw.Read: %s", i, err)
-				}
-				// Reassambly does not take care of checksum. Here we write our own
-				// check routine instead of using checker.IPv4.
-				ip := header.IPv4(buf.Bytes())
-				for _, check := range []checker.NetworkChecker{
-					checker.FragmentFlags(0),
-					checker.FragmentOffset(0),
-					checker.IPFullLength(uint16(header.IPv4MinimumSize + header.UDPMinimumSize + len(expectedPayload))),
-				} {
-					check(t, []header.Network{ip})
-				}
-			}
-
-			res, err := ep.Read(ioutil.Discard, tcpip.ReadOptions{})
-			if _, ok := err.(*tcpip.ErrWouldBlock); !ok {
-				t.Fatalf("(last) got Read = (%#v, %v), want = (_, %s)", res, err, &tcpip.ErrWouldBlock{})
-			}
-		})
-	}
-}
-
-func TestWriteStats(t *testing.T) {
-	const nPackets = 3
-
-	tests := []struct {
-		name          string
-		setup         func(*testing.T, *stack.Stack)
-		allowPackets  int
-		expectSent    int
-		expectDropped int
-		expectWritten int
-	}{
-		{
-			name: "Accept all",
-			// No setup needed, tables accept everything by default.
-			setup:         func(*testing.T, *stack.Stack) {},
-			allowPackets:  math.MaxInt32,
-			expectSent:    nPackets,
-			expectDropped: 0,
-			expectWritten: nPackets,
-		}, {
-			name: "Accept all with error",
-			// No setup needed, tables accept everything by default.
-			setup:         func(*testing.T, *stack.Stack) {},
-			allowPackets:  nPackets - 1,
-			expectSent:    nPackets - 1,
-			expectDropped: 0,
-			expectWritten: nPackets - 1,
-		}, {
-			name: "Drop all",
-			setup: func(t *testing.T, stk *stack.Stack) {
-				// Install Output DROP rule.
-				t.Helper()
-				ipt := stk.IPTables()
-				filter := ipt.GetTable(stack.FilterID, false /* ipv6 */)
-				ruleIdx := filter.BuiltinChains[stack.Output]
-				filter.Rules[ruleIdx].Target = &stack.DropTarget{}
-				if err := ipt.ReplaceTable(stack.FilterID, filter, false /* ipv6 */); err != nil {
-					t.Fatalf("failed to replace table: %s", err)
-				}
-			},
-			allowPackets:  math.MaxInt32,
-			expectSent:    0,
-			expectDropped: nPackets,
-			expectWritten: nPackets,
-		}, {
-			name: "Drop some",
-			setup: func(t *testing.T, stk *stack.Stack) {
-				// Install Output DROP rule that matches only 1
-				// of the 3 packets.
-				t.Helper()
-				ipt := stk.IPTables()
-				filter := ipt.GetTable(stack.FilterID, false /* ipv6 */)
-				// We'll match and DROP the last packet.
-				ruleIdx := filter.BuiltinChains[stack.Output]
-				filter.Rules[ruleIdx].Target = &stack.DropTarget{}
-				filter.Rules[ruleIdx].Matchers = []stack.Matcher{&limitedMatcher{nPackets - 1}}
-				// Make sure the next rule is ACCEPT.
-				filter.Rules[ruleIdx+1].Target = &stack.AcceptTarget{}
-				if err := ipt.ReplaceTable(stack.FilterID, filter, false /* ipv6 */); err != nil {
-					t.Fatalf("failed to replace table: %s", err)
-				}
-			},
-			allowPackets:  math.MaxInt32,
-			expectSent:    nPackets - 1,
-			expectDropped: 1,
-			expectWritten: nPackets,
-		},
-	}
-
-	// Parameterize the tests to run with both WritePacket and WritePackets.
-	writers := []struct {
-		name         string
-		writePackets func(*stack.Route, stack.PacketBufferList) (int, tcpip.Error)
-	}{
-		{
-			name: "WritePacket",
-			writePackets: func(rt *stack.Route, pkts stack.PacketBufferList) (int, tcpip.Error) {
-				nWritten := 0
-				for pkt := pkts.Front(); pkt != nil; pkt = pkt.Next() {
-					if err := rt.WritePacket(nil, stack.NetworkHeaderParams{}, pkt); err != nil {
-						return nWritten, err
-					}
-					nWritten++
-				}
-				return nWritten, nil
-			},
-		}, {
-			name: "WritePackets",
-			writePackets: func(rt *stack.Route, pkts stack.PacketBufferList) (int, tcpip.Error) {
-				return rt.WritePackets(nil, pkts, stack.NetworkHeaderParams{})
-			},
-		},
-	}
-
-	for _, writer := range writers {
-		t.Run(writer.name, func(t *testing.T) {
-			for _, test := range tests {
-				t.Run(test.name, func(t *testing.T) {
-					ep := testutil.NewMockLinkEndpoint(header.IPv4MinimumMTU, &tcpip.ErrInvalidEndpointState{}, test.allowPackets)
-					rt := buildRoute(t, ep)
-
-					var pkts stack.PacketBufferList
-					for i := 0; i < nPackets; i++ {
-						pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{
-							ReserveHeaderBytes: header.UDPMinimumSize + int(rt.MaxHeaderLength()),
-							Data:               buffer.NewView(0).ToVectorisedView(),
-						})
-						pkt.TransportHeader().Push(header.UDPMinimumSize)
-						pkts.PushBack(pkt)
-					}
-
-					test.setup(t, rt.Stack())
-
-					nWritten, _ := writer.writePackets(rt, pkts)
-
-					if got := int(rt.Stats().IP.PacketsSent.Value()); got != test.expectSent {
-						t.Errorf("sent %d packets, but expected to send %d", got, test.expectSent)
-					}
-					if got := int(rt.Stats().IP.IPTablesOutputDropped.Value()); got != test.expectDropped {
-						t.Errorf("dropped %d packets, but expected to drop %d", got, test.expectDropped)
-					}
-					if nWritten != test.expectWritten {
-						t.Errorf("wrote %d packets, but expected WritePackets to return %d", nWritten, test.expectWritten)
-					}
-				})
-			}
-		})
-	}
-}
-
-func buildRoute(t *testing.T, ep stack.LinkEndpoint) *stack.Route {
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol},
-	})
-	if err := s.CreateNIC(1, ep); err != nil {
-		t.Fatalf("CreateNIC(1, _) failed: %s", err)
-	}
-	const (
-		src = "\x10\x00\x00\x01"
-		dst = "\x10\x00\x00\x02"
-	)
-	if err := s.AddAddress(1, ipv4.ProtocolNumber, src); err != nil {
-		t.Fatalf("AddAddress(1, %d, %s) failed: %s", ipv4.ProtocolNumber, src, err)
-	}
-	{
-		mask := tcpip.AddressMask(header.IPv4Broadcast)
-		subnet, err := tcpip.NewSubnet(dst, mask)
-		if err != nil {
-			t.Fatalf("NewSubnet(%s, %s) failed: %v", dst, mask, err)
-		}
-		s.SetRouteTable([]tcpip.Route{{
-			Destination: subnet,
-			NIC:         1,
-		}})
-	}
-	rt, err := s.FindRoute(1, src, dst, ipv4.ProtocolNumber, false /* multicastLoop */)
-	if err != nil {
-		t.Fatalf("FindRoute(1, %s, %s, %d, false) = %s", src, dst, ipv4.ProtocolNumber, err)
-	}
-	return rt
-}
-
-// limitedMatcher is an iptables matcher that matches after a certain number of
-// packets are checked against it.
-type limitedMatcher struct {
-	limit int
-}
-
-// Name implements Matcher.Name.
-func (*limitedMatcher) Name() string {
-	return "limitedMatcher"
-}
-
-// Match implements Matcher.Match.
-func (lm *limitedMatcher) Match(stack.Hook, *stack.PacketBuffer, string, string) (bool, bool) {
-	if lm.limit == 0 {
-		return true, false
-	}
-	lm.limit--
-	return false, false
-}
-
-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")
-
-		host1IPv4Addr = tcpip.ProtocolAddress{
-			Protocol: ipv4.ProtocolNumber,
-			AddressWithPrefix: tcpip.AddressWithPrefix{
-				Address:   tcpip.Address(net.ParseIP("192.168.0.1").To4()),
-				PrefixLen: 24,
-			},
-		}
-		host2IPv4Addr = tcpip.ProtocolAddress{
-			Protocol: ipv4.ProtocolNumber,
-			AddressWithPrefix: tcpip.AddressWithPrefix{
-				Address:   tcpip.Address(net.ParseIP("192.168.0.2").To4()),
-				PrefixLen: 8,
-			},
-		}
-	)
-
-	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.IPv4MinimumSize + 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, host2IPv4Addr.AddressWithPrefix.Address, host1IPv4Addr.AddressWithPrefix.Address, header.UDPMinimumSize)
-				sum = header.Checksum(header.UDP([]byte{}), sum)
-				u.SetChecksum(^u.CalculateChecksum(sum))
-				ip := header.IPv4(hdr.Prepend(header.IPv4MinimumSize))
-				ip.Encode(&header.IPv4Fields{
-					TotalLength: header.IPv4MinimumSize + header.UDPMinimumSize,
-					TTL:         ipv4.DefaultTTL,
-					Protocol:    uint8(udp.ProtocolNumber),
-					SrcAddr:     host2IPv4Addr.AddressWithPrefix.Address,
-					DstAddr:     host1IPv4Addr.AddressWithPrefix.Address,
-				})
-				ip.SetChecksum(^ip.CalculateChecksum())
-				e.InjectInbound(ipv4.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 != header.IPv4ProtocolNumber {
-					t.Errorf("got p.Proto = %d, want = %d", p.Proto, header.IPv4ProtocolNumber)
-				}
-				if p.Route.RemoteLinkAddress != host2NICLinkAddr {
-					t.Errorf("got p.Route.RemoteLinkAddress = %s, want = %s", p.Route.RemoteLinkAddress, host2NICLinkAddr)
-				}
-				checker.IPv4(t, stack.PayloadSince(p.Pkt.NetworkHeader()),
-					checker.SrcAddr(host1IPv4Addr.AddressWithPrefix.Address),
-					checker.DstAddr(host2IPv4Addr.AddressWithPrefix.Address),
-					checker.ICMPv4(
-						checker.ICMPv4Type(header.ICMPv4DstUnreachable),
-						checker.ICMPv4Code(header.ICMPv4PortUnreachable)))
-			},
-		},
-
-		{
-			name: "Ping",
-			rxPkt: func(e *channel.Endpoint) {
-				totalLen := header.IPv4MinimumSize + header.ICMPv4MinimumSize
-				hdr := buffer.NewPrependable(totalLen)
-				pkt := header.ICMPv4(hdr.Prepend(header.ICMPv4MinimumSize))
-				pkt.SetType(header.ICMPv4Echo)
-				pkt.SetCode(0)
-				pkt.SetChecksum(0)
-				pkt.SetChecksum(^header.Checksum(pkt, 0))
-				ip := header.IPv4(hdr.Prepend(header.IPv4MinimumSize))
-				ip.Encode(&header.IPv4Fields{
-					TotalLength: uint16(totalLen),
-					Protocol:    uint8(icmp.ProtocolNumber4),
-					TTL:         ipv4.DefaultTTL,
-					SrcAddr:     host2IPv4Addr.AddressWithPrefix.Address,
-					DstAddr:     host1IPv4Addr.AddressWithPrefix.Address,
-				})
-				ip.SetChecksum(^ip.CalculateChecksum())
-				e.InjectInbound(header.IPv4ProtocolNumber, 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 != header.IPv4ProtocolNumber {
-					t.Errorf("got p.Proto = %d, want = %d", p.Proto, header.IPv4ProtocolNumber)
-				}
-				if p.Route.RemoteLinkAddress != host2NICLinkAddr {
-					t.Errorf("got p.Route.RemoteLinkAddress = %s, want = %s", p.Route.RemoteLinkAddress, host2NICLinkAddr)
-				}
-				checker.IPv4(t, stack.PayloadSince(p.Pkt.NetworkHeader()),
-					checker.SrcAddr(host1IPv4Addr.AddressWithPrefix.Address),
-					checker.DstAddr(host2IPv4Addr.AddressWithPrefix.Address),
-					checker.ICMPv4(
-						checker.ICMPv4Type(header.ICMPv4EchoReply),
-						checker.ICMPv4Code(header.ICMPv4UnusedCode)))
-			},
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			e := channel.New(1, defaultMTU, host1NICLinkAddr)
-			e.LinkEPCapabilities |= stack.CapabilityResolutionRequired
-			s := stack.New(stack.Options{
-				NetworkProtocols:   []stack.NetworkProtocolFactory{arp.NewProtocol, ipv4.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, host1IPv4Addr); err != nil {
-				t.Fatalf("s.AddProtocolAddress(%d, %#v): %s", nicID, host1IPv4Addr, err)
-			}
-
-			s.SetRouteTable([]tcpip.Route{
-				{
-					Destination: host1IPv4Addr.AddressWithPrefix.Subnet(),
-					NIC:         nicID,
-				},
-			})
-
-			// Receive a packet to trigger link resolution before a response is sent.
-			test.rxPkt(e)
-
-			// Wait for a ARP request 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 != arp.ProtocolNumber {
-					t.Errorf("got p.Proto = %d, want = %d", p.Proto, arp.ProtocolNumber)
-				}
-				if p.Route.RemoteLinkAddress != header.EthernetBroadcastAddress {
-					t.Errorf("got p.Route.RemoteLinkAddress = %s, want = %s", p.Route.RemoteLinkAddress, header.EthernetBroadcastAddress)
-				}
-				rep := header.ARP(p.Pkt.NetworkHeader().View())
-				if got := rep.Op(); got != header.ARPRequest {
-					t.Errorf("got Op() = %d, want = %d", got, header.ARPRequest)
-				}
-				if got := tcpip.LinkAddress(rep.HardwareAddressSender()); got != host1NICLinkAddr {
-					t.Errorf("got HardwareAddressSender = %s, want = %s", got, host1NICLinkAddr)
-				}
-				if got := tcpip.Address(rep.ProtocolAddressSender()); got != host1IPv4Addr.AddressWithPrefix.Address {
-					t.Errorf("got ProtocolAddressSender = %s, want = %s", got, host1IPv4Addr.AddressWithPrefix.Address)
-				}
-				if got := tcpip.Address(rep.ProtocolAddressTarget()); got != host2IPv4Addr.AddressWithPrefix.Address {
-					t.Errorf("got ProtocolAddressTarget = %s, want = %s", got, host2IPv4Addr.AddressWithPrefix.Address)
-				}
-			}
-
-			// Send an ARP reply to complete link address resolution.
-			{
-				hdr := buffer.View(make([]byte, header.ARPSize))
-				packet := header.ARP(hdr)
-				packet.SetIPv4OverEthernet()
-				packet.SetOp(header.ARPReply)
-				copy(packet.HardwareAddressSender(), host2NICLinkAddr)
-				copy(packet.ProtocolAddressSender(), host2IPv4Addr.AddressWithPrefix.Address)
-				copy(packet.HardwareAddressTarget(), host1NICLinkAddr)
-				copy(packet.ProtocolAddressTarget(), host1IPv4Addr.AddressWithPrefix.Address)
-				e.InjectInbound(arp.ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
-					Data: hdr.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)
-		})
-	}
-}
-
-// TestCloseLocking test that lock ordering is followed when closing an
-// endpoint.
-func TestCloseLocking(t *testing.T) {
-	const (
-		nicID1 = 1
-		nicID2 = 2
-
-		src = tcpip.Address("\x10\x00\x00\x01")
-		dst = tcpip.Address("\x10\x00\x00\x02")
-
-		iterations = 1000
-	)
-
-	s := stack.New(stack.Options{
-		NetworkProtocols:   []stack.NetworkProtocolFactory{ipv4.NewProtocol},
-		TransportProtocols: []stack.TransportProtocolFactory{udp.NewProtocol},
-	})
-
-	// Perform NAT so that the endoint tries to search for a sibling endpoint
-	// which ends up taking the protocol and endpoint lock (in that order).
-	table := stack.Table{
-		Rules: []stack.Rule{
-			{Target: &stack.AcceptTarget{NetworkProtocol: header.IPv4ProtocolNumber}},
-			{Target: &stack.AcceptTarget{NetworkProtocol: header.IPv4ProtocolNumber}},
-			{Target: &stack.RedirectTarget{Port: 5, NetworkProtocol: header.IPv4ProtocolNumber}},
-			{Target: &stack.AcceptTarget{NetworkProtocol: header.IPv4ProtocolNumber}},
-			{Target: &stack.ErrorTarget{NetworkProtocol: header.IPv4ProtocolNumber}},
-		},
-		BuiltinChains: [stack.NumHooks]int{
-			stack.Prerouting:  0,
-			stack.Input:       1,
-			stack.Forward:     stack.HookUnset,
-			stack.Output:      2,
-			stack.Postrouting: 3,
-		},
-		Underflows: [stack.NumHooks]int{
-			stack.Prerouting:  0,
-			stack.Input:       1,
-			stack.Forward:     stack.HookUnset,
-			stack.Output:      2,
-			stack.Postrouting: 3,
-		},
-	}
-	if err := s.IPTables().ReplaceTable(stack.NATID, table, false /* ipv6 */); err != nil {
-		t.Fatalf("s.IPTables().ReplaceTable(...): %s", err)
-	}
-
-	e := channel.New(0, defaultMTU, "")
-	if err := s.CreateNIC(nicID1, e); err != nil {
-		t.Fatalf("CreateNIC(%d, _): %s", nicID1, err)
-	}
-
-	if err := s.AddAddress(nicID1, ipv4.ProtocolNumber, src); err != nil {
-		t.Fatalf("AddAddress(%d, %d, %s) failed: %s", nicID1, ipv4.ProtocolNumber, src, err)
-	}
-
-	s.SetRouteTable([]tcpip.Route{{
-		Destination: header.IPv4EmptySubnet,
-		NIC:         nicID1,
-	}})
-
-	var wq waiter.Queue
-	ep, err := s.NewEndpoint(udp.ProtocolNumber, ipv4.ProtocolNumber, &wq)
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer ep.Close()
-
-	addr := tcpip.FullAddress{NIC: nicID1, Addr: dst, Port: 53}
-	if err := ep.Connect(addr); err != nil {
-		t.Errorf("ep.Connect(%#v): %s", addr, err)
-	}
-
-	var wg sync.WaitGroup
-	defer wg.Wait()
-
-	// Writing packets should trigger NAT which requires the stack to search the
-	// protocol for network endpoints with the destination address.
-	//
-	// Creating and removing interfaces should modify the protocol and endpoint
-	// which requires taking the locks of each.
-	//
-	// We expect the protocol > endpoint lock ordering to be followed here.
-	wg.Add(2)
-	go func() {
-		defer wg.Done()
-
-		data := []byte{1, 2, 3, 4}
-
-		for i := 0; i < iterations; i++ {
-			var r bytes.Reader
-			r.Reset(data)
-			if n, err := ep.Write(&r, tcpip.WriteOptions{}); err != nil {
-				t.Errorf("ep.Write(_, _): %s", err)
-				return
-			} else if want := int64(len(data)); n != want {
-				t.Errorf("got ep.Write(_, _) = (%d, _), want = (%d, _)", n, want)
-				return
-			}
-		}
-	}()
-	go func() {
-		defer wg.Done()
-
-		for i := 0; i < iterations; i++ {
-			if err := s.CreateNIC(nicID2, loopback.New()); err != nil {
-				t.Errorf("CreateNIC(%d, _): %s", nicID2, err)
-				return
-			}
-			if err := s.RemoveNIC(nicID2); err != nil {
-				t.Errorf("RemoveNIC(%d): %s", nicID2, err)
-				return
-			}
-		}
-	}()
-}
diff --git a/pkg/tcpip/network/ipv4/stats_test.go b/pkg/tcpip/network/ipv4/stats_test.go
deleted file mode 100644
index a637f9d..0000000
--- a/pkg/tcpip/network/ipv4/stats_test.go
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright 2020 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 ipv4
-
-import (
-	"reflect"
-	"testing"
-
-	"gvisor.dev/gvisor/pkg/tcpip"
-	"gvisor.dev/gvisor/pkg/tcpip/network/internal/testutil"
-	"gvisor.dev/gvisor/pkg/tcpip/stack"
-)
-
-var _ stack.NetworkInterface = (*testInterface)(nil)
-
-type testInterface struct {
-	stack.NetworkInterface
-	nicID tcpip.NICID
-}
-
-func (t *testInterface) ID() tcpip.NICID {
-	return t.nicID
-}
-
-func knownNICIDs(proto *protocol) []tcpip.NICID {
-	var nicIDs []tcpip.NICID
-
-	for k := range proto.mu.eps {
-		nicIDs = append(nicIDs, k)
-	}
-
-	return nicIDs
-}
-
-func TestClearEndpointFromProtocolOnClose(t *testing.T) {
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocolFactory{NewProtocol},
-	})
-	proto := s.NetworkProtocolInstance(ProtocolNumber).(*protocol)
-	nic := testInterface{nicID: 1}
-	ep := proto.NewEndpoint(&nic, nil).(*endpoint)
-	var nicIDs []tcpip.NICID
-
-	proto.mu.Lock()
-	foundEP, hasEndpointBeforeClose := proto.mu.eps[nic.ID()]
-	nicIDs = knownNICIDs(proto)
-	proto.mu.Unlock()
-
-	if !hasEndpointBeforeClose {
-		t.Fatalf("expected to find the nic id %d in the protocol's endpoint map (%v)", nic.ID(), nicIDs)
-	}
-	if foundEP != ep {
-		t.Fatalf("found an incorrect endpoint mapped to nic id %d", nic.ID())
-	}
-
-	ep.Close()
-
-	proto.mu.Lock()
-	_, hasEP := proto.mu.eps[nic.ID()]
-	nicIDs = knownNICIDs(proto)
-	proto.mu.Unlock()
-	if hasEP {
-		t.Fatalf("unexpectedly found an endpoint mapped to the nic id %d in the protocol's known nic ids (%v)", nic.ID(), nicIDs)
-	}
-}
-
-func TestMultiCounterStatsInitialization(t *testing.T) {
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocolFactory{NewProtocol},
-	})
-	proto := s.NetworkProtocolInstance(ProtocolNumber).(*protocol)
-	var nic testInterface
-	ep := proto.NewEndpoint(&nic, nil).(*endpoint)
-	// At this point, the Stack's stats and the NetworkEndpoint's stats are
-	// expected to be bound by a MultiCounterStat.
-	refStack := s.Stats()
-	refEP := ep.stats.localStats
-	if err := testutil.ValidateMultiCounterStats(reflect.ValueOf(&ep.stats.ip).Elem(), []reflect.Value{reflect.ValueOf(&refEP.IP).Elem(), reflect.ValueOf(&refStack.IP).Elem()}); err != nil {
-		t.Error(err)
-	}
-	if err := testutil.ValidateMultiCounterStats(reflect.ValueOf(&ep.stats.icmp).Elem(), []reflect.Value{reflect.ValueOf(&refEP.ICMP).Elem(), reflect.ValueOf(&refStack.ICMP.V4).Elem()}); err != nil {
-		t.Error(err)
-	}
-	if err := testutil.ValidateMultiCounterStats(reflect.ValueOf(&ep.stats.igmp).Elem(), []reflect.Value{reflect.ValueOf(&refEP.IGMP).Elem(), reflect.ValueOf(&refStack.IGMP).Elem()}); err != nil {
-		t.Error(err)
-	}
-}
diff --git a/pkg/tcpip/network/ipv6/icmp_test.go b/pkg/tcpip/network/ipv6/icmp_test.go
deleted file mode 100644
index 47d713f..0000000
--- a/pkg/tcpip/network/ipv6/icmp_test.go
+++ /dev/null
@@ -1,1716 +0,0 @@
-// 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)
-			}
-		})
-	}
-}
diff --git a/pkg/tcpip/network/ipv6/ipv6_state_autogen.go b/pkg/tcpip/network/ipv6/ipv6_state_autogen.go
new file mode 100644
index 0000000..13d4278
--- /dev/null
+++ b/pkg/tcpip/network/ipv6/ipv6_state_autogen.go
@@ -0,0 +1,136 @@
+// automatically generated by stateify.
+
+package ipv6
+
+import (
+	"gvisor.dev/gvisor/pkg/state"
+)
+
+func (i *icmpv6DestinationUnreachableSockError) StateTypeName() string {
+	return "pkg/tcpip/network/ipv6.icmpv6DestinationUnreachableSockError"
+}
+
+func (i *icmpv6DestinationUnreachableSockError) StateFields() []string {
+	return []string{}
+}
+
+func (i *icmpv6DestinationUnreachableSockError) beforeSave() {}
+
+// +checklocksignore
+func (i *icmpv6DestinationUnreachableSockError) StateSave(stateSinkObject state.Sink) {
+	i.beforeSave()
+}
+
+func (i *icmpv6DestinationUnreachableSockError) afterLoad() {}
+
+// +checklocksignore
+func (i *icmpv6DestinationUnreachableSockError) StateLoad(stateSourceObject state.Source) {
+}
+
+func (i *icmpv6DestinationNetworkUnreachableSockError) StateTypeName() string {
+	return "pkg/tcpip/network/ipv6.icmpv6DestinationNetworkUnreachableSockError"
+}
+
+func (i *icmpv6DestinationNetworkUnreachableSockError) StateFields() []string {
+	return []string{
+		"icmpv6DestinationUnreachableSockError",
+	}
+}
+
+func (i *icmpv6DestinationNetworkUnreachableSockError) beforeSave() {}
+
+// +checklocksignore
+func (i *icmpv6DestinationNetworkUnreachableSockError) StateSave(stateSinkObject state.Sink) {
+	i.beforeSave()
+	stateSinkObject.Save(0, &i.icmpv6DestinationUnreachableSockError)
+}
+
+func (i *icmpv6DestinationNetworkUnreachableSockError) afterLoad() {}
+
+// +checklocksignore
+func (i *icmpv6DestinationNetworkUnreachableSockError) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &i.icmpv6DestinationUnreachableSockError)
+}
+
+func (i *icmpv6DestinationPortUnreachableSockError) StateTypeName() string {
+	return "pkg/tcpip/network/ipv6.icmpv6DestinationPortUnreachableSockError"
+}
+
+func (i *icmpv6DestinationPortUnreachableSockError) StateFields() []string {
+	return []string{
+		"icmpv6DestinationUnreachableSockError",
+	}
+}
+
+func (i *icmpv6DestinationPortUnreachableSockError) beforeSave() {}
+
+// +checklocksignore
+func (i *icmpv6DestinationPortUnreachableSockError) StateSave(stateSinkObject state.Sink) {
+	i.beforeSave()
+	stateSinkObject.Save(0, &i.icmpv6DestinationUnreachableSockError)
+}
+
+func (i *icmpv6DestinationPortUnreachableSockError) afterLoad() {}
+
+// +checklocksignore
+func (i *icmpv6DestinationPortUnreachableSockError) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &i.icmpv6DestinationUnreachableSockError)
+}
+
+func (i *icmpv6DestinationAddressUnreachableSockError) StateTypeName() string {
+	return "pkg/tcpip/network/ipv6.icmpv6DestinationAddressUnreachableSockError"
+}
+
+func (i *icmpv6DestinationAddressUnreachableSockError) StateFields() []string {
+	return []string{
+		"icmpv6DestinationUnreachableSockError",
+	}
+}
+
+func (i *icmpv6DestinationAddressUnreachableSockError) beforeSave() {}
+
+// +checklocksignore
+func (i *icmpv6DestinationAddressUnreachableSockError) StateSave(stateSinkObject state.Sink) {
+	i.beforeSave()
+	stateSinkObject.Save(0, &i.icmpv6DestinationUnreachableSockError)
+}
+
+func (i *icmpv6DestinationAddressUnreachableSockError) afterLoad() {}
+
+// +checklocksignore
+func (i *icmpv6DestinationAddressUnreachableSockError) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &i.icmpv6DestinationUnreachableSockError)
+}
+
+func (e *icmpv6PacketTooBigSockError) StateTypeName() string {
+	return "pkg/tcpip/network/ipv6.icmpv6PacketTooBigSockError"
+}
+
+func (e *icmpv6PacketTooBigSockError) StateFields() []string {
+	return []string{
+		"mtu",
+	}
+}
+
+func (e *icmpv6PacketTooBigSockError) beforeSave() {}
+
+// +checklocksignore
+func (e *icmpv6PacketTooBigSockError) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+	stateSinkObject.Save(0, &e.mtu)
+}
+
+func (e *icmpv6PacketTooBigSockError) afterLoad() {}
+
+// +checklocksignore
+func (e *icmpv6PacketTooBigSockError) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &e.mtu)
+}
+
+func init() {
+	state.Register((*icmpv6DestinationUnreachableSockError)(nil))
+	state.Register((*icmpv6DestinationNetworkUnreachableSockError)(nil))
+	state.Register((*icmpv6DestinationPortUnreachableSockError)(nil))
+	state.Register((*icmpv6DestinationAddressUnreachableSockError)(nil))
+	state.Register((*icmpv6PacketTooBigSockError)(nil))
+}
diff --git a/pkg/tcpip/network/ipv6/ipv6_test.go b/pkg/tcpip/network/ipv6/ipv6_test.go
deleted file mode 100644
index 81f5f23..0000000
--- a/pkg/tcpip/network/ipv6/ipv6_test.go
+++ /dev/null
@@ -1,3154 +0,0 @@
-// 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 ipv6
-
-import (
-	"bytes"
-	"encoding/hex"
-	"fmt"
-	"io/ioutil"
-	"math"
-	"net"
-	"reflect"
-	"testing"
-
-	"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/faketime"
-	"gvisor.dev/gvisor/pkg/tcpip/header"
-	"gvisor.dev/gvisor/pkg/tcpip/link/channel"
-	"gvisor.dev/gvisor/pkg/tcpip/network/internal/testutil"
-	"gvisor.dev/gvisor/pkg/tcpip/stack"
-	"gvisor.dev/gvisor/pkg/tcpip/transport/icmp"
-	"gvisor.dev/gvisor/pkg/tcpip/transport/tcp"
-	"gvisor.dev/gvisor/pkg/tcpip/transport/udp"
-	"gvisor.dev/gvisor/pkg/waiter"
-)
-
-const (
-	addr1 = "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"
-	addr2 = "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02"
-	// The least significant 3 bytes are the same as addr2 so both addr2 and
-	// addr3 will have the same solicited-node address.
-	addr3 = "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x02"
-	addr4 = "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x03"
-
-	// Tests use the extension header identifier values as uint8 instead of
-	// header.IPv6ExtensionHeaderIdentifier.
-	hopByHopExtHdrID    = uint8(header.IPv6HopByHopOptionsExtHdrIdentifier)
-	routingExtHdrID     = uint8(header.IPv6RoutingExtHdrIdentifier)
-	fragmentExtHdrID    = uint8(header.IPv6FragmentExtHdrIdentifier)
-	destinationExtHdrID = uint8(header.IPv6DestinationOptionsExtHdrIdentifier)
-	noNextHdrID         = uint8(header.IPv6NoNextHeaderIdentifier)
-	unknownHdrID        = uint8(header.IPv6UnknownExtHdrIdentifier)
-
-	extraHeaderReserve = 50
-)
-
-// testReceiveICMP tests receiving an ICMP packet from src to dst. want is the
-// expected Neighbor Advertisement received count after receiving the packet.
-func testReceiveICMP(t *testing.T, s *stack.Stack, e *channel.Endpoint, src, dst tcpip.Address, want uint64) {
-	t.Helper()
-
-	// Receive ICMP packet.
-	hdr := buffer.NewPrependable(header.IPv6MinimumSize + header.ICMPv6NeighborAdvertMinimumSize)
-	pkt := header.ICMPv6(hdr.Prepend(header.ICMPv6NeighborAdvertMinimumSize))
-	pkt.SetType(header.ICMPv6NeighborAdvert)
-	pkt.SetChecksum(header.ICMPv6Checksum(header.ICMPv6ChecksumParams{
-		Header: pkt,
-		Src:    src,
-		Dst:    dst,
-	}))
-	payloadLength := hdr.UsedLength()
-	ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize))
-	ip.Encode(&header.IPv6Fields{
-		PayloadLength:     uint16(payloadLength),
-		TransportProtocol: header.ICMPv6ProtocolNumber,
-		HopLimit:          255,
-		SrcAddr:           src,
-		DstAddr:           dst,
-	})
-
-	e.InjectInbound(ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
-		Data: hdr.View().ToVectorisedView(),
-	}))
-
-	stats := s.Stats().ICMP.V6.PacketsReceived
-
-	if got := stats.NeighborAdvert.Value(); got != want {
-		t.Fatalf("got NeighborAdvert = %d, want = %d", got, want)
-	}
-}
-
-// testReceiveUDP tests receiving a UDP packet from src to dst. want is the
-// expected UDP received count after receiving the packet.
-func testReceiveUDP(t *testing.T, s *stack.Stack, e *channel.Endpoint, src, dst tcpip.Address, want uint64) {
-	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(udp.ProtocolNumber, ProtocolNumber, &wq)
-	if err != nil {
-		t.Fatalf("NewEndpoint failed: %v", err)
-	}
-	defer ep.Close()
-
-	if err := ep.Bind(tcpip.FullAddress{Addr: dst, Port: 80}); err != nil {
-		t.Fatalf("ep.Bind(...) failed: %v", err)
-	}
-
-	// Receive UDP Packet.
-	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,
-	})
-
-	// UDP pseudo-header checksum.
-	sum := header.PseudoHeaderChecksum(udp.ProtocolNumber, src, dst, header.UDPMinimumSize)
-
-	// UDP checksum
-	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:          255,
-		SrcAddr:           src,
-		DstAddr:           dst,
-	})
-
-	e.InjectInbound(ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
-		Data: hdr.View().ToVectorisedView(),
-	}))
-
-	stat := s.Stats().UDP.PacketsReceived
-
-	if got := stat.Value(); got != want {
-		t.Fatalf("got UDPPacketsReceived = %d, want = %d", got, want)
-	}
-}
-
-func compareFragments(packets []*stack.PacketBuffer, sourcePacket *stack.PacketBuffer, mtu uint32, wantFragments []fragmentInfo, proto tcpip.TransportProtocolNumber) error {
-	// sourcePacket does not have its IP Header populated. Let's copy the one
-	// from the first fragment.
-	source := header.IPv6(packets[0].NetworkHeader().View())
-	sourceIPHeadersLen := len(source)
-	vv := buffer.NewVectorisedView(sourcePacket.Size(), sourcePacket.Views())
-	source = append(source, vv.ToView()...)
-
-	var reassembledPayload buffer.VectorisedView
-	for i, fragment := range packets {
-		// Confirm that the packet is valid.
-		allBytes := buffer.NewVectorisedView(fragment.Size(), fragment.Views())
-		fragmentIPHeaders := header.IPv6(allBytes.ToView())
-		if !fragmentIPHeaders.IsValid(len(fragmentIPHeaders)) {
-			return fmt.Errorf("fragment #%d: IP packet is invalid:\n%s", i, hex.Dump(fragmentIPHeaders))
-		}
-
-		fragmentIPHeadersLength := fragment.NetworkHeader().View().Size()
-		if fragmentIPHeadersLength != sourceIPHeadersLen {
-			return fmt.Errorf("fragment #%d: got fragmentIPHeadersLength = %d, want = %d", i, fragmentIPHeadersLength, sourceIPHeadersLen)
-		}
-
-		if got := len(fragmentIPHeaders); got > int(mtu) {
-			return fmt.Errorf("fragment #%d: got len(fragmentIPHeaders) = %d, want <= %d", i, got, mtu)
-		}
-
-		sourceIPHeader := source[:header.IPv6MinimumSize]
-		fragmentIPHeader := fragmentIPHeaders[:header.IPv6MinimumSize]
-
-		if got := fragmentIPHeaders.PayloadLength(); got != wantFragments[i].payloadSize {
-			return fmt.Errorf("fragment #%d: got fragmentIPHeaders.PayloadLength() = %d, want = %d", i, got, wantFragments[i].payloadSize)
-		}
-
-		// We expect the IPv6 Header to be similar across each fragment, besides the
-		// payload length.
-		sourceIPHeader.SetPayloadLength(0)
-		fragmentIPHeader.SetPayloadLength(0)
-		if diff := cmp.Diff(fragmentIPHeader, sourceIPHeader); diff != "" {
-			return fmt.Errorf("fragment #%d: fragmentIPHeader mismatch (-want +got):\n%s", i, diff)
-		}
-
-		if got := fragment.AvailableHeaderBytes(); got != extraHeaderReserve {
-			return fmt.Errorf("fragment #%d: got packet.AvailableHeaderBytes() = %d, want = %d", i, got, extraHeaderReserve)
-		}
-		if fragment.NetworkProtocolNumber != sourcePacket.NetworkProtocolNumber {
-			return fmt.Errorf("fragment #%d: got fragment.NetworkProtocolNumber = %d, want = %d", i, fragment.NetworkProtocolNumber, sourcePacket.NetworkProtocolNumber)
-		}
-
-		if len(packets) > 1 {
-			// If the source packet was big enough that it needed fragmentation, let's
-			// inspect the fragment header. Because no other extension headers are
-			// supported, it will always be the last extension header.
-			fragmentHeader := header.IPv6Fragment(fragmentIPHeaders[fragmentIPHeadersLength-header.IPv6FragmentHeaderSize : fragmentIPHeadersLength])
-
-			if got := fragmentHeader.More(); got != wantFragments[i].more {
-				return fmt.Errorf("fragment #%d: got fragmentHeader.More() = %t, want = %t", i, got, wantFragments[i].more)
-			}
-			if got := fragmentHeader.FragmentOffset(); got != wantFragments[i].offset {
-				return fmt.Errorf("fragment #%d: got fragmentHeader.FragmentOffset() = %d, want = %d", i, got, wantFragments[i].offset)
-			}
-			if got := fragmentHeader.NextHeader(); got != uint8(proto) {
-				return fmt.Errorf("fragment #%d: got fragmentHeader.NextHeader() = %d, want = %d", i, got, uint8(proto))
-			}
-		}
-
-		// Store the reassembled payload as we parse each fragment. The payload
-		// includes the Transport header and everything after.
-		reassembledPayload.AppendView(fragment.TransportHeader().View())
-		reassembledPayload.AppendView(fragment.Data().AsRange().ToOwnedView())
-	}
-
-	if diff := cmp.Diff(buffer.View(source[sourceIPHeadersLen:]), reassembledPayload.ToView()); diff != "" {
-		return fmt.Errorf("reassembledPayload mismatch (-want +got):\n%s", diff)
-	}
-
-	return nil
-}
-
-// TestReceiveOnAllNodesMulticastAddr tests that IPv6 endpoints receive ICMP and
-// UDP packets destined to the IPv6 link-local all-nodes multicast address.
-func TestReceiveOnAllNodesMulticastAddr(t *testing.T) {
-	tests := []struct {
-		name            string
-		protocolFactory stack.TransportProtocolFactory
-		rxf             func(t *testing.T, s *stack.Stack, e *channel.Endpoint, src, dst tcpip.Address, want uint64)
-	}{
-		{"ICMP", icmp.NewProtocol6, testReceiveICMP},
-		{"UDP", udp.NewProtocol, testReceiveUDP},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			s := stack.New(stack.Options{
-				NetworkProtocols:   []stack.NetworkProtocolFactory{NewProtocol},
-				TransportProtocols: []stack.TransportProtocolFactory{test.protocolFactory},
-			})
-			e := channel.New(10, header.IPv6MinimumMTU, linkAddr1)
-			if err := s.CreateNIC(1, e); err != nil {
-				t.Fatalf("CreateNIC(_) = %s", err)
-			}
-
-			// Should receive a packet destined to the all-nodes
-			// multicast address.
-			test.rxf(t, s, e, addr1, header.IPv6AllNodesMulticastAddress, 1)
-		})
-	}
-}
-
-// TestReceiveOnSolicitedNodeAddr tests that IPv6 endpoints receive ICMP and UDP
-// packets destined to the IPv6 solicited-node address of an assigned IPv6
-// address.
-func TestReceiveOnSolicitedNodeAddr(t *testing.T) {
-	tests := []struct {
-		name            string
-		protocolFactory stack.TransportProtocolFactory
-		rxf             func(t *testing.T, s *stack.Stack, e *channel.Endpoint, src, dst tcpip.Address, want uint64)
-	}{
-		{"ICMP", icmp.NewProtocol6, testReceiveICMP},
-		{"UDP", udp.NewProtocol, testReceiveUDP},
-	}
-
-	snmc := header.SolicitedNodeAddr(addr2)
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			s := stack.New(stack.Options{
-				NetworkProtocols:   []stack.NetworkProtocolFactory{NewProtocol},
-				TransportProtocols: []stack.TransportProtocolFactory{test.protocolFactory},
-			})
-			e := channel.New(1, header.IPv6MinimumMTU, linkAddr1)
-			if err := s.CreateNIC(nicID, e); err != nil {
-				t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
-			}
-
-			s.SetRouteTable([]tcpip.Route{
-				{
-					Destination: header.IPv6EmptySubnet,
-					NIC:         nicID,
-				},
-			})
-
-			// Should not receive a packet destined to the solicited node address of
-			// addr2/addr3 yet as we haven't added those addresses.
-			test.rxf(t, s, e, addr1, snmc, 0)
-
-			if err := s.AddAddress(nicID, ProtocolNumber, addr2); err != nil {
-				t.Fatalf("AddAddress(%d, %d, %s) = %s", nicID, ProtocolNumber, addr2, err)
-			}
-
-			// Should receive a packet destined to the solicited node address of
-			// addr2/addr3 now that we have added added addr2.
-			test.rxf(t, s, e, addr1, snmc, 1)
-
-			if err := s.AddAddress(nicID, ProtocolNumber, addr3); err != nil {
-				t.Fatalf("AddAddress(%d, %d, %s) = %s", nicID, ProtocolNumber, addr3, err)
-			}
-
-			// Should still receive a packet destined to the solicited node address of
-			// addr2/addr3 now that we have added addr3.
-			test.rxf(t, s, e, addr1, snmc, 2)
-
-			if err := s.RemoveAddress(nicID, addr2); err != nil {
-				t.Fatalf("RemoveAddress(%d, %s) = %s", nicID, addr2, err)
-			}
-
-			// Should still receive a packet destined to the solicited node address of
-			// addr2/addr3 now that we have removed addr2.
-			test.rxf(t, s, e, addr1, snmc, 3)
-
-			// Make sure addr3's endpoint does not get removed from the NIC by
-			// incrementing its reference count with a route.
-			r, err := s.FindRoute(nicID, addr3, addr4, ProtocolNumber, false)
-			if err != nil {
-				t.Fatalf("FindRoute(%d, %s, %s, %d, false): %s", nicID, addr3, addr4, ProtocolNumber, err)
-			}
-			defer r.Release()
-
-			if err := s.RemoveAddress(nicID, addr3); err != nil {
-				t.Fatalf("RemoveAddress(%d, %s) = %s", nicID, addr3, err)
-			}
-
-			// Should not receive a packet destined to the solicited node address of
-			// addr2/addr3 yet as both of them got removed, even though a route using
-			// addr3 exists.
-			test.rxf(t, s, e, addr1, snmc, 3)
-		})
-	}
-}
-
-// TestAddIpv6Address tests adding IPv6 addresses.
-func TestAddIpv6Address(t *testing.T) {
-	const nicID = 1
-
-	tests := []struct {
-		name string
-		addr tcpip.Address
-	}{
-		// This test is in response to b/140943433.
-		{
-			"Nil",
-			tcpip.Address([]byte(nil)),
-		},
-		{
-			"ValidUnicast",
-			addr1,
-		},
-		{
-			"ValidLinkLocalUnicast",
-			lladdr0,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			s := stack.New(stack.Options{
-				NetworkProtocols: []stack.NetworkProtocolFactory{NewProtocol},
-			})
-			if err := s.CreateNIC(nicID, &stubLinkEndpoint{}); err != nil {
-				t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
-			}
-
-			if err := s.AddAddress(nicID, ProtocolNumber, test.addr); err != nil {
-				t.Fatalf("AddAddress(%d, %d, nil) = %s", nicID, ProtocolNumber, err)
-			}
-
-			if addr, err := s.GetMainNICAddress(nicID, ProtocolNumber); err != nil {
-				t.Fatalf("stack.GetMainNICAddress(%d, %d): %s", nicID, ProtocolNumber, err)
-			} else if addr.Address != test.addr {
-				t.Fatalf("got stack.GetMainNICAddress(%d, %d) = %s, want = %s", nicID, ProtocolNumber, addr.Address, test.addr)
-			}
-		})
-	}
-}
-
-func TestReceiveIPv6ExtHdrs(t *testing.T) {
-	tests := []struct {
-		name                    string
-		extHdr                  func(nextHdr uint8) ([]byte, uint8)
-		shouldAccept            bool
-		countersToBeIncremented func(*tcpip.Stats) []*tcpip.StatCounter
-		// Should we expect an ICMP response and if so, with what contents?
-		expectICMP bool
-		ICMPType   header.ICMPv6Type
-		ICMPCode   header.ICMPv6Code
-		pointer    uint32
-		multicast  bool
-	}{
-		{
-			name:         "None",
-			extHdr:       func(nextHdr uint8) ([]byte, uint8) { return []byte{}, nextHdr },
-			shouldAccept: true,
-			expectICMP:   false,
-		},
-		{
-			name: "hopbyhop with router alert option",
-			extHdr: func(nextHdr uint8) ([]byte, uint8) {
-				return []byte{
-					nextHdr, 0,
-
-					// Router Alert option.
-					5, 2, 0, 0, 0, 0,
-				}, hopByHopExtHdrID
-			},
-			shouldAccept: true,
-			countersToBeIncremented: func(stats *tcpip.Stats) []*tcpip.StatCounter {
-				return []*tcpip.StatCounter{stats.IP.OptionRouterAlertReceived}
-			},
-		},
-		{
-			name: "hopbyhop with two router alert options",
-			extHdr: func(nextHdr uint8) ([]byte, uint8) {
-				return []byte{
-					nextHdr, 1,
-
-					// Router Alert option.
-					5, 2, 0, 0, 0, 0,
-
-					// Router Alert option.
-					5, 2, 0, 0, 0, 0, 0, 0,
-				}, hopByHopExtHdrID
-			},
-			shouldAccept: false,
-			countersToBeIncremented: func(stats *tcpip.Stats) []*tcpip.StatCounter {
-				return []*tcpip.StatCounter{
-					stats.IP.OptionRouterAlertReceived,
-					stats.IP.MalformedPacketsReceived,
-				}
-			},
-		},
-		{
-			name: "hopbyhop with unknown option skippable action",
-			extHdr: func(nextHdr uint8) ([]byte, uint8) {
-				return []byte{
-					nextHdr, 1,
-
-					// Skippable unknown.
-					63, 4, 1, 2, 3, 4,
-
-					// Skippable unknown.
-					62, 6, 1, 2, 3, 4, 5, 6,
-				}, hopByHopExtHdrID
-			},
-			shouldAccept: true,
-		},
-		{
-			name: "hopbyhop with unknown option discard action",
-			extHdr: func(nextHdr uint8) ([]byte, uint8) {
-				return []byte{
-					nextHdr, 1,
-
-					// Skippable unknown.
-					63, 4, 1, 2, 3, 4,
-
-					// Discard unknown.
-					127, 6, 1, 2, 3, 4, 5, 6,
-				}, hopByHopExtHdrID
-			},
-			shouldAccept: false,
-			expectICMP:   false,
-		},
-		{
-			name: "hopbyhop with unknown option discard and send icmp action (unicast)",
-			extHdr: func(nextHdr uint8) ([]byte, uint8) {
-				return []byte{
-					nextHdr, 1,
-
-					// Skippable unknown.
-					63, 4, 1, 2, 3, 4,
-
-					// Discard & send ICMP if option is unknown.
-					191, 6, 1, 2, 3, 4, 5, 6,
-					//^ Unknown option.
-				}, hopByHopExtHdrID
-			},
-			shouldAccept: false,
-			expectICMP:   true,
-			ICMPType:     header.ICMPv6ParamProblem,
-			ICMPCode:     header.ICMPv6UnknownOption,
-			pointer:      header.IPv6FixedHeaderSize + 8,
-		},
-		{
-			name: "hopbyhop with unknown option discard and send icmp action (multicast)",
-			extHdr: func(nextHdr uint8) ([]byte, uint8) {
-				return []byte{
-					nextHdr, 1,
-
-					// Skippable unknown.
-					63, 4, 1, 2, 3, 4,
-
-					// Discard & send ICMP if option is unknown.
-					191, 6, 1, 2, 3, 4, 5, 6,
-					//^ Unknown option.
-				}, hopByHopExtHdrID
-			},
-			multicast:    true,
-			shouldAccept: false,
-			expectICMP:   true,
-			ICMPType:     header.ICMPv6ParamProblem,
-			ICMPCode:     header.ICMPv6UnknownOption,
-			pointer:      header.IPv6FixedHeaderSize + 8,
-		},
-		{
-			name: "hopbyhop with unknown option discard and send icmp action unless multicast dest (unicast)",
-			extHdr: func(nextHdr uint8) ([]byte, uint8) {
-				return []byte{
-					nextHdr, 1,
-
-					// Skippable unknown.
-					63, 4, 1, 2, 3, 4,
-
-					// Discard & send ICMP unless packet is for multicast destination if
-					// option is unknown.
-					255, 6, 1, 2, 3, 4, 5, 6,
-					//^ Unknown option.
-				}, hopByHopExtHdrID
-			},
-			expectICMP: true,
-			ICMPType:   header.ICMPv6ParamProblem,
-			ICMPCode:   header.ICMPv6UnknownOption,
-			pointer:    header.IPv6FixedHeaderSize + 8,
-		},
-		{
-			name: "hopbyhop with unknown option discard and send icmp action unless multicast dest (multicast)",
-			extHdr: func(nextHdr uint8) ([]byte, uint8) {
-				return []byte{
-					nextHdr, 1,
-
-					// Skippable unknown.
-					63, 4, 1, 2, 3, 4,
-
-					// Discard & send ICMP unless packet is for multicast destination if
-					// option is unknown.
-					255, 6, 1, 2, 3, 4, 5, 6,
-					//^ Unknown option.
-				}, hopByHopExtHdrID
-			},
-			multicast:    true,
-			shouldAccept: false,
-			expectICMP:   false,
-		},
-		{
-			name: "routing with zero segments left",
-			extHdr: func(nextHdr uint8) ([]byte, uint8) {
-				return []byte{
-					nextHdr, 0,
-					1, 0, 2, 3, 4, 5,
-				}, routingExtHdrID
-			},
-			shouldAccept: true,
-		},
-		{
-			name: "routing with non-zero segments left",
-			extHdr: func(nextHdr uint8) ([]byte, uint8) {
-				return []byte{
-					nextHdr, 0,
-					1, 1, 2, 3, 4, 5,
-				}, routingExtHdrID
-			},
-			shouldAccept: false,
-			expectICMP:   true,
-			ICMPType:     header.ICMPv6ParamProblem,
-			ICMPCode:     header.ICMPv6ErroneousHeader,
-			pointer:      header.IPv6FixedHeaderSize + 2,
-		},
-		{
-			name: "atomic fragment with zero ID",
-			extHdr: func(nextHdr uint8) ([]byte, uint8) {
-				return []byte{
-					nextHdr, 0,
-					0, 0, 0, 0, 0, 0,
-				}, fragmentExtHdrID
-			},
-			shouldAccept: true,
-		},
-		{
-			name: "atomic fragment with non-zero ID",
-			extHdr: func(nextHdr uint8) ([]byte, uint8) {
-				return []byte{
-					nextHdr, 0,
-					0, 0, 1, 2, 3, 4,
-				}, fragmentExtHdrID
-			},
-			shouldAccept: true,
-			expectICMP:   false,
-		},
-		{
-			name: "fragment",
-			extHdr: func(nextHdr uint8) ([]byte, uint8) {
-				return []byte{
-					nextHdr, 0,
-					1, 0, 1, 2, 3, 4,
-				}, fragmentExtHdrID
-			},
-			shouldAccept: false,
-			expectICMP:   false,
-		},
-		{
-			name: "No next header",
-			extHdr: func(nextHdr uint8) ([]byte, uint8) {
-				return []byte{},
-					noNextHdrID
-			},
-			shouldAccept: false,
-			expectICMP:   false,
-		},
-		{
-			name: "unknown next header (first)",
-			extHdr: func(nextHdr uint8) ([]byte, uint8) {
-				return []byte{
-					nextHdr, 0, 63, 4, 1, 2, 3, 4,
-				}, unknownHdrID
-			},
-			shouldAccept: false,
-			expectICMP:   true,
-			ICMPType:     header.ICMPv6ParamProblem,
-			ICMPCode:     header.ICMPv6UnknownHeader,
-			pointer:      header.IPv6NextHeaderOffset,
-		},
-		{
-			name: "unknown next header (not first)",
-			extHdr: func(nextHdr uint8) ([]byte, uint8) {
-				return []byte{
-					unknownHdrID, 0,
-					63, 4, 1, 2, 3, 4,
-				}, hopByHopExtHdrID
-			},
-			shouldAccept: false,
-			expectICMP:   true,
-			ICMPType:     header.ICMPv6ParamProblem,
-			ICMPCode:     header.ICMPv6UnknownHeader,
-			pointer:      header.IPv6FixedHeaderSize,
-		},
-		{
-			name: "destination with unknown option skippable action",
-			extHdr: func(nextHdr uint8) ([]byte, uint8) {
-				return []byte{
-					nextHdr, 1,
-
-					// Skippable unknown.
-					63, 4, 1, 2, 3, 4,
-
-					// Skippable unknown.
-					62, 6, 1, 2, 3, 4, 5, 6,
-				}, destinationExtHdrID
-			},
-			shouldAccept: true,
-			expectICMP:   false,
-		},
-		{
-			name: "destination with unknown option discard action",
-			extHdr: func(nextHdr uint8) ([]byte, uint8) {
-				return []byte{
-					nextHdr, 1,
-
-					// Skippable unknown.
-					63, 4, 1, 2, 3, 4,
-
-					// Discard unknown.
-					127, 6, 1, 2, 3, 4, 5, 6,
-				}, destinationExtHdrID
-			},
-			shouldAccept: false,
-			expectICMP:   false,
-		},
-		{
-			name: "destination with unknown option discard and send icmp action (unicast)",
-			extHdr: func(nextHdr uint8) ([]byte, uint8) {
-				return []byte{
-					nextHdr, 1,
-
-					// Skippable unknown.
-					63, 4, 1, 2, 3, 4,
-
-					// Discard & send ICMP if option is unknown.
-					191, 6, 1, 2, 3, 4, 5, 6,
-					//^  191 is an unknown option.
-				}, destinationExtHdrID
-			},
-			shouldAccept: false,
-			expectICMP:   true,
-			ICMPType:     header.ICMPv6ParamProblem,
-			ICMPCode:     header.ICMPv6UnknownOption,
-			pointer:      header.IPv6FixedHeaderSize + 8,
-		},
-		{
-			name: "destination with unknown option discard and send icmp action (muilticast)",
-			extHdr: func(nextHdr uint8) ([]byte, uint8) {
-				return []byte{
-					nextHdr, 1,
-
-					// Skippable unknown.
-					63, 4, 1, 2, 3, 4,
-
-					// Discard & send ICMP if option is unknown.
-					191, 6, 1, 2, 3, 4, 5, 6,
-					//^  191 is an unknown option.
-				}, destinationExtHdrID
-			},
-			multicast:    true,
-			shouldAccept: false,
-			expectICMP:   true,
-			ICMPType:     header.ICMPv6ParamProblem,
-			ICMPCode:     header.ICMPv6UnknownOption,
-			pointer:      header.IPv6FixedHeaderSize + 8,
-		},
-		{
-			name: "destination with unknown option discard and send icmp action unless multicast dest (unicast)",
-			extHdr: func(nextHdr uint8) ([]byte, uint8) {
-				return []byte{
-					nextHdr, 1,
-
-					// Skippable unknown.
-					63, 4, 1, 2, 3, 4,
-
-					// Discard & send ICMP unless packet is for multicast destination if
-					// option is unknown.
-					255, 6, 1, 2, 3, 4, 5, 6,
-					//^ 255 is unknown.
-				}, destinationExtHdrID
-			},
-			shouldAccept: false,
-			expectICMP:   true,
-			ICMPType:     header.ICMPv6ParamProblem,
-			ICMPCode:     header.ICMPv6UnknownOption,
-			pointer:      header.IPv6FixedHeaderSize + 8,
-		},
-		{
-			name: "destination with unknown option discard and send icmp action unless multicast dest (multicast)",
-			extHdr: func(nextHdr uint8) ([]byte, uint8) {
-				return []byte{
-					nextHdr, 1,
-
-					// Skippable unknown.
-					63, 4, 1, 2, 3, 4,
-
-					// Discard & send ICMP unless packet is for multicast destination if
-					// option is unknown.
-					255, 6, 1, 2, 3, 4, 5, 6,
-					//^ 255 is unknown.
-				}, destinationExtHdrID
-			},
-			shouldAccept: false,
-			expectICMP:   false,
-			multicast:    true,
-		},
-		{
-			name: "atomic fragment - routing",
-			extHdr: func(nextHdr uint8) ([]byte, uint8) {
-				return []byte{
-					// Fragment extension header.
-					routingExtHdrID, 0, 0, 0, 1, 2, 3, 4,
-
-					// Routing extension header.
-					nextHdr, 0, 1, 0, 2, 3, 4, 5,
-				}, fragmentExtHdrID
-			},
-			shouldAccept: true,
-		},
-		{
-			name: "hop by hop (with skippable unknown) - routing",
-			extHdr: func(nextHdr uint8) ([]byte, uint8) {
-				return []byte{
-					// Hop By Hop extension header with skippable unknown option.
-					routingExtHdrID, 0, 62, 4, 1, 2, 3, 4,
-
-					// Routing extension header.
-					nextHdr, 0, 1, 0, 2, 3, 4, 5,
-				}, hopByHopExtHdrID
-			},
-			shouldAccept: true,
-		},
-		{
-			name: "routing - hop by hop (with skippable unknown)",
-			extHdr: func(nextHdr uint8) ([]byte, uint8) {
-				return []byte{
-					// Routing extension header.
-					hopByHopExtHdrID, 0, 1, 0, 2, 3, 4, 5,
-					// ^^^   The HopByHop extension header may not appear after the first
-					// extension header.
-
-					// Hop By Hop extension header with skippable unknown option.
-					nextHdr, 0, 62, 4, 1, 2, 3, 4,
-				}, routingExtHdrID
-			},
-			shouldAccept: false,
-			expectICMP:   true,
-			ICMPType:     header.ICMPv6ParamProblem,
-			ICMPCode:     header.ICMPv6UnknownHeader,
-			pointer:      header.IPv6FixedHeaderSize,
-		},
-		{
-			name: "routing - hop by hop (with send icmp unknown)",
-			extHdr: func(nextHdr uint8) ([]byte, uint8) {
-				return []byte{
-					// Routing extension header.
-					hopByHopExtHdrID, 0, 1, 0, 2, 3, 4, 5,
-					// ^^^   The HopByHop extension header may not appear after the first
-					// extension header.
-
-					nextHdr, 1,
-
-					// Skippable unknown.
-					63, 4, 1, 2, 3, 4,
-
-					// Skippable unknown.
-					191, 6, 1, 2, 3, 4, 5, 6,
-				}, routingExtHdrID
-			},
-			shouldAccept: false,
-			expectICMP:   true,
-			ICMPType:     header.ICMPv6ParamProblem,
-			ICMPCode:     header.ICMPv6UnknownHeader,
-			pointer:      header.IPv6FixedHeaderSize,
-		},
-		{
-			name: "hopbyhop (with skippable unknown) - routing - atomic fragment - destination (with skippable unknown)",
-			extHdr: func(nextHdr uint8) ([]byte, uint8) {
-				return []byte{
-					// Hop By Hop extension header with skippable unknown option.
-					routingExtHdrID, 0, 62, 4, 1, 2, 3, 4,
-
-					// Routing extension header.
-					fragmentExtHdrID, 0, 1, 0, 2, 3, 4, 5,
-
-					// Fragment extension header.
-					destinationExtHdrID, 0, 0, 0, 1, 2, 3, 4,
-
-					// Destination extension header with skippable unknown option.
-					nextHdr, 0, 63, 4, 1, 2, 3, 4,
-				}, hopByHopExtHdrID
-			},
-			shouldAccept: true,
-		},
-		{
-			name: "hopbyhop (with discard unknown) - routing - atomic fragment - destination (with skippable unknown)",
-			extHdr: func(nextHdr uint8) ([]byte, uint8) {
-				return []byte{
-					// Hop By Hop extension header with discard action for unknown option.
-					routingExtHdrID, 0, 65, 4, 1, 2, 3, 4,
-
-					// Routing extension header.
-					fragmentExtHdrID, 0, 1, 0, 2, 3, 4, 5,
-
-					// Fragment extension header.
-					destinationExtHdrID, 0, 0, 0, 1, 2, 3, 4,
-
-					// Destination extension header with skippable unknown option.
-					nextHdr, 0, 63, 4, 1, 2, 3, 4,
-				}, hopByHopExtHdrID
-			},
-			shouldAccept: false,
-			expectICMP:   false,
-		},
-		{
-			name: "hopbyhop (with skippable unknown) - routing - atomic fragment - destination (with discard unknown)",
-			extHdr: func(nextHdr uint8) ([]byte, uint8) {
-				return []byte{
-					// Hop By Hop extension header with skippable unknown option.
-					routingExtHdrID, 0, 62, 4, 1, 2, 3, 4,
-
-					// Routing extension header.
-					fragmentExtHdrID, 0, 1, 0, 2, 3, 4, 5,
-
-					// Fragment extension header.
-					destinationExtHdrID, 0, 0, 0, 1, 2, 3, 4,
-
-					// Destination extension header with discard action for unknown
-					// option.
-					nextHdr, 0, 65, 4, 1, 2, 3, 4,
-				}, hopByHopExtHdrID
-			},
-			shouldAccept: false,
-			expectICMP:   false,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			s := stack.New(stack.Options{
-				NetworkProtocols:   []stack.NetworkProtocolFactory{NewProtocol},
-				TransportProtocols: []stack.TransportProtocolFactory{udp.NewProtocol},
-			})
-			e := channel.New(1, header.IPv6MinimumMTU, linkAddr1)
-			if err := s.CreateNIC(nicID, e); err != nil {
-				t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
-			}
-			if err := s.AddAddress(nicID, ProtocolNumber, addr2); err != nil {
-				t.Fatalf("AddAddress(%d, %d, %s) = %s", nicID, ProtocolNumber, addr2, err)
-			}
-
-			// Add a default route so that a return packet knows where to go.
-			s.SetRouteTable([]tcpip.Route{
-				{
-					Destination: header.IPv6EmptySubnet,
-					NIC:         nicID,
-				},
-			})
-
-			wq := waiter.Queue{}
-			we, ch := waiter.NewChannelEntry(nil)
-			wq.EventRegister(&we, waiter.EventIn)
-			defer wq.EventUnregister(&we)
-			defer close(ch)
-			ep, err := s.NewEndpoint(udp.ProtocolNumber, ProtocolNumber, &wq)
-			if err != nil {
-				t.Fatalf("NewEndpoint(%d, %d, _): %s", udp.ProtocolNumber, ProtocolNumber, err)
-			}
-			defer ep.Close()
-
-			bindAddr := tcpip.FullAddress{Addr: addr2, Port: 80}
-			if err := ep.Bind(bindAddr); err != nil {
-				t.Fatalf("Bind(%+v): %s", bindAddr, err)
-			}
-
-			udpPayload := []byte{1, 2, 3, 4, 5, 6, 7, 8}
-			udpLength := header.UDPMinimumSize + len(udpPayload)
-			extHdrBytes, ipv6NextHdr := test.extHdr(uint8(header.UDPProtocolNumber))
-			extHdrLen := len(extHdrBytes)
-			hdr := buffer.NewPrependable(header.IPv6MinimumSize + extHdrLen + udpLength)
-
-			// Serialize UDP message.
-			u := header.UDP(hdr.Prepend(udpLength))
-			u.Encode(&header.UDPFields{
-				SrcPort: 5555,
-				DstPort: 80,
-				Length:  uint16(udpLength),
-			})
-			copy(u.Payload(), udpPayload)
-
-			dstAddr := tcpip.Address(addr2)
-			if test.multicast {
-				dstAddr = header.IPv6AllNodesMulticastAddress
-			}
-
-			sum := header.PseudoHeaderChecksum(udp.ProtocolNumber, addr1, dstAddr, uint16(udpLength))
-			sum = header.Checksum(udpPayload, sum)
-			u.SetChecksum(^u.CalculateChecksum(sum))
-
-			// Copy extension header bytes between the UDP message and the IPv6
-			// fixed header.
-			copy(hdr.Prepend(extHdrLen), extHdrBytes)
-
-			// Serialize IPv6 fixed header.
-			payloadLength := hdr.UsedLength()
-			ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize))
-			ip.Encode(&header.IPv6Fields{
-				PayloadLength: uint16(payloadLength),
-				// We're lying about transport protocol here to be able to generate
-				// raw extension headers from the test definitions.
-				TransportProtocol: tcpip.TransportProtocolNumber(ipv6NextHdr),
-				HopLimit:          255,
-				SrcAddr:           addr1,
-				DstAddr:           dstAddr,
-			})
-
-			stats := s.Stats()
-			var counters []*tcpip.StatCounter
-			// Make sure that the counters we expect to be incremented are initially
-			// set to zero.
-			if fn := test.countersToBeIncremented; fn != nil {
-				counters = fn(&stats)
-			}
-			for i := range counters {
-				if got := counters[i].Value(); got != 0 {
-					t.Errorf("before writing packet: got test.countersToBeIncremented(&stats)[%d].Value() = %d, want = 0", i, got)
-				}
-			}
-
-			e.InjectInbound(ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
-				Data: hdr.View().ToVectorisedView(),
-			}))
-
-			for i := range counters {
-				if got := counters[i].Value(); got != 1 {
-					t.Errorf("after writing packet: got test.countersToBeIncremented(&stats)[%d].Value() = %d, want = 1", i, got)
-				}
-			}
-
-			udpReceiveStat := stats.UDP.PacketsReceived
-			if !test.shouldAccept {
-				if got := udpReceiveStat.Value(); got != 0 {
-					t.Errorf("got UDP Rx Packets = %d, want = 0", got)
-				}
-
-				if !test.expectICMP {
-					if p, ok := e.Read(); ok {
-						t.Fatalf("unexpected packet received: %#v", p)
-					}
-					return
-				}
-
-				// ICMP required.
-				p, ok := e.Read()
-				if !ok {
-					t.Fatalf("expected packet wasn't written out")
-				}
-
-				// Pack the output packet into a single buffer.View as the checkers
-				// assume that.
-				vv := buffer.NewVectorisedView(p.Pkt.Size(), p.Pkt.Views())
-				pkt := vv.ToView()
-				if got, want := len(pkt), header.IPv6FixedHeaderSize+header.ICMPv6MinimumSize+hdr.UsedLength(); got != want {
-					t.Fatalf("got an ICMP packet of size = %d, want = %d", got, want)
-				}
-
-				ipHdr := header.IPv6(pkt)
-				checker.IPv6(t, ipHdr, checker.ICMPv6(
-					checker.ICMPv6Type(test.ICMPType),
-					checker.ICMPv6Code(test.ICMPCode)))
-
-				// We know we are looking at no extension headers in the error ICMP
-				// packets.
-				icmpPkt := header.ICMPv6(ipHdr.Payload())
-				// We know we sent small packets that won't be truncated when reflected
-				// back to us.
-				originalPacket := icmpPkt.Payload()
-				if got, want := icmpPkt.TypeSpecific(), test.pointer; got != want {
-					t.Errorf("unexpected ICMPv6 pointer, got = %d, want = %d\n", got, want)
-				}
-				if diff := cmp.Diff(hdr.View(), buffer.View(originalPacket)); diff != "" {
-					t.Errorf("ICMPv6 payload mismatch (-want +got):\n%s", diff)
-				}
-				return
-			}
-
-			// Expect a UDP packet.
-			if got := udpReceiveStat.Value(); got != 1 {
-				t.Errorf("got UDP Rx Packets = %d, want = 1", got)
-			}
-			var buf bytes.Buffer
-			result, err := ep.Read(&buf, tcpip.ReadOptions{})
-			if err != nil {
-				t.Fatalf("Read: %s", err)
-			}
-			if diff := cmp.Diff(tcpip.ReadResult{
-				Count: len(udpPayload),
-				Total: len(udpPayload),
-			}, result, checker.IgnoreCmpPath("ControlMessages")); diff != "" {
-				t.Errorf("Read: unexpected result (-want +got):\n%s", diff)
-			}
-			if diff := cmp.Diff(udpPayload, buf.Bytes()); diff != "" {
-				t.Errorf("got UDP payload mismatch (-want +got):\n%s", diff)
-			}
-
-			// Should not have any more UDP packets.
-			res, err := ep.Read(ioutil.Discard, tcpip.ReadOptions{})
-			if _, ok := err.(*tcpip.ErrWouldBlock); !ok {
-				t.Fatalf("got Read = (%v, %v), want = (_, %s)", res, err, &tcpip.ErrWouldBlock{})
-			}
-		})
-	}
-}
-
-// fragmentData holds the IPv6 payload for a fragmented IPv6 packet.
-type fragmentData struct {
-	srcAddr tcpip.Address
-	dstAddr tcpip.Address
-	nextHdr uint8
-	data    buffer.VectorisedView
-}
-
-func TestReceiveIPv6Fragments(t *testing.T) {
-	const (
-		udpPayload1Length = 256
-		udpPayload2Length = 128
-		// Used to test cases where the fragment blocks are not a multiple of
-		// the fragment block size of 8 (RFC 8200 section 4.5).
-		udpPayload3Length     = 127
-		udpPayload4Length     = header.IPv6MaximumPayloadSize - header.UDPMinimumSize
-		udpMaximumSizeMinus15 = header.UDPMaximumSize - 15
-		fragmentExtHdrLen     = 8
-		// Note, not all routing extension headers will be 8 bytes but this test
-		// uses 8 byte routing extension headers for most sub tests.
-		routingExtHdrLen = 8
-	)
-
-	udpGen := func(payload []byte, multiplier uint8, src, dst tcpip.Address) buffer.View {
-		payloadLen := len(payload)
-		for i := 0; i < payloadLen; i++ {
-			payload[i] = uint8(i) * multiplier
-		}
-
-		udpLength := header.UDPMinimumSize + payloadLen
-
-		hdr := buffer.NewPrependable(udpLength)
-		u := header.UDP(hdr.Prepend(udpLength))
-		u.Encode(&header.UDPFields{
-			SrcPort: 5555,
-			DstPort: 80,
-			Length:  uint16(udpLength),
-		})
-		copy(u.Payload(), payload)
-		sum := header.PseudoHeaderChecksum(udp.ProtocolNumber, src, dst, uint16(udpLength))
-		sum = header.Checksum(payload, sum)
-		u.SetChecksum(^u.CalculateChecksum(sum))
-		return hdr.View()
-	}
-
-	var udpPayload1Addr1ToAddr2Buf [udpPayload1Length]byte
-	udpPayload1Addr1ToAddr2 := udpPayload1Addr1ToAddr2Buf[:]
-	ipv6Payload1Addr1ToAddr2 := udpGen(udpPayload1Addr1ToAddr2, 1, addr1, addr2)
-
-	var udpPayload1Addr3ToAddr2Buf [udpPayload1Length]byte
-	udpPayload1Addr3ToAddr2 := udpPayload1Addr3ToAddr2Buf[:]
-	ipv6Payload1Addr3ToAddr2 := udpGen(udpPayload1Addr3ToAddr2, 4, addr3, addr2)
-
-	var udpPayload2Addr1ToAddr2Buf [udpPayload2Length]byte
-	udpPayload2Addr1ToAddr2 := udpPayload2Addr1ToAddr2Buf[:]
-	ipv6Payload2Addr1ToAddr2 := udpGen(udpPayload2Addr1ToAddr2, 2, addr1, addr2)
-
-	var udpPayload3Addr1ToAddr2Buf [udpPayload3Length]byte
-	udpPayload3Addr1ToAddr2 := udpPayload3Addr1ToAddr2Buf[:]
-	ipv6Payload3Addr1ToAddr2 := udpGen(udpPayload3Addr1ToAddr2, 3, addr1, addr2)
-
-	var udpPayload4Addr1ToAddr2Buf [udpPayload4Length]byte
-	udpPayload4Addr1ToAddr2 := udpPayload4Addr1ToAddr2Buf[:]
-	ipv6Payload4Addr1ToAddr2 := udpGen(udpPayload4Addr1ToAddr2, 4, addr1, addr2)
-
-	tests := []struct {
-		name             string
-		expectedPayload  []byte
-		fragments        []fragmentData
-		expectedPayloads [][]byte
-	}{
-		{
-			name: "No fragmentation",
-			fragments: []fragmentData{
-				{
-					srcAddr: addr1,
-					dstAddr: addr2,
-					nextHdr: uint8(header.UDPProtocolNumber),
-					data:    ipv6Payload1Addr1ToAddr2.ToVectorisedView(),
-				},
-			},
-			expectedPayloads: [][]byte{udpPayload1Addr1ToAddr2},
-		},
-		{
-			name: "Atomic fragment",
-			fragments: []fragmentData{
-				{
-					srcAddr: addr1,
-					dstAddr: addr2,
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						fragmentExtHdrLen+len(ipv6Payload1Addr1ToAddr2),
-						[]buffer.View{
-							// Fragment extension header.
-							buffer.View([]byte{uint8(header.UDPProtocolNumber), 0, 0, 0, 0, 0, 0, 0}),
-
-							ipv6Payload1Addr1ToAddr2,
-						},
-					),
-				},
-			},
-			expectedPayloads: [][]byte{udpPayload1Addr1ToAddr2},
-		},
-		{
-			name: "Atomic fragment with size not a multiple of fragment block size",
-			fragments: []fragmentData{
-				{
-					srcAddr: addr1,
-					dstAddr: addr2,
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						fragmentExtHdrLen+len(ipv6Payload3Addr1ToAddr2),
-						[]buffer.View{
-							// Fragment extension header.
-							buffer.View([]byte{uint8(header.UDPProtocolNumber), 0, 0, 0, 0, 0, 0, 0}),
-
-							ipv6Payload3Addr1ToAddr2,
-						},
-					),
-				},
-			},
-			expectedPayloads: [][]byte{udpPayload3Addr1ToAddr2},
-		},
-		{
-			name: "Two fragments",
-			fragments: []fragmentData{
-				{
-					srcAddr: addr1,
-					dstAddr: addr2,
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						fragmentExtHdrLen+64,
-						[]buffer.View{
-							// Fragment extension header.
-							//
-							// Fragment offset = 0, More = true, ID = 1
-							buffer.View([]byte{uint8(header.UDPProtocolNumber), 0, 0, 1, 0, 0, 0, 1}),
-
-							ipv6Payload1Addr1ToAddr2[:64],
-						},
-					),
-				},
-				{
-					srcAddr: addr1,
-					dstAddr: addr2,
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						fragmentExtHdrLen+len(ipv6Payload1Addr1ToAddr2)-64,
-						[]buffer.View{
-							// Fragment extension header.
-							//
-							// Fragment offset = 8, More = false, ID = 1
-							buffer.View([]byte{uint8(header.UDPProtocolNumber), 0, 0, 64, 0, 0, 0, 1}),
-
-							ipv6Payload1Addr1ToAddr2[64:],
-						},
-					),
-				},
-			},
-			expectedPayloads: [][]byte{udpPayload1Addr1ToAddr2},
-		},
-		{
-			name: "Two fragments out of order",
-			fragments: []fragmentData{
-				{
-					srcAddr: addr1,
-					dstAddr: addr2,
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						fragmentExtHdrLen+len(ipv6Payload1Addr1ToAddr2)-64,
-						[]buffer.View{
-							// Fragment extension header.
-							//
-							// Fragment offset = 8, More = false, ID = 1
-							buffer.View([]byte{uint8(header.UDPProtocolNumber), 0, 0, 64, 0, 0, 0, 1}),
-
-							ipv6Payload1Addr1ToAddr2[64:],
-						},
-					),
-				},
-				{
-					srcAddr: addr1,
-					dstAddr: addr2,
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						fragmentExtHdrLen+64,
-						[]buffer.View{
-							// Fragment extension header.
-							//
-							// Fragment offset = 0, More = true, ID = 1
-							buffer.View([]byte{uint8(header.UDPProtocolNumber), 0, 0, 1, 0, 0, 0, 1}),
-
-							ipv6Payload1Addr1ToAddr2[:64],
-						},
-					),
-				},
-			},
-			expectedPayloads: [][]byte{udpPayload1Addr1ToAddr2},
-		},
-		{
-			name: "Two fragments with different Next Header values",
-			fragments: []fragmentData{
-				{
-					srcAddr: addr1,
-					dstAddr: addr2,
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						fragmentExtHdrLen+64,
-						[]buffer.View{
-							// Fragment extension header.
-							//
-							// Fragment offset = 0, More = true, ID = 1
-							buffer.View([]byte{uint8(header.UDPProtocolNumber), 0, 0, 1, 0, 0, 0, 1}),
-
-							ipv6Payload1Addr1ToAddr2[:64],
-						},
-					),
-				},
-				{
-					srcAddr: addr1,
-					dstAddr: addr2,
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						fragmentExtHdrLen+len(ipv6Payload1Addr1ToAddr2)-64,
-						[]buffer.View{
-							// Fragment extension header.
-							//
-							// Fragment offset = 8, More = false, ID = 1
-							// NextHeader value is different than the one in the first fragment, so
-							// this NextHeader should be ignored.
-							buffer.View([]byte{uint8(header.IPv6NoNextHeaderIdentifier), 0, 0, 64, 0, 0, 0, 1}),
-
-							ipv6Payload1Addr1ToAddr2[64:],
-						},
-					),
-				},
-			},
-			expectedPayloads: [][]byte{udpPayload1Addr1ToAddr2},
-		},
-		{
-			name: "Two fragments with last fragment size not a multiple of fragment block size",
-			fragments: []fragmentData{
-				{
-					srcAddr: addr1,
-					dstAddr: addr2,
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						fragmentExtHdrLen+64,
-						[]buffer.View{
-							// Fragment extension header.
-							//
-							// Fragment offset = 0, More = true, ID = 1
-							buffer.View([]byte{uint8(header.UDPProtocolNumber), 0, 0, 1, 0, 0, 0, 1}),
-
-							ipv6Payload3Addr1ToAddr2[:64],
-						},
-					),
-				},
-				{
-					srcAddr: addr1,
-					dstAddr: addr2,
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						fragmentExtHdrLen+len(ipv6Payload3Addr1ToAddr2)-64,
-						[]buffer.View{
-							// Fragment extension header.
-							//
-							// Fragment offset = 8, More = false, ID = 1
-							buffer.View([]byte{uint8(header.UDPProtocolNumber), 0, 0, 64, 0, 0, 0, 1}),
-
-							ipv6Payload3Addr1ToAddr2[64:],
-						},
-					),
-				},
-			},
-			expectedPayloads: [][]byte{udpPayload3Addr1ToAddr2},
-		},
-		{
-			name: "Two fragments with first fragment size not a multiple of fragment block size",
-			fragments: []fragmentData{
-				{
-					srcAddr: addr1,
-					dstAddr: addr2,
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						fragmentExtHdrLen+63,
-						[]buffer.View{
-							// Fragment extension header.
-							//
-							// Fragment offset = 0, More = true, ID = 1
-							buffer.View([]byte{uint8(header.UDPProtocolNumber), 0, 0, 1, 0, 0, 0, 1}),
-
-							ipv6Payload3Addr1ToAddr2[:63],
-						},
-					),
-				},
-				{
-					srcAddr: addr1,
-					dstAddr: addr2,
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						fragmentExtHdrLen+len(ipv6Payload3Addr1ToAddr2)-63,
-						[]buffer.View{
-							// Fragment extension header.
-							//
-							// Fragment offset = 8, More = false, ID = 1
-							buffer.View([]byte{uint8(header.UDPProtocolNumber), 0, 0, 64, 0, 0, 0, 1}),
-
-							ipv6Payload3Addr1ToAddr2[63:],
-						},
-					),
-				},
-			},
-			expectedPayloads: nil,
-		},
-		{
-			name: "Two fragments with different IDs",
-			fragments: []fragmentData{
-				{
-					srcAddr: addr1,
-					dstAddr: addr2,
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						fragmentExtHdrLen+64,
-						[]buffer.View{
-							// Fragment extension header.
-							//
-							// Fragment offset = 0, More = true, ID = 1
-							buffer.View([]byte{uint8(header.UDPProtocolNumber), 0, 0, 1, 0, 0, 0, 1}),
-
-							ipv6Payload1Addr1ToAddr2[:64],
-						},
-					),
-				},
-				{
-					srcAddr: addr1,
-					dstAddr: addr2,
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						fragmentExtHdrLen+len(ipv6Payload1Addr1ToAddr2)-64,
-						[]buffer.View{
-							// Fragment extension header.
-							//
-							// Fragment offset = 8, More = false, ID = 2
-							buffer.View([]byte{uint8(header.UDPProtocolNumber), 0, 0, 64, 0, 0, 0, 2}),
-
-							ipv6Payload1Addr1ToAddr2[64:],
-						},
-					),
-				},
-			},
-			expectedPayloads: nil,
-		},
-		{
-			name: "Two fragments reassembled into a maximum UDP packet",
-			fragments: []fragmentData{
-				{
-					srcAddr: addr1,
-					dstAddr: addr2,
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						fragmentExtHdrLen+udpMaximumSizeMinus15,
-						[]buffer.View{
-							// Fragment extension header.
-							//
-							// Fragment offset = 0, More = true, ID = 1
-							buffer.View([]byte{uint8(header.UDPProtocolNumber), 0, 0, 1, 0, 0, 0, 1}),
-
-							ipv6Payload4Addr1ToAddr2[:udpMaximumSizeMinus15],
-						},
-					),
-				},
-				{
-					srcAddr: addr1,
-					dstAddr: addr2,
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						fragmentExtHdrLen+len(ipv6Payload4Addr1ToAddr2)-udpMaximumSizeMinus15,
-						[]buffer.View{
-							// Fragment extension header.
-							//
-							// Fragment offset = udpMaximumSizeMinus15/8, More = false, ID = 1
-							buffer.View([]byte{uint8(header.UDPProtocolNumber), 0,
-								udpMaximumSizeMinus15 >> 8,
-								udpMaximumSizeMinus15 & 0xff,
-								0, 0, 0, 1}),
-
-							ipv6Payload4Addr1ToAddr2[udpMaximumSizeMinus15:],
-						},
-					),
-				},
-			},
-			expectedPayloads: [][]byte{udpPayload4Addr1ToAddr2},
-		},
-		{
-			name: "Two fragments with MF flag reassembled into a maximum UDP packet",
-			fragments: []fragmentData{
-				{
-					srcAddr: addr1,
-					dstAddr: addr2,
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						fragmentExtHdrLen+udpMaximumSizeMinus15,
-						[]buffer.View{
-							// Fragment extension header.
-							//
-							// Fragment offset = 0, More = true, ID = 1
-							buffer.View([]byte{uint8(header.UDPProtocolNumber), 0, 0, 1, 0, 0, 0, 1}),
-
-							ipv6Payload4Addr1ToAddr2[:udpMaximumSizeMinus15],
-						},
-					),
-				},
-				{
-					srcAddr: addr1,
-					dstAddr: addr2,
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						fragmentExtHdrLen+len(ipv6Payload4Addr1ToAddr2)-udpMaximumSizeMinus15,
-						[]buffer.View{
-							// Fragment extension header.
-							//
-							// Fragment offset = udpMaximumSizeMinus15/8, More = true, ID = 1
-							buffer.View([]byte{uint8(header.UDPProtocolNumber), 0,
-								udpMaximumSizeMinus15 >> 8,
-								(udpMaximumSizeMinus15 & 0xff) + 1,
-								0, 0, 0, 1}),
-
-							ipv6Payload4Addr1ToAddr2[udpMaximumSizeMinus15:],
-						},
-					),
-				},
-			},
-			expectedPayloads: nil,
-		},
-		{
-			name: "Two fragments with per-fragment routing header with zero segments left",
-			fragments: []fragmentData{
-				{
-					srcAddr: addr1,
-					dstAddr: addr2,
-					nextHdr: routingExtHdrID,
-					data: buffer.NewVectorisedView(
-						routingExtHdrLen+fragmentExtHdrLen+64,
-						[]buffer.View{
-							// Routing extension header.
-							//
-							// Segments left = 0.
-							buffer.View([]byte{fragmentExtHdrID, 0, 1, 0, 2, 3, 4, 5}),
-
-							// Fragment extension header.
-							//
-							// Fragment offset = 0, More = true, ID = 1
-							buffer.View([]byte{uint8(header.UDPProtocolNumber), 0, 0, 1, 0, 0, 0, 1}),
-
-							ipv6Payload1Addr1ToAddr2[:64],
-						},
-					),
-				},
-				{
-					srcAddr: addr1,
-					dstAddr: addr2,
-					nextHdr: routingExtHdrID,
-					data: buffer.NewVectorisedView(
-						routingExtHdrLen+fragmentExtHdrLen+len(ipv6Payload1Addr1ToAddr2)-64,
-						[]buffer.View{
-							// Routing extension header.
-							//
-							// Segments left = 0.
-							buffer.View([]byte{fragmentExtHdrID, 0, 1, 0, 2, 3, 4, 5}),
-
-							// Fragment extension header.
-							//
-							// Fragment offset = 8, More = false, ID = 1
-							buffer.View([]byte{uint8(header.UDPProtocolNumber), 0, 0, 64, 0, 0, 0, 1}),
-
-							ipv6Payload1Addr1ToAddr2[64:],
-						},
-					),
-				},
-			},
-			expectedPayloads: [][]byte{udpPayload1Addr1ToAddr2},
-		},
-		{
-			name: "Two fragments with per-fragment routing header with non-zero segments left",
-			fragments: []fragmentData{
-				{
-					srcAddr: addr1,
-					dstAddr: addr2,
-					nextHdr: routingExtHdrID,
-					data: buffer.NewVectorisedView(
-						routingExtHdrLen+fragmentExtHdrLen+64,
-						[]buffer.View{
-							// Routing extension header.
-							//
-							// Segments left = 1.
-							buffer.View([]byte{fragmentExtHdrID, 0, 1, 1, 2, 3, 4, 5}),
-
-							// Fragment extension header.
-							//
-							// Fragment offset = 0, More = true, ID = 1
-							buffer.View([]byte{uint8(header.UDPProtocolNumber), 0, 0, 1, 0, 0, 0, 1}),
-
-							ipv6Payload1Addr1ToAddr2[:64],
-						},
-					),
-				},
-				{
-					srcAddr: addr1,
-					dstAddr: addr2,
-					nextHdr: routingExtHdrID,
-					data: buffer.NewVectorisedView(
-						routingExtHdrLen+fragmentExtHdrLen+len(ipv6Payload1Addr1ToAddr2)-64,
-						[]buffer.View{
-							// Routing extension header.
-							//
-							// Segments left = 1.
-							buffer.View([]byte{fragmentExtHdrID, 0, 1, 1, 2, 3, 4, 5}),
-
-							// Fragment extension header.
-							//
-							// Fragment offset = 9, More = false, ID = 1
-							buffer.View([]byte{uint8(header.UDPProtocolNumber), 0, 0, 72, 0, 0, 0, 1}),
-
-							ipv6Payload1Addr1ToAddr2[64:],
-						},
-					),
-				},
-			},
-			expectedPayloads: nil,
-		},
-		{
-			name: "Two fragments with routing header with zero segments left",
-			fragments: []fragmentData{
-				{
-					srcAddr: addr1,
-					dstAddr: addr2,
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						routingExtHdrLen+fragmentExtHdrLen+64,
-						[]buffer.View{
-							// Fragment extension header.
-							//
-							// Fragment offset = 0, More = true, ID = 1
-							buffer.View([]byte{routingExtHdrID, 0, 0, 1, 0, 0, 0, 1}),
-
-							// Routing extension header.
-							//
-							// Segments left = 0.
-							buffer.View([]byte{uint8(header.UDPProtocolNumber), 0, 1, 0, 2, 3, 4, 5}),
-
-							ipv6Payload1Addr1ToAddr2[:64],
-						},
-					),
-				},
-				{
-					srcAddr: addr1,
-					dstAddr: addr2,
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						fragmentExtHdrLen+len(ipv6Payload1Addr1ToAddr2)-64,
-						[]buffer.View{
-							// Fragment extension header.
-							//
-							// Fragment offset = 9, More = false, ID = 1
-							buffer.View([]byte{routingExtHdrID, 0, 0, 72, 0, 0, 0, 1}),
-
-							ipv6Payload1Addr1ToAddr2[64:],
-						},
-					),
-				},
-			},
-			expectedPayloads: [][]byte{udpPayload1Addr1ToAddr2},
-		},
-		{
-			name: "Two fragments with routing header with non-zero segments left",
-			fragments: []fragmentData{
-				{
-					srcAddr: addr1,
-					dstAddr: addr2,
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						routingExtHdrLen+fragmentExtHdrLen+64,
-						[]buffer.View{
-							// Fragment extension header.
-							//
-							// Fragment offset = 0, More = true, ID = 1
-							buffer.View([]byte{routingExtHdrID, 0, 0, 1, 0, 0, 0, 1}),
-
-							// Routing extension header.
-							//
-							// Segments left = 1.
-							buffer.View([]byte{uint8(header.UDPProtocolNumber), 0, 1, 1, 2, 3, 4, 5}),
-
-							ipv6Payload1Addr1ToAddr2[:64],
-						},
-					),
-				},
-				{
-					srcAddr: addr1,
-					dstAddr: addr2,
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						fragmentExtHdrLen+len(ipv6Payload1Addr1ToAddr2)-64,
-						[]buffer.View{
-							// Fragment extension header.
-							//
-							// Fragment offset = 9, More = false, ID = 1
-							buffer.View([]byte{routingExtHdrID, 0, 0, 72, 0, 0, 0, 1}),
-
-							ipv6Payload1Addr1ToAddr2[64:],
-						},
-					),
-				},
-			},
-			expectedPayloads: nil,
-		},
-		{
-			name: "Two fragments with routing header with zero segments left across fragments",
-			fragments: []fragmentData{
-				{
-					srcAddr: addr1,
-					dstAddr: addr2,
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						// The length of this payload is fragmentExtHdrLen+8 because the
-						// first 8 bytes of the 16 byte routing extension header is in
-						// this fragment.
-						fragmentExtHdrLen+8,
-						[]buffer.View{
-							// Fragment extension header.
-							//
-							// Fragment offset = 0, More = true, ID = 1
-							buffer.View([]byte{routingExtHdrID, 0, 0, 1, 0, 0, 0, 1}),
-
-							// Routing extension header (part 1)
-							//
-							// Segments left = 0.
-							buffer.View([]byte{uint8(header.UDPProtocolNumber), 1, 1, 0, 2, 3, 4, 5}),
-						},
-					),
-				},
-				{
-					srcAddr: addr1,
-					dstAddr: addr2,
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						// The length of this payload is
-						// fragmentExtHdrLen+8+len(ipv6Payload1Addr1ToAddr2) because the last 8 bytes of
-						// the 16 byte routing extension header is in this fagment.
-						fragmentExtHdrLen+8+len(ipv6Payload1Addr1ToAddr2),
-						[]buffer.View{
-							// Fragment extension header.
-							//
-							// Fragment offset = 1, More = false, ID = 1
-							buffer.View([]byte{routingExtHdrID, 0, 0, 8, 0, 0, 0, 1}),
-
-							// Routing extension header (part 2)
-							buffer.View([]byte{6, 7, 8, 9, 10, 11, 12, 13}),
-
-							ipv6Payload1Addr1ToAddr2,
-						},
-					),
-				},
-			},
-			expectedPayloads: nil,
-		},
-		{
-			name: "Two fragments with routing header with non-zero segments left across fragments",
-			fragments: []fragmentData{
-				{
-					srcAddr: addr1,
-					dstAddr: addr2,
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						// The length of this payload is fragmentExtHdrLen+8 because the
-						// first 8 bytes of the 16 byte routing extension header is in
-						// this fragment.
-						fragmentExtHdrLen+8,
-						[]buffer.View{
-							// Fragment extension header.
-							//
-							// Fragment offset = 0, More = true, ID = 1
-							buffer.View([]byte{routingExtHdrID, 0, 0, 1, 0, 0, 0, 1}),
-
-							// Routing extension header (part 1)
-							//
-							// Segments left = 1.
-							buffer.View([]byte{uint8(header.UDPProtocolNumber), 1, 1, 1, 2, 3, 4, 5}),
-						},
-					),
-				},
-				{
-					srcAddr: addr1,
-					dstAddr: addr2,
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						// The length of this payload is
-						// fragmentExtHdrLen+8+len(ipv6Payload1Addr1ToAddr2) because the last 8 bytes of
-						// the 16 byte routing extension header is in this fagment.
-						fragmentExtHdrLen+8+len(ipv6Payload1Addr1ToAddr2),
-						[]buffer.View{
-							// Fragment extension header.
-							//
-							// Fragment offset = 1, More = false, ID = 1
-							buffer.View([]byte{routingExtHdrID, 0, 0, 8, 0, 0, 0, 1}),
-
-							// Routing extension header (part 2)
-							buffer.View([]byte{6, 7, 8, 9, 10, 11, 12, 13}),
-
-							ipv6Payload1Addr1ToAddr2,
-						},
-					),
-				},
-			},
-			expectedPayloads: nil,
-		},
-		// As per RFC 6946, IPv6 atomic fragments MUST NOT interfere with "normal"
-		// fragmented traffic.
-		{
-			name: "Two fragments with atomic",
-			fragments: []fragmentData{
-				{
-					srcAddr: addr1,
-					dstAddr: addr2,
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						fragmentExtHdrLen+64,
-						[]buffer.View{
-							// Fragment extension header.
-							//
-							// Fragment offset = 0, More = true, ID = 1
-							buffer.View([]byte{uint8(header.UDPProtocolNumber), 0, 0, 1, 0, 0, 0, 1}),
-
-							ipv6Payload1Addr1ToAddr2[:64],
-						},
-					),
-				},
-				// This fragment has the same ID as the other fragments but is an atomic
-				// fragment. It should not interfere with the other fragments.
-				{
-					srcAddr: addr1,
-					dstAddr: addr2,
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						fragmentExtHdrLen+len(ipv6Payload2Addr1ToAddr2),
-						[]buffer.View{
-							// Fragment extension header.
-							//
-							// Fragment offset = 0, More = false, ID = 1
-							buffer.View([]byte{uint8(header.UDPProtocolNumber), 0, 0, 0, 0, 0, 0, 1}),
-
-							ipv6Payload2Addr1ToAddr2,
-						},
-					),
-				},
-				{
-					srcAddr: addr1,
-					dstAddr: addr2,
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						fragmentExtHdrLen+len(ipv6Payload1Addr1ToAddr2)-64,
-						[]buffer.View{
-							// Fragment extension header.
-							//
-							// Fragment offset = 8, More = false, ID = 1
-							buffer.View([]byte{uint8(header.UDPProtocolNumber), 0, 0, 64, 0, 0, 0, 1}),
-
-							ipv6Payload1Addr1ToAddr2[64:],
-						},
-					),
-				},
-			},
-			expectedPayloads: [][]byte{udpPayload2Addr1ToAddr2, udpPayload1Addr1ToAddr2},
-		},
-		{
-			name: "Two interleaved fragmented packets",
-			fragments: []fragmentData{
-				{
-					srcAddr: addr1,
-					dstAddr: addr2,
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						fragmentExtHdrLen+64,
-						[]buffer.View{
-							// Fragment extension header.
-							//
-							// Fragment offset = 0, More = true, ID = 1
-							buffer.View([]byte{uint8(header.UDPProtocolNumber), 0, 0, 1, 0, 0, 0, 1}),
-
-							ipv6Payload1Addr1ToAddr2[:64],
-						},
-					),
-				},
-				{
-					srcAddr: addr1,
-					dstAddr: addr2,
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						fragmentExtHdrLen+32,
-						[]buffer.View{
-							// Fragment extension header.
-							//
-							// Fragment offset = 0, More = true, ID = 2
-							buffer.View([]byte{uint8(header.UDPProtocolNumber), 0, 0, 1, 0, 0, 0, 2}),
-
-							ipv6Payload2Addr1ToAddr2[:32],
-						},
-					),
-				},
-				{
-					srcAddr: addr1,
-					dstAddr: addr2,
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						fragmentExtHdrLen+len(ipv6Payload1Addr1ToAddr2)-64,
-						[]buffer.View{
-							// Fragment extension header.
-							//
-							// Fragment offset = 8, More = false, ID = 1
-							buffer.View([]byte{uint8(header.UDPProtocolNumber), 0, 0, 64, 0, 0, 0, 1}),
-
-							ipv6Payload1Addr1ToAddr2[64:],
-						},
-					),
-				},
-				{
-					srcAddr: addr1,
-					dstAddr: addr2,
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						fragmentExtHdrLen+len(ipv6Payload2Addr1ToAddr2)-32,
-						[]buffer.View{
-							// Fragment extension header.
-							//
-							// Fragment offset = 4, More = false, ID = 2
-							buffer.View([]byte{uint8(header.UDPProtocolNumber), 0, 0, 32, 0, 0, 0, 2}),
-
-							ipv6Payload2Addr1ToAddr2[32:],
-						},
-					),
-				},
-			},
-			expectedPayloads: [][]byte{udpPayload1Addr1ToAddr2, udpPayload2Addr1ToAddr2},
-		},
-		{
-			name: "Two interleaved fragmented packets from different sources but with same ID",
-			fragments: []fragmentData{
-				{
-					srcAddr: addr1,
-					dstAddr: addr2,
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						fragmentExtHdrLen+64,
-						[]buffer.View{
-							// Fragment extension header.
-							//
-							// Fragment offset = 0, More = true, ID = 1
-							buffer.View([]byte{uint8(header.UDPProtocolNumber), 0, 0, 1, 0, 0, 0, 1}),
-
-							ipv6Payload1Addr1ToAddr2[:64],
-						},
-					),
-				},
-				{
-					srcAddr: addr3,
-					dstAddr: addr2,
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						fragmentExtHdrLen+32,
-						[]buffer.View{
-							// Fragment extension header.
-							//
-							// Fragment offset = 0, More = true, ID = 1
-							buffer.View([]byte{uint8(header.UDPProtocolNumber), 0, 0, 1, 0, 0, 0, 1}),
-
-							ipv6Payload1Addr3ToAddr2[:32],
-						},
-					),
-				},
-				{
-					srcAddr: addr1,
-					dstAddr: addr2,
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						fragmentExtHdrLen+len(ipv6Payload1Addr1ToAddr2)-64,
-						[]buffer.View{
-							// Fragment extension header.
-							//
-							// Fragment offset = 8, More = false, ID = 1
-							buffer.View([]byte{uint8(header.UDPProtocolNumber), 0, 0, 64, 0, 0, 0, 1}),
-
-							ipv6Payload1Addr1ToAddr2[64:],
-						},
-					),
-				},
-				{
-					srcAddr: addr3,
-					dstAddr: addr2,
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						fragmentExtHdrLen+len(ipv6Payload1Addr1ToAddr2)-32,
-						[]buffer.View{
-							// Fragment extension header.
-							//
-							// Fragment offset = 4, More = false, ID = 1
-							buffer.View([]byte{uint8(header.UDPProtocolNumber), 0, 0, 32, 0, 0, 0, 1}),
-
-							ipv6Payload1Addr3ToAddr2[32:],
-						},
-					),
-				},
-			},
-			expectedPayloads: [][]byte{udpPayload1Addr1ToAddr2, udpPayload1Addr3ToAddr2},
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			s := stack.New(stack.Options{
-				NetworkProtocols:   []stack.NetworkProtocolFactory{NewProtocol},
-				TransportProtocols: []stack.TransportProtocolFactory{udp.NewProtocol},
-			})
-			e := channel.New(0, header.IPv6MinimumMTU, linkAddr1)
-			if err := s.CreateNIC(nicID, e); err != nil {
-				t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
-			}
-			if err := s.AddAddress(nicID, ProtocolNumber, addr2); err != nil {
-				t.Fatalf("AddAddress(%d, %d, %s) = %s", nicID, ProtocolNumber, addr2, 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(udp.ProtocolNumber, ProtocolNumber, &wq)
-			if err != nil {
-				t.Fatalf("NewEndpoint(%d, %d, _): %s", udp.ProtocolNumber, ProtocolNumber, err)
-			}
-			defer ep.Close()
-
-			bindAddr := tcpip.FullAddress{Addr: addr2, Port: 80}
-			if err := ep.Bind(bindAddr); err != nil {
-				t.Fatalf("Bind(%+v): %s", bindAddr, err)
-			}
-
-			for _, f := range test.fragments {
-				hdr := buffer.NewPrependable(header.IPv6MinimumSize)
-
-				// Serialize IPv6 fixed header.
-				ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize))
-				ip.Encode(&header.IPv6Fields{
-					PayloadLength: uint16(f.data.Size()),
-					// We're lying about transport protocol here so that we can generate
-					// raw extension headers for the tests.
-					TransportProtocol: tcpip.TransportProtocolNumber(f.nextHdr),
-					HopLimit:          255,
-					SrcAddr:           f.srcAddr,
-					DstAddr:           f.dstAddr,
-				})
-
-				vv := hdr.View().ToVectorisedView()
-				vv.Append(f.data)
-
-				e.InjectInbound(ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
-					Data: vv,
-				}))
-			}
-
-			if got, want := s.Stats().UDP.PacketsReceived.Value(), uint64(len(test.expectedPayloads)); got != want {
-				t.Errorf("got UDP Rx Packets = %d, want = %d", got, want)
-			}
-
-			for i, p := range test.expectedPayloads {
-				var buf bytes.Buffer
-				_, err := ep.Read(&buf, tcpip.ReadOptions{})
-				if err != nil {
-					t.Fatalf("(i=%d) Read: %s", i, err)
-				}
-				if diff := cmp.Diff(p, buf.Bytes()); diff != "" {
-					t.Errorf("(i=%d) got UDP payload mismatch (-want +got):\n%s", i, diff)
-				}
-			}
-
-			res, err := ep.Read(ioutil.Discard, tcpip.ReadOptions{})
-			if _, ok := err.(*tcpip.ErrWouldBlock); !ok {
-				t.Fatalf("(last) got Read = (%v, %v), want = (_, %s)", res, err, &tcpip.ErrWouldBlock{})
-			}
-		})
-	}
-}
-
-func TestInvalidIPv6Fragments(t *testing.T) {
-	const (
-		addr1     = "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"
-		addr2     = "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02"
-		linkAddr1 = tcpip.LinkAddress("\x0a\x0b\x0c\x0d\x0e\x0e")
-		nicID     = 1
-		hoplimit  = 255
-		ident     = 1
-		data      = "TEST_INVALID_IPV6_FRAGMENTS"
-	)
-
-	type fragmentData struct {
-		ipv6Fields         header.IPv6Fields
-		ipv6FragmentFields header.IPv6SerializableFragmentExtHdr
-		payload            []byte
-	}
-
-	tests := []struct {
-		name                   string
-		fragments              []fragmentData
-		wantMalformedIPPackets uint64
-		wantMalformedFragments uint64
-		expectICMP             bool
-		expectICMPType         header.ICMPv6Type
-		expectICMPCode         header.ICMPv6Code
-		expectICMPTypeSpecific uint32
-	}{
-		{
-			name: "fragment size is not a multiple of 8 and the M flag is true",
-			fragments: []fragmentData{
-				{
-					ipv6Fields: header.IPv6Fields{
-						PayloadLength:     header.IPv6FragmentHeaderSize + 9,
-						TransportProtocol: header.UDPProtocolNumber,
-						HopLimit:          hoplimit,
-						SrcAddr:           addr1,
-						DstAddr:           addr2,
-					},
-					ipv6FragmentFields: header.IPv6SerializableFragmentExtHdr{
-						FragmentOffset: 0 >> 3,
-						M:              true,
-						Identification: ident,
-					},
-					payload: []byte(data)[:9],
-				},
-			},
-			wantMalformedIPPackets: 1,
-			wantMalformedFragments: 1,
-			expectICMP:             true,
-			expectICMPType:         header.ICMPv6ParamProblem,
-			expectICMPCode:         header.ICMPv6ErroneousHeader,
-			expectICMPTypeSpecific: header.IPv6PayloadLenOffset,
-		},
-		{
-			name: "fragments reassembled into a payload exceeding the max IPv6 payload size",
-			fragments: []fragmentData{
-				{
-					ipv6Fields: header.IPv6Fields{
-						PayloadLength:     header.IPv6FragmentHeaderSize + 16,
-						TransportProtocol: header.UDPProtocolNumber,
-						HopLimit:          hoplimit,
-						SrcAddr:           addr1,
-						DstAddr:           addr2,
-					},
-					ipv6FragmentFields: header.IPv6SerializableFragmentExtHdr{
-						FragmentOffset: ((header.IPv6MaximumPayloadSize + 1) - 16) >> 3,
-						M:              false,
-						Identification: ident,
-					},
-					payload: []byte(data)[:16],
-				},
-			},
-			wantMalformedIPPackets: 1,
-			wantMalformedFragments: 1,
-			expectICMP:             true,
-			expectICMPType:         header.ICMPv6ParamProblem,
-			expectICMPCode:         header.ICMPv6ErroneousHeader,
-			expectICMPTypeSpecific: header.IPv6MinimumSize + 2, /* offset for 'Fragment Offset' in the fragment header */
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			s := stack.New(stack.Options{
-				NetworkProtocols: []stack.NetworkProtocolFactory{
-					NewProtocol,
-				},
-			})
-			e := channel.New(1, 1500, linkAddr1)
-			if err := s.CreateNIC(nicID, e); err != nil {
-				t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
-			}
-			if err := s.AddAddress(nicID, ProtocolNumber, addr2); err != nil {
-				t.Fatalf("AddAddress(%d, %d, %s) = %s", nicID, ProtocolNumber, addr2, err)
-			}
-			s.SetRouteTable([]tcpip.Route{{
-				Destination: header.IPv6EmptySubnet,
-				NIC:         nicID,
-			}})
-
-			var expectICMPPayload buffer.View
-			for _, f := range test.fragments {
-				hdr := buffer.NewPrependable(header.IPv6MinimumSize + header.IPv6FragmentHeaderSize)
-
-				ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize + header.IPv6FragmentHeaderSize))
-				encodeArgs := f.ipv6Fields
-				encodeArgs.ExtensionHeaders = append(encodeArgs.ExtensionHeaders, &f.ipv6FragmentFields)
-				ip.Encode(&encodeArgs)
-
-				vv := hdr.View().ToVectorisedView()
-				vv.AppendView(f.payload)
-
-				pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{
-					Data: vv,
-				})
-
-				if test.expectICMP {
-					expectICMPPayload = stack.PayloadSince(pkt.NetworkHeader())
-				}
-
-				e.InjectInbound(ProtocolNumber, pkt)
-			}
-
-			if got, want := s.Stats().IP.MalformedPacketsReceived.Value(), test.wantMalformedIPPackets; got != want {
-				t.Errorf("got Stats.IP.MalformedPacketsReceived = %d, want = %d", got, want)
-			}
-			if got, want := s.Stats().IP.MalformedFragmentsReceived.Value(), test.wantMalformedFragments; got != want {
-				t.Errorf("got Stats.IP.MalformedFragmentsReceived = %d, want = %d", got, want)
-			}
-
-			reply, ok := e.Read()
-			if !test.expectICMP {
-				if ok {
-					t.Fatalf("unexpected ICMP error message received: %#v", reply)
-				}
-				return
-			}
-			if !ok {
-				t.Fatal("expected ICMP error message missing")
-			}
-
-			checker.IPv6(t, stack.PayloadSince(reply.Pkt.NetworkHeader()),
-				checker.SrcAddr(addr2),
-				checker.DstAddr(addr1),
-				checker.IPFullLength(uint16(header.IPv6MinimumSize+header.ICMPv6MinimumSize+expectICMPPayload.Size())),
-				checker.ICMPv6(
-					checker.ICMPv6Type(test.expectICMPType),
-					checker.ICMPv6Code(test.expectICMPCode),
-					checker.ICMPv6TypeSpecific(test.expectICMPTypeSpecific),
-					checker.ICMPv6Payload([]byte(expectICMPPayload)),
-				),
-			)
-		})
-	}
-}
-
-func TestFragmentReassemblyTimeout(t *testing.T) {
-	const (
-		addr1     = "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"
-		addr2     = "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02"
-		linkAddr1 = tcpip.LinkAddress("\x0a\x0b\x0c\x0d\x0e\x0e")
-		nicID     = 1
-		hoplimit  = 255
-		ident     = 1
-		data      = "TEST_FRAGMENT_REASSEMBLY_TIMEOUT"
-	)
-
-	type fragmentData struct {
-		ipv6Fields         header.IPv6Fields
-		ipv6FragmentFields header.IPv6SerializableFragmentExtHdr
-		payload            []byte
-	}
-
-	tests := []struct {
-		name       string
-		fragments  []fragmentData
-		expectICMP bool
-	}{
-		{
-			name: "first fragment only",
-			fragments: []fragmentData{
-				{
-					ipv6Fields: header.IPv6Fields{
-						PayloadLength:     header.IPv6FragmentHeaderSize + 16,
-						TransportProtocol: header.UDPProtocolNumber,
-						HopLimit:          hoplimit,
-						SrcAddr:           addr1,
-						DstAddr:           addr2,
-					},
-					ipv6FragmentFields: header.IPv6SerializableFragmentExtHdr{
-						FragmentOffset: 0,
-						M:              true,
-						Identification: ident,
-					},
-					payload: []byte(data)[:16],
-				},
-			},
-			expectICMP: true,
-		},
-		{
-			name: "two first fragments",
-			fragments: []fragmentData{
-				{
-					ipv6Fields: header.IPv6Fields{
-						PayloadLength:     header.IPv6FragmentHeaderSize + 16,
-						TransportProtocol: header.UDPProtocolNumber,
-						HopLimit:          hoplimit,
-						SrcAddr:           addr1,
-						DstAddr:           addr2,
-					},
-					ipv6FragmentFields: header.IPv6SerializableFragmentExtHdr{
-						FragmentOffset: 0,
-						M:              true,
-						Identification: ident,
-					},
-					payload: []byte(data)[:16],
-				},
-				{
-					ipv6Fields: header.IPv6Fields{
-						PayloadLength:     header.IPv6FragmentHeaderSize + 16,
-						TransportProtocol: header.UDPProtocolNumber,
-						HopLimit:          hoplimit,
-						SrcAddr:           addr1,
-						DstAddr:           addr2,
-					},
-					ipv6FragmentFields: header.IPv6SerializableFragmentExtHdr{
-						FragmentOffset: 0,
-						M:              true,
-						Identification: ident,
-					},
-					payload: []byte(data)[:16],
-				},
-			},
-			expectICMP: true,
-		},
-		{
-			name: "second fragment only",
-			fragments: []fragmentData{
-				{
-					ipv6Fields: header.IPv6Fields{
-						PayloadLength:     uint16(header.IPv6FragmentHeaderSize + len(data) - 16),
-						TransportProtocol: header.UDPProtocolNumber,
-						HopLimit:          hoplimit,
-						SrcAddr:           addr1,
-						DstAddr:           addr2,
-					},
-					ipv6FragmentFields: header.IPv6SerializableFragmentExtHdr{
-						FragmentOffset: 8,
-						M:              false,
-						Identification: ident,
-					},
-					payload: []byte(data)[16:],
-				},
-			},
-			expectICMP: false,
-		},
-		{
-			name: "two fragments with a gap",
-			fragments: []fragmentData{
-				{
-					ipv6Fields: header.IPv6Fields{
-						PayloadLength:     header.IPv6FragmentHeaderSize + 16,
-						TransportProtocol: header.UDPProtocolNumber,
-						HopLimit:          hoplimit,
-						SrcAddr:           addr1,
-						DstAddr:           addr2,
-					},
-					ipv6FragmentFields: header.IPv6SerializableFragmentExtHdr{
-						FragmentOffset: 0,
-						M:              true,
-						Identification: ident,
-					},
-					payload: []byte(data)[:16],
-				},
-				{
-					ipv6Fields: header.IPv6Fields{
-						PayloadLength:     uint16(header.IPv6FragmentHeaderSize + len(data) - 16),
-						TransportProtocol: header.UDPProtocolNumber,
-						HopLimit:          hoplimit,
-						SrcAddr:           addr1,
-						DstAddr:           addr2,
-					},
-					ipv6FragmentFields: header.IPv6SerializableFragmentExtHdr{
-						FragmentOffset: 8,
-						M:              false,
-						Identification: ident,
-					},
-					payload: []byte(data)[16:],
-				},
-			},
-			expectICMP: true,
-		},
-		{
-			name: "two fragments with a gap in reverse order",
-			fragments: []fragmentData{
-				{
-					ipv6Fields: header.IPv6Fields{
-						PayloadLength:     uint16(header.IPv6FragmentHeaderSize + len(data) - 16),
-						TransportProtocol: header.UDPProtocolNumber,
-						HopLimit:          hoplimit,
-						SrcAddr:           addr1,
-						DstAddr:           addr2,
-					},
-					ipv6FragmentFields: header.IPv6SerializableFragmentExtHdr{
-						FragmentOffset: 8,
-						M:              false,
-						Identification: ident,
-					},
-					payload: []byte(data)[16:],
-				},
-				{
-					ipv6Fields: header.IPv6Fields{
-						PayloadLength:     header.IPv6FragmentHeaderSize + 16,
-						TransportProtocol: header.UDPProtocolNumber,
-						HopLimit:          hoplimit,
-						SrcAddr:           addr1,
-						DstAddr:           addr2,
-					},
-					ipv6FragmentFields: header.IPv6SerializableFragmentExtHdr{
-						FragmentOffset: 0,
-						M:              true,
-						Identification: ident,
-					},
-					payload: []byte(data)[:16],
-				},
-			},
-			expectICMP: true,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			clock := faketime.NewManualClock()
-			s := stack.New(stack.Options{
-				NetworkProtocols: []stack.NetworkProtocolFactory{
-					NewProtocol,
-				},
-				Clock: clock,
-			})
-
-			e := channel.New(1, 1500, linkAddr1)
-			if err := s.CreateNIC(nicID, e); err != nil {
-				t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
-			}
-			if err := s.AddAddress(nicID, ProtocolNumber, addr2); err != nil {
-				t.Fatalf("AddAddress(%d, %d, %s) = %s", nicID, header.IPv6ProtocolNumber, addr2, err)
-			}
-			s.SetRouteTable([]tcpip.Route{{
-				Destination: header.IPv6EmptySubnet,
-				NIC:         nicID,
-			}})
-
-			var firstFragmentSent buffer.View
-			for _, f := range test.fragments {
-				hdr := buffer.NewPrependable(header.IPv6MinimumSize + header.IPv6FragmentHeaderSize)
-
-				ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize + header.IPv6FragmentHeaderSize))
-				encodeArgs := f.ipv6Fields
-				encodeArgs.ExtensionHeaders = append(encodeArgs.ExtensionHeaders, &f.ipv6FragmentFields)
-				ip.Encode(&encodeArgs)
-
-				fragHDR := header.IPv6Fragment(hdr.View()[header.IPv6MinimumSize:])
-
-				vv := hdr.View().ToVectorisedView()
-				vv.AppendView(f.payload)
-
-				pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{
-					Data: vv,
-				})
-
-				if firstFragmentSent == nil && fragHDR.FragmentOffset() == 0 {
-					firstFragmentSent = stack.PayloadSince(pkt.NetworkHeader())
-				}
-
-				e.InjectInbound(ProtocolNumber, pkt)
-			}
-
-			clock.Advance(ReassembleTimeout)
-
-			reply, ok := e.Read()
-			if !test.expectICMP {
-				if ok {
-					t.Fatalf("unexpected ICMP error message received: %#v", reply)
-				}
-				return
-			}
-			if !ok {
-				t.Fatal("expected ICMP error message missing")
-			}
-			if firstFragmentSent == nil {
-				t.Fatalf("unexpected ICMP error message received: %#v", reply)
-			}
-
-			checker.IPv6(t, stack.PayloadSince(reply.Pkt.NetworkHeader()),
-				checker.SrcAddr(addr2),
-				checker.DstAddr(addr1),
-				checker.IPFullLength(uint16(header.IPv6MinimumSize+header.ICMPv6MinimumSize+firstFragmentSent.Size())),
-				checker.ICMPv6(
-					checker.ICMPv6Type(header.ICMPv6TimeExceeded),
-					checker.ICMPv6Code(header.ICMPv6ReassemblyTimeout),
-					checker.ICMPv6Payload([]byte(firstFragmentSent)),
-				),
-			)
-		})
-	}
-}
-
-func TestWriteStats(t *testing.T) {
-	const nPackets = 3
-	tests := []struct {
-		name          string
-		setup         func(*testing.T, *stack.Stack)
-		allowPackets  int
-		expectSent    int
-		expectDropped int
-		expectWritten int
-	}{
-		{
-			name: "Accept all",
-			// No setup needed, tables accept everything by default.
-			setup:         func(*testing.T, *stack.Stack) {},
-			allowPackets:  math.MaxInt32,
-			expectSent:    nPackets,
-			expectDropped: 0,
-			expectWritten: nPackets,
-		}, {
-			name: "Accept all with error",
-			// No setup needed, tables accept everything by default.
-			setup:         func(*testing.T, *stack.Stack) {},
-			allowPackets:  nPackets - 1,
-			expectSent:    nPackets - 1,
-			expectDropped: 0,
-			expectWritten: nPackets - 1,
-		}, {
-			name: "Drop all",
-			setup: func(t *testing.T, stk *stack.Stack) {
-				// Install Output DROP rule.
-				t.Helper()
-				ipt := stk.IPTables()
-				filter := ipt.GetTable(stack.FilterID, true /* ipv6 */)
-				ruleIdx := filter.BuiltinChains[stack.Output]
-				filter.Rules[ruleIdx].Target = &stack.DropTarget{}
-				if err := ipt.ReplaceTable(stack.FilterID, filter, true /* ipv6 */); err != nil {
-					t.Fatalf("failed to replace table: %v", err)
-				}
-			},
-			allowPackets:  math.MaxInt32,
-			expectSent:    0,
-			expectDropped: nPackets,
-			expectWritten: nPackets,
-		}, {
-			name: "Drop some",
-			setup: func(t *testing.T, stk *stack.Stack) {
-				// Install Output DROP rule that matches only 1
-				// of the 3 packets.
-				t.Helper()
-				ipt := stk.IPTables()
-				filter := ipt.GetTable(stack.FilterID, true /* ipv6 */)
-				// We'll match and DROP the last packet.
-				ruleIdx := filter.BuiltinChains[stack.Output]
-				filter.Rules[ruleIdx].Target = &stack.DropTarget{}
-				filter.Rules[ruleIdx].Matchers = []stack.Matcher{&limitedMatcher{nPackets - 1}}
-				// Make sure the next rule is ACCEPT.
-				filter.Rules[ruleIdx+1].Target = &stack.AcceptTarget{}
-				if err := ipt.ReplaceTable(stack.FilterID, filter, true /* ipv6 */); err != nil {
-					t.Fatalf("failed to replace table: %v", err)
-				}
-			},
-			allowPackets:  math.MaxInt32,
-			expectSent:    nPackets - 1,
-			expectDropped: 1,
-			expectWritten: nPackets,
-		},
-	}
-
-	writers := []struct {
-		name         string
-		writePackets func(*stack.Route, stack.PacketBufferList) (int, tcpip.Error)
-	}{
-		{
-			name: "WritePacket",
-			writePackets: func(rt *stack.Route, pkts stack.PacketBufferList) (int, tcpip.Error) {
-				nWritten := 0
-				for pkt := pkts.Front(); pkt != nil; pkt = pkt.Next() {
-					if err := rt.WritePacket(nil, stack.NetworkHeaderParams{}, pkt); err != nil {
-						return nWritten, err
-					}
-					nWritten++
-				}
-				return nWritten, nil
-			},
-		}, {
-			name: "WritePackets",
-			writePackets: func(rt *stack.Route, pkts stack.PacketBufferList) (int, tcpip.Error) {
-				return rt.WritePackets(nil, pkts, stack.NetworkHeaderParams{})
-			},
-		},
-	}
-
-	for _, writer := range writers {
-		t.Run(writer.name, func(t *testing.T) {
-			for _, test := range tests {
-				t.Run(test.name, func(t *testing.T) {
-					ep := testutil.NewMockLinkEndpoint(header.IPv6MinimumMTU, &tcpip.ErrInvalidEndpointState{}, test.allowPackets)
-					rt := buildRoute(t, ep)
-					var pkts stack.PacketBufferList
-					for i := 0; i < nPackets; i++ {
-						pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{
-							ReserveHeaderBytes: header.UDPMinimumSize + int(rt.MaxHeaderLength()),
-							Data:               buffer.NewView(0).ToVectorisedView(),
-						})
-						pkt.TransportHeader().Push(header.UDPMinimumSize)
-						pkts.PushBack(pkt)
-					}
-
-					test.setup(t, rt.Stack())
-
-					nWritten, _ := writer.writePackets(rt, pkts)
-
-					if got := int(rt.Stats().IP.PacketsSent.Value()); got != test.expectSent {
-						t.Errorf("sent %d packets, but expected to send %d", got, test.expectSent)
-					}
-					if got := int(rt.Stats().IP.IPTablesOutputDropped.Value()); got != test.expectDropped {
-						t.Errorf("dropped %d packets, but expected to drop %d", got, test.expectDropped)
-					}
-					if nWritten != test.expectWritten {
-						t.Errorf("wrote %d packets, but expected WritePackets to return %d", nWritten, test.expectWritten)
-					}
-				})
-			}
-		})
-	}
-}
-
-func buildRoute(t *testing.T, ep stack.LinkEndpoint) *stack.Route {
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocolFactory{NewProtocol},
-	})
-	if err := s.CreateNIC(1, ep); err != nil {
-		t.Fatalf("CreateNIC(1, _) failed: %s", err)
-	}
-	const (
-		src = "\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"
-		dst = "\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02"
-	)
-	if err := s.AddAddress(1, ProtocolNumber, src); err != nil {
-		t.Fatalf("AddAddress(1, %d, %s) failed: %s", ProtocolNumber, src, err)
-	}
-	{
-		mask := tcpip.AddressMask("\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff")
-		subnet, err := tcpip.NewSubnet(dst, mask)
-		if err != nil {
-			t.Fatalf("NewSubnet(%s, %s) failed: %v", dst, mask, err)
-		}
-		s.SetRouteTable([]tcpip.Route{{
-			Destination: subnet,
-			NIC:         1,
-		}})
-	}
-	rt, err := s.FindRoute(1, src, dst, ProtocolNumber, false /* multicastLoop */)
-	if err != nil {
-		t.Fatalf("FindRoute(1, %s, %s, %d, false) = %s, want = nil", src, dst, ProtocolNumber, err)
-	}
-	return rt
-}
-
-// limitedMatcher is an iptables matcher that matches after a certain number of
-// packets are checked against it.
-type limitedMatcher struct {
-	limit int
-}
-
-// Name implements Matcher.Name.
-func (*limitedMatcher) Name() string {
-	return "limitedMatcher"
-}
-
-// Match implements Matcher.Match.
-func (lm *limitedMatcher) Match(stack.Hook, *stack.PacketBuffer, string, string) (bool, bool) {
-	if lm.limit == 0 {
-		return true, false
-	}
-	lm.limit--
-	return false, false
-}
-
-func knownNICIDs(proto *protocol) []tcpip.NICID {
-	var nicIDs []tcpip.NICID
-
-	for k := range proto.mu.eps {
-		nicIDs = append(nicIDs, k)
-	}
-
-	return nicIDs
-}
-
-func TestClearEndpointFromProtocolOnClose(t *testing.T) {
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocolFactory{NewProtocol},
-	})
-	proto := s.NetworkProtocolInstance(ProtocolNumber).(*protocol)
-	var nic testInterface
-	ep := proto.NewEndpoint(&nic, nil).(*endpoint)
-	var nicIDs []tcpip.NICID
-
-	proto.mu.Lock()
-	foundEP, hasEndpointBeforeClose := proto.mu.eps[nic.ID()]
-	nicIDs = knownNICIDs(proto)
-	proto.mu.Unlock()
-	if !hasEndpointBeforeClose {
-		t.Fatalf("expected to find the nic id %d in the protocol's known nic ids (%v)", nic.ID(), nicIDs)
-	}
-	if foundEP != ep {
-		t.Fatalf("found an incorrect endpoint mapped to nic id %d", nic.ID())
-	}
-
-	ep.Close()
-
-	proto.mu.Lock()
-	_, hasEndpointAfterClose := proto.mu.eps[nic.ID()]
-	nicIDs = knownNICIDs(proto)
-	proto.mu.Unlock()
-	if hasEndpointAfterClose {
-		t.Fatalf("unexpectedly found an endpoint mapped to the nic id %d in the protocol's known nic ids (%v)", nic.ID(), nicIDs)
-	}
-}
-
-type fragmentInfo struct {
-	offset      uint16
-	more        bool
-	payloadSize uint16
-}
-
-var fragmentationTests = []struct {
-	description   string
-	mtu           uint32
-	gso           *stack.GSO
-	transHdrLen   int
-	payloadSize   int
-	wantFragments []fragmentInfo
-}{
-	{
-		description: "No fragmentation",
-		mtu:         header.IPv6MinimumMTU,
-		gso:         nil,
-		transHdrLen: 0,
-		payloadSize: 1000,
-		wantFragments: []fragmentInfo{
-			{offset: 0, payloadSize: 1000, more: false},
-		},
-	},
-	{
-		description: "Fragmented",
-		mtu:         header.IPv6MinimumMTU,
-		gso:         nil,
-		transHdrLen: 0,
-		payloadSize: 2000,
-		wantFragments: []fragmentInfo{
-			{offset: 0, payloadSize: 1240, more: true},
-			{offset: 154, payloadSize: 776, more: false},
-		},
-	},
-	{
-		description: "Fragmented with mtu not a multiple of 8",
-		mtu:         header.IPv6MinimumMTU + 1,
-		gso:         nil,
-		transHdrLen: 0,
-		payloadSize: 2000,
-		wantFragments: []fragmentInfo{
-			{offset: 0, payloadSize: 1240, more: true},
-			{offset: 154, payloadSize: 776, more: false},
-		},
-	},
-	{
-		description: "No fragmentation with big header",
-		mtu:         2000,
-		gso:         nil,
-		transHdrLen: 100,
-		payloadSize: 1000,
-		wantFragments: []fragmentInfo{
-			{offset: 0, payloadSize: 1100, more: false},
-		},
-	},
-	{
-		description: "Fragmented with gso none",
-		mtu:         header.IPv6MinimumMTU,
-		gso:         &stack.GSO{Type: stack.GSONone},
-		transHdrLen: 0,
-		payloadSize: 1400,
-		wantFragments: []fragmentInfo{
-			{offset: 0, payloadSize: 1240, more: true},
-			{offset: 154, payloadSize: 176, more: false},
-		},
-	},
-	{
-		description: "Fragmented with big header",
-		mtu:         header.IPv6MinimumMTU,
-		gso:         nil,
-		transHdrLen: 100,
-		payloadSize: 1200,
-		wantFragments: []fragmentInfo{
-			{offset: 0, payloadSize: 1240, more: true},
-			{offset: 154, payloadSize: 76, more: false},
-		},
-	},
-}
-
-func TestFragmentationWritePacket(t *testing.T) {
-	const (
-		ttl            = 42
-		tos            = stack.DefaultTOS
-		transportProto = tcp.ProtocolNumber
-	)
-
-	for _, ft := range fragmentationTests {
-		t.Run(ft.description, func(t *testing.T) {
-			pkt := testutil.MakeRandPkt(ft.transHdrLen, extraHeaderReserve+header.IPv6MinimumSize, []int{ft.payloadSize}, header.IPv6ProtocolNumber)
-			source := pkt.Clone()
-			ep := testutil.NewMockLinkEndpoint(ft.mtu, nil, math.MaxInt32)
-			r := buildRoute(t, ep)
-			err := r.WritePacket(ft.gso, stack.NetworkHeaderParams{
-				Protocol: tcp.ProtocolNumber,
-				TTL:      ttl,
-				TOS:      stack.DefaultTOS,
-			}, pkt)
-			if err != nil {
-				t.Fatalf("WritePacket(_, _, _): = %s", err)
-			}
-			if got := len(ep.WrittenPackets); got != len(ft.wantFragments) {
-				t.Errorf("got len(ep.WrittenPackets) = %d, want = %d", got, len(ft.wantFragments))
-			}
-			if got := int(r.Stats().IP.PacketsSent.Value()); got != len(ft.wantFragments) {
-				t.Errorf("got c.Route.Stats().IP.PacketsSent.Value() = %d, want = %d", got, len(ft.wantFragments))
-			}
-			if got := r.Stats().IP.OutgoingPacketErrors.Value(); got != 0 {
-				t.Errorf("got r.Stats().IP.OutgoingPacketErrors.Value() = %d, want = 0", got)
-			}
-			if err := compareFragments(ep.WrittenPackets, source, ft.mtu, ft.wantFragments, tcp.ProtocolNumber); err != nil {
-				t.Error(err)
-			}
-		})
-	}
-}
-
-func TestFragmentationWritePackets(t *testing.T) {
-	const ttl = 42
-	tests := []struct {
-		description  string
-		insertBefore int
-		insertAfter  int
-	}{
-		{
-			description:  "Single packet",
-			insertBefore: 0,
-			insertAfter:  0,
-		},
-		{
-			description:  "With packet before",
-			insertBefore: 1,
-			insertAfter:  0,
-		},
-		{
-			description:  "With packet after",
-			insertBefore: 0,
-			insertAfter:  1,
-		},
-		{
-			description:  "With packet before and after",
-			insertBefore: 1,
-			insertAfter:  1,
-		},
-	}
-	tinyPacket := testutil.MakeRandPkt(header.TCPMinimumSize, extraHeaderReserve+header.IPv6MinimumSize, []int{1}, header.IPv6ProtocolNumber)
-
-	for _, test := range tests {
-		t.Run(test.description, func(t *testing.T) {
-			for _, ft := range fragmentationTests {
-				t.Run(ft.description, func(t *testing.T) {
-					var pkts stack.PacketBufferList
-					for i := 0; i < test.insertBefore; i++ {
-						pkts.PushBack(tinyPacket.Clone())
-					}
-					pkt := testutil.MakeRandPkt(ft.transHdrLen, extraHeaderReserve+header.IPv6MinimumSize, []int{ft.payloadSize}, header.IPv6ProtocolNumber)
-					source := pkt
-					pkts.PushBack(pkt.Clone())
-					for i := 0; i < test.insertAfter; i++ {
-						pkts.PushBack(tinyPacket.Clone())
-					}
-
-					ep := testutil.NewMockLinkEndpoint(ft.mtu, nil, math.MaxInt32)
-					r := buildRoute(t, ep)
-
-					wantTotalPackets := len(ft.wantFragments) + test.insertBefore + test.insertAfter
-					n, err := r.WritePackets(ft.gso, pkts, stack.NetworkHeaderParams{
-						Protocol: tcp.ProtocolNumber,
-						TTL:      ttl,
-						TOS:      stack.DefaultTOS,
-					})
-					if n != wantTotalPackets || err != nil {
-						t.Errorf("got WritePackets(_, _, _) = (%d, %s), want = (%d, nil)", n, err, wantTotalPackets)
-					}
-					if got := len(ep.WrittenPackets); got != wantTotalPackets {
-						t.Errorf("got len(ep.WrittenPackets) = %d, want = %d", got, wantTotalPackets)
-					}
-					if got := int(r.Stats().IP.PacketsSent.Value()); got != wantTotalPackets {
-						t.Errorf("got c.Route.Stats().IP.PacketsSent.Value() = %d, want = %d", got, wantTotalPackets)
-					}
-					if got := r.Stats().IP.OutgoingPacketErrors.Value(); got != 0 {
-						t.Errorf("got r.Stats().IP.OutgoingPacketErrors.Value() = %d, want = 0", got)
-					}
-
-					if wantTotalPackets == 0 {
-						return
-					}
-
-					fragments := ep.WrittenPackets[test.insertBefore : len(ft.wantFragments)+test.insertBefore]
-					if err := compareFragments(fragments, source, ft.mtu, ft.wantFragments, tcp.ProtocolNumber); err != nil {
-						t.Error(err)
-					}
-				})
-			}
-		})
-	}
-}
-
-// TestFragmentationErrors checks that errors are returned from WritePacket
-// correctly.
-func TestFragmentationErrors(t *testing.T) {
-	const ttl = 42
-
-	tests := []struct {
-		description    string
-		mtu            uint32
-		transHdrLen    int
-		payloadSize    int
-		allowPackets   int
-		outgoingErrors int
-		mockError      tcpip.Error
-		wantError      tcpip.Error
-	}{
-		{
-			description:    "No frag",
-			mtu:            2000,
-			payloadSize:    1000,
-			transHdrLen:    0,
-			allowPackets:   0,
-			outgoingErrors: 1,
-			mockError:      &tcpip.ErrAborted{},
-			wantError:      &tcpip.ErrAborted{},
-		},
-		{
-			description:    "Error on first frag",
-			mtu:            1300,
-			payloadSize:    3000,
-			transHdrLen:    0,
-			allowPackets:   0,
-			outgoingErrors: 3,
-			mockError:      &tcpip.ErrAborted{},
-			wantError:      &tcpip.ErrAborted{},
-		},
-		{
-			description:    "Error on second frag",
-			mtu:            1500,
-			payloadSize:    4000,
-			transHdrLen:    0,
-			allowPackets:   1,
-			outgoingErrors: 2,
-			mockError:      &tcpip.ErrAborted{},
-			wantError:      &tcpip.ErrAborted{},
-		},
-		{
-			description:    "Error when MTU is smaller than transport header",
-			mtu:            header.IPv6MinimumMTU,
-			transHdrLen:    1500,
-			payloadSize:    500,
-			allowPackets:   0,
-			outgoingErrors: 1,
-			mockError:      nil,
-			wantError:      &tcpip.ErrMessageTooLong{},
-		},
-		{
-			description:    "Error when MTU is smaller than IPv6 minimum MTU",
-			mtu:            header.IPv6MinimumMTU - 1,
-			transHdrLen:    0,
-			payloadSize:    500,
-			allowPackets:   0,
-			outgoingErrors: 1,
-			mockError:      nil,
-			wantError:      &tcpip.ErrInvalidEndpointState{},
-		},
-	}
-
-	for _, ft := range tests {
-		t.Run(ft.description, func(t *testing.T) {
-			pkt := testutil.MakeRandPkt(ft.transHdrLen, extraHeaderReserve+header.IPv6MinimumSize, []int{ft.payloadSize}, header.IPv6ProtocolNumber)
-			ep := testutil.NewMockLinkEndpoint(ft.mtu, ft.mockError, ft.allowPackets)
-			r := buildRoute(t, ep)
-			err := r.WritePacket(&stack.GSO{}, stack.NetworkHeaderParams{
-				Protocol: tcp.ProtocolNumber,
-				TTL:      ttl,
-				TOS:      stack.DefaultTOS,
-			}, pkt)
-			if diff := cmp.Diff(ft.wantError, err); diff != "" {
-				t.Errorf("unexpected error from WritePacket(_, _, _), (-want, +got):\n%s", diff)
-			}
-			if got := int(r.Stats().IP.PacketsSent.Value()); got != ft.allowPackets {
-				t.Errorf("got r.Stats().IP.PacketsSent.Value() = %d, want = %d", got, ft.allowPackets)
-			}
-			if got := int(r.Stats().IP.OutgoingPacketErrors.Value()); got != ft.outgoingErrors {
-				t.Errorf("got r.Stats().IP.OutgoingPacketErrors.Value() = %d, want = %d", got, ft.outgoingErrors)
-			}
-		})
-	}
-}
-
-func TestForwarding(t *testing.T) {
-	const (
-		nicID1         = 1
-		nicID2         = 2
-		randomSequence = 123
-		randomIdent    = 42
-	)
-
-	ipv6Addr1 := tcpip.AddressWithPrefix{
-		Address:   tcpip.Address(net.ParseIP("10::1").To16()),
-		PrefixLen: 64,
-	}
-	ipv6Addr2 := tcpip.AddressWithPrefix{
-		Address:   tcpip.Address(net.ParseIP("11::1").To16()),
-		PrefixLen: 64,
-	}
-	remoteIPv6Addr1 := tcpip.Address(net.ParseIP("10::2").To16())
-	remoteIPv6Addr2 := tcpip.Address(net.ParseIP("11::2").To16())
-
-	tests := []struct {
-		name            string
-		TTL             uint8
-		expectErrorICMP bool
-	}{
-		{
-			name:            "TTL of zero",
-			TTL:             0,
-			expectErrorICMP: true,
-		},
-		{
-			name:            "TTL of one",
-			TTL:             1,
-			expectErrorICMP: true,
-		},
-		{
-			name:            "TTL of two",
-			TTL:             2,
-			expectErrorICMP: false,
-		},
-		{
-			name:            "TTL of three",
-			TTL:             3,
-			expectErrorICMP: false,
-		},
-		{
-			name:            "Max TTL",
-			TTL:             math.MaxUint8,
-			expectErrorICMP: false,
-		},
-	}
-
-	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},
-			})
-			// We expect at most a single packet in response to our ICMP Echo Request.
-			e1 := channel.New(1, header.IPv6MinimumMTU, "")
-			if err := s.CreateNIC(nicID1, e1); err != nil {
-				t.Fatalf("CreateNIC(%d, _): %s", nicID1, err)
-			}
-			ipv6ProtoAddr1 := tcpip.ProtocolAddress{Protocol: ProtocolNumber, AddressWithPrefix: ipv6Addr1}
-			if err := s.AddProtocolAddress(nicID1, ipv6ProtoAddr1); err != nil {
-				t.Fatalf("AddProtocolAddress(%d, %#v): %s", nicID1, ipv6ProtoAddr1, err)
-			}
-
-			e2 := channel.New(1, header.IPv6MinimumMTU, "")
-			if err := s.CreateNIC(nicID2, e2); err != nil {
-				t.Fatalf("CreateNIC(%d, _): %s", nicID2, err)
-			}
-			ipv6ProtoAddr2 := tcpip.ProtocolAddress{Protocol: ProtocolNumber, AddressWithPrefix: ipv6Addr2}
-			if err := s.AddProtocolAddress(nicID2, ipv6ProtoAddr2); err != nil {
-				t.Fatalf("AddProtocolAddress(%d, %#v): %s", nicID2, ipv6ProtoAddr2, err)
-			}
-
-			s.SetRouteTable([]tcpip.Route{
-				{
-					Destination: ipv6Addr1.Subnet(),
-					NIC:         nicID1,
-				},
-				{
-					Destination: ipv6Addr2.Subnet(),
-					NIC:         nicID2,
-				},
-			})
-
-			if err := s.SetForwarding(ProtocolNumber, true); err != nil {
-				t.Fatalf("SetForwarding(%d, true): %s", ProtocolNumber, err)
-			}
-
-			hdr := buffer.NewPrependable(header.IPv6MinimumSize + header.ICMPv6MinimumSize)
-			icmp := header.ICMPv6(hdr.Prepend(header.ICMPv6MinimumSize))
-			icmp.SetIdent(randomIdent)
-			icmp.SetSequence(randomSequence)
-			icmp.SetType(header.ICMPv6EchoRequest)
-			icmp.SetCode(header.ICMPv6UnusedCode)
-			icmp.SetChecksum(0)
-			icmp.SetChecksum(header.ICMPv6Checksum(header.ICMPv6ChecksumParams{
-				Header: icmp,
-				Src:    remoteIPv6Addr1,
-				Dst:    remoteIPv6Addr2,
-			}))
-			ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize))
-			ip.Encode(&header.IPv6Fields{
-				PayloadLength:     header.ICMPv6MinimumSize,
-				TransportProtocol: header.ICMPv6ProtocolNumber,
-				HopLimit:          test.TTL,
-				SrcAddr:           remoteIPv6Addr1,
-				DstAddr:           remoteIPv6Addr2,
-			})
-			requestPkt := stack.NewPacketBuffer(stack.PacketBufferOptions{
-				Data: hdr.View().ToVectorisedView(),
-			})
-			e1.InjectInbound(ProtocolNumber, requestPkt)
-
-			if test.expectErrorICMP {
-				reply, ok := e1.Read()
-				if !ok {
-					t.Fatal("expected ICMP Hop Limit Exceeded packet through incoming NIC")
-				}
-
-				checker.IPv6(t, header.IPv6(stack.PayloadSince(reply.Pkt.NetworkHeader())),
-					checker.SrcAddr(ipv6Addr1.Address),
-					checker.DstAddr(remoteIPv6Addr1),
-					checker.TTL(DefaultTTL),
-					checker.ICMPv6(
-						checker.ICMPv6Type(header.ICMPv6TimeExceeded),
-						checker.ICMPv6Code(header.ICMPv6HopLimitExceeded),
-						checker.ICMPv6Payload([]byte(hdr.View())),
-					),
-				)
-
-				if n := e2.Drain(); n != 0 {
-					t.Fatalf("got e2.Drain() = %d, want = 0", n)
-				}
-			} else {
-				reply, ok := e2.Read()
-				if !ok {
-					t.Fatal("expected ICMP Echo Request packet through outgoing NIC")
-				}
-
-				checker.IPv6(t, header.IPv6(stack.PayloadSince(reply.Pkt.NetworkHeader())),
-					checker.SrcAddr(remoteIPv6Addr1),
-					checker.DstAddr(remoteIPv6Addr2),
-					checker.TTL(test.TTL-1),
-					checker.ICMPv6(
-						checker.ICMPv6Type(header.ICMPv6EchoRequest),
-						checker.ICMPv6Code(header.ICMPv6UnusedCode),
-						checker.ICMPv6Payload(nil),
-					),
-				)
-
-				if n := e1.Drain(); n != 0 {
-					t.Fatalf("got e1.Drain() = %d, want = 0", n)
-				}
-			}
-		})
-	}
-}
-
-func TestMultiCounterStatsInitialization(t *testing.T) {
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocolFactory{NewProtocol},
-	})
-	proto := s.NetworkProtocolInstance(ProtocolNumber).(*protocol)
-	var nic testInterface
-	ep := proto.NewEndpoint(&nic, nil).(*endpoint)
-	// At this point, the Stack's stats and the NetworkEndpoint's stats are
-	// supposed to be bound.
-	refStack := s.Stats()
-	refEP := ep.stats.localStats
-	if err := testutil.ValidateMultiCounterStats(reflect.ValueOf(&ep.stats.ip).Elem(), []reflect.Value{reflect.ValueOf(&refStack.IP).Elem(), reflect.ValueOf(&refEP.IP).Elem()}); err != nil {
-		t.Error(err)
-	}
-	if err := testutil.ValidateMultiCounterStats(reflect.ValueOf(&ep.stats.icmp).Elem(), []reflect.Value{reflect.ValueOf(&refStack.ICMP.V6).Elem(), reflect.ValueOf(&refEP.ICMP).Elem()}); err != nil {
-		t.Error(err)
-	}
-}
diff --git a/pkg/tcpip/network/ipv6/mld_test.go b/pkg/tcpip/network/ipv6/mld_test.go
deleted file mode 100644
index 85a8f99..0000000
--- a/pkg/tcpip/network/ipv6/mld_test.go
+++ /dev/null
@@ -1,466 +0,0 @@
-// Copyright 2020 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_test
-
-import (
-	"bytes"
-	"testing"
-	"time"
-
-	"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/network/ipv6"
-	"gvisor.dev/gvisor/pkg/tcpip/stack"
-)
-
-const (
-	linkLocalAddr       = "\xfe\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"
-	globalAddr          = "\x0a\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"
-	globalMulticastAddr = "\xff\x05\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02"
-)
-
-var (
-	linkLocalAddrSNMC = header.SolicitedNodeAddr(linkLocalAddr)
-	globalAddrSNMC    = header.SolicitedNodeAddr(globalAddr)
-)
-
-func validateMLDPacket(t *testing.T, p buffer.View, localAddress, remoteAddress tcpip.Address, mldType header.ICMPv6Type, groupAddress tcpip.Address) {
-	t.Helper()
-
-	checker.IPv6WithExtHdr(t, p,
-		checker.IPv6ExtHdr(
-			checker.IPv6HopByHopExtensionHeader(checker.IPv6RouterAlert(header.IPv6RouterAlertMLD)),
-		),
-		checker.SrcAddr(localAddress),
-		checker.DstAddr(remoteAddress),
-		checker.TTL(header.MLDHopLimit),
-		checker.MLD(mldType, header.MLDMinimumSize,
-			checker.MLDMaxRespDelay(0),
-			checker.MLDMulticastAddress(groupAddress),
-		),
-	)
-}
-
-func TestIPv6JoinLeaveSolicitedNodeAddressPerformsMLD(t *testing.T) {
-	const nicID = 1
-
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
-			MLD: ipv6.MLDOptions{
-				Enabled: true,
-			},
-		})},
-	})
-	e := channel.New(1, header.IPv6MinimumMTU, "")
-	if err := s.CreateNIC(nicID, e); err != nil {
-		t.Fatalf("CreateNIC(%d, _): %s", nicID, err)
-	}
-
-	// The stack will join an address's solicited node multicast address when
-	// an address is added. An MLD report message should be sent for the
-	// solicited-node group.
-	if err := s.AddAddress(nicID, ipv6.ProtocolNumber, linkLocalAddr); err != nil {
-		t.Fatalf("AddAddress(%d, %d, %s) = %s", nicID, ipv6.ProtocolNumber, linkLocalAddr, err)
-	}
-	if p, ok := e.Read(); !ok {
-		t.Fatal("expected a report message to be sent")
-	} else {
-		validateMLDPacket(t, stack.PayloadSince(p.Pkt.NetworkHeader()), linkLocalAddr, linkLocalAddrSNMC, header.ICMPv6MulticastListenerReport, linkLocalAddrSNMC)
-	}
-
-	// The stack will leave an address's solicited node multicast address when
-	// an address is removed. An MLD done message should be sent for the
-	// solicited-node group.
-	if err := s.RemoveAddress(nicID, linkLocalAddr); err != nil {
-		t.Fatalf("RemoveAddress(%d, %s) = %s", nicID, linkLocalAddr, err)
-	}
-	if p, ok := e.Read(); !ok {
-		t.Fatal("expected a done message to be sent")
-	} else {
-		validateMLDPacket(t, stack.PayloadSince(p.Pkt.NetworkHeader()), header.IPv6Any, header.IPv6AllRoutersMulticastAddress, header.ICMPv6MulticastListenerDone, linkLocalAddrSNMC)
-	}
-}
-
-func TestSendQueuedMLDReports(t *testing.T) {
-	const (
-		nicID      = 1
-		maxReports = 2
-	)
-
-	tests := []struct {
-		name            string
-		dadTransmits    uint8
-		retransmitTimer time.Duration
-	}{
-		{
-			name:            "DAD Disabled",
-			dadTransmits:    0,
-			retransmitTimer: 0,
-		},
-		{
-			name:            "DAD Enabled",
-			dadTransmits:    1,
-			retransmitTimer: time.Second,
-		},
-	}
-
-	nonce := [...]byte{
-		1, 2, 3, 4, 5, 6,
-	}
-
-	const maxNSMessages = 2
-	secureRNGBytes := make([]byte, len(nonce)*maxNSMessages)
-	for b := secureRNGBytes[:]; len(b) > 0; b = b[len(nonce):] {
-		if n := copy(b, nonce[:]); n != len(nonce) {
-			t.Fatalf("got copy(...) = %d, want = %d", n, len(nonce))
-		}
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			dadResolutionTime := test.retransmitTimer * time.Duration(test.dadTransmits)
-			clock := faketime.NewManualClock()
-			var secureRNG bytes.Reader
-			secureRNG.Reset(secureRNGBytes[:])
-			s := stack.New(stack.Options{
-				SecureRNG: &secureRNG,
-				NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
-					DADConfigs: stack.DADConfigurations{
-						DupAddrDetectTransmits: test.dadTransmits,
-						RetransmitTimer:        test.retransmitTimer,
-					},
-					MLD: ipv6.MLDOptions{
-						Enabled: true,
-					},
-				})},
-				Clock: clock,
-			})
-
-			// Allow space for an extra packet so we can observe packets that were
-			// unexpectedly sent.
-			e := channel.New(maxReports+int(test.dadTransmits)+1 /* extra */, header.IPv6MinimumMTU, "")
-			if err := s.CreateNIC(nicID, e); err != nil {
-				t.Fatalf("CreateNIC(%d, _): %s", nicID, err)
-			}
-
-			resolveDAD := func(addr, snmc tcpip.Address) {
-				clock.Advance(dadResolutionTime)
-				if p, ok := e.Read(); !ok {
-					t.Fatal("expected DAD packet")
-				} else {
-					checker.IPv6(t, stack.PayloadSince(p.Pkt.NetworkHeader()),
-						checker.SrcAddr(header.IPv6Any),
-						checker.DstAddr(snmc),
-						checker.TTL(header.NDPHopLimit),
-						checker.NDPNS(
-							checker.NDPNSTargetAddress(addr),
-							checker.NDPNSOptions([]header.NDPOption{header.NDPNonceOption(nonce[:])}),
-						))
-				}
-			}
-
-			var reportCounter uint64
-			reportStat := s.Stats().ICMP.V6.PacketsSent.MulticastListenerReport
-			if got := reportStat.Value(); got != reportCounter {
-				t.Errorf("got reportStat.Value() = %d, want = %d", got, reportCounter)
-			}
-			var doneCounter uint64
-			doneStat := s.Stats().ICMP.V6.PacketsSent.MulticastListenerDone
-			if got := doneStat.Value(); got != doneCounter {
-				t.Errorf("got doneStat.Value() = %d, want = %d", got, doneCounter)
-			}
-
-			// Joining a group without an assigned address should send an MLD report
-			// with the unspecified address.
-			if err := s.JoinGroup(ipv6.ProtocolNumber, nicID, globalMulticastAddr); err != nil {
-				t.Fatalf("JoinGroup(%d, %d, %s): %s", ipv6.ProtocolNumber, nicID, globalMulticastAddr, err)
-			}
-			reportCounter++
-			if got := reportStat.Value(); got != reportCounter {
-				t.Errorf("got reportStat.Value() = %d, want = %d", got, reportCounter)
-			}
-			if p, ok := e.Read(); !ok {
-				t.Errorf("expected MLD report for %s", globalMulticastAddr)
-			} else {
-				validateMLDPacket(t, stack.PayloadSince(p.Pkt.NetworkHeader()), header.IPv6Any, globalMulticastAddr, header.ICMPv6MulticastListenerReport, globalMulticastAddr)
-			}
-			clock.Advance(time.Hour)
-			if p, ok := e.Read(); ok {
-				t.Errorf("got unexpected packet = %#v", p)
-			}
-			if t.Failed() {
-				t.FailNow()
-			}
-
-			// Adding a global address should not send reports for the already joined
-			// group since we should only send queued reports when a link-local
-			// address is assigned.
-			//
-			// Note, we will still expect to send a report for the global address's
-			// solicited node address from the unspecified address as per  RFC 3590
-			// section 4.
-			if err := s.AddAddressWithOptions(nicID, ipv6.ProtocolNumber, globalAddr, stack.FirstPrimaryEndpoint); err != nil {
-				t.Fatalf("AddAddressWithOptions(%d, %d, %s, %d): %s", nicID, ipv6.ProtocolNumber, globalAddr, stack.FirstPrimaryEndpoint, err)
-			}
-			reportCounter++
-			if got := reportStat.Value(); got != reportCounter {
-				t.Errorf("got reportStat.Value() = %d, want = %d", got, reportCounter)
-			}
-			if p, ok := e.Read(); !ok {
-				t.Errorf("expected MLD report for %s", globalAddrSNMC)
-			} else {
-				validateMLDPacket(t, stack.PayloadSince(p.Pkt.NetworkHeader()), header.IPv6Any, globalAddrSNMC, header.ICMPv6MulticastListenerReport, globalAddrSNMC)
-			}
-			if dadResolutionTime != 0 {
-				// Reports should not be sent when the address resolves.
-				resolveDAD(globalAddr, globalAddrSNMC)
-				if got := reportStat.Value(); got != reportCounter {
-					t.Errorf("got reportStat.Value() = %d, want = %d", got, reportCounter)
-				}
-			}
-			// Leave the group since we don't care about the global address's
-			// solicited node multicast group membership.
-			if err := s.LeaveGroup(ipv6.ProtocolNumber, nicID, globalAddrSNMC); err != nil {
-				t.Fatalf("LeaveGroup(%d, %d, %s): %s", ipv6.ProtocolNumber, nicID, globalAddrSNMC, err)
-			}
-			if got := doneStat.Value(); got != doneCounter {
-				t.Errorf("got doneStat.Value() = %d, want = %d", got, doneCounter)
-			}
-			if p, ok := e.Read(); ok {
-				t.Errorf("got unexpected packet = %#v", p)
-			}
-			if t.Failed() {
-				t.FailNow()
-			}
-
-			// Adding a link-local address should send a report for its solicited node
-			// address and globalMulticastAddr.
-			if err := s.AddAddressWithOptions(nicID, ipv6.ProtocolNumber, linkLocalAddr, stack.CanBePrimaryEndpoint); err != nil {
-				t.Fatalf("AddAddressWithOptions(%d, %d, %s, %d): %s", nicID, ipv6.ProtocolNumber, linkLocalAddr, stack.CanBePrimaryEndpoint, err)
-			}
-			if dadResolutionTime != 0 {
-				reportCounter++
-				if got := reportStat.Value(); got != reportCounter {
-					t.Errorf("got reportStat.Value() = %d, want = %d", got, reportCounter)
-				}
-				if p, ok := e.Read(); !ok {
-					t.Errorf("expected MLD report for %s", linkLocalAddrSNMC)
-				} else {
-					validateMLDPacket(t, stack.PayloadSince(p.Pkt.NetworkHeader()), header.IPv6Any, linkLocalAddrSNMC, header.ICMPv6MulticastListenerReport, linkLocalAddrSNMC)
-				}
-				resolveDAD(linkLocalAddr, linkLocalAddrSNMC)
-			}
-
-			// We expect two batches of reports to be sent (1 batch when the
-			// link-local address is assigned, and another after the maximum
-			// unsolicited report interval.
-			for i := 0; i < 2; i++ {
-				// We expect reports to be sent (one for globalMulticastAddr and another
-				// for linkLocalAddrSNMC).
-				reportCounter += maxReports
-				if got := reportStat.Value(); got != reportCounter {
-					t.Errorf("got reportStat.Value() = %d, want = %d", got, reportCounter)
-				}
-
-				addrs := map[tcpip.Address]bool{
-					globalMulticastAddr: false,
-					linkLocalAddrSNMC:   false,
-				}
-				for range addrs {
-					p, ok := e.Read()
-					if !ok {
-						t.Fatalf("expected MLD report for %s and %s; addrs = %#v", globalMulticastAddr, linkLocalAddrSNMC, addrs)
-					}
-
-					addr := header.IPv6(stack.PayloadSince(p.Pkt.NetworkHeader())).DestinationAddress()
-					if seen, ok := addrs[addr]; !ok {
-						t.Fatalf("got unexpected packet destined to %s", addr)
-					} else if seen {
-						t.Fatalf("got another packet destined to %s", addr)
-					}
-
-					addrs[addr] = true
-					validateMLDPacket(t, stack.PayloadSince(p.Pkt.NetworkHeader()), linkLocalAddr, addr, header.ICMPv6MulticastListenerReport, addr)
-
-					clock.Advance(ipv6.UnsolicitedReportIntervalMax)
-				}
-			}
-
-			// Should not send any more reports.
-			clock.Advance(time.Hour)
-			if p, ok := e.Read(); ok {
-				t.Errorf("got unexpected packet = %#v", p)
-			}
-		})
-	}
-}
-
-// createAndInjectMLDPacket creates and injects an MLD packet with the
-// specified fields.
-func createAndInjectMLDPacket(e *channel.Endpoint, mldType header.ICMPv6Type, hopLimit uint8, srcAddress tcpip.Address, withRouterAlertOption bool, routerAlertValue header.IPv6RouterAlertValue) {
-	var extensionHeaders header.IPv6ExtHdrSerializer
-	if withRouterAlertOption {
-		extensionHeaders = header.IPv6ExtHdrSerializer{
-			header.IPv6SerializableHopByHopExtHdr{
-				&header.IPv6RouterAlertOption{Value: routerAlertValue},
-			},
-		}
-	}
-
-	extensionHeadersLength := extensionHeaders.Length()
-	payloadLength := extensionHeadersLength + header.ICMPv6HeaderSize + header.MLDMinimumSize
-	buf := buffer.NewView(header.IPv6MinimumSize + payloadLength)
-
-	ip := header.IPv6(buf)
-	ip.Encode(&header.IPv6Fields{
-		PayloadLength:     uint16(payloadLength),
-		HopLimit:          hopLimit,
-		TransportProtocol: header.ICMPv6ProtocolNumber,
-		SrcAddr:           srcAddress,
-		DstAddr:           header.IPv6AllNodesMulticastAddress,
-		ExtensionHeaders:  extensionHeaders,
-	})
-
-	icmp := header.ICMPv6(ip.Payload()[extensionHeadersLength:])
-	icmp.SetType(mldType)
-	mld := header.MLD(icmp.MessageBody())
-	mld.SetMaximumResponseDelay(0)
-	mld.SetMulticastAddress(header.IPv6Any)
-	icmp.SetChecksum(header.ICMPv6Checksum(header.ICMPv6ChecksumParams{
-		Header: icmp,
-		Src:    srcAddress,
-		Dst:    header.IPv6AllNodesMulticastAddress,
-	}))
-
-	e.InjectInbound(ipv6.ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
-		Data: buf.ToVectorisedView(),
-	}))
-}
-
-func TestMLDPacketValidation(t *testing.T) {
-	const (
-		nicID          = 1
-		linkLocalAddr2 = tcpip.Address("\xfe\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02")
-	)
-
-	tests := []struct {
-		name                     string
-		messageType              header.ICMPv6Type
-		srcAddr                  tcpip.Address
-		includeRouterAlertOption bool
-		routerAlertValue         header.IPv6RouterAlertValue
-		hopLimit                 uint8
-		expectValidMLD           bool
-		getMessageTypeStatValue  func(tcpip.Stats) uint64
-	}{
-		{
-			name:                     "valid",
-			messageType:              header.ICMPv6MulticastListenerQuery,
-			includeRouterAlertOption: true,
-			routerAlertValue:         header.IPv6RouterAlertMLD,
-			srcAddr:                  linkLocalAddr2,
-			hopLimit:                 header.MLDHopLimit,
-			expectValidMLD:           true,
-			getMessageTypeStatValue:  func(stats tcpip.Stats) uint64 { return stats.ICMP.V6.PacketsReceived.MulticastListenerQuery.Value() },
-		},
-		{
-			name:                     "bad hop limit",
-			messageType:              header.ICMPv6MulticastListenerReport,
-			includeRouterAlertOption: true,
-			routerAlertValue:         header.IPv6RouterAlertMLD,
-			srcAddr:                  linkLocalAddr2,
-			hopLimit:                 header.MLDHopLimit + 1,
-			expectValidMLD:           false,
-			getMessageTypeStatValue:  func(stats tcpip.Stats) uint64 { return stats.ICMP.V6.PacketsReceived.MulticastListenerReport.Value() },
-		},
-		{
-			name:                     "src ip not link local",
-			messageType:              header.ICMPv6MulticastListenerReport,
-			includeRouterAlertOption: true,
-			routerAlertValue:         header.IPv6RouterAlertMLD,
-			srcAddr:                  globalAddr,
-			hopLimit:                 header.MLDHopLimit,
-			expectValidMLD:           false,
-			getMessageTypeStatValue:  func(stats tcpip.Stats) uint64 { return stats.ICMP.V6.PacketsReceived.MulticastListenerReport.Value() },
-		},
-		{
-			name:                     "missing router alert ip option",
-			messageType:              header.ICMPv6MulticastListenerDone,
-			includeRouterAlertOption: false,
-			srcAddr:                  linkLocalAddr2,
-			hopLimit:                 header.MLDHopLimit,
-			expectValidMLD:           false,
-			getMessageTypeStatValue:  func(stats tcpip.Stats) uint64 { return stats.ICMP.V6.PacketsReceived.MulticastListenerDone.Value() },
-		},
-		{
-			name:                     "incorrect router alert value",
-			messageType:              header.ICMPv6MulticastListenerDone,
-			includeRouterAlertOption: true,
-			routerAlertValue:         header.IPv6RouterAlertRSVP,
-			srcAddr:                  linkLocalAddr2,
-			hopLimit:                 header.MLDHopLimit,
-			expectValidMLD:           false,
-			getMessageTypeStatValue:  func(stats tcpip.Stats) uint64 { return stats.ICMP.V6.PacketsReceived.MulticastListenerDone.Value() },
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			s := stack.New(stack.Options{
-				NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
-					MLD: ipv6.MLDOptions{
-						Enabled: true,
-					},
-				})},
-			})
-			e := channel.New(nicID, header.IPv6MinimumMTU, "")
-			if err := s.CreateNIC(nicID, e); err != nil {
-				t.Fatalf("CreateNIC(%d, _): %s", nicID, err)
-			}
-			stats := s.Stats()
-			// Verify that every relevant stats is zero'd before we send a packet.
-			if got := test.getMessageTypeStatValue(s.Stats()); got != 0 {
-				t.Errorf("got test.getMessageTypeStatValue(s.Stats()) = %d, want = 0", got)
-			}
-			if got := stats.ICMP.V6.PacketsReceived.Invalid.Value(); got != 0 {
-				t.Errorf("got stats.ICMP.V6.PacketsReceived.Invalid.Value() = %d, want = 0", got)
-			}
-			if got := stats.IP.PacketsDelivered.Value(); got != 0 {
-				t.Fatalf("got stats.IP.PacketsDelivered.Value() = %d, want = 0", got)
-			}
-			createAndInjectMLDPacket(e, test.messageType, test.hopLimit, test.srcAddr, test.includeRouterAlertOption, test.routerAlertValue)
-			// We always expect the packet to pass IP validation.
-			if got := stats.IP.PacketsDelivered.Value(); got != 1 {
-				t.Fatalf("got stats.IP.PacketsDelivered.Value() = %d, want = 1", got)
-			}
-			// Even when the MLD-specific validation checks fail, we expect the
-			// corresponding MLD counter to be incremented.
-			if got := test.getMessageTypeStatValue(s.Stats()); got != 1 {
-				t.Errorf("got test.getMessageTypeStatValue(s.Stats()) = %d, want = 1", got)
-			}
-			var expectedInvalidCount uint64
-			if !test.expectValidMLD {
-				expectedInvalidCount = 1
-			}
-			if got := stats.ICMP.V6.PacketsReceived.Invalid.Value(); got != expectedInvalidCount {
-				t.Errorf("got stats.ICMP.V6.PacketsReceived.Invalid.Value() = %d, want = %d", got, expectedInvalidCount)
-			}
-		})
-	}
-}
diff --git a/pkg/tcpip/network/ipv6/ndp_test.go b/pkg/tcpip/network/ipv6/ndp_test.go
deleted file mode 100644
index 52b9a20..0000000
--- a/pkg/tcpip/network/ipv6/ndp_test.go
+++ /dev/null
@@ -1,1376 +0,0 @@
-// 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 ipv6
-
-import (
-	"bytes"
-	"context"
-	"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/faketime"
-	"gvisor.dev/gvisor/pkg/tcpip/header"
-	"gvisor.dev/gvisor/pkg/tcpip/link/channel"
-	"gvisor.dev/gvisor/pkg/tcpip/stack"
-	"gvisor.dev/gvisor/pkg/tcpip/transport/icmp"
-)
-
-// setupStackAndEndpoint creates a stack with a single NIC with a link-local
-// address llladdr and an IPv6 endpoint to a remote with link-local address
-// rlladdr
-func setupStackAndEndpoint(t *testing.T, llladdr, rlladdr tcpip.Address) (*stack.Stack, stack.NetworkEndpoint) {
-	t.Helper()
-
-	s := stack.New(stack.Options{
-		NetworkProtocols:   []stack.NetworkProtocolFactory{NewProtocol},
-		TransportProtocols: []stack.TransportProtocolFactory{icmp.NewProtocol6},
-	})
-
-	if err := s.CreateNIC(1, &stubLinkEndpoint{}); err != nil {
-		t.Fatalf("CreateNIC(_) = %s", err)
-	}
-	{
-		subnet, err := tcpip.NewSubnet(rlladdr, tcpip.AddressMask(strings.Repeat("\xff", len(rlladdr))))
-		if err != nil {
-			t.Fatal(err)
-		}
-		s.SetRouteTable(
-			[]tcpip.Route{{
-				Destination: subnet,
-				NIC:         1,
-			}},
-		)
-	}
-
-	netProto := s.NetworkProtocolInstance(ProtocolNumber)
-	if netProto == nil {
-		t.Fatalf("cannot find protocol instance for network protocol %d", ProtocolNumber)
-	}
-
-	ep := netProto.NewEndpoint(&testInterface{}, &stubDispatcher{})
-	if err := ep.Enable(); err != nil {
-		t.Fatalf("ep.Enable(): %s", err)
-	}
-	t.Cleanup(ep.Close)
-
-	addressableEndpoint, ok := ep.(stack.AddressableEndpoint)
-	if !ok {
-		t.Fatalf("expected network endpoint to implement stack.AddressableEndpoint")
-	}
-	addr := llladdr.WithPrefix()
-	if addressEP, err := addressableEndpoint.AddAndAcquirePermanentAddress(addr, stack.CanBePrimaryEndpoint, stack.AddressConfigStatic, false /* deprecated */); err != nil {
-		t.Fatalf("addressableEndpoint.AddAndAcquirePermanentAddress(%s, CanBePrimaryEndpoint, AddressConfigStatic, false): %s", addr, err)
-	} else {
-		addressEP.DecRef()
-	}
-
-	return s, ep
-}
-
-var _ NDPDispatcher = (*testNDPDispatcher)(nil)
-
-// testNDPDispatcher is an NDPDispatcher only allows default router discovery.
-type testNDPDispatcher struct {
-	addr tcpip.Address
-}
-
-func (*testNDPDispatcher) OnDuplicateAddressDetectionResult(tcpip.NICID, tcpip.Address, stack.DADResult) {
-}
-
-func (t *testNDPDispatcher) OnDefaultRouterDiscovered(_ tcpip.NICID, addr tcpip.Address) bool {
-	t.addr = addr
-	return true
-}
-
-func (t *testNDPDispatcher) OnDefaultRouterInvalidated(_ tcpip.NICID, addr tcpip.Address) {
-	t.addr = addr
-}
-
-func (*testNDPDispatcher) OnOnLinkPrefixDiscovered(tcpip.NICID, tcpip.Subnet) bool {
-	return false
-}
-
-func (*testNDPDispatcher) OnOnLinkPrefixInvalidated(tcpip.NICID, tcpip.Subnet) {
-}
-
-func (*testNDPDispatcher) OnAutoGenAddress(tcpip.NICID, tcpip.AddressWithPrefix) bool {
-	return false
-}
-
-func (*testNDPDispatcher) OnAutoGenAddressDeprecated(tcpip.NICID, tcpip.AddressWithPrefix) {
-}
-
-func (*testNDPDispatcher) OnAutoGenAddressInvalidated(tcpip.NICID, tcpip.AddressWithPrefix) {
-}
-
-func (*testNDPDispatcher) OnRecursiveDNSServerOption(tcpip.NICID, []tcpip.Address, time.Duration) {
-}
-
-func (*testNDPDispatcher) OnDNSSearchListOption(tcpip.NICID, []string, time.Duration) {
-}
-
-func (*testNDPDispatcher) OnDHCPv6Configuration(tcpip.NICID, DHCPv6ConfigurationFromNDPRA) {
-}
-
-func TestStackNDPEndpointInvalidateDefaultRouter(t *testing.T) {
-	var ndpDisp testNDPDispatcher
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocolFactory{NewProtocolWithOptions(Options{
-			NDPDisp: &ndpDisp,
-		})},
-	})
-
-	if err := s.CreateNIC(nicID, &stubLinkEndpoint{}); 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)
-	}
-
-	ipv6EP := ep.(*endpoint)
-	ipv6EP.mu.Lock()
-	ipv6EP.mu.ndp.rememberDefaultRouter(lladdr1, time.Hour)
-	ipv6EP.mu.Unlock()
-
-	if ndpDisp.addr != lladdr1 {
-		t.Fatalf("got ndpDisp.addr = %s, want = %s", ndpDisp.addr, lladdr1)
-	}
-
-	ndpDisp.addr = ""
-	ndpEP := ep.(stack.NDPEndpoint)
-	ndpEP.InvalidateDefaultRouter(lladdr1)
-	if ndpDisp.addr != lladdr1 {
-		t.Fatalf("got ndpDisp.addr = %s, want = %s", ndpDisp.addr, lladdr1)
-	}
-}
-
-type linkResolutionResult struct {
-	linkAddr tcpip.LinkAddress
-	ok       bool
-}
-
-// TestNeighborSolicitationWithSourceLinkLayerOption tests that receiving a
-// valid NDP NS message with the Source Link Layer Address option results in a
-// new entry in the link address cache for the sender of the message.
-func TestNeighborSolicitationWithSourceLinkLayerOption(t *testing.T) {
-	const nicID = 1
-
-	tests := []struct {
-		name             string
-		optsBuf          []byte
-		expectedLinkAddr tcpip.LinkAddress
-	}{
-		{
-			name:             "Valid",
-			optsBuf:          []byte{1, 1, 2, 3, 4, 5, 6, 7},
-			expectedLinkAddr: "\x02\x03\x04\x05\x06\x07",
-		},
-		{
-			name:    "Too Small",
-			optsBuf: []byte{1, 1, 2, 3, 4, 5, 6},
-		},
-		{
-			name:    "Invalid Length",
-			optsBuf: []byte{1, 2, 2, 3, 4, 5, 6, 7},
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			s := stack.New(stack.Options{
-				NetworkProtocols: []stack.NetworkProtocolFactory{NewProtocol},
-			})
-			e := channel.New(0, 1280, linkAddr0)
-			e.LinkEPCapabilities |= stack.CapabilityResolutionRequired
-			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)
-			}
-
-			ndpNSSize := header.ICMPv6NeighborSolicitMinimumSize + len(test.optsBuf)
-			hdr := buffer.NewPrependable(header.IPv6MinimumSize + ndpNSSize)
-			pkt := header.ICMPv6(hdr.Prepend(ndpNSSize))
-			pkt.SetType(header.ICMPv6NeighborSolicit)
-			ns := header.NDPNeighborSolicit(pkt.MessageBody())
-			ns.SetTargetAddress(lladdr0)
-			opts := ns.Options()
-			copy(opts, test.optsBuf)
-			pkt.SetChecksum(header.ICMPv6Checksum(header.ICMPv6ChecksumParams{
-				Header: pkt,
-				Src:    lladdr1,
-				Dst:    lladdr0,
-			}))
-			payloadLength := hdr.UsedLength()
-			ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize))
-			ip.Encode(&header.IPv6Fields{
-				PayloadLength:     uint16(payloadLength),
-				TransportProtocol: header.ICMPv6ProtocolNumber,
-				HopLimit:          255,
-				SrcAddr:           lladdr1,
-				DstAddr:           lladdr0,
-			})
-
-			invalid := s.Stats().ICMP.V6.PacketsReceived.Invalid
-
-			// Invalid count should initially be 0.
-			if got := invalid.Value(); got != 0 {
-				t.Fatalf("got invalid = %d, want = 0", got)
-			}
-
-			e.InjectInbound(ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
-				Data: hdr.View().ToVectorisedView(),
-			}))
-
-			neighbors, err := s.Neighbors(nicID, ProtocolNumber)
-			if err != nil {
-				t.Fatalf("s.Neighbors(%d, %d): %s", nicID, ProtocolNumber, err)
-			}
-
-			neighborByAddr := make(map[tcpip.Address]stack.NeighborEntry)
-			for _, n := range neighbors {
-				if existing, ok := neighborByAddr[n.Addr]; ok {
-					if diff := cmp.Diff(existing, n); diff != "" {
-						t.Fatalf("s.Neighbors(%d, %d) returned unexpected duplicate neighbor entry (-existing +got):\n%s", nicID, ProtocolNumber, diff)
-					}
-					t.Fatalf("s.Neighbors(%d, %d) returned unexpected duplicate neighbor entry: %#v", nicID, ProtocolNumber, existing)
-				}
-				neighborByAddr[n.Addr] = n
-			}
-
-			if neigh, ok := neighborByAddr[lladdr1]; len(test.expectedLinkAddr) != 0 {
-				// Invalid count should not have increased.
-				if got := invalid.Value(); got != 0 {
-					t.Errorf("got invalid = %d, want = 0", got)
-				}
-
-				if !ok {
-					t.Fatalf("expected a neighbor entry for %q", lladdr1)
-				}
-				if neigh.LinkAddr != test.expectedLinkAddr {
-					t.Errorf("got link address = %s, want = %s", neigh.LinkAddr, test.expectedLinkAddr)
-				}
-				if neigh.State != stack.Stale {
-					t.Errorf("got NUD state = %s, want = %s", neigh.State, stack.Stale)
-				}
-			} else {
-				// Invalid count should have increased.
-				if got := invalid.Value(); got != 1 {
-					t.Errorf("got invalid = %d, want = 1", got)
-				}
-
-				if ok {
-					t.Fatalf("unexpectedly got neighbor entry: %#v", neigh)
-				}
-			}
-		})
-	}
-}
-
-func TestNeighborSolicitationResponse(t *testing.T) {
-	const nicID = 1
-	nicAddr := lladdr0
-	remoteAddr := lladdr1
-	nicAddrSNMC := header.SolicitedNodeAddr(nicAddr)
-	nicLinkAddr := linkAddr0
-	remoteLinkAddr0 := linkAddr1
-	remoteLinkAddr1 := linkAddr2
-
-	tests := []struct {
-		name                   string
-		nsOpts                 header.NDPOptionsSerializer
-		nsSrcLinkAddr          tcpip.LinkAddress
-		nsSrc                  tcpip.Address
-		nsDst                  tcpip.Address
-		nsInvalid              bool
-		naDstLinkAddr          tcpip.LinkAddress
-		naSolicited            bool
-		naSrc                  tcpip.Address
-		naDst                  tcpip.Address
-		performsLinkResolution bool
-	}{
-		{
-			name:          "Unspecified source to solicited-node multicast destination",
-			nsOpts:        nil,
-			nsSrcLinkAddr: remoteLinkAddr0,
-			nsSrc:         header.IPv6Any,
-			nsDst:         nicAddrSNMC,
-			nsInvalid:     false,
-			naDstLinkAddr: header.EthernetAddressFromMulticastIPv6Address(header.IPv6AllNodesMulticastAddress),
-			naSolicited:   false,
-			naSrc:         nicAddr,
-			naDst:         header.IPv6AllNodesMulticastAddress,
-		},
-		{
-			name: "Unspecified source with source ll option to multicast destination",
-			nsOpts: header.NDPOptionsSerializer{
-				header.NDPSourceLinkLayerAddressOption(remoteLinkAddr0[:]),
-			},
-			nsSrcLinkAddr: remoteLinkAddr0,
-			nsSrc:         header.IPv6Any,
-			nsDst:         nicAddrSNMC,
-			nsInvalid:     true,
-		},
-		{
-			name:          "Unspecified source to unicast destination",
-			nsOpts:        nil,
-			nsSrcLinkAddr: remoteLinkAddr0,
-			nsSrc:         header.IPv6Any,
-			nsDst:         nicAddr,
-			nsInvalid:     true,
-		},
-		{
-			name: "Unspecified source with source ll option to unicast destination",
-			nsOpts: header.NDPOptionsSerializer{
-				header.NDPSourceLinkLayerAddressOption(remoteLinkAddr0[:]),
-			},
-			nsSrcLinkAddr: remoteLinkAddr0,
-			nsSrc:         header.IPv6Any,
-			nsDst:         nicAddr,
-			nsInvalid:     true,
-		},
-		{
-			name: "Specified source with 1 source ll to multicast destination",
-			nsOpts: header.NDPOptionsSerializer{
-				header.NDPSourceLinkLayerAddressOption(remoteLinkAddr0[:]),
-			},
-			nsSrcLinkAddr: remoteLinkAddr0,
-			nsSrc:         remoteAddr,
-			nsDst:         nicAddrSNMC,
-			nsInvalid:     false,
-			naDstLinkAddr: remoteLinkAddr0,
-			naSolicited:   true,
-			naSrc:         nicAddr,
-			naDst:         remoteAddr,
-		},
-		{
-			name: "Specified source with 1 source ll different from route to multicast destination",
-			nsOpts: header.NDPOptionsSerializer{
-				header.NDPSourceLinkLayerAddressOption(remoteLinkAddr1[:]),
-			},
-			nsSrcLinkAddr: remoteLinkAddr0,
-			nsSrc:         remoteAddr,
-			nsDst:         nicAddrSNMC,
-			nsInvalid:     false,
-			naDstLinkAddr: remoteLinkAddr1,
-			naSolicited:   true,
-			naSrc:         nicAddr,
-			naDst:         remoteAddr,
-		},
-		{
-			name:          "Specified source to multicast destination",
-			nsOpts:        nil,
-			nsSrcLinkAddr: remoteLinkAddr0,
-			nsSrc:         remoteAddr,
-			nsDst:         nicAddrSNMC,
-			nsInvalid:     true,
-		},
-		{
-			name: "Specified source with 2 source ll to multicast destination",
-			nsOpts: header.NDPOptionsSerializer{
-				header.NDPSourceLinkLayerAddressOption(remoteLinkAddr0[:]),
-				header.NDPSourceLinkLayerAddressOption(remoteLinkAddr1[:]),
-			},
-			nsSrcLinkAddr: remoteLinkAddr0,
-			nsSrc:         remoteAddr,
-			nsDst:         nicAddrSNMC,
-			nsInvalid:     true,
-		},
-
-		{
-			name:          "Specified source to unicast destination",
-			nsOpts:        nil,
-			nsSrcLinkAddr: remoteLinkAddr0,
-			nsSrc:         remoteAddr,
-			nsDst:         nicAddr,
-			nsInvalid:     false,
-			naDstLinkAddr: remoteLinkAddr0,
-			naSolicited:   true,
-			naSrc:         nicAddr,
-			naDst:         remoteAddr,
-			// Since we send a unicast solicitations to a node without an entry for
-			// the remote, the node needs to perform neighbor discovery to get the
-			// remote's link address to send the advertisement response.
-			performsLinkResolution: true,
-		},
-		{
-			name: "Specified source with 1 source ll to unicast destination",
-			nsOpts: header.NDPOptionsSerializer{
-				header.NDPSourceLinkLayerAddressOption(remoteLinkAddr0[:]),
-			},
-			nsSrcLinkAddr: remoteLinkAddr0,
-			nsSrc:         remoteAddr,
-			nsDst:         nicAddr,
-			nsInvalid:     false,
-			naDstLinkAddr: remoteLinkAddr0,
-			naSolicited:   true,
-			naSrc:         nicAddr,
-			naDst:         remoteAddr,
-		},
-		{
-			name: "Specified source with 1 source ll different from route to unicast destination",
-			nsOpts: header.NDPOptionsSerializer{
-				header.NDPSourceLinkLayerAddressOption(remoteLinkAddr1[:]),
-			},
-			nsSrcLinkAddr: remoteLinkAddr0,
-			nsSrc:         remoteAddr,
-			nsDst:         nicAddr,
-			nsInvalid:     false,
-			naDstLinkAddr: remoteLinkAddr1,
-			naSolicited:   true,
-			naSrc:         nicAddr,
-			naDst:         remoteAddr,
-		},
-		{
-			name: "Specified source with 2 source ll to unicast destination",
-			nsOpts: header.NDPOptionsSerializer{
-				header.NDPSourceLinkLayerAddressOption(remoteLinkAddr0[:]),
-				header.NDPSourceLinkLayerAddressOption(remoteLinkAddr1[:]),
-			},
-			nsSrcLinkAddr: remoteLinkAddr0,
-			nsSrc:         remoteAddr,
-			nsDst:         nicAddr,
-			nsInvalid:     true,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			s := stack.New(stack.Options{
-				NetworkProtocols: []stack.NetworkProtocolFactory{NewProtocol},
-			})
-			e := channel.New(1, 1280, nicLinkAddr)
-			e.LinkEPCapabilities |= stack.CapabilityResolutionRequired
-			if err := s.CreateNIC(nicID, e); err != nil {
-				t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
-			}
-			if err := s.AddAddress(nicID, ProtocolNumber, nicAddr); err != nil {
-				t.Fatalf("AddAddress(%d, %d, %s) = %s", nicID, ProtocolNumber, nicAddr, err)
-			}
-
-			s.SetRouteTable([]tcpip.Route{
-				{
-					Destination: header.IPv6EmptySubnet,
-					NIC:         1,
-				},
-			})
-
-			ndpNSSize := header.ICMPv6NeighborSolicitMinimumSize + test.nsOpts.Length()
-			hdr := buffer.NewPrependable(header.IPv6MinimumSize + ndpNSSize)
-			pkt := header.ICMPv6(hdr.Prepend(ndpNSSize))
-			pkt.SetType(header.ICMPv6NeighborSolicit)
-			ns := header.NDPNeighborSolicit(pkt.MessageBody())
-			ns.SetTargetAddress(nicAddr)
-			opts := ns.Options()
-			opts.Serialize(test.nsOpts)
-			pkt.SetChecksum(header.ICMPv6Checksum(header.ICMPv6ChecksumParams{
-				Header: pkt,
-				Src:    test.nsSrc,
-				Dst:    test.nsDst,
-			}))
-			payloadLength := hdr.UsedLength()
-			ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize))
-			ip.Encode(&header.IPv6Fields{
-				PayloadLength:     uint16(payloadLength),
-				TransportProtocol: header.ICMPv6ProtocolNumber,
-				HopLimit:          255,
-				SrcAddr:           test.nsSrc,
-				DstAddr:           test.nsDst,
-			})
-
-			invalid := s.Stats().ICMP.V6.PacketsReceived.Invalid
-
-			// Invalid count should initially be 0.
-			if got := invalid.Value(); got != 0 {
-				t.Fatalf("got invalid = %d, want = 0", got)
-			}
-
-			e.InjectLinkAddr(ProtocolNumber, test.nsSrcLinkAddr, stack.NewPacketBuffer(stack.PacketBufferOptions{
-				Data: hdr.View().ToVectorisedView(),
-			}))
-
-			if test.nsInvalid {
-				if got := invalid.Value(); got != 1 {
-					t.Fatalf("got invalid = %d, want = 1", got)
-				}
-
-				if p, got := e.Read(); got {
-					t.Fatalf("unexpected response to an invalid NS = %+v", p.Pkt)
-				}
-
-				// If we expected the NS to be invalid, we have nothing else to check.
-				return
-			}
-
-			if got := invalid.Value(); got != 0 {
-				t.Fatalf("got invalid = %d, want = 0", got)
-			}
-
-			if test.performsLinkResolution {
-				p, got := e.ReadContext(context.Background())
-				if !got {
-					t.Fatal("expected an NDP NS response")
-				}
-
-				respNSDst := header.SolicitedNodeAddr(test.nsSrc)
-				var want stack.RouteInfo
-				want.NetProto = ProtocolNumber
-				want.RemoteLinkAddress = header.EthernetAddressFromMulticastIPv6Address(respNSDst)
-				if diff := cmp.Diff(want, p.Route, cmp.AllowUnexported(want)); diff != "" {
-					t.Errorf("route info mismatch (-want +got):\n%s", diff)
-				}
-
-				checker.IPv6(t, stack.PayloadSince(p.Pkt.NetworkHeader()),
-					checker.SrcAddr(nicAddr),
-					checker.DstAddr(respNSDst),
-					checker.TTL(header.NDPHopLimit),
-					checker.NDPNS(
-						checker.NDPNSTargetAddress(test.nsSrc),
-						checker.NDPNSOptions([]header.NDPOption{
-							header.NDPSourceLinkLayerAddressOption(nicLinkAddr),
-						}),
-					))
-
-				ser := header.NDPOptionsSerializer{
-					header.NDPTargetLinkLayerAddressOption(linkAddr1),
-				}
-				ndpNASize := header.ICMPv6NeighborAdvertMinimumSize + ser.Length()
-				hdr := buffer.NewPrependable(header.IPv6MinimumSize + ndpNASize)
-				pkt := header.ICMPv6(hdr.Prepend(ndpNASize))
-				pkt.SetType(header.ICMPv6NeighborAdvert)
-				na := header.NDPNeighborAdvert(pkt.MessageBody())
-				na.SetSolicitedFlag(true)
-				na.SetOverrideFlag(true)
-				na.SetTargetAddress(test.nsSrc)
-				na.Options().Serialize(ser)
-				pkt.SetChecksum(header.ICMPv6Checksum(header.ICMPv6ChecksumParams{
-					Header: pkt,
-					Src:    test.nsSrc,
-					Dst:    nicAddr,
-				}))
-				payloadLength := hdr.UsedLength()
-				ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize))
-				ip.Encode(&header.IPv6Fields{
-					PayloadLength:     uint16(payloadLength),
-					TransportProtocol: header.ICMPv6ProtocolNumber,
-					HopLimit:          header.NDPHopLimit,
-					SrcAddr:           test.nsSrc,
-					DstAddr:           nicAddr,
-				})
-				e.InjectLinkAddr(ProtocolNumber, "", stack.NewPacketBuffer(stack.PacketBufferOptions{
-					Data: hdr.View().ToVectorisedView(),
-				}))
-			}
-
-			p, got := e.ReadContext(context.Background())
-			if !got {
-				t.Fatal("expected an NDP NA response")
-			}
-
-			if p.Route.LocalAddress != test.naSrc {
-				t.Errorf("got p.Route.LocalAddress = %s, want = %s", p.Route.LocalAddress, test.naSrc)
-			}
-			if p.Route.LocalLinkAddress != nicLinkAddr {
-				t.Errorf("p.Route.LocalLinkAddress = %s, want = %s", p.Route.LocalLinkAddress, nicLinkAddr)
-			}
-			if p.Route.RemoteAddress != test.naDst {
-				t.Errorf("got p.Route.RemoteAddress = %s, want = %s", p.Route.RemoteAddress, test.naDst)
-			}
-			if p.Route.RemoteLinkAddress != test.naDstLinkAddr {
-				t.Errorf("got p.Route.RemoteLinkAddress = %s, want = %s", p.Route.RemoteLinkAddress, test.naDstLinkAddr)
-			}
-
-			checker.IPv6(t, stack.PayloadSince(p.Pkt.NetworkHeader()),
-				checker.SrcAddr(test.naSrc),
-				checker.DstAddr(test.naDst),
-				checker.TTL(header.NDPHopLimit),
-				checker.NDPNA(
-					checker.NDPNASolicitedFlag(test.naSolicited),
-					checker.NDPNATargetAddress(nicAddr),
-					checker.NDPNAOptions([]header.NDPOption{
-						header.NDPTargetLinkLayerAddressOption(nicLinkAddr[:]),
-					}),
-				))
-		})
-	}
-}
-
-// TestNeighborAdvertisementWithTargetLinkLayerOption tests that receiving a
-// valid NDP NA message with the Target Link Layer Address option does not
-// result in a new entry in the neighbor cache for the target of the message.
-func TestNeighborAdvertisementWithTargetLinkLayerOption(t *testing.T) {
-	const nicID = 1
-
-	tests := []struct {
-		name    string
-		optsBuf []byte
-		isValid bool
-	}{
-		{
-			name:    "Valid",
-			optsBuf: []byte{2, 1, 2, 3, 4, 5, 6, 7},
-			isValid: true,
-		},
-		{
-			name:    "Too Small",
-			optsBuf: []byte{2, 1, 2, 3, 4, 5, 6},
-		},
-		{
-			name:    "Invalid Length",
-			optsBuf: []byte{2, 2, 2, 3, 4, 5, 6, 7},
-		},
-		{
-			name: "Multiple",
-			optsBuf: []byte{
-				2, 1, 2, 3, 4, 5, 6, 7,
-				2, 1, 2, 3, 4, 5, 6, 8,
-			},
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			s := stack.New(stack.Options{
-				NetworkProtocols: []stack.NetworkProtocolFactory{NewProtocol},
-			})
-			e := channel.New(0, 1280, linkAddr0)
-			e.LinkEPCapabilities |= stack.CapabilityResolutionRequired
-			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)
-			}
-
-			ndpNASize := header.ICMPv6NeighborAdvertMinimumSize + len(test.optsBuf)
-			hdr := buffer.NewPrependable(header.IPv6MinimumSize + ndpNASize)
-			pkt := header.ICMPv6(hdr.Prepend(ndpNASize))
-			pkt.SetType(header.ICMPv6NeighborAdvert)
-			ns := header.NDPNeighborAdvert(pkt.MessageBody())
-			ns.SetTargetAddress(lladdr1)
-			opts := ns.Options()
-			copy(opts, test.optsBuf)
-			pkt.SetChecksum(header.ICMPv6Checksum(header.ICMPv6ChecksumParams{
-				Header: pkt,
-				Src:    lladdr1,
-				Dst:    lladdr0,
-			}))
-			payloadLength := hdr.UsedLength()
-			ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize))
-			ip.Encode(&header.IPv6Fields{
-				PayloadLength:     uint16(payloadLength),
-				TransportProtocol: header.ICMPv6ProtocolNumber,
-				HopLimit:          255,
-				SrcAddr:           lladdr1,
-				DstAddr:           lladdr0,
-			})
-
-			invalid := s.Stats().ICMP.V6.PacketsReceived.Invalid
-
-			// Invalid count should initially be 0.
-			if got := invalid.Value(); got != 0 {
-				t.Fatalf("got invalid = %d, want = 0", got)
-			}
-
-			e.InjectInbound(ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
-				Data: hdr.View().ToVectorisedView(),
-			}))
-
-			neighbors, err := s.Neighbors(nicID, ProtocolNumber)
-			if err != nil {
-				t.Fatalf("s.Neighbors(%d, %d): %s", nicID, ProtocolNumber, err)
-			}
-
-			neighborByAddr := make(map[tcpip.Address]stack.NeighborEntry)
-			for _, n := range neighbors {
-				if existing, ok := neighborByAddr[n.Addr]; ok {
-					if diff := cmp.Diff(existing, n); diff != "" {
-						t.Fatalf("s.Neighbors(%d, %d) returned unexpected duplicate neighbor entry (-existing +got):\n%s", nicID, ProtocolNumber, diff)
-					}
-					t.Fatalf("s.Neighbors(%d, %d) returned unexpected duplicate neighbor entry: %#v", nicID, ProtocolNumber, existing)
-				}
-				neighborByAddr[n.Addr] = n
-			}
-
-			if neigh, ok := neighborByAddr[lladdr1]; ok {
-				t.Fatalf("unexpectedly got neighbor entry: %#v", neigh)
-			}
-
-			if test.isValid {
-				// Invalid count should not have increased.
-				if got := invalid.Value(); got != 0 {
-					t.Errorf("got invalid = %d, want = 0", got)
-				}
-			} else {
-				// Invalid count should have increased.
-				if got := invalid.Value(); got != 1 {
-					t.Errorf("got invalid = %d, want = 1", got)
-				}
-			}
-		})
-	}
-}
-
-func TestNDPValidation(t *testing.T) {
-	setup := func(t *testing.T) (*stack.Stack, stack.NetworkEndpoint) {
-		t.Helper()
-
-		// Create a stack with the assigned link-local address lladdr0
-		// and an endpoint to lladdr1.
-		s, ep := setupStackAndEndpoint(t, lladdr0, lladdr1)
-
-		return s, ep
-	}
-
-	handleIPv6Payload := func(payload buffer.View, hopLimit uint8, atomicFragment bool, ep stack.NetworkEndpoint) {
-		var extHdrs header.IPv6ExtHdrSerializer
-		if atomicFragment {
-			extHdrs = append(extHdrs, &header.IPv6SerializableFragmentExtHdr{})
-		}
-		extHdrsLen := extHdrs.Length()
-
-		ip := buffer.NewView(header.IPv6MinimumSize + extHdrsLen)
-		header.IPv6(ip).Encode(&header.IPv6Fields{
-			PayloadLength:     uint16(len(payload) + extHdrsLen),
-			TransportProtocol: header.ICMPv6ProtocolNumber,
-			HopLimit:          hopLimit,
-			SrcAddr:           lladdr1,
-			DstAddr:           lladdr0,
-			ExtensionHeaders:  extHdrs,
-		})
-		vv := ip.ToVectorisedView()
-		vv.AppendView(payload)
-		ep.HandlePacket(stack.NewPacketBuffer(stack.PacketBufferOptions{
-			Data: vv,
-		}))
-	}
-
-	var tllData [header.NDPLinkLayerAddressSize]byte
-	header.NDPOptions(tllData[:]).Serialize(header.NDPOptionsSerializer{
-		header.NDPTargetLinkLayerAddressOption(linkAddr1),
-	})
-
-	var sllData [header.NDPLinkLayerAddressSize]byte
-	header.NDPOptions(sllData[:]).Serialize(header.NDPOptionsSerializer{
-		header.NDPSourceLinkLayerAddressOption(linkAddr1),
-	})
-
-	types := []struct {
-		name        string
-		typ         header.ICMPv6Type
-		size        int
-		extraData   []byte
-		statCounter func(tcpip.ICMPv6ReceivedPacketStats) *tcpip.StatCounter
-		routerOnly  bool
-	}{
-		{
-			name: "RouterSolicit",
-			typ:  header.ICMPv6RouterSolicit,
-			size: header.ICMPv6MinimumSize,
-			statCounter: func(stats tcpip.ICMPv6ReceivedPacketStats) *tcpip.StatCounter {
-				return stats.RouterSolicit
-			},
-			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,
-			extraData: sllData[:],
-			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
-			},
-		},
-	}
-
-	subTests := []struct {
-		name           string
-		atomicFragment bool
-		hopLimit       uint8
-		code           header.ICMPv6Code
-		valid          bool
-	}{
-		{
-			name:           "Valid",
-			atomicFragment: false,
-			hopLimit:       header.NDPHopLimit,
-			code:           0,
-			valid:          true,
-		},
-		{
-			name:           "Fragmented",
-			atomicFragment: true,
-			hopLimit:       header.NDPHopLimit,
-			code:           0,
-			valid:          false,
-		},
-		{
-			name:           "Invalid hop limit",
-			atomicFragment: false,
-			hopLimit:       header.NDPHopLimit - 1,
-			code:           0,
-			valid:          false,
-		},
-		{
-			name:           "Invalid ICMPv6 code",
-			atomicFragment: false,
-			hopLimit:       header.NDPHopLimit,
-			code:           1,
-			valid:          false,
-		},
-	}
-
-	for _, typ := range types {
-		for _, isRouter := range []bool{false, true} {
-			name := typ.name
-			if isRouter {
-				name += " (Router)"
-			}
-
-			t.Run(name, func(t *testing.T) {
-				for _, test := range subTests {
-					t.Run(test.name, func(t *testing.T) {
-						s, ep := setup(t)
-
-						if isRouter {
-							// Enabling forwarding makes the stack act as a router.
-							s.SetForwarding(ProtocolNumber, true)
-						}
-
-						stats := s.Stats().ICMP.V6.PacketsReceived
-						invalid := stats.Invalid
-						routerOnly := stats.RouterOnlyPacketsDroppedByHost
-						typStat := typ.statCounter(stats)
-
-						icmp := header.ICMPv6(buffer.NewView(typ.size + len(typ.extraData)))
-						copy(icmp[typ.size:], typ.extraData)
-						icmp.SetType(typ.typ)
-						icmp.SetCode(test.code)
-						icmp.SetChecksum(header.ICMPv6Checksum(header.ICMPv6ChecksumParams{
-							Header:      icmp[:typ.size],
-							Src:         lladdr0,
-							Dst:         lladdr1,
-							PayloadCsum: header.Checksum(typ.extraData /* initial */, 0),
-							PayloadLen:  len(typ.extraData),
-						}))
-
-						// Rx count of the NDP message should initially be 0.
-						if got := typStat.Value(); got != 0 {
-							t.Errorf("got %s = %d, want = 0", typ.name, got)
-						}
-
-						// Invalid count should initially be 0.
-						if got := invalid.Value(); got != 0 {
-							t.Errorf("got invalid = %d, want = 0", got)
-						}
-
-						// RouterOnlyPacketsReceivedByHost count should initially be 0.
-						if got := routerOnly.Value(); got != 0 {
-							t.Errorf("got RouterOnlyPacketsReceivedByHost = %d, want = 0", got)
-						}
-
-						if t.Failed() {
-							t.FailNow()
-						}
-
-						handleIPv6Payload(buffer.View(icmp), test.hopLimit, test.atomicFragment, ep)
-
-						// Rx count of the NDP packet should have increased.
-						if got := typStat.Value(); got != 1 {
-							t.Errorf("got %s = %d, want = 1", typ.name, got)
-						}
-
-						want := uint64(0)
-						if !test.valid {
-							// Invalid count should have increased.
-							want = 1
-						}
-						if got := invalid.Value(); got != want {
-							t.Errorf("got invalid = %d, want = %d", got, want)
-						}
-
-						want = 0
-						if test.valid && !isRouter && typ.routerOnly {
-							// RouterOnlyPacketsReceivedByHost count should have increased.
-							want = 1
-						}
-						if got := routerOnly.Value(); got != want {
-							t.Errorf("got RouterOnlyPacketsReceivedByHost = %d, want = %d", got, want)
-						}
-
-					})
-				}
-			})
-		}
-	}
-}
-
-// TestNeighborAdvertisementValidation tests that the NIC validates received
-// Neighbor Advertisements.
-//
-// In particular, if the IP Destination Address is a multicast address, and the
-// Solicited flag is not zero, the Neighbor Advertisement is invalid and should
-// be discarded.
-func TestNeighborAdvertisementValidation(t *testing.T) {
-	tests := []struct {
-		name          string
-		ipDstAddr     tcpip.Address
-		solicitedFlag bool
-		valid         bool
-	}{
-		{
-			name:          "Multicast IP destination address with Solicited flag set",
-			ipDstAddr:     header.IPv6AllNodesMulticastAddress,
-			solicitedFlag: true,
-			valid:         false,
-		},
-		{
-			name:          "Multicast IP destination address with Solicited flag unset",
-			ipDstAddr:     header.IPv6AllNodesMulticastAddress,
-			solicitedFlag: false,
-			valid:         true,
-		},
-		{
-			name:          "Unicast IP destination address with Solicited flag set",
-			ipDstAddr:     lladdr0,
-			solicitedFlag: true,
-			valid:         true,
-		},
-		{
-			name:          "Unicast IP destination address with Solicited flag unset",
-			ipDstAddr:     lladdr0,
-			solicitedFlag: false,
-			valid:         true,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			s := stack.New(stack.Options{
-				NetworkProtocols: []stack.NetworkProtocolFactory{NewProtocol},
-			})
-			e := channel.New(0, header.IPv6MinimumMTU, linkAddr0)
-			e.LinkEPCapabilities |= stack.CapabilityResolutionRequired
-			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)
-			}
-
-			ndpNASize := header.ICMPv6NeighborAdvertMinimumSize
-			hdr := buffer.NewPrependable(header.IPv6MinimumSize + ndpNASize)
-			pkt := header.ICMPv6(hdr.Prepend(ndpNASize))
-			pkt.SetType(header.ICMPv6NeighborAdvert)
-			na := header.NDPNeighborAdvert(pkt.MessageBody())
-			na.SetTargetAddress(lladdr1)
-			na.SetSolicitedFlag(test.solicitedFlag)
-			pkt.SetChecksum(header.ICMPv6Checksum(header.ICMPv6ChecksumParams{
-				Header: pkt,
-				Src:    lladdr1,
-				Dst:    test.ipDstAddr,
-			}))
-			payloadLength := hdr.UsedLength()
-			ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize))
-			ip.Encode(&header.IPv6Fields{
-				PayloadLength:     uint16(payloadLength),
-				TransportProtocol: header.ICMPv6ProtocolNumber,
-				HopLimit:          255,
-				SrcAddr:           lladdr1,
-				DstAddr:           test.ipDstAddr,
-			})
-
-			stats := s.Stats().ICMP.V6.PacketsReceived
-			invalid := stats.Invalid
-			rxNA := stats.NeighborAdvert
-
-			if got := rxNA.Value(); got != 0 {
-				t.Fatalf("got rxNA = %d, want = 0", got)
-			}
-			if got := invalid.Value(); got != 0 {
-				t.Fatalf("got invalid = %d, want = 0", got)
-			}
-
-			e.InjectInbound(header.IPv6ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
-				Data: hdr.View().ToVectorisedView(),
-			}))
-
-			if got := rxNA.Value(); got != 1 {
-				t.Fatalf("got rxNA = %d, want = 1", got)
-			}
-			var wantInvalid uint64 = 1
-			if test.valid {
-				wantInvalid = 0
-			}
-			if got := invalid.Value(); got != wantInvalid {
-				t.Fatalf("got invalid = %d, want = %d", got, wantInvalid)
-			}
-			// As per RFC 4861 section 7.2.5:
-			//   When a valid Neighbor Advertisement is received ...
-			//   If no entry exists, the advertisement SHOULD be silently discarded.
-			//   There is no need to create an entry if none exists, since the
-			//   recipient has apparently not initiated any communication with the
-			//   target.
-			if neighbors, err := s.Neighbors(nicID, ProtocolNumber); err != nil {
-				t.Fatalf("s.Neighbors(%d, %d): %s", nicID, ProtocolNumber, err)
-			} else if len(neighbors) != 0 {
-				t.Fatalf("got len(neighbors) = %d, want = 0; neighbors = %#v", len(neighbors), neighbors)
-			}
-		})
-	}
-}
-
-// TestRouterAdvertValidation tests that when the NIC is configured to handle
-// NDP Router Advertisement packets, it validates the Router Advertisement
-// properly before handling them.
-func TestRouterAdvertValidation(t *testing.T) {
-	tests := []struct {
-		name            string
-		src             tcpip.Address
-		hopLimit        uint8
-		code            header.ICMPv6Code
-		ndpPayload      []byte
-		expectedSuccess bool
-	}{
-		{
-			"OK",
-			lladdr0,
-			255,
-			0,
-			[]byte{
-				0, 0, 0, 0,
-				0, 0, 0, 0,
-				0, 0, 0, 0,
-			},
-			true,
-		},
-		{
-			"NonLinkLocalSourceAddr",
-			addr1,
-			255,
-			0,
-			[]byte{
-				0, 0, 0, 0,
-				0, 0, 0, 0,
-				0, 0, 0, 0,
-			},
-			false,
-		},
-		{
-			"HopLimitNot255",
-			lladdr0,
-			254,
-			0,
-			[]byte{
-				0, 0, 0, 0,
-				0, 0, 0, 0,
-				0, 0, 0, 0,
-			},
-			false,
-		},
-		{
-			"NonZeroCode",
-			lladdr0,
-			255,
-			1,
-			[]byte{
-				0, 0, 0, 0,
-				0, 0, 0, 0,
-				0, 0, 0, 0,
-			},
-			false,
-		},
-		{
-			"NDPPayloadTooSmall",
-			lladdr0,
-			255,
-			0,
-			[]byte{
-				0, 0, 0, 0,
-				0, 0, 0, 0,
-				0, 0, 0,
-			},
-			false,
-		},
-		{
-			"OKWithOptions",
-			lladdr0,
-			255,
-			0,
-			[]byte{
-				// RA payload
-				0, 0, 0, 0,
-				0, 0, 0, 0,
-				0, 0, 0, 0,
-
-				// Option #1 (TargetLinkLayerAddress)
-				2, 1, 0, 0, 0, 0, 0, 0,
-
-				// Option #2 (unrecognized)
-				255, 1, 0, 0, 0, 0, 0, 0,
-
-				// Option #3 (PrefixInformation)
-				3, 4, 0, 0, 0, 0, 0, 0,
-				0, 0, 0, 0, 0, 0, 0, 0,
-				0, 0, 0, 0, 0, 0, 0, 0,
-				0, 0, 0, 0, 0, 0, 0, 0,
-			},
-			true,
-		},
-		{
-			"OptionWithZeroLength",
-			lladdr0,
-			255,
-			0,
-			[]byte{
-				// RA payload
-				0, 0, 0, 0,
-				0, 0, 0, 0,
-				0, 0, 0, 0,
-
-				// Option #1 (TargetLinkLayerAddress)
-				// Invalid as it has 0 length.
-				2, 0, 0, 0, 0, 0, 0, 0,
-
-				// Option #2 (unrecognized)
-				255, 1, 0, 0, 0, 0, 0, 0,
-
-				// Option #3 (PrefixInformation)
-				3, 4, 0, 0, 0, 0, 0, 0,
-				0, 0, 0, 0, 0, 0, 0, 0,
-				0, 0, 0, 0, 0, 0, 0, 0,
-				0, 0, 0, 0, 0, 0, 0, 0,
-			},
-			false,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			e := channel.New(10, 1280, linkAddr1)
-			e.LinkEPCapabilities |= stack.CapabilityResolutionRequired
-			s := stack.New(stack.Options{
-				NetworkProtocols: []stack.NetworkProtocolFactory{NewProtocol},
-			})
-
-			if err := s.CreateNIC(1, e); err != nil {
-				t.Fatalf("CreateNIC(_) = %s", err)
-			}
-
-			icmpSize := header.ICMPv6HeaderSize + len(test.ndpPayload)
-			hdr := buffer.NewPrependable(header.IPv6MinimumSize + icmpSize)
-			pkt := header.ICMPv6(hdr.Prepend(icmpSize))
-			pkt.SetType(header.ICMPv6RouterAdvert)
-			pkt.SetCode(test.code)
-			copy(pkt.MessageBody(), test.ndpPayload)
-			payloadLength := hdr.UsedLength()
-			pkt.SetChecksum(header.ICMPv6Checksum(header.ICMPv6ChecksumParams{
-				Header: pkt,
-				Src:    test.src,
-				Dst:    header.IPv6AllNodesMulticastAddress,
-			}))
-			ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize))
-			ip.Encode(&header.IPv6Fields{
-				PayloadLength:     uint16(payloadLength),
-				TransportProtocol: icmp.ProtocolNumber6,
-				HopLimit:          test.hopLimit,
-				SrcAddr:           test.src,
-				DstAddr:           header.IPv6AllNodesMulticastAddress,
-			})
-
-			stats := s.Stats().ICMP.V6.PacketsReceived
-			invalid := stats.Invalid
-			rxRA := stats.RouterAdvert
-
-			if got := invalid.Value(); got != 0 {
-				t.Fatalf("got invalid = %d, want = 0", got)
-			}
-			if got := rxRA.Value(); got != 0 {
-				t.Fatalf("got rxRA = %d, want = 0", got)
-			}
-
-			e.InjectInbound(header.IPv6ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
-				Data: hdr.View().ToVectorisedView(),
-			}))
-
-			if got := rxRA.Value(); got != 1 {
-				t.Fatalf("got rxRA = %d, want = 1", got)
-			}
-
-			if test.expectedSuccess {
-				if got := invalid.Value(); got != 0 {
-					t.Fatalf("got invalid = %d, want = 0", got)
-				}
-			} else {
-				if got := invalid.Value(); got != 1 {
-					t.Fatalf("got invalid = %d, want = 1", got)
-				}
-			}
-		})
-	}
-}
-
-// TestCheckDuplicateAddress checks that calls to CheckDuplicateAddress and DAD
-// performed when adding new addresses do not interfere with each other.
-func TestCheckDuplicateAddress(t *testing.T) {
-	const nicID = 1
-
-	clock := faketime.NewManualClock()
-	dadConfigs := stack.DADConfigurations{
-		DupAddrDetectTransmits: 1,
-		RetransmitTimer:        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...)
-	}
-	var secureRNG bytes.Reader
-	secureRNG.Reset(secureRNGBytes[:])
-	s := stack.New(stack.Options{
-		SecureRNG: &secureRNG,
-		Clock:     clock,
-		NetworkProtocols: []stack.NetworkProtocolFactory{NewProtocolWithOptions(Options{
-			DADConfigs: dadConfigs,
-		})},
-	})
-	// This test is expected to send at max 2 DAD messages. We allow an extra
-	// packet to be stored to catch unexpected packets.
-	e := channel.New(3, header.IPv6MinimumMTU, linkAddr0)
-	e.LinkEPCapabilities |= stack.CapabilityResolutionRequired
-	if err := s.CreateNIC(nicID, e); err != nil {
-		t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
-	}
-
-	dadPacketsSent := 0
-	snmc := header.SolicitedNodeAddr(lladdr0)
-	remoteLinkAddr := header.EthernetAddressFromMulticastIPv6Address(snmc)
-	checkDADMsg := func() {
-		p, ok := e.ReadContext(context.Background())
-		if !ok {
-			t.Fatalf("expected %d-th DAD message", dadPacketsSent)
-		}
-
-		if p.Proto != header.IPv6ProtocolNumber {
-			t.Errorf("(i=%d) got p.Proto = %d, want = %d", dadPacketsSent, p.Proto, header.IPv6ProtocolNumber)
-		}
-
-		if p.Route.RemoteLinkAddress != remoteLinkAddr {
-			t.Errorf("(i=%d) got p.Route.RemoteLinkAddress = %s, want = %s", dadPacketsSent, p.Route.RemoteLinkAddress, remoteLinkAddr)
-		}
-
-		checker.IPv6(t, stack.PayloadSince(p.Pkt.NetworkHeader()),
-			checker.SrcAddr(header.IPv6Any),
-			checker.DstAddr(snmc),
-			checker.TTL(header.NDPHopLimit),
-			checker.NDPNS(
-				checker.NDPNSTargetAddress(lladdr0),
-				checker.NDPNSOptions([]header.NDPOption{header.NDPNonceOption(nonces[dadPacketsSent])}),
-			))
-	}
-	if err := s.AddAddress(nicID, ProtocolNumber, lladdr0); err != nil {
-		t.Fatalf("AddAddress(%d, %d, %s) = %s", nicID, ProtocolNumber, lladdr0, err)
-	}
-	checkDADMsg()
-
-	// Start DAD for the address we just added.
-	//
-	// Even though the stack will perform DAD before the added address transitions
-	// from tentative to assigned, this DAD request should be independent of that.
-	ch := make(chan stack.DADResult, 3)
-	dadRequestsMade := 1
-	dadPacketsSent++
-	if res, err := s.CheckDuplicateAddress(nicID, ProtocolNumber, lladdr0, func(r stack.DADResult) {
-		ch <- r
-	}); err != nil {
-		t.Fatalf("s.CheckDuplicateAddress(%d, %d, %s, _): %s", nicID, ProtocolNumber, lladdr0, err)
-	} else if res != stack.DADStarting {
-		t.Fatalf("got s.CheckDuplicateAddress(%d, %d, %s, _) = %d, want = %d", nicID, ProtocolNumber, lladdr0, res, stack.DADStarting)
-	}
-	checkDADMsg()
-
-	// Remove the address and make sure our DAD request was not stopped.
-	if err := s.RemoveAddress(nicID, lladdr0); err != nil {
-		t.Fatalf("RemoveAddress(%d, %s): %s", nicID, lladdr0, err)
-	}
-	// Should not restart DAD since we already requested DAD above - the handler
-	// should be called when the original request compeletes so we should not send
-	// an extra DAD message here.
-	dadRequestsMade++
-	if res, err := s.CheckDuplicateAddress(nicID, ProtocolNumber, lladdr0, func(r stack.DADResult) {
-		ch <- r
-	}); err != nil {
-		t.Fatalf("s.CheckDuplicateAddress(%d, %d, %s, _): %s", nicID, ProtocolNumber, lladdr0, err)
-	} else if res != stack.DADAlreadyRunning {
-		t.Fatalf("got s.CheckDuplicateAddress(%d, %d, %s, _) = %d, want = %d", nicID, ProtocolNumber, lladdr0, res, stack.DADAlreadyRunning)
-	}
-
-	// Wait for DAD to complete.
-	clock.Advance(time.Duration(dadConfigs.DupAddrDetectTransmits) * dadConfigs.RetransmitTimer)
-	for i := 0; i < dadRequestsMade; i++ {
-		if diff := cmp.Diff(&stack.DADSucceeded{}, <-ch); diff != "" {
-			t.Errorf("(i=%d) DAD result mismatch (-want +got):\n%s", i, diff)
-		}
-	}
-	// Should have no more results.
-	select {
-	case r := <-ch:
-		t.Errorf("unexpectedly got an extra DAD result; r = %#v", r)
-	default:
-	}
-
-	// Should have no more packets.
-	if p, ok := e.Read(); ok {
-		t.Errorf("got unexpected packet = %#v", p)
-	}
-}
diff --git a/pkg/tcpip/ports/ports_state_autogen.go b/pkg/tcpip/ports/ports_state_autogen.go
new file mode 100644
index 0000000..2719f6c
--- /dev/null
+++ b/pkg/tcpip/ports/ports_state_autogen.go
@@ -0,0 +1,42 @@
+// automatically generated by stateify.
+
+package ports
+
+import (
+	"gvisor.dev/gvisor/pkg/state"
+)
+
+func (f *Flags) StateTypeName() string {
+	return "pkg/tcpip/ports.Flags"
+}
+
+func (f *Flags) StateFields() []string {
+	return []string{
+		"MostRecent",
+		"LoadBalanced",
+		"TupleOnly",
+	}
+}
+
+func (f *Flags) beforeSave() {}
+
+// +checklocksignore
+func (f *Flags) StateSave(stateSinkObject state.Sink) {
+	f.beforeSave()
+	stateSinkObject.Save(0, &f.MostRecent)
+	stateSinkObject.Save(1, &f.LoadBalanced)
+	stateSinkObject.Save(2, &f.TupleOnly)
+}
+
+func (f *Flags) afterLoad() {}
+
+// +checklocksignore
+func (f *Flags) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &f.MostRecent)
+	stateSourceObject.Load(1, &f.LoadBalanced)
+	stateSourceObject.Load(2, &f.TupleOnly)
+}
+
+func init() {
+	state.Register((*Flags)(nil))
+}
diff --git a/pkg/tcpip/ports/ports_test.go b/pkg/tcpip/ports/ports_test.go
deleted file mode 100644
index 0f43dc8..0000000
--- a/pkg/tcpip/ports/ports_test.go
+++ /dev/null
@@ -1,492 +0,0 @@
-// 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 ports
-
-import (
-	"math/rand"
-	"testing"
-
-	"github.com/google/go-cmp/cmp"
-	"gvisor.dev/gvisor/pkg/tcpip"
-)
-
-const (
-	fakeTransNumber   tcpip.TransportProtocolNumber = 1
-	fakeNetworkNumber tcpip.NetworkProtocolNumber   = 2
-
-	fakeIPAddress  = tcpip.Address("\x08\x08\x08\x08")
-	fakeIPAddress1 = tcpip.Address("\x08\x08\x08\x09")
-)
-
-type portReserveTestAction struct {
-	port    uint16
-	ip      tcpip.Address
-	want    tcpip.Error
-	flags   Flags
-	release bool
-	device  tcpip.NICID
-	dest    tcpip.FullAddress
-}
-
-func TestPortReservation(t *testing.T) {
-	for _, test := range []struct {
-		tname   string
-		actions []portReserveTestAction
-	}{
-		{
-			tname: "bind to ip",
-			actions: []portReserveTestAction{
-				{port: 80, ip: fakeIPAddress, want: nil},
-				{port: 80, ip: fakeIPAddress1, want: nil},
-				/* N.B. Order of tests matters! */
-				{port: 80, ip: anyIPAddress, want: &tcpip.ErrPortInUse{}},
-				{port: 80, ip: fakeIPAddress, want: &tcpip.ErrPortInUse{}, flags: Flags{LoadBalanced: true}},
-			},
-		},
-		{
-			tname: "bind to inaddr any",
-			actions: []portReserveTestAction{
-				{port: 22, ip: anyIPAddress, want: nil},
-				{port: 22, ip: fakeIPAddress, want: &tcpip.ErrPortInUse{}},
-				/* release fakeIPAddress, but anyIPAddress is still inuse */
-				{port: 22, ip: fakeIPAddress, release: true},
-				{port: 22, ip: fakeIPAddress, want: &tcpip.ErrPortInUse{}},
-				{port: 22, ip: fakeIPAddress, want: &tcpip.ErrPortInUse{}, flags: Flags{LoadBalanced: true}},
-				/* Release port 22 from any IP address, then try to reserve fake IP address on 22 */
-				{port: 22, ip: anyIPAddress, want: nil, release: true},
-				{port: 22, ip: fakeIPAddress, want: nil},
-			},
-		}, {
-			tname: "bind to zero port",
-			actions: []portReserveTestAction{
-				{port: 00, ip: fakeIPAddress, want: nil},
-				{port: 00, ip: fakeIPAddress, want: nil},
-				{port: 00, ip: fakeIPAddress, flags: Flags{LoadBalanced: true}, want: nil},
-			},
-		}, {
-			tname: "bind to ip with reuseport",
-			actions: []portReserveTestAction{
-				{port: 25, ip: fakeIPAddress, flags: Flags{LoadBalanced: true}, want: nil},
-				{port: 25, ip: fakeIPAddress, flags: Flags{LoadBalanced: true}, want: nil},
-
-				{port: 25, ip: fakeIPAddress, flags: Flags{}, want: &tcpip.ErrPortInUse{}},
-				{port: 25, ip: anyIPAddress, flags: Flags{}, want: &tcpip.ErrPortInUse{}},
-
-				{port: 25, ip: anyIPAddress, flags: Flags{LoadBalanced: true}, want: nil},
-			},
-		}, {
-			tname: "bind to inaddr any with reuseport",
-			actions: []portReserveTestAction{
-				{port: 24, ip: anyIPAddress, flags: Flags{LoadBalanced: true}, want: nil},
-				{port: 24, ip: anyIPAddress, flags: Flags{LoadBalanced: true}, want: nil},
-
-				{port: 24, ip: anyIPAddress, flags: Flags{}, want: &tcpip.ErrPortInUse{}},
-				{port: 24, ip: fakeIPAddress, flags: Flags{}, want: &tcpip.ErrPortInUse{}},
-
-				{port: 24, ip: fakeIPAddress, flags: Flags{LoadBalanced: true}, want: nil},
-				{port: 24, ip: fakeIPAddress, flags: Flags{LoadBalanced: true}, release: true, want: nil},
-
-				{port: 24, ip: anyIPAddress, flags: Flags{LoadBalanced: true}, release: true},
-				{port: 24, ip: anyIPAddress, flags: Flags{}, want: &tcpip.ErrPortInUse{}},
-
-				{port: 24, ip: anyIPAddress, flags: Flags{LoadBalanced: true}, release: true},
-				{port: 24, ip: anyIPAddress, flags: Flags{}, want: nil},
-			},
-		}, {
-			tname: "bind twice with device fails",
-			actions: []portReserveTestAction{
-				{port: 24, ip: fakeIPAddress, device: 3, want: nil},
-				{port: 24, ip: fakeIPAddress, device: 3, want: &tcpip.ErrPortInUse{}},
-			},
-		}, {
-			tname: "bind to device",
-			actions: []portReserveTestAction{
-				{port: 24, ip: fakeIPAddress, device: 1, want: nil},
-				{port: 24, ip: fakeIPAddress, device: 2, want: nil},
-			},
-		}, {
-			tname: "bind to device and then without device",
-			actions: []portReserveTestAction{
-				{port: 24, ip: fakeIPAddress, device: 123, want: nil},
-				{port: 24, ip: fakeIPAddress, device: 0, want: &tcpip.ErrPortInUse{}},
-			},
-		}, {
-			tname: "bind without device",
-			actions: []portReserveTestAction{
-				{port: 24, ip: fakeIPAddress, want: nil},
-				{port: 24, ip: fakeIPAddress, device: 123, want: &tcpip.ErrPortInUse{}},
-				{port: 24, ip: fakeIPAddress, device: 123, flags: Flags{LoadBalanced: true}, want: &tcpip.ErrPortInUse{}},
-				{port: 24, ip: fakeIPAddress, want: &tcpip.ErrPortInUse{}},
-				{port: 24, ip: fakeIPAddress, flags: Flags{LoadBalanced: true}, want: &tcpip.ErrPortInUse{}},
-			},
-		}, {
-			tname: "bind with device",
-			actions: []portReserveTestAction{
-				{port: 24, ip: fakeIPAddress, device: 123, want: nil},
-				{port: 24, ip: fakeIPAddress, device: 123, want: &tcpip.ErrPortInUse{}},
-				{port: 24, ip: fakeIPAddress, device: 123, flags: Flags{LoadBalanced: true}, want: &tcpip.ErrPortInUse{}},
-				{port: 24, ip: fakeIPAddress, device: 0, want: &tcpip.ErrPortInUse{}},
-				{port: 24, ip: fakeIPAddress, device: 0, flags: Flags{LoadBalanced: true}, want: &tcpip.ErrPortInUse{}},
-				{port: 24, ip: fakeIPAddress, device: 456, flags: Flags{LoadBalanced: true}, want: nil},
-				{port: 24, ip: fakeIPAddress, device: 789, want: nil},
-				{port: 24, ip: fakeIPAddress, want: &tcpip.ErrPortInUse{}},
-				{port: 24, ip: fakeIPAddress, flags: Flags{LoadBalanced: true}, want: &tcpip.ErrPortInUse{}},
-			},
-		}, {
-			tname: "bind with reuseport",
-			actions: []portReserveTestAction{
-				{port: 24, ip: fakeIPAddress, flags: Flags{LoadBalanced: true}, want: nil},
-				{port: 24, ip: fakeIPAddress, device: 123, want: &tcpip.ErrPortInUse{}},
-				{port: 24, ip: fakeIPAddress, device: 123, flags: Flags{LoadBalanced: true}, want: nil},
-				{port: 24, ip: fakeIPAddress, device: 0, want: &tcpip.ErrPortInUse{}},
-				{port: 24, ip: fakeIPAddress, device: 0, flags: Flags{LoadBalanced: true}, want: nil},
-			},
-		}, {
-			tname: "binding with reuseport and device",
-			actions: []portReserveTestAction{
-				{port: 24, ip: fakeIPAddress, device: 123, flags: Flags{LoadBalanced: true}, want: nil},
-				{port: 24, ip: fakeIPAddress, device: 123, want: &tcpip.ErrPortInUse{}},
-				{port: 24, ip: fakeIPAddress, device: 123, flags: Flags{LoadBalanced: true}, want: nil},
-				{port: 24, ip: fakeIPAddress, device: 0, want: &tcpip.ErrPortInUse{}},
-				{port: 24, ip: fakeIPAddress, device: 456, flags: Flags{LoadBalanced: true}, want: nil},
-				{port: 24, ip: fakeIPAddress, device: 0, flags: Flags{LoadBalanced: true}, want: nil},
-				{port: 24, ip: fakeIPAddress, device: 789, flags: Flags{LoadBalanced: true}, want: nil},
-				{port: 24, ip: fakeIPAddress, device: 999, want: &tcpip.ErrPortInUse{}},
-			},
-		}, {
-			tname: "mixing reuseport and not reuseport by binding to device",
-			actions: []portReserveTestAction{
-				{port: 24, ip: fakeIPAddress, device: 123, flags: Flags{LoadBalanced: true}, want: nil},
-				{port: 24, ip: fakeIPAddress, device: 456, want: nil},
-				{port: 24, ip: fakeIPAddress, device: 789, flags: Flags{LoadBalanced: true}, want: nil},
-				{port: 24, ip: fakeIPAddress, device: 999, want: nil},
-			},
-		}, {
-			tname: "can't bind to 0 after mixing reuseport and not reuseport",
-			actions: []portReserveTestAction{
-				{port: 24, ip: fakeIPAddress, device: 123, flags: Flags{LoadBalanced: true}, want: nil},
-				{port: 24, ip: fakeIPAddress, device: 456, want: nil},
-				{port: 24, ip: fakeIPAddress, device: 0, flags: Flags{LoadBalanced: true}, want: &tcpip.ErrPortInUse{}},
-			},
-		}, {
-			tname: "bind and release",
-			actions: []portReserveTestAction{
-				{port: 24, ip: fakeIPAddress, device: 123, flags: Flags{LoadBalanced: true}, want: nil},
-				{port: 24, ip: fakeIPAddress, device: 0, flags: Flags{LoadBalanced: true}, want: nil},
-				{port: 24, ip: fakeIPAddress, device: 345, flags: Flags{}, want: &tcpip.ErrPortInUse{}},
-				{port: 24, ip: fakeIPAddress, device: 789, flags: Flags{LoadBalanced: true}, want: nil},
-
-				// Release the bind to device 0 and try again.
-				{port: 24, ip: fakeIPAddress, device: 0, flags: Flags{LoadBalanced: true}, want: nil, release: true},
-				{port: 24, ip: fakeIPAddress, device: 345, flags: Flags{}, want: nil},
-			},
-		}, {
-			tname: "bind twice with reuseport once",
-			actions: []portReserveTestAction{
-				{port: 24, ip: fakeIPAddress, device: 123, flags: Flags{}, want: nil},
-				{port: 24, ip: fakeIPAddress, device: 0, flags: Flags{LoadBalanced: true}, want: &tcpip.ErrPortInUse{}},
-			},
-		}, {
-			tname: "release an unreserved device",
-			actions: []portReserveTestAction{
-				{port: 24, ip: fakeIPAddress, device: 123, flags: Flags{}, want: nil},
-				{port: 24, ip: fakeIPAddress, device: 456, flags: Flags{}, want: nil},
-				// The below don't exist.
-				{port: 24, ip: fakeIPAddress, device: 345, flags: Flags{}, want: nil, release: true},
-				{port: 9999, ip: fakeIPAddress, device: 123, flags: Flags{}, want: nil, release: true},
-				// Release all.
-				{port: 24, ip: fakeIPAddress, device: 123, flags: Flags{}, want: nil, release: true},
-				{port: 24, ip: fakeIPAddress, device: 456, flags: Flags{}, want: nil, release: true},
-			},
-		}, {
-			tname: "bind with reuseaddr",
-			actions: []portReserveTestAction{
-				{port: 24, ip: fakeIPAddress, flags: Flags{MostRecent: true}, want: nil},
-				{port: 24, ip: fakeIPAddress, device: 123, want: &tcpip.ErrPortInUse{}},
-				{port: 24, ip: fakeIPAddress, device: 123, flags: Flags{MostRecent: true}, want: nil},
-				{port: 24, ip: fakeIPAddress, device: 0, want: &tcpip.ErrPortInUse{}},
-				{port: 24, ip: fakeIPAddress, device: 0, flags: Flags{MostRecent: true}, want: nil},
-			},
-		}, {
-			tname: "bind twice with reuseaddr once",
-			actions: []portReserveTestAction{
-				{port: 24, ip: fakeIPAddress, device: 123, flags: Flags{}, want: nil},
-				{port: 24, ip: fakeIPAddress, device: 0, flags: Flags{MostRecent: true}, want: &tcpip.ErrPortInUse{}},
-			},
-		}, {
-			tname: "bind with reuseaddr and reuseport",
-			actions: []portReserveTestAction{
-				{port: 24, ip: fakeIPAddress, flags: Flags{MostRecent: true, LoadBalanced: true}, want: nil},
-				{port: 24, ip: fakeIPAddress, flags: Flags{MostRecent: true, LoadBalanced: true}, want: nil},
-				{port: 24, ip: fakeIPAddress, flags: Flags{MostRecent: true, LoadBalanced: true}, want: nil},
-			},
-		}, {
-			tname: "bind with reuseaddr and reuseport, and then reuseaddr",
-			actions: []portReserveTestAction{
-				{port: 24, ip: fakeIPAddress, flags: Flags{MostRecent: true, LoadBalanced: true}, want: nil},
-				{port: 24, ip: fakeIPAddress, flags: Flags{MostRecent: true}, want: nil},
-				{port: 24, ip: fakeIPAddress, flags: Flags{LoadBalanced: true}, want: &tcpip.ErrPortInUse{}},
-			},
-		}, {
-			tname: "bind with reuseaddr and reuseport, and then reuseport",
-			actions: []portReserveTestAction{
-				{port: 24, ip: fakeIPAddress, flags: Flags{MostRecent: true, LoadBalanced: true}, want: nil},
-				{port: 24, ip: fakeIPAddress, flags: Flags{LoadBalanced: true}, want: nil},
-				{port: 24, ip: fakeIPAddress, flags: Flags{MostRecent: true}, want: &tcpip.ErrPortInUse{}},
-			},
-		}, {
-			tname: "bind with reuseaddr and reuseport twice, and then reuseaddr",
-			actions: []portReserveTestAction{
-				{port: 24, ip: fakeIPAddress, flags: Flags{MostRecent: true, LoadBalanced: true}, want: nil},
-				{port: 24, ip: fakeIPAddress, flags: Flags{MostRecent: true, LoadBalanced: true}, want: nil},
-				{port: 24, ip: fakeIPAddress, flags: Flags{MostRecent: true}, want: nil},
-			},
-		}, {
-			tname: "bind with reuseaddr and reuseport twice, and then reuseport",
-			actions: []portReserveTestAction{
-				{port: 24, ip: fakeIPAddress, flags: Flags{MostRecent: true, LoadBalanced: true}, want: nil},
-				{port: 24, ip: fakeIPAddress, flags: Flags{MostRecent: true, LoadBalanced: true}, want: nil},
-				{port: 24, ip: fakeIPAddress, flags: Flags{LoadBalanced: true}, want: nil},
-			},
-		}, {
-			tname: "bind with reuseaddr, and then reuseaddr and reuseport",
-			actions: []portReserveTestAction{
-				{port: 24, ip: fakeIPAddress, flags: Flags{MostRecent: true}, want: nil},
-				{port: 24, ip: fakeIPAddress, flags: Flags{MostRecent: true, LoadBalanced: true}, want: nil},
-				{port: 24, ip: fakeIPAddress, flags: Flags{LoadBalanced: true}, want: &tcpip.ErrPortInUse{}},
-			},
-		}, {
-			tname: "bind with reuseport, and then reuseaddr and reuseport",
-			actions: []portReserveTestAction{
-				{port: 24, ip: fakeIPAddress, flags: Flags{LoadBalanced: true}, want: nil},
-				{port: 24, ip: fakeIPAddress, flags: Flags{MostRecent: true, LoadBalanced: true}, want: nil},
-				{port: 24, ip: fakeIPAddress, flags: Flags{MostRecent: true}, want: &tcpip.ErrPortInUse{}},
-			},
-		}, {
-			tname: "bind tuple with reuseaddr, and then wildcard with reuseaddr",
-			actions: []portReserveTestAction{
-				{port: 24, ip: fakeIPAddress, flags: Flags{TupleOnly: true}, dest: tcpip.FullAddress{Addr: fakeIPAddress, Port: 24}, want: nil},
-				{port: 24, ip: fakeIPAddress, flags: Flags{TupleOnly: true}, dest: tcpip.FullAddress{}, want: nil},
-			},
-		}, {
-			tname: "bind tuple with reuseaddr, and then wildcard",
-			actions: []portReserveTestAction{
-				{port: 24, ip: fakeIPAddress, flags: Flags{TupleOnly: true}, dest: tcpip.FullAddress{Addr: fakeIPAddress, Port: 24}, want: nil},
-				{port: 24, ip: fakeIPAddress, want: &tcpip.ErrPortInUse{}},
-			},
-		}, {
-			tname: "bind wildcard with reuseaddr, and then tuple with reuseaddr",
-			actions: []portReserveTestAction{
-				{port: 24, ip: fakeIPAddress, flags: Flags{TupleOnly: true}, dest: tcpip.FullAddress{}, want: nil},
-				{port: 24, ip: fakeIPAddress, flags: Flags{TupleOnly: true}, dest: tcpip.FullAddress{Addr: fakeIPAddress, Port: 24}, want: nil},
-			},
-		}, {
-			tname: "bind tuple with reuseaddr, and then wildcard",
-			actions: []portReserveTestAction{
-				{port: 24, ip: fakeIPAddress, want: nil},
-				{port: 24, ip: fakeIPAddress, flags: Flags{TupleOnly: true}, dest: tcpip.FullAddress{Addr: fakeIPAddress, Port: 24}, want: &tcpip.ErrPortInUse{}},
-			},
-		}, {
-			tname: "bind two tuples with reuseaddr",
-			actions: []portReserveTestAction{
-				{port: 24, ip: fakeIPAddress, flags: Flags{TupleOnly: true}, dest: tcpip.FullAddress{Addr: fakeIPAddress, Port: 24}, want: nil},
-				{port: 24, ip: fakeIPAddress, flags: Flags{TupleOnly: true}, dest: tcpip.FullAddress{Addr: fakeIPAddress, Port: 25}, want: nil},
-			},
-		}, {
-			tname: "bind two tuples",
-			actions: []portReserveTestAction{
-				{port: 24, ip: fakeIPAddress, dest: tcpip.FullAddress{Addr: fakeIPAddress, Port: 24}, want: nil},
-				{port: 24, ip: fakeIPAddress, dest: tcpip.FullAddress{Addr: fakeIPAddress, Port: 25}, want: nil},
-			},
-		}, {
-			tname: "bind wildcard, and then tuple with reuseaddr",
-			actions: []portReserveTestAction{
-				{port: 24, ip: fakeIPAddress, dest: tcpip.FullAddress{}, want: nil},
-				{port: 24, ip: fakeIPAddress, flags: Flags{TupleOnly: true}, dest: tcpip.FullAddress{Addr: fakeIPAddress, Port: 24}, want: &tcpip.ErrPortInUse{}},
-			},
-		}, {
-			tname: "bind wildcard twice with reuseaddr",
-			actions: []portReserveTestAction{
-				{port: 24, ip: anyIPAddress, flags: Flags{TupleOnly: true}, want: nil},
-				{port: 24, ip: anyIPAddress, flags: Flags{TupleOnly: true}, want: nil},
-			},
-		},
-	} {
-		t.Run(test.tname, func(t *testing.T) {
-			pm := NewPortManager()
-			net := []tcpip.NetworkProtocolNumber{fakeNetworkNumber}
-
-			for _, test := range test.actions {
-				first, _ := pm.PortRange()
-				if test.release {
-					portRes := Reservation{
-						Networks:     net,
-						Transport:    fakeTransNumber,
-						Addr:         test.ip,
-						Port:         test.port,
-						Flags:        test.flags,
-						BindToDevice: test.device,
-						Dest:         test.dest,
-					}
-					pm.ReleasePort(portRes)
-					continue
-				}
-				portRes := Reservation{
-					Networks:     net,
-					Transport:    fakeTransNumber,
-					Addr:         test.ip,
-					Port:         test.port,
-					Flags:        test.flags,
-					BindToDevice: test.device,
-					Dest:         test.dest,
-				}
-				gotPort, err := pm.ReservePort(portRes, nil /* testPort */)
-				if diff := cmp.Diff(test.want, err); diff != "" {
-					t.Fatalf("unexpected error from ReservePort(%+v, _), (-want, +got):\n%s", portRes, diff)
-				}
-				if test.port == 0 && (gotPort == 0 || gotPort < first) {
-					t.Fatalf("ReservePort(%+v, _) = %d, want port number >= %d to be picked", portRes, gotPort, first)
-				}
-			}
-		})
-	}
-}
-
-func TestPickEphemeralPort(t *testing.T) {
-	const (
-		firstEphemeral    = 32000
-		numEphemeralPorts = 1000
-	)
-
-	for _, test := range []struct {
-		name     string
-		f        func(port uint16) (bool, tcpip.Error)
-		wantErr  tcpip.Error
-		wantPort uint16
-	}{
-		{
-			name: "no-port-available",
-			f: func(port uint16) (bool, tcpip.Error) {
-				return false, nil
-			},
-			wantErr: &tcpip.ErrNoPortAvailable{},
-		},
-		{
-			name: "port-tester-error",
-			f: func(port uint16) (bool, tcpip.Error) {
-				return false, &tcpip.ErrBadBuffer{}
-			},
-			wantErr: &tcpip.ErrBadBuffer{},
-		},
-		{
-			name: "only-port-16042-available",
-			f: func(port uint16) (bool, tcpip.Error) {
-				if port == firstEphemeral+42 {
-					return true, nil
-				}
-				return false, nil
-			},
-			wantPort: firstEphemeral + 42,
-		},
-		{
-			name: "only-port-under-16000-available",
-			f: func(port uint16) (bool, tcpip.Error) {
-				if port < firstEphemeral {
-					return true, nil
-				}
-				return false, nil
-			},
-			wantErr: &tcpip.ErrNoPortAvailable{},
-		},
-	} {
-		t.Run(test.name, func(t *testing.T) {
-			pm := NewPortManager()
-			if err := pm.SetPortRange(firstEphemeral, firstEphemeral+numEphemeralPorts); err != nil {
-				t.Fatalf("failed to set ephemeral port range: %s", err)
-			}
-			port, err := pm.PickEphemeralPort(test.f)
-			if diff := cmp.Diff(test.wantErr, err); diff != "" {
-				t.Fatalf("unexpected error from PickEphemeralPort(..), (-want, +got):\n%s", diff)
-			}
-			if port != test.wantPort {
-				t.Errorf("got PickEphemeralPort(..) = (%d, nil); want (%d, nil)", port, test.wantPort)
-			}
-		})
-	}
-}
-
-func TestPickEphemeralPortStable(t *testing.T) {
-	const (
-		firstEphemeral    = 32000
-		numEphemeralPorts = 1000
-	)
-
-	for _, test := range []struct {
-		name     string
-		f        func(port uint16) (bool, tcpip.Error)
-		wantErr  tcpip.Error
-		wantPort uint16
-	}{
-		{
-			name: "no-port-available",
-			f: func(port uint16) (bool, tcpip.Error) {
-				return false, nil
-			},
-			wantErr: &tcpip.ErrNoPortAvailable{},
-		},
-		{
-			name: "port-tester-error",
-			f: func(port uint16) (bool, tcpip.Error) {
-				return false, &tcpip.ErrBadBuffer{}
-			},
-			wantErr: &tcpip.ErrBadBuffer{},
-		},
-		{
-			name: "only-port-16042-available",
-			f: func(port uint16) (bool, tcpip.Error) {
-				if port == firstEphemeral+42 {
-					return true, nil
-				}
-				return false, nil
-			},
-			wantPort: firstEphemeral + 42,
-		},
-		{
-			name: "only-port-under-16000-available",
-			f: func(port uint16) (bool, tcpip.Error) {
-				if port < firstEphemeral {
-					return true, nil
-				}
-				return false, nil
-			},
-			wantErr: &tcpip.ErrNoPortAvailable{},
-		},
-	} {
-		t.Run(test.name, func(t *testing.T) {
-			pm := NewPortManager()
-			if err := pm.SetPortRange(firstEphemeral, firstEphemeral+numEphemeralPorts); err != nil {
-				t.Fatalf("failed to set ephemeral port range: %s", err)
-			}
-			portOffset := uint16(rand.Int31n(int32(numEphemeralPorts)))
-			port, err := pm.PickEphemeralPortStable(portOffset, test.f)
-			if diff := cmp.Diff(test.wantErr, err); diff != "" {
-				t.Fatalf("unexpected error from PickEphemeralPort(..), (-want, +got):\n%s", diff)
-			}
-			if port != test.wantPort {
-				t.Errorf("got PickEphemeralPort(..) = (%d, nil); want (%d, nil)", port, test.wantPort)
-			}
-		})
-	}
-}
diff --git a/pkg/tcpip/seqnum/seqnum_state_autogen.go b/pkg/tcpip/seqnum/seqnum_state_autogen.go
new file mode 100644
index 0000000..23e7981
--- /dev/null
+++ b/pkg/tcpip/seqnum/seqnum_state_autogen.go
@@ -0,0 +1,3 @@
+// automatically generated by stateify.
+
+package seqnum
diff --git a/pkg/tcpip/sock_err_list.go b/pkg/tcpip/sock_err_list.go
new file mode 100644
index 0000000..0be1993
--- /dev/null
+++ b/pkg/tcpip/sock_err_list.go
@@ -0,0 +1,221 @@
+package tcpip
+
+// ElementMapper provides an identity mapping by default.
+//
+// This can be replaced to provide a struct that maps elements to linker
+// objects, if they are not the same. An ElementMapper is not typically
+// required if: Linker is left as is, Element is left as is, or Linker and
+// Element are the same type.
+type sockErrorElementMapper struct{}
+
+// linkerFor maps an Element to a Linker.
+//
+// This default implementation should be inlined.
+//
+//go:nosplit
+func (sockErrorElementMapper) linkerFor(elem *SockError) *SockError { return elem }
+
+// List is an intrusive list. Entries can be added to or removed from the list
+// in O(1) time and with no additional memory allocations.
+//
+// The zero value for List is an empty list ready to use.
+//
+// To iterate over a list (where l is a List):
+//      for e := l.Front(); e != nil; e = e.Next() {
+// 		// do something with e.
+//      }
+//
+// +stateify savable
+type sockErrorList struct {
+	head *SockError
+	tail *SockError
+}
+
+// Reset resets list l to the empty state.
+func (l *sockErrorList) Reset() {
+	l.head = nil
+	l.tail = nil
+}
+
+// Empty returns true iff the list is empty.
+//
+//go:nosplit
+func (l *sockErrorList) Empty() bool {
+	return l.head == nil
+}
+
+// Front returns the first element of list l or nil.
+//
+//go:nosplit
+func (l *sockErrorList) Front() *SockError {
+	return l.head
+}
+
+// Back returns the last element of list l or nil.
+//
+//go:nosplit
+func (l *sockErrorList) Back() *SockError {
+	return l.tail
+}
+
+// Len returns the number of elements in the list.
+//
+// NOTE: This is an O(n) operation.
+//
+//go:nosplit
+func (l *sockErrorList) Len() (count int) {
+	for e := l.Front(); e != nil; e = (sockErrorElementMapper{}.linkerFor(e)).Next() {
+		count++
+	}
+	return count
+}
+
+// PushFront inserts the element e at the front of list l.
+//
+//go:nosplit
+func (l *sockErrorList) PushFront(e *SockError) {
+	linker := sockErrorElementMapper{}.linkerFor(e)
+	linker.SetNext(l.head)
+	linker.SetPrev(nil)
+	if l.head != nil {
+		sockErrorElementMapper{}.linkerFor(l.head).SetPrev(e)
+	} else {
+		l.tail = e
+	}
+
+	l.head = e
+}
+
+// PushBack inserts the element e at the back of list l.
+//
+//go:nosplit
+func (l *sockErrorList) PushBack(e *SockError) {
+	linker := sockErrorElementMapper{}.linkerFor(e)
+	linker.SetNext(nil)
+	linker.SetPrev(l.tail)
+	if l.tail != nil {
+		sockErrorElementMapper{}.linkerFor(l.tail).SetNext(e)
+	} else {
+		l.head = e
+	}
+
+	l.tail = e
+}
+
+// PushBackList inserts list m at the end of list l, emptying m.
+//
+//go:nosplit
+func (l *sockErrorList) PushBackList(m *sockErrorList) {
+	if l.head == nil {
+		l.head = m.head
+		l.tail = m.tail
+	} else if m.head != nil {
+		sockErrorElementMapper{}.linkerFor(l.tail).SetNext(m.head)
+		sockErrorElementMapper{}.linkerFor(m.head).SetPrev(l.tail)
+
+		l.tail = m.tail
+	}
+	m.head = nil
+	m.tail = nil
+}
+
+// InsertAfter inserts e after b.
+//
+//go:nosplit
+func (l *sockErrorList) InsertAfter(b, e *SockError) {
+	bLinker := sockErrorElementMapper{}.linkerFor(b)
+	eLinker := sockErrorElementMapper{}.linkerFor(e)
+
+	a := bLinker.Next()
+
+	eLinker.SetNext(a)
+	eLinker.SetPrev(b)
+	bLinker.SetNext(e)
+
+	if a != nil {
+		sockErrorElementMapper{}.linkerFor(a).SetPrev(e)
+	} else {
+		l.tail = e
+	}
+}
+
+// InsertBefore inserts e before a.
+//
+//go:nosplit
+func (l *sockErrorList) InsertBefore(a, e *SockError) {
+	aLinker := sockErrorElementMapper{}.linkerFor(a)
+	eLinker := sockErrorElementMapper{}.linkerFor(e)
+
+	b := aLinker.Prev()
+	eLinker.SetNext(a)
+	eLinker.SetPrev(b)
+	aLinker.SetPrev(e)
+
+	if b != nil {
+		sockErrorElementMapper{}.linkerFor(b).SetNext(e)
+	} else {
+		l.head = e
+	}
+}
+
+// Remove removes e from l.
+//
+//go:nosplit
+func (l *sockErrorList) Remove(e *SockError) {
+	linker := sockErrorElementMapper{}.linkerFor(e)
+	prev := linker.Prev()
+	next := linker.Next()
+
+	if prev != nil {
+		sockErrorElementMapper{}.linkerFor(prev).SetNext(next)
+	} else if l.head == e {
+		l.head = next
+	}
+
+	if next != nil {
+		sockErrorElementMapper{}.linkerFor(next).SetPrev(prev)
+	} else if l.tail == e {
+		l.tail = prev
+	}
+
+	linker.SetNext(nil)
+	linker.SetPrev(nil)
+}
+
+// Entry is a default implementation of Linker. Users can add anonymous fields
+// of this type to their structs to make them automatically implement the
+// methods needed by List.
+//
+// +stateify savable
+type sockErrorEntry struct {
+	next *SockError
+	prev *SockError
+}
+
+// Next returns the entry that follows e in the list.
+//
+//go:nosplit
+func (e *sockErrorEntry) Next() *SockError {
+	return e.next
+}
+
+// Prev returns the entry that precedes e in the list.
+//
+//go:nosplit
+func (e *sockErrorEntry) Prev() *SockError {
+	return e.prev
+}
+
+// SetNext assigns 'entry' as the entry that follows e in the list.
+//
+//go:nosplit
+func (e *sockErrorEntry) SetNext(elem *SockError) {
+	e.next = elem
+}
+
+// SetPrev assigns 'entry' as the entry that precedes e in the list.
+//
+//go:nosplit
+func (e *sockErrorEntry) SetPrev(elem *SockError) {
+	e.prev = elem
+}
diff --git a/pkg/tcpip/stack/addressable_endpoint_state_test.go b/pkg/tcpip/stack/addressable_endpoint_state_test.go
deleted file mode 100644
index 140f146..0000000
--- a/pkg/tcpip/stack/addressable_endpoint_state_test.go
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2020 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 (
-	"testing"
-
-	"gvisor.dev/gvisor/pkg/tcpip"
-	"gvisor.dev/gvisor/pkg/tcpip/stack"
-)
-
-// TestAddressableEndpointStateCleanup tests that cleaning up an addressable
-// endpoint state removes permanent addresses and leaves groups.
-func TestAddressableEndpointStateCleanup(t *testing.T) {
-	var ep fakeNetworkEndpoint
-	if err := ep.Enable(); err != nil {
-		t.Fatalf("ep.Enable(): %s", err)
-	}
-
-	var s stack.AddressableEndpointState
-	s.Init(&ep)
-
-	addr := tcpip.AddressWithPrefix{
-		Address:   "\x01",
-		PrefixLen: 8,
-	}
-
-	{
-		ep, err := s.AddAndAcquirePermanentAddress(addr, stack.NeverPrimaryEndpoint, stack.AddressConfigStatic, false /* deprecated */)
-		if err != nil {
-			t.Fatalf("s.AddAndAcquirePermanentAddress(%s, %d, %d, false): %s", addr, stack.NeverPrimaryEndpoint, stack.AddressConfigStatic, err)
-		}
-		// We don't need the address endpoint.
-		ep.DecRef()
-	}
-	{
-		ep := s.AcquireAssignedAddress(addr.Address, false /* allowTemp */, stack.NeverPrimaryEndpoint)
-		if ep == nil {
-			t.Fatalf("got s.AcquireAssignedAddress(%s, false, NeverPrimaryEndpoint) = nil, want = non-nil", addr.Address)
-		}
-		ep.DecRef()
-	}
-
-	s.Cleanup()
-	if ep := s.AcquireAssignedAddress(addr.Address, false /* allowTemp */, stack.NeverPrimaryEndpoint); ep != nil {
-		ep.DecRef()
-		t.Fatalf("got s.AcquireAssignedAddress(%s, false, NeverPrimaryEndpoint) = %s, want = nil", addr.Address, ep.AddressWithPrefix())
-	}
-}
diff --git a/pkg/tcpip/stack/forwarding_test.go b/pkg/tcpip/stack/forwarding_test.go
deleted file mode 100644
index c987c18..0000000
--- a/pkg/tcpip/stack/forwarding_test.go
+++ /dev/null
@@ -1,785 +0,0 @@
-// Copyright 2020 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
-
-import (
-	"encoding/binary"
-	"math"
-	"testing"
-	"time"
-
-	"gvisor.dev/gvisor/pkg/sync"
-	"gvisor.dev/gvisor/pkg/tcpip"
-	"gvisor.dev/gvisor/pkg/tcpip/buffer"
-	"gvisor.dev/gvisor/pkg/tcpip/header"
-)
-
-const (
-	fwdTestNetNumber           tcpip.NetworkProtocolNumber = math.MaxUint32
-	fwdTestNetHeaderLen                                    = 12
-	fwdTestNetDefaultPrefixLen                             = 8
-
-	// fwdTestNetDefaultMTU is the MTU, in bytes, used throughout the tests,
-	// except where another value is explicitly used. It is chosen to match
-	// the MTU of loopback interfaces on linux systems.
-	fwdTestNetDefaultMTU = 65536
-
-	dstAddrOffset        = 0
-	srcAddrOffset        = 1
-	protocolNumberOffset = 2
-)
-
-var _ LinkAddressResolver = (*fwdTestNetworkEndpoint)(nil)
-var _ NetworkEndpoint = (*fwdTestNetworkEndpoint)(nil)
-
-// fwdTestNetworkEndpoint is a network-layer protocol endpoint.
-// Headers of this protocol are fwdTestNetHeaderLen bytes, but we currently only
-// use the first three: destination address, source address, and transport
-// protocol. They're all one byte fields to simplify parsing.
-type fwdTestNetworkEndpoint struct {
-	AddressableEndpointState
-
-	nic        NetworkInterface
-	proto      *fwdTestNetworkProtocol
-	dispatcher TransportDispatcher
-}
-
-func (*fwdTestNetworkEndpoint) Enable() tcpip.Error {
-	return nil
-}
-
-func (*fwdTestNetworkEndpoint) Enabled() bool {
-	return true
-}
-
-func (*fwdTestNetworkEndpoint) Disable() {}
-
-func (f *fwdTestNetworkEndpoint) MTU() uint32 {
-	return f.nic.MTU() - uint32(f.MaxHeaderLength())
-}
-
-func (*fwdTestNetworkEndpoint) DefaultTTL() uint8 {
-	return 123
-}
-
-func (f *fwdTestNetworkEndpoint) HandlePacket(pkt *PacketBuffer) {
-	if _, _, ok := f.proto.Parse(pkt); !ok {
-		return
-	}
-
-	netHdr := pkt.NetworkHeader().View()
-	_, dst := f.proto.ParseAddresses(netHdr)
-
-	addressEndpoint := f.AcquireAssignedAddress(dst, f.nic.Promiscuous(), CanBePrimaryEndpoint)
-	if addressEndpoint != nil {
-		addressEndpoint.DecRef()
-		// Dispatch the packet to the transport protocol.
-		f.dispatcher.DeliverTransportPacket(tcpip.TransportProtocolNumber(netHdr[protocolNumberOffset]), pkt)
-		return
-	}
-
-	r, err := f.proto.stack.FindRoute(0, "", dst, fwdTestNetNumber, false /* multicastLoop */)
-	if err != nil {
-		return
-	}
-	defer r.Release()
-
-	vv := buffer.NewVectorisedView(pkt.Size(), pkt.Views())
-	pkt = NewPacketBuffer(PacketBufferOptions{
-		ReserveHeaderBytes: int(r.MaxHeaderLength()),
-		Data:               vv.ToView().ToVectorisedView(),
-	})
-	// TODO(b/143425874) Decrease the TTL field in forwarded packets.
-	_ = r.WriteHeaderIncludedPacket(pkt)
-}
-
-func (f *fwdTestNetworkEndpoint) MaxHeaderLength() uint16 {
-	return f.nic.MaxHeaderLength() + fwdTestNetHeaderLen
-}
-
-func (*fwdTestNetworkEndpoint) PseudoHeaderChecksum(protocol tcpip.TransportProtocolNumber, dstAddr tcpip.Address) uint16 {
-	return 0
-}
-
-func (f *fwdTestNetworkEndpoint) NetworkProtocolNumber() tcpip.NetworkProtocolNumber {
-	return f.proto.Number()
-}
-
-func (f *fwdTestNetworkEndpoint) WritePacket(r *Route, gso *GSO, params NetworkHeaderParams, pkt *PacketBuffer) tcpip.Error {
-	// Add the protocol's header to the packet and send it to the link
-	// endpoint.
-	b := pkt.NetworkHeader().Push(fwdTestNetHeaderLen)
-	b[dstAddrOffset] = r.RemoteAddress[0]
-	b[srcAddrOffset] = r.LocalAddress[0]
-	b[protocolNumberOffset] = byte(params.Protocol)
-
-	return f.nic.WritePacket(r, gso, fwdTestNetNumber, pkt)
-}
-
-// WritePackets implements LinkEndpoint.WritePackets.
-func (*fwdTestNetworkEndpoint) WritePackets(r *Route, gso *GSO, pkts PacketBufferList, params NetworkHeaderParams) (int, tcpip.Error) {
-	panic("not implemented")
-}
-
-func (f *fwdTestNetworkEndpoint) WriteHeaderIncludedPacket(r *Route, pkt *PacketBuffer) tcpip.Error {
-	// The network header should not already be populated.
-	if _, ok := pkt.NetworkHeader().Consume(fwdTestNetHeaderLen); !ok {
-		return &tcpip.ErrMalformedHeader{}
-	}
-
-	return f.nic.WritePacket(r, nil /* gso */, fwdTestNetNumber, pkt)
-}
-
-func (f *fwdTestNetworkEndpoint) Close() {
-	f.AddressableEndpointState.Cleanup()
-}
-
-// Stats implements stack.NetworkEndpoint.
-func (*fwdTestNetworkEndpoint) Stats() NetworkEndpointStats {
-	return &fwdTestNetworkEndpointStats{}
-}
-
-var _ NetworkEndpointStats = (*fwdTestNetworkEndpointStats)(nil)
-
-type fwdTestNetworkEndpointStats struct{}
-
-// IsNetworkEndpointStats implements stack.NetworkEndpointStats.
-func (*fwdTestNetworkEndpointStats) IsNetworkEndpointStats() {}
-
-var _ NetworkProtocol = (*fwdTestNetworkProtocol)(nil)
-
-// fwdTestNetworkProtocol is a network-layer protocol that implements Address
-// resolution.
-type fwdTestNetworkProtocol struct {
-	stack *Stack
-
-	neigh                  *neighborCache
-	addrResolveDelay       time.Duration
-	onLinkAddressResolved  func(*neighborCache, tcpip.Address, tcpip.LinkAddress)
-	onResolveStaticAddress func(tcpip.Address) (tcpip.LinkAddress, bool)
-
-	mu struct {
-		sync.RWMutex
-		forwarding bool
-	}
-}
-
-func (*fwdTestNetworkProtocol) Number() tcpip.NetworkProtocolNumber {
-	return fwdTestNetNumber
-}
-
-func (*fwdTestNetworkProtocol) MinimumPacketSize() int {
-	return fwdTestNetHeaderLen
-}
-
-func (*fwdTestNetworkProtocol) DefaultPrefixLen() int {
-	return fwdTestNetDefaultPrefixLen
-}
-
-func (*fwdTestNetworkProtocol) ParseAddresses(v buffer.View) (src, dst tcpip.Address) {
-	return tcpip.Address(v[srcAddrOffset : srcAddrOffset+1]), tcpip.Address(v[dstAddrOffset : dstAddrOffset+1])
-}
-
-func (*fwdTestNetworkProtocol) Parse(pkt *PacketBuffer) (tcpip.TransportProtocolNumber, bool, bool) {
-	netHeader, ok := pkt.NetworkHeader().Consume(fwdTestNetHeaderLen)
-	if !ok {
-		return 0, false, false
-	}
-	return tcpip.TransportProtocolNumber(netHeader[protocolNumberOffset]), true, true
-}
-
-func (f *fwdTestNetworkProtocol) NewEndpoint(nic NetworkInterface, dispatcher TransportDispatcher) NetworkEndpoint {
-	e := &fwdTestNetworkEndpoint{
-		nic:        nic,
-		proto:      f,
-		dispatcher: dispatcher,
-	}
-	e.AddressableEndpointState.Init(e)
-	return e
-}
-
-func (*fwdTestNetworkProtocol) SetOption(tcpip.SettableNetworkProtocolOption) tcpip.Error {
-	return &tcpip.ErrUnknownProtocolOption{}
-}
-
-func (*fwdTestNetworkProtocol) Option(tcpip.GettableNetworkProtocolOption) tcpip.Error {
-	return &tcpip.ErrUnknownProtocolOption{}
-}
-
-func (*fwdTestNetworkProtocol) Close() {}
-
-func (*fwdTestNetworkProtocol) Wait() {}
-
-func (f *fwdTestNetworkEndpoint) LinkAddressRequest(addr, _ tcpip.Address, remoteLinkAddr tcpip.LinkAddress) tcpip.Error {
-	if fn := f.proto.onLinkAddressResolved; fn != nil {
-		time.AfterFunc(f.proto.addrResolveDelay, func() {
-			fn(f.proto.neigh, addr, remoteLinkAddr)
-		})
-	}
-	return nil
-}
-
-func (f *fwdTestNetworkEndpoint) ResolveStaticAddress(addr tcpip.Address) (tcpip.LinkAddress, bool) {
-	if fn := f.proto.onResolveStaticAddress; fn != nil {
-		return fn(addr)
-	}
-	return "", false
-}
-
-func (*fwdTestNetworkEndpoint) LinkAddressProtocol() tcpip.NetworkProtocolNumber {
-	return fwdTestNetNumber
-}
-
-// Forwarding implements stack.ForwardingNetworkProtocol.
-func (f *fwdTestNetworkProtocol) Forwarding() bool {
-	f.mu.RLock()
-	defer f.mu.RUnlock()
-	return f.mu.forwarding
-
-}
-
-// SetForwarding implements stack.ForwardingNetworkProtocol.
-func (f *fwdTestNetworkProtocol) SetForwarding(v bool) {
-	f.mu.Lock()
-	defer f.mu.Unlock()
-	f.mu.forwarding = v
-}
-
-// fwdTestPacketInfo holds all the information about an outbound packet.
-type fwdTestPacketInfo struct {
-	RemoteLinkAddress tcpip.LinkAddress
-	LocalLinkAddress  tcpip.LinkAddress
-	Pkt               *PacketBuffer
-}
-
-type fwdTestLinkEndpoint struct {
-	dispatcher NetworkDispatcher
-	mtu        uint32
-	linkAddr   tcpip.LinkAddress
-
-	// C is where outbound packets are queued.
-	C chan fwdTestPacketInfo
-}
-
-// InjectInbound injects an inbound packet.
-func (e *fwdTestLinkEndpoint) InjectInbound(protocol tcpip.NetworkProtocolNumber, pkt *PacketBuffer) {
-	e.InjectLinkAddr(protocol, "", pkt)
-}
-
-// InjectLinkAddr injects an inbound packet with a remote link address.
-func (e *fwdTestLinkEndpoint) InjectLinkAddr(protocol tcpip.NetworkProtocolNumber, remote tcpip.LinkAddress, pkt *PacketBuffer) {
-	e.dispatcher.DeliverNetworkPacket(remote, "" /* local */, protocol, pkt)
-}
-
-// Attach saves the stack network-layer dispatcher for use later when packets
-// are injected.
-func (e *fwdTestLinkEndpoint) Attach(dispatcher NetworkDispatcher) {
-	e.dispatcher = dispatcher
-}
-
-// IsAttached implements stack.LinkEndpoint.IsAttached.
-func (e *fwdTestLinkEndpoint) IsAttached() bool {
-	return e.dispatcher != nil
-}
-
-// MTU implements stack.LinkEndpoint.MTU. It returns the value initialized
-// during construction.
-func (e *fwdTestLinkEndpoint) MTU() uint32 {
-	return e.mtu
-}
-
-// Capabilities implements stack.LinkEndpoint.Capabilities.
-func (e fwdTestLinkEndpoint) Capabilities() LinkEndpointCapabilities {
-	caps := LinkEndpointCapabilities(0)
-	return caps | CapabilityResolutionRequired
-}
-
-// GSOMaxSize returns the maximum GSO packet size.
-func (*fwdTestLinkEndpoint) GSOMaxSize() uint32 {
-	return 1 << 15
-}
-
-// MaxHeaderLength returns the maximum size of the link layer header. Given it
-// doesn't have a header, it just returns 0.
-func (*fwdTestLinkEndpoint) MaxHeaderLength() uint16 {
-	return 0
-}
-
-// LinkAddress returns the link address of this endpoint.
-func (e *fwdTestLinkEndpoint) LinkAddress() tcpip.LinkAddress {
-	return e.linkAddr
-}
-
-func (e fwdTestLinkEndpoint) WritePacket(r RouteInfo, gso *GSO, protocol tcpip.NetworkProtocolNumber, pkt *PacketBuffer) tcpip.Error {
-	p := fwdTestPacketInfo{
-		RemoteLinkAddress: r.RemoteLinkAddress,
-		LocalLinkAddress:  r.LocalLinkAddress,
-		Pkt:               pkt,
-	}
-
-	select {
-	case e.C <- p:
-	default:
-	}
-
-	return nil
-}
-
-// WritePackets stores outbound packets into the channel.
-func (e *fwdTestLinkEndpoint) WritePackets(r RouteInfo, gso *GSO, pkts PacketBufferList, protocol tcpip.NetworkProtocolNumber) (int, tcpip.Error) {
-	n := 0
-	for pkt := pkts.Front(); pkt != nil; pkt = pkt.Next() {
-		e.WritePacket(r, gso, protocol, pkt)
-		n++
-	}
-
-	return n, nil
-}
-
-// Wait implements stack.LinkEndpoint.Wait.
-func (*fwdTestLinkEndpoint) Wait() {}
-
-// ARPHardwareType implements stack.LinkEndpoint.ARPHardwareType.
-func (*fwdTestLinkEndpoint) ARPHardwareType() header.ARPHardwareType {
-	panic("not implemented")
-}
-
-// AddHeader implements stack.LinkEndpoint.AddHeader.
-func (e *fwdTestLinkEndpoint) AddHeader(local, remote tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, pkt *PacketBuffer) {
-	panic("not implemented")
-}
-
-func fwdTestNetFactory(t *testing.T, proto *fwdTestNetworkProtocol) (ep1, ep2 *fwdTestLinkEndpoint) {
-	// Create a stack with the network protocol and two NICs.
-	s := New(Options{
-		NetworkProtocols: []NetworkProtocolFactory{func(s *Stack) NetworkProtocol {
-			proto.stack = s
-			return proto
-		}},
-	})
-
-	// Enable forwarding.
-	s.SetForwarding(proto.Number(), true)
-
-	// NIC 1 has the link address "a", and added the network address 1.
-	ep1 = &fwdTestLinkEndpoint{
-		C:        make(chan fwdTestPacketInfo, 300),
-		mtu:      fwdTestNetDefaultMTU,
-		linkAddr: "a",
-	}
-	if err := s.CreateNIC(1, ep1); err != nil {
-		t.Fatal("CreateNIC #1 failed:", err)
-	}
-	if err := s.AddAddress(1, fwdTestNetNumber, "\x01"); err != nil {
-		t.Fatal("AddAddress #1 failed:", err)
-	}
-
-	// NIC 2 has the link address "b", and added the network address 2.
-	ep2 = &fwdTestLinkEndpoint{
-		C:        make(chan fwdTestPacketInfo, 300),
-		mtu:      fwdTestNetDefaultMTU,
-		linkAddr: "b",
-	}
-	if err := s.CreateNIC(2, ep2); err != nil {
-		t.Fatal("CreateNIC #2 failed:", err)
-	}
-	if err := s.AddAddress(2, fwdTestNetNumber, "\x02"); err != nil {
-		t.Fatal("AddAddress #2 failed:", err)
-	}
-
-	nic, ok := s.nics[2]
-	if !ok {
-		t.Fatal("NIC 2 does not exist")
-	}
-
-	if l, ok := nic.linkAddrResolvers[fwdTestNetNumber]; ok {
-		proto.neigh = &l.neigh
-	}
-
-	// Route all packets to NIC 2.
-	{
-		subnet, err := tcpip.NewSubnet("\x00", "\x00")
-		if err != nil {
-			t.Fatal(err)
-		}
-		s.SetRouteTable([]tcpip.Route{{Destination: subnet, NIC: 2}})
-	}
-
-	return ep1, ep2
-}
-
-func TestForwardingWithStaticResolver(t *testing.T) {
-	// Create a network protocol with a static resolver.
-	proto := &fwdTestNetworkProtocol{
-		onResolveStaticAddress:
-		// The network address 3 is resolved to the link address "c".
-		func(addr tcpip.Address) (tcpip.LinkAddress, bool) {
-			if addr == "\x03" {
-				return "c", true
-			}
-			return "", false
-		},
-	}
-
-	ep1, ep2 := fwdTestNetFactory(t, proto)
-
-	// Inject an inbound packet to address 3 on NIC 1, and see if it is
-	// forwarded to NIC 2.
-	buf := buffer.NewView(30)
-	buf[dstAddrOffset] = 3
-	ep1.InjectInbound(fwdTestNetNumber, NewPacketBuffer(PacketBufferOptions{
-		Data: buf.ToVectorisedView(),
-	}))
-
-	var p fwdTestPacketInfo
-
-	select {
-	case p = <-ep2.C:
-	default:
-		t.Fatal("packet not forwarded")
-	}
-
-	// Test that the static address resolution happened correctly.
-	if p.RemoteLinkAddress != "c" {
-		t.Fatalf("got p.RemoteLinkAddress = %s, want = c", p.RemoteLinkAddress)
-	}
-	if p.LocalLinkAddress != "b" {
-		t.Fatalf("got p.LocalLinkAddress = %s, want = b", p.LocalLinkAddress)
-	}
-}
-
-func TestForwardingWithFakeResolver(t *testing.T) {
-	proto := fwdTestNetworkProtocol{
-		addrResolveDelay: 500 * time.Millisecond,
-		onLinkAddressResolved: func(neigh *neighborCache, addr tcpip.Address, linkAddr tcpip.LinkAddress) {
-			t.Helper()
-			if len(linkAddr) != 0 {
-				t.Fatalf("got linkAddr=%q, want unspecified", linkAddr)
-			}
-			// Any address will be resolved to the link address "c".
-			neigh.handleConfirmation(addr, "c", ReachabilityConfirmationFlags{
-				Solicited: true,
-				Override:  false,
-				IsRouter:  false,
-			})
-		},
-	}
-	ep1, ep2 := fwdTestNetFactory(t, &proto)
-
-	// Inject an inbound packet to address 3 on NIC 1, and see if it is
-	// forwarded to NIC 2.
-	buf := buffer.NewView(30)
-	buf[dstAddrOffset] = 3
-	ep1.InjectInbound(fwdTestNetNumber, NewPacketBuffer(PacketBufferOptions{
-		Data: buf.ToVectorisedView(),
-	}))
-
-	var p fwdTestPacketInfo
-
-	select {
-	case p = <-ep2.C:
-	case <-time.After(time.Second):
-		t.Fatal("packet not forwarded")
-	}
-
-	// Test that the address resolution happened correctly.
-	if p.RemoteLinkAddress != "c" {
-		t.Fatalf("got p.RemoteLinkAddress = %s, want = c", p.RemoteLinkAddress)
-	}
-	if p.LocalLinkAddress != "b" {
-		t.Fatalf("got p.LocalLinkAddress = %s, want = b", p.LocalLinkAddress)
-	}
-}
-
-func TestForwardingWithNoResolver(t *testing.T) {
-	// Create a network protocol without a resolver.
-	proto := &fwdTestNetworkProtocol{}
-
-	// Whether or not we use the neighbor cache here does not matter since
-	// neither linkAddrCache nor neighborCache will be used.
-	ep1, ep2 := fwdTestNetFactory(t, proto)
-
-	// inject an inbound packet to address 3 on NIC 1, and see if it is
-	// forwarded to NIC 2.
-	buf := buffer.NewView(30)
-	buf[dstAddrOffset] = 3
-	ep1.InjectInbound(fwdTestNetNumber, NewPacketBuffer(PacketBufferOptions{
-		Data: buf.ToVectorisedView(),
-	}))
-
-	select {
-	case <-ep2.C:
-		t.Fatal("Packet should not be forwarded")
-	case <-time.After(time.Second):
-	}
-}
-
-func TestForwardingResolutionFailsForQueuedPackets(t *testing.T) {
-	proto := &fwdTestNetworkProtocol{
-		addrResolveDelay: 50 * time.Millisecond,
-		onLinkAddressResolved: func(*neighborCache, tcpip.Address, tcpip.LinkAddress) {
-			// Don't resolve the link address.
-		},
-	}
-
-	ep1, ep2 := fwdTestNetFactory(t, proto)
-
-	const numPackets int = 5
-	// These packets will all be enqueued in the packet queue to wait for link
-	// address resolution.
-	for i := 0; i < numPackets; i++ {
-		buf := buffer.NewView(30)
-		buf[dstAddrOffset] = 3
-		ep1.InjectInbound(fwdTestNetNumber, NewPacketBuffer(PacketBufferOptions{
-			Data: buf.ToVectorisedView(),
-		}))
-	}
-
-	// All packets should fail resolution.
-	// TODO(gvisor.dev/issue/5141): Use a fake clock.
-	for i := 0; i < numPackets; i++ {
-		select {
-		case got := <-ep2.C:
-			t.Fatalf("got %#v; packets should have failed resolution and not been forwarded", got)
-		case <-time.After(100 * time.Millisecond):
-		}
-	}
-}
-
-func TestForwardingWithFakeResolverPartialTimeout(t *testing.T) {
-	proto := fwdTestNetworkProtocol{
-		addrResolveDelay: 500 * time.Millisecond,
-		onLinkAddressResolved: func(neigh *neighborCache, addr tcpip.Address, linkAddr tcpip.LinkAddress) {
-			t.Helper()
-			if len(linkAddr) != 0 {
-				t.Fatalf("got linkAddr=%q, want unspecified", linkAddr)
-			}
-			// Only packets to address 3 will be resolved to the
-			// link address "c".
-			if addr == "\x03" {
-				neigh.handleConfirmation(addr, "c", ReachabilityConfirmationFlags{
-					Solicited: true,
-					Override:  false,
-					IsRouter:  false,
-				})
-			}
-		},
-	}
-	ep1, ep2 := fwdTestNetFactory(t, &proto)
-
-	// Inject an inbound packet to address 4 on NIC 1. This packet should
-	// not be forwarded.
-	buf := buffer.NewView(30)
-	buf[dstAddrOffset] = 4
-	ep1.InjectInbound(fwdTestNetNumber, NewPacketBuffer(PacketBufferOptions{
-		Data: buf.ToVectorisedView(),
-	}))
-
-	// Inject an inbound packet to address 3 on NIC 1, and see if it is
-	// forwarded to NIC 2.
-	buf = buffer.NewView(30)
-	buf[dstAddrOffset] = 3
-	ep1.InjectInbound(fwdTestNetNumber, NewPacketBuffer(PacketBufferOptions{
-		Data: buf.ToVectorisedView(),
-	}))
-
-	var p fwdTestPacketInfo
-
-	select {
-	case p = <-ep2.C:
-	case <-time.After(time.Second):
-		t.Fatal("packet not forwarded")
-	}
-
-	if nh := PayloadSince(p.Pkt.NetworkHeader()); nh[dstAddrOffset] != 3 {
-		t.Fatalf("got p.Pkt.NetworkHeader[dstAddrOffset] = %d, want = 3", nh[dstAddrOffset])
-	}
-
-	// Test that the address resolution happened correctly.
-	if p.RemoteLinkAddress != "c" {
-		t.Fatalf("got p.RemoteLinkAddress = %s, want = c", p.RemoteLinkAddress)
-	}
-	if p.LocalLinkAddress != "b" {
-		t.Fatalf("got p.LocalLinkAddress = %s, want = b", p.LocalLinkAddress)
-	}
-}
-
-func TestForwardingWithFakeResolverTwoPackets(t *testing.T) {
-	proto := fwdTestNetworkProtocol{
-		addrResolveDelay: 500 * time.Millisecond,
-		onLinkAddressResolved: func(neigh *neighborCache, addr tcpip.Address, linkAddr tcpip.LinkAddress) {
-			t.Helper()
-			if len(linkAddr) != 0 {
-				t.Fatalf("got linkAddr=%q, want unspecified", linkAddr)
-			}
-			// Any packets will be resolved to the link address "c".
-			neigh.handleConfirmation(addr, "c", ReachabilityConfirmationFlags{
-				Solicited: true,
-				Override:  false,
-				IsRouter:  false,
-			})
-		},
-	}
-	ep1, ep2 := fwdTestNetFactory(t, &proto)
-
-	// Inject two inbound packets to address 3 on NIC 1.
-	for i := 0; i < 2; i++ {
-		buf := buffer.NewView(30)
-		buf[dstAddrOffset] = 3
-		ep1.InjectInbound(fwdTestNetNumber, NewPacketBuffer(PacketBufferOptions{
-			Data: buf.ToVectorisedView(),
-		}))
-	}
-
-	for i := 0; i < 2; i++ {
-		var p fwdTestPacketInfo
-
-		select {
-		case p = <-ep2.C:
-		case <-time.After(time.Second):
-			t.Fatal("packet not forwarded")
-		}
-
-		if nh := PayloadSince(p.Pkt.NetworkHeader()); nh[dstAddrOffset] != 3 {
-			t.Fatalf("got p.Pkt.NetworkHeader[dstAddrOffset] = %d, want = 3", nh[dstAddrOffset])
-		}
-
-		// Test that the address resolution happened correctly.
-		if p.RemoteLinkAddress != "c" {
-			t.Fatalf("got p.RemoteLinkAddress = %s, want = c", p.RemoteLinkAddress)
-		}
-		if p.LocalLinkAddress != "b" {
-			t.Fatalf("got p.LocalLinkAddress = %s, want = b", p.LocalLinkAddress)
-		}
-	}
-}
-
-func TestForwardingWithFakeResolverManyPackets(t *testing.T) {
-	proto := fwdTestNetworkProtocol{
-		addrResolveDelay: 500 * time.Millisecond,
-		onLinkAddressResolved: func(neigh *neighborCache, addr tcpip.Address, linkAddr tcpip.LinkAddress) {
-			t.Helper()
-			if len(linkAddr) != 0 {
-				t.Fatalf("got linkAddr=%q, want unspecified", linkAddr)
-			}
-			// Any packets will be resolved to the link address "c".
-			neigh.handleConfirmation(addr, "c", ReachabilityConfirmationFlags{
-				Solicited: true,
-				Override:  false,
-				IsRouter:  false,
-			})
-		},
-	}
-	ep1, ep2 := fwdTestNetFactory(t, &proto)
-
-	for i := 0; i < maxPendingPacketsPerResolution+5; i++ {
-		// Inject inbound 'maxPendingPacketsPerResolution + 5' packets on NIC 1.
-		buf := buffer.NewView(30)
-		buf[dstAddrOffset] = 3
-		// Set the packet sequence number.
-		binary.BigEndian.PutUint16(buf[fwdTestNetHeaderLen:], uint16(i))
-		ep1.InjectInbound(fwdTestNetNumber, NewPacketBuffer(PacketBufferOptions{
-			Data: buf.ToVectorisedView(),
-		}))
-	}
-
-	for i := 0; i < maxPendingPacketsPerResolution; i++ {
-		var p fwdTestPacketInfo
-
-		select {
-		case p = <-ep2.C:
-		case <-time.After(time.Second):
-			t.Fatal("packet not forwarded")
-		}
-
-		b := PayloadSince(p.Pkt.NetworkHeader())
-		if b[dstAddrOffset] != 3 {
-			t.Fatalf("got b[dstAddrOffset] = %d, want = 3", b[dstAddrOffset])
-		}
-		if len(b) < fwdTestNetHeaderLen+2 {
-			t.Fatalf("packet is too short to hold a sequence number: len(b) = %d", b)
-		}
-		seqNumBuf := b[fwdTestNetHeaderLen:]
-
-		// The first 5 packets should not be forwarded so the sequence number should
-		// start with 5.
-		want := uint16(i + 5)
-		if n := binary.BigEndian.Uint16(seqNumBuf); n != want {
-			t.Fatalf("got the packet #%d, want = #%d", n, want)
-		}
-
-		// Test that the address resolution happened correctly.
-		if p.RemoteLinkAddress != "c" {
-			t.Fatalf("got p.RemoteLinkAddress = %s, want = c", p.RemoteLinkAddress)
-		}
-		if p.LocalLinkAddress != "b" {
-			t.Fatalf("got p.LocalLinkAddress = %s, want = b", p.LocalLinkAddress)
-		}
-	}
-}
-
-func TestForwardingWithFakeResolverManyResolutions(t *testing.T) {
-	proto := fwdTestNetworkProtocol{
-		addrResolveDelay: 500 * time.Millisecond,
-		onLinkAddressResolved: func(neigh *neighborCache, addr tcpip.Address, linkAddr tcpip.LinkAddress) {
-			t.Helper()
-			if len(linkAddr) != 0 {
-				t.Fatalf("got linkAddr=%q, want unspecified", linkAddr)
-			}
-			// Any packets will be resolved to the link address "c".
-			neigh.handleConfirmation(addr, "c", ReachabilityConfirmationFlags{
-				Solicited: true,
-				Override:  false,
-				IsRouter:  false,
-			})
-		},
-	}
-	ep1, ep2 := fwdTestNetFactory(t, &proto)
-
-	for i := 0; i < maxPendingResolutions+5; i++ {
-		// Inject inbound 'maxPendingResolutions + 5' packets on NIC 1.
-		// Each packet has a different destination address (3 to
-		// maxPendingResolutions + 7).
-		buf := buffer.NewView(30)
-		buf[dstAddrOffset] = byte(3 + i)
-		ep1.InjectInbound(fwdTestNetNumber, NewPacketBuffer(PacketBufferOptions{
-			Data: buf.ToVectorisedView(),
-		}))
-	}
-
-	for i := 0; i < maxPendingResolutions; i++ {
-		var p fwdTestPacketInfo
-
-		select {
-		case p = <-ep2.C:
-		case <-time.After(time.Second):
-			t.Fatal("packet not forwarded")
-		}
-
-		// The first 5 packets (address 3 to 7) should not be forwarded
-		// because their address resolutions are interrupted.
-		if nh := PayloadSince(p.Pkt.NetworkHeader()); nh[dstAddrOffset] < 8 {
-			t.Fatalf("got p.Pkt.NetworkHeader[dstAddrOffset] = %d, want p.Pkt.NetworkHeader[dstAddrOffset] >= 8", nh[dstAddrOffset])
-		}
-
-		// Test that the address resolution happened correctly.
-		if p.RemoteLinkAddress != "c" {
-			t.Fatalf("got p.RemoteLinkAddress = %s, want = c", p.RemoteLinkAddress)
-		}
-		if p.LocalLinkAddress != "b" {
-			t.Fatalf("got p.LocalLinkAddress = %s, want = b", p.LocalLinkAddress)
-		}
-	}
-}
diff --git a/pkg/tcpip/stack/ndp_test.go b/pkg/tcpip/stack/ndp_test.go
deleted file mode 100644
index 43e6d10..0000000
--- a/pkg/tcpip/stack/ndp_test.go
+++ /dev/null
@@ -1,5430 +0,0 @@
-// 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")
-			}
-		})
-	}
-}
diff --git a/pkg/tcpip/stack/neighbor_cache_test.go b/pkg/tcpip/stack/neighbor_cache_test.go
deleted file mode 100644
index 48bb75e..0000000
--- a/pkg/tcpip/stack/neighbor_cache_test.go
+++ /dev/null
@@ -1,1592 +0,0 @@
-// 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
-
-import (
-	"bytes"
-	"encoding/binary"
-	"fmt"
-	"math"
-	"math/rand"
-	"strings"
-	"sync"
-	"sync/atomic"
-	"testing"
-	"time"
-
-	"github.com/google/go-cmp/cmp"
-	"github.com/google/go-cmp/cmp/cmpopts"
-	"gvisor.dev/gvisor/pkg/tcpip"
-	"gvisor.dev/gvisor/pkg/tcpip/faketime"
-)
-
-const (
-	// entryStoreSize is the default number of entries that will be generated and
-	// added to the entry store. This number needs to be larger than the size of
-	// the neighbor cache to give ample opportunity for verifying behavior during
-	// cache overflows. Four times the size of the neighbor cache allows for
-	// three complete cache overflows.
-	entryStoreSize = 4 * neighborCacheSize
-
-	// typicalLatency is the typical latency for an ARP or NDP packet to travel
-	// to a router and back.
-	typicalLatency = time.Millisecond
-
-	// testEntryBroadcastAddr is a special address that indicates a packet should
-	// be sent to all nodes.
-	testEntryBroadcastAddr = tcpip.Address("broadcast")
-
-	// testEntryLocalAddr is the source address of neighbor probes.
-	testEntryLocalAddr = tcpip.Address("local_addr")
-
-	// testEntryBroadcastLinkAddr is a special link address sent back to
-	// multicast neighbor probes.
-	testEntryBroadcastLinkAddr = tcpip.LinkAddress("mac_broadcast")
-
-	// infiniteDuration indicates that a task will not occur in our lifetime.
-	infiniteDuration = time.Duration(math.MaxInt64)
-)
-
-// unorderedEventsDiffOpts returns options passed to cmp.Diff to sort slices of
-// events for cases where ordering must be ignored.
-func unorderedEventsDiffOpts() []cmp.Option {
-	return []cmp.Option{
-		cmpopts.SortSlices(func(a, b testEntryEventInfo) bool {
-			return strings.Compare(string(a.Entry.Addr), string(b.Entry.Addr)) < 0
-		}),
-	}
-}
-
-// unorderedEntriesDiffOpts returns options passed to cmp.Diff to sort slices of
-// entries for cases where ordering must be ignored.
-func unorderedEntriesDiffOpts() []cmp.Option {
-	return []cmp.Option{
-		cmpopts.SortSlices(func(a, b NeighborEntry) bool {
-			return strings.Compare(string(a.Addr), string(b.Addr)) < 0
-		}),
-	}
-}
-
-func newTestNeighborResolver(nudDisp NUDDispatcher, config NUDConfigurations, clock tcpip.Clock) *testNeighborResolver {
-	config.resetInvalidFields()
-	rng := rand.New(rand.NewSource(time.Now().UnixNano()))
-	linkRes := &testNeighborResolver{
-		clock:   clock,
-		entries: newTestEntryStore(),
-		delay:   typicalLatency,
-	}
-	linkRes.neigh.init(&nic{
-		stack: &Stack{
-			clock:           clock,
-			nudDisp:         nudDisp,
-			nudConfigs:      config,
-			randomGenerator: rng,
-		},
-		id:    1,
-		stats: makeNICStats(),
-	}, linkRes)
-	return linkRes
-}
-
-// testEntryStore contains a set of IP to NeighborEntry mappings.
-type testEntryStore struct {
-	mu         sync.RWMutex
-	entriesMap map[tcpip.Address]NeighborEntry
-}
-
-func toAddress(i int) tcpip.Address {
-	buf := new(bytes.Buffer)
-	binary.Write(buf, binary.BigEndian, uint8(1))
-	binary.Write(buf, binary.BigEndian, uint8(0))
-	binary.Write(buf, binary.BigEndian, uint16(i))
-	return tcpip.Address(buf.String())
-}
-
-func toLinkAddress(i int) tcpip.LinkAddress {
-	buf := new(bytes.Buffer)
-	binary.Write(buf, binary.BigEndian, uint8(1))
-	binary.Write(buf, binary.BigEndian, uint8(0))
-	binary.Write(buf, binary.BigEndian, uint32(i))
-	return tcpip.LinkAddress(buf.String())
-}
-
-// newTestEntryStore returns a testEntryStore pre-populated with entries.
-func newTestEntryStore() *testEntryStore {
-	store := &testEntryStore{
-		entriesMap: make(map[tcpip.Address]NeighborEntry),
-	}
-	for i := 0; i < entryStoreSize; i++ {
-		addr := toAddress(i)
-		linkAddr := toLinkAddress(i)
-
-		store.entriesMap[addr] = NeighborEntry{
-			Addr:     addr,
-			LinkAddr: linkAddr,
-		}
-	}
-	return store
-}
-
-// size returns the number of entries in the store.
-func (s *testEntryStore) size() int {
-	s.mu.RLock()
-	defer s.mu.RUnlock()
-	return len(s.entriesMap)
-}
-
-// entry returns the entry at index i. Returns an empty entry and false if i is
-// out of bounds.
-func (s *testEntryStore) entry(i int) (NeighborEntry, bool) {
-	return s.entryByAddr(toAddress(i))
-}
-
-// entryByAddr returns the entry matching addr for situations when the index is
-// not available. Returns an empty entry and false if no entries match addr.
-func (s *testEntryStore) entryByAddr(addr tcpip.Address) (NeighborEntry, bool) {
-	s.mu.RLock()
-	defer s.mu.RUnlock()
-	entry, ok := s.entriesMap[addr]
-	return entry, ok
-}
-
-// entries returns all entries in the store.
-func (s *testEntryStore) entries() []NeighborEntry {
-	entries := make([]NeighborEntry, 0, len(s.entriesMap))
-	s.mu.RLock()
-	defer s.mu.RUnlock()
-	for i := 0; i < entryStoreSize; i++ {
-		addr := toAddress(i)
-		if entry, ok := s.entriesMap[addr]; ok {
-			entries = append(entries, entry)
-		}
-	}
-	return entries
-}
-
-// set modifies the link addresses of an entry.
-func (s *testEntryStore) set(i int, linkAddr tcpip.LinkAddress) {
-	addr := toAddress(i)
-	s.mu.Lock()
-	defer s.mu.Unlock()
-	if entry, ok := s.entriesMap[addr]; ok {
-		entry.LinkAddr = linkAddr
-		s.entriesMap[addr] = entry
-	}
-}
-
-// testNeighborResolver implements LinkAddressResolver to emulate sending a
-// neighbor probe.
-type testNeighborResolver struct {
-	clock                tcpip.Clock
-	neigh                neighborCache
-	entries              *testEntryStore
-	delay                time.Duration
-	onLinkAddressRequest func()
-	dropReplies          bool
-}
-
-var _ LinkAddressResolver = (*testNeighborResolver)(nil)
-
-func (r *testNeighborResolver) LinkAddressRequest(targetAddr, _ tcpip.Address, _ tcpip.LinkAddress) tcpip.Error {
-	if !r.dropReplies {
-		// Delay handling the request to emulate network latency.
-		r.clock.AfterFunc(r.delay, func() {
-			r.fakeRequest(targetAddr)
-		})
-	}
-
-	// Execute post address resolution action, if available.
-	if f := r.onLinkAddressRequest; f != nil {
-		f()
-	}
-	return nil
-}
-
-// fakeRequest emulates handling a response for a link address request.
-func (r *testNeighborResolver) fakeRequest(addr tcpip.Address) {
-	if entry, ok := r.entries.entryByAddr(addr); ok {
-		r.neigh.handleConfirmation(addr, entry.LinkAddr, ReachabilityConfirmationFlags{
-			Solicited: true,
-			Override:  false,
-			IsRouter:  false,
-		})
-	}
-}
-
-func (*testNeighborResolver) ResolveStaticAddress(addr tcpip.Address) (tcpip.LinkAddress, bool) {
-	if addr == testEntryBroadcastAddr {
-		return testEntryBroadcastLinkAddr, true
-	}
-	return "", false
-}
-
-func (*testNeighborResolver) LinkAddressProtocol() tcpip.NetworkProtocolNumber {
-	return 0
-}
-
-type entryEvent struct {
-	nicID    tcpip.NICID
-	address  tcpip.Address
-	linkAddr tcpip.LinkAddress
-	state    NeighborState
-}
-
-func TestNeighborCacheGetConfig(t *testing.T) {
-	nudDisp := testNUDDispatcher{}
-	c := DefaultNUDConfigurations()
-	clock := faketime.NewManualClock()
-	linkRes := newTestNeighborResolver(&nudDisp, c, clock)
-
-	if got, want := linkRes.neigh.config(), c; got != want {
-		t.Errorf("got linkRes.neigh.config() = %+v, want = %+v", got, want)
-	}
-
-	// No events should have been dispatched.
-	nudDisp.mu.Lock()
-	defer nudDisp.mu.Unlock()
-	if diff := cmp.Diff([]testEntryEventInfo(nil), nudDisp.mu.events); diff != "" {
-		t.Errorf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-	}
-}
-
-func TestNeighborCacheSetConfig(t *testing.T) {
-	nudDisp := testNUDDispatcher{}
-	c := DefaultNUDConfigurations()
-	clock := faketime.NewManualClock()
-	linkRes := newTestNeighborResolver(&nudDisp, c, clock)
-
-	c.MinRandomFactor = 1
-	c.MaxRandomFactor = 1
-	linkRes.neigh.setConfig(c)
-
-	if got, want := linkRes.neigh.config(), c; got != want {
-		t.Errorf("got linkRes.neigh.config() = %+v, want = %+v", got, want)
-	}
-
-	// No events should have been dispatched.
-	nudDisp.mu.Lock()
-	defer nudDisp.mu.Unlock()
-	if diff := cmp.Diff([]testEntryEventInfo(nil), nudDisp.mu.events); diff != "" {
-		t.Errorf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-	}
-}
-
-func addReachableEntryWithRemoved(nudDisp *testNUDDispatcher, clock *faketime.ManualClock, linkRes *testNeighborResolver, entry NeighborEntry, removed []NeighborEntry) error {
-	var gotLinkResolutionResult LinkResolutionResult
-
-	_, ch, err := linkRes.neigh.entry(entry.Addr, "", func(r LinkResolutionResult) {
-		gotLinkResolutionResult = r
-	})
-	if _, ok := err.(*tcpip.ErrWouldBlock); !ok {
-		return fmt.Errorf("got linkRes.neigh.entry(%s, '', _) = %v, want = %s", entry.Addr, err, &tcpip.ErrWouldBlock{})
-	}
-
-	{
-		var wantEvents []testEntryEventInfo
-
-		for _, removedEntry := range removed {
-			wantEvents = append(wantEvents, testEntryEventInfo{
-				EventType: entryTestRemoved,
-				NICID:     1,
-				Entry: NeighborEntry{
-					Addr:           removedEntry.Addr,
-					LinkAddr:       removedEntry.LinkAddr,
-					State:          Reachable,
-					UpdatedAtNanos: clock.NowNanoseconds(),
-				},
-			})
-		}
-
-		wantEvents = append(wantEvents, testEntryEventInfo{
-			EventType: entryTestAdded,
-			NICID:     1,
-			Entry: NeighborEntry{
-				Addr:           entry.Addr,
-				LinkAddr:       "",
-				State:          Incomplete,
-				UpdatedAtNanos: clock.NowNanoseconds(),
-			},
-		})
-
-		nudDisp.mu.Lock()
-		diff := cmp.Diff(wantEvents, nudDisp.mu.events)
-		nudDisp.mu.events = nil
-		nudDisp.mu.Unlock()
-		if diff != "" {
-			return fmt.Errorf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-		}
-	}
-
-	clock.Advance(typicalLatency)
-
-	select {
-	case <-ch:
-	default:
-		return fmt.Errorf("expected notification from done channel returned by linkRes.neigh.entry(%s, '', _)", entry.Addr)
-	}
-	wantLinkResolutionResult := LinkResolutionResult{LinkAddress: entry.LinkAddr, Err: nil}
-	if diff := cmp.Diff(wantLinkResolutionResult, gotLinkResolutionResult); diff != "" {
-		return fmt.Errorf("got link resolution result mismatch (-want +got):\n%s", diff)
-	}
-
-	{
-		wantEvents := []testEntryEventInfo{
-			{
-				EventType: entryTestChanged,
-				NICID:     1,
-				Entry: NeighborEntry{
-					Addr:           entry.Addr,
-					LinkAddr:       entry.LinkAddr,
-					State:          Reachable,
-					UpdatedAtNanos: clock.NowNanoseconds(),
-				},
-			},
-		}
-		nudDisp.mu.Lock()
-		diff := cmp.Diff(wantEvents, nudDisp.mu.events)
-		nudDisp.mu.events = nil
-		nudDisp.mu.Unlock()
-		if diff != "" {
-			return fmt.Errorf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-		}
-	}
-
-	return nil
-}
-
-func addReachableEntry(nudDisp *testNUDDispatcher, clock *faketime.ManualClock, linkRes *testNeighborResolver, entry NeighborEntry) error {
-	return addReachableEntryWithRemoved(nudDisp, clock, linkRes, entry, nil /* removed */)
-}
-
-func TestNeighborCacheEntry(t *testing.T) {
-	c := DefaultNUDConfigurations()
-	nudDisp := testNUDDispatcher{}
-	clock := faketime.NewManualClock()
-	linkRes := newTestNeighborResolver(&nudDisp, c, clock)
-
-	entry, ok := linkRes.entries.entry(0)
-	if !ok {
-		t.Fatal("got linkRes.entries.entry(0) = _, false, want = true ")
-	}
-	if err := addReachableEntry(&nudDisp, clock, linkRes, entry); err != nil {
-		t.Fatalf("addReachableEntry(...) = %s", err)
-	}
-
-	if _, _, err := linkRes.neigh.entry(entry.Addr, "", nil); err != nil {
-		t.Fatalf("unexpected error from linkRes.neigh.entry(%s, '', nil): %s", entry.Addr, err)
-	}
-
-	// No more events should have been dispatched.
-	nudDisp.mu.Lock()
-	defer nudDisp.mu.Unlock()
-	if diff := cmp.Diff([]testEntryEventInfo(nil), nudDisp.mu.events); diff != "" {
-		t.Errorf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-	}
-}
-
-func TestNeighborCacheRemoveEntry(t *testing.T) {
-	config := DefaultNUDConfigurations()
-
-	nudDisp := testNUDDispatcher{}
-	clock := faketime.NewManualClock()
-	linkRes := newTestNeighborResolver(&nudDisp, config, clock)
-
-	entry, ok := linkRes.entries.entry(0)
-	if !ok {
-		t.Fatal("got linkRes.entries.entry(0) = _, false, want = true ")
-	}
-	if err := addReachableEntry(&nudDisp, clock, linkRes, entry); err != nil {
-		t.Fatalf("addReachableEntry(...) = %s", err)
-	}
-
-	linkRes.neigh.removeEntry(entry.Addr)
-
-	{
-		wantEvents := []testEntryEventInfo{
-			{
-				EventType: entryTestRemoved,
-				NICID:     1,
-				Entry: NeighborEntry{
-					Addr:           entry.Addr,
-					LinkAddr:       entry.LinkAddr,
-					State:          Reachable,
-					UpdatedAtNanos: clock.NowNanoseconds(),
-				},
-			},
-		}
-		nudDisp.mu.Lock()
-		diff := cmp.Diff(wantEvents, nudDisp.mu.events)
-		nudDisp.mu.Unlock()
-		if diff != "" {
-			t.Fatalf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-		}
-	}
-
-	{
-		_, _, err := linkRes.neigh.entry(entry.Addr, "", nil)
-		if _, ok := err.(*tcpip.ErrWouldBlock); !ok {
-			t.Errorf("got linkRes.neigh.entry(%s, '', nil) = %v, want = %s", entry.Addr, err, &tcpip.ErrWouldBlock{})
-		}
-	}
-}
-
-type testContext struct {
-	clock   *faketime.ManualClock
-	linkRes *testNeighborResolver
-	nudDisp *testNUDDispatcher
-}
-
-func newTestContext(c NUDConfigurations) testContext {
-	nudDisp := &testNUDDispatcher{}
-	clock := faketime.NewManualClock()
-	linkRes := newTestNeighborResolver(nudDisp, c, clock)
-
-	return testContext{
-		clock:   clock,
-		linkRes: linkRes,
-		nudDisp: nudDisp,
-	}
-}
-
-type overflowOptions struct {
-	startAtEntryIndex int
-	wantStaticEntries []NeighborEntry
-}
-
-func (c *testContext) overflowCache(opts overflowOptions) error {
-	// Fill the neighbor cache to capacity to verify the LRU eviction strategy is
-	// working properly after the entry removal.
-	for i := opts.startAtEntryIndex; i < c.linkRes.entries.size(); i++ {
-		var removedEntries []NeighborEntry
-
-		// When beyond the full capacity, the cache will evict an entry as per the
-		// LRU eviction strategy. Note that the number of static entries should not
-		// affect the total number of dynamic entries that can be added.
-		if i >= neighborCacheSize+opts.startAtEntryIndex {
-			removedEntry, ok := c.linkRes.entries.entry(i - neighborCacheSize)
-			if !ok {
-				return fmt.Errorf("got linkRes.entries.entry(%d) = _, false, want = true", i-neighborCacheSize)
-			}
-			removedEntries = append(removedEntries, removedEntry)
-		}
-
-		entry, ok := c.linkRes.entries.entry(i)
-		if !ok {
-			return fmt.Errorf("got c.linkRes.entries.entry(%d) = _, false, want = true", i)
-		}
-		if err := addReachableEntryWithRemoved(c.nudDisp, c.clock, c.linkRes, entry, removedEntries); err != nil {
-			return fmt.Errorf("addReachableEntryWithRemoved(...) = %s", err)
-		}
-	}
-
-	// Expect to find only the most recent entries. The order of entries reported
-	// by entries() is nondeterministic, so entries have to be sorted before
-	// comparison.
-	wantUnorderedEntries := opts.wantStaticEntries
-	for i := c.linkRes.entries.size() - neighborCacheSize; i < c.linkRes.entries.size(); i++ {
-		entry, ok := c.linkRes.entries.entry(i)
-		if !ok {
-			return fmt.Errorf("got c.linkRes.entries.entry(%d) = _, false, want = true", i)
-		}
-		durationReachableNanos := int64(c.linkRes.entries.size()-i-1) * typicalLatency.Nanoseconds()
-		wantEntry := NeighborEntry{
-			Addr:           entry.Addr,
-			LinkAddr:       entry.LinkAddr,
-			State:          Reachable,
-			UpdatedAtNanos: c.clock.NowNanoseconds() - durationReachableNanos,
-		}
-		wantUnorderedEntries = append(wantUnorderedEntries, wantEntry)
-	}
-
-	if diff := cmp.Diff(wantUnorderedEntries, c.linkRes.neigh.entries(), unorderedEntriesDiffOpts()...); diff != "" {
-		return fmt.Errorf("neighbor entries mismatch (-want, +got):\n%s", diff)
-	}
-
-	// No more events should have been dispatched.
-	c.nudDisp.mu.Lock()
-	defer c.nudDisp.mu.Unlock()
-	if diff := cmp.Diff([]testEntryEventInfo(nil), c.nudDisp.mu.events); diff != "" {
-		return fmt.Errorf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-	}
-
-	return nil
-}
-
-// TestNeighborCacheOverflow verifies that the LRU cache eviction strategy
-// respects the dynamic entry count.
-func TestNeighborCacheOverflow(t *testing.T) {
-	config := DefaultNUDConfigurations()
-	// Stay in Reachable so the cache can overflow
-	config.BaseReachableTime = infiniteDuration
-	config.MinRandomFactor = 1
-	config.MaxRandomFactor = 1
-
-	c := newTestContext(config)
-	opts := overflowOptions{
-		startAtEntryIndex: 0,
-	}
-	if err := c.overflowCache(opts); err != nil {
-		t.Errorf("c.overflowCache(%+v): %s", opts, err)
-	}
-}
-
-// TestNeighborCacheRemoveEntryThenOverflow verifies that the LRU cache
-// eviction strategy respects the dynamic entry count when an entry is removed.
-func TestNeighborCacheRemoveEntryThenOverflow(t *testing.T) {
-	config := DefaultNUDConfigurations()
-	// Stay in Reachable so the cache can overflow
-	config.BaseReachableTime = infiniteDuration
-	config.MinRandomFactor = 1
-	config.MaxRandomFactor = 1
-
-	c := newTestContext(config)
-
-	// Add a dynamic entry
-	entry, ok := c.linkRes.entries.entry(0)
-	if !ok {
-		t.Fatal("got c.linkRes.entries.entry(0) = _, false, want = true ")
-	}
-	if err := addReachableEntry(c.nudDisp, c.clock, c.linkRes, entry); err != nil {
-		t.Fatalf("addReachableEntry(...) = %s", err)
-	}
-
-	// Remove the entry
-	c.linkRes.neigh.removeEntry(entry.Addr)
-
-	{
-		wantEvents := []testEntryEventInfo{
-			{
-				EventType: entryTestRemoved,
-				NICID:     1,
-				Entry: NeighborEntry{
-					Addr:           entry.Addr,
-					LinkAddr:       entry.LinkAddr,
-					State:          Reachable,
-					UpdatedAtNanos: c.clock.NowNanoseconds(),
-				},
-			},
-		}
-		c.nudDisp.mu.Lock()
-		diff := cmp.Diff(wantEvents, c.nudDisp.mu.events)
-		c.nudDisp.mu.events = nil
-		c.nudDisp.mu.Unlock()
-		if diff != "" {
-			t.Fatalf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-		}
-	}
-
-	opts := overflowOptions{
-		startAtEntryIndex: 0,
-	}
-	if err := c.overflowCache(opts); err != nil {
-		t.Errorf("c.overflowCache(%+v): %s", opts, err)
-	}
-}
-
-// TestNeighborCacheDuplicateStaticEntryWithSameLinkAddress verifies that
-// adding a duplicate static entry with the same link address does not dispatch
-// any events.
-func TestNeighborCacheDuplicateStaticEntryWithSameLinkAddress(t *testing.T) {
-	config := DefaultNUDConfigurations()
-	c := newTestContext(config)
-
-	// Add a static entry
-	entry, ok := c.linkRes.entries.entry(0)
-	if !ok {
-		t.Fatal("got c.linkRes.entries.entry(0) = _, false, want = true ")
-	}
-	staticLinkAddr := entry.LinkAddr + "static"
-	c.linkRes.neigh.addStaticEntry(entry.Addr, staticLinkAddr)
-
-	{
-		wantEvents := []testEntryEventInfo{
-			{
-				EventType: entryTestAdded,
-				NICID:     1,
-				Entry: NeighborEntry{
-					Addr:           entry.Addr,
-					LinkAddr:       staticLinkAddr,
-					State:          Static,
-					UpdatedAtNanos: c.clock.NowNanoseconds(),
-				},
-			},
-		}
-		c.nudDisp.mu.Lock()
-		diff := cmp.Diff(wantEvents, c.nudDisp.mu.events)
-		c.nudDisp.mu.events = nil
-		c.nudDisp.mu.Unlock()
-		if diff != "" {
-			t.Fatalf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-		}
-	}
-
-	// Add a duplicate static entry with the same link address.
-	c.linkRes.neigh.addStaticEntry(entry.Addr, staticLinkAddr)
-
-	c.nudDisp.mu.Lock()
-	defer c.nudDisp.mu.Unlock()
-	if diff := cmp.Diff([]testEntryEventInfo(nil), c.nudDisp.mu.events); diff != "" {
-		t.Errorf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-	}
-}
-
-// TestNeighborCacheDuplicateStaticEntryWithDifferentLinkAddress verifies that
-// adding a duplicate static entry with a different link address dispatches a
-// change event.
-func TestNeighborCacheDuplicateStaticEntryWithDifferentLinkAddress(t *testing.T) {
-	config := DefaultNUDConfigurations()
-	c := newTestContext(config)
-
-	// Add a static entry
-	entry, ok := c.linkRes.entries.entry(0)
-	if !ok {
-		t.Fatal("got c.linkRes.entries.entry(0) = _, false, want = true ")
-	}
-	staticLinkAddr := entry.LinkAddr + "static"
-	c.linkRes.neigh.addStaticEntry(entry.Addr, staticLinkAddr)
-
-	{
-		wantEvents := []testEntryEventInfo{
-			{
-				EventType: entryTestAdded,
-				NICID:     1,
-				Entry: NeighborEntry{
-					Addr:           entry.Addr,
-					LinkAddr:       staticLinkAddr,
-					State:          Static,
-					UpdatedAtNanos: c.clock.NowNanoseconds(),
-				},
-			},
-		}
-		c.nudDisp.mu.Lock()
-		diff := cmp.Diff(wantEvents, c.nudDisp.mu.events)
-		c.nudDisp.mu.events = nil
-		c.nudDisp.mu.Unlock()
-		if diff != "" {
-			t.Fatalf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-		}
-	}
-
-	// Add a duplicate entry with a different link address
-	staticLinkAddr += "duplicate"
-	c.linkRes.neigh.addStaticEntry(entry.Addr, staticLinkAddr)
-
-	{
-		wantEvents := []testEntryEventInfo{
-			{
-				EventType: entryTestChanged,
-				NICID:     1,
-				Entry: NeighborEntry{
-					Addr:           entry.Addr,
-					LinkAddr:       staticLinkAddr,
-					State:          Static,
-					UpdatedAtNanos: c.clock.NowNanoseconds(),
-				},
-			},
-		}
-		c.nudDisp.mu.Lock()
-		diff := cmp.Diff(wantEvents, c.nudDisp.mu.events)
-		c.nudDisp.mu.events = nil
-		c.nudDisp.mu.Unlock()
-		if diff != "" {
-			t.Fatalf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-		}
-	}
-}
-
-// TestNeighborCacheRemoveStaticEntryThenOverflow verifies that the LRU cache
-// eviction strategy respects the dynamic entry count when a static entry is
-// added then removed. In this case, the dynamic entry count shouldn't have
-// been touched.
-func TestNeighborCacheRemoveStaticEntryThenOverflow(t *testing.T) {
-	config := DefaultNUDConfigurations()
-	// Stay in Reachable so the cache can overflow
-	config.BaseReachableTime = infiniteDuration
-	config.MinRandomFactor = 1
-	config.MaxRandomFactor = 1
-
-	c := newTestContext(config)
-
-	// Add a static entry
-	entry, ok := c.linkRes.entries.entry(0)
-	if !ok {
-		t.Fatal("got c.linkRes.entries.entry(0) = _, false, want = true ")
-	}
-	staticLinkAddr := entry.LinkAddr + "static"
-	c.linkRes.neigh.addStaticEntry(entry.Addr, staticLinkAddr)
-
-	{
-		wantEvents := []testEntryEventInfo{
-			{
-				EventType: entryTestAdded,
-				NICID:     1,
-				Entry: NeighborEntry{
-					Addr:           entry.Addr,
-					LinkAddr:       staticLinkAddr,
-					State:          Static,
-					UpdatedAtNanos: c.clock.NowNanoseconds(),
-				},
-			},
-		}
-		c.nudDisp.mu.Lock()
-		diff := cmp.Diff(wantEvents, c.nudDisp.mu.events)
-		c.nudDisp.mu.events = nil
-		c.nudDisp.mu.Unlock()
-		if diff != "" {
-			t.Fatalf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-		}
-	}
-
-	// Remove the static entry that was just added
-	c.linkRes.neigh.removeEntry(entry.Addr)
-
-	{
-		wantEvents := []testEntryEventInfo{
-			{
-				EventType: entryTestRemoved,
-				NICID:     1,
-				Entry: NeighborEntry{
-					Addr:           entry.Addr,
-					LinkAddr:       staticLinkAddr,
-					State:          Static,
-					UpdatedAtNanos: c.clock.NowNanoseconds(),
-				},
-			},
-		}
-		c.nudDisp.mu.Lock()
-		diff := cmp.Diff(wantEvents, c.nudDisp.mu.events)
-		c.nudDisp.mu.events = nil
-		c.nudDisp.mu.Unlock()
-		if diff != "" {
-			t.Fatalf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-		}
-	}
-
-	opts := overflowOptions{
-		startAtEntryIndex: 0,
-	}
-	if err := c.overflowCache(opts); err != nil {
-		t.Errorf("c.overflowCache(%+v): %s", opts, err)
-	}
-}
-
-// TestNeighborCacheOverwriteWithStaticEntryThenOverflow verifies that the LRU
-// cache eviction strategy keeps count of the dynamic entry count when an entry
-// is overwritten by a static entry. Static entries should not count towards
-// the size of the LRU cache.
-func TestNeighborCacheOverwriteWithStaticEntryThenOverflow(t *testing.T) {
-	config := DefaultNUDConfigurations()
-	// Stay in Reachable so the cache can overflow
-	config.BaseReachableTime = infiniteDuration
-	config.MinRandomFactor = 1
-	config.MaxRandomFactor = 1
-
-	c := newTestContext(config)
-
-	// Add a dynamic entry
-	entry, ok := c.linkRes.entries.entry(0)
-	if !ok {
-		t.Fatal("got c.linkRes.entries.entry(0) = _, false, want = true ")
-	}
-	if err := addReachableEntry(c.nudDisp, c.clock, c.linkRes, entry); err != nil {
-		t.Fatalf("addReachableEntry(...) = %s", err)
-	}
-
-	// Override the entry with a static one using the same address
-	staticLinkAddr := entry.LinkAddr + "static"
-	c.linkRes.neigh.addStaticEntry(entry.Addr, staticLinkAddr)
-
-	{
-		wantEvents := []testEntryEventInfo{
-			{
-				EventType: entryTestRemoved,
-				NICID:     1,
-				Entry: NeighborEntry{
-					Addr:           entry.Addr,
-					LinkAddr:       entry.LinkAddr,
-					State:          Reachable,
-					UpdatedAtNanos: c.clock.NowNanoseconds(),
-				},
-			},
-			{
-				EventType: entryTestAdded,
-				NICID:     1,
-				Entry: NeighborEntry{
-					Addr:           entry.Addr,
-					LinkAddr:       staticLinkAddr,
-					State:          Static,
-					UpdatedAtNanos: c.clock.NowNanoseconds(),
-				},
-			},
-		}
-		c.nudDisp.mu.Lock()
-		diff := cmp.Diff(wantEvents, c.nudDisp.mu.events)
-		c.nudDisp.mu.events = nil
-		c.nudDisp.mu.Unlock()
-		if diff != "" {
-			t.Fatalf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-		}
-	}
-
-	opts := overflowOptions{
-		startAtEntryIndex: 1,
-		wantStaticEntries: []NeighborEntry{
-			{
-				Addr:           entry.Addr,
-				LinkAddr:       staticLinkAddr,
-				State:          Static,
-				UpdatedAtNanos: c.clock.NowNanoseconds(),
-			},
-		},
-	}
-	if err := c.overflowCache(opts); err != nil {
-		t.Errorf("c.overflowCache(%+v): %s", opts, err)
-	}
-}
-
-func TestNeighborCacheAddStaticEntryThenOverflow(t *testing.T) {
-	config := DefaultNUDConfigurations()
-	// Stay in Reachable so the cache can overflow
-	config.BaseReachableTime = infiniteDuration
-	config.MinRandomFactor = 1
-	config.MaxRandomFactor = 1
-
-	c := newTestContext(config)
-
-	entry, ok := c.linkRes.entries.entry(0)
-	if !ok {
-		t.Fatal("got c.linkRes.entries.entry(0) = _, false, want = true ")
-	}
-	c.linkRes.neigh.addStaticEntry(entry.Addr, entry.LinkAddr)
-	e, _, err := c.linkRes.neigh.entry(entry.Addr, "", nil)
-	if err != nil {
-		t.Errorf("unexpected error from c.linkRes.neigh.entry(%s, \"\", nil): %s", entry.Addr, err)
-	}
-	want := NeighborEntry{
-		Addr:           entry.Addr,
-		LinkAddr:       entry.LinkAddr,
-		State:          Static,
-		UpdatedAtNanos: c.clock.NowNanoseconds(),
-	}
-	if diff := cmp.Diff(want, e); diff != "" {
-		t.Errorf("c.linkRes.neigh.entry(%s, \"\", nil) mismatch (-want, +got):\n%s", entry.Addr, diff)
-	}
-
-	{
-		wantEvents := []testEntryEventInfo{
-			{
-				EventType: entryTestAdded,
-				NICID:     1,
-				Entry: NeighborEntry{
-					Addr:           entry.Addr,
-					LinkAddr:       entry.LinkAddr,
-					State:          Static,
-					UpdatedAtNanos: c.clock.NowNanoseconds(),
-				},
-			},
-		}
-		c.nudDisp.mu.Lock()
-		diff := cmp.Diff(wantEvents, c.nudDisp.mu.events)
-		c.nudDisp.mu.events = nil
-		c.nudDisp.mu.Unlock()
-		if diff != "" {
-			t.Fatalf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-		}
-	}
-
-	opts := overflowOptions{
-		startAtEntryIndex: 1,
-		wantStaticEntries: []NeighborEntry{
-			{
-				Addr:           entry.Addr,
-				LinkAddr:       entry.LinkAddr,
-				State:          Static,
-				UpdatedAtNanos: c.clock.NowNanoseconds(),
-			},
-		},
-	}
-	if err := c.overflowCache(opts); err != nil {
-		t.Errorf("c.overflowCache(%+v): %s", opts, err)
-	}
-}
-
-func TestNeighborCacheClear(t *testing.T) {
-	config := DefaultNUDConfigurations()
-
-	nudDisp := testNUDDispatcher{}
-	clock := faketime.NewManualClock()
-	linkRes := newTestNeighborResolver(&nudDisp, config, clock)
-
-	// Add a dynamic entry.
-	entry, ok := linkRes.entries.entry(0)
-	if !ok {
-		t.Fatal("got linkRes.entries.entry(0) = _, false, want = true ")
-	}
-	if err := addReachableEntry(&nudDisp, clock, linkRes, entry); err != nil {
-		t.Fatalf("addReachableEntry(...) = %s", err)
-	}
-
-	// Add a static entry.
-	linkRes.neigh.addStaticEntry(entryTestAddr1, entryTestLinkAddr1)
-
-	{
-		wantEvents := []testEntryEventInfo{
-			{
-				EventType: entryTestAdded,
-				NICID:     1,
-				Entry: NeighborEntry{
-					Addr:           entryTestAddr1,
-					LinkAddr:       entryTestLinkAddr1,
-					State:          Static,
-					UpdatedAtNanos: clock.NowNanoseconds(),
-				},
-			},
-		}
-		nudDisp.mu.Lock()
-		diff := cmp.Diff(wantEvents, nudDisp.mu.events)
-		nudDisp.mu.events = nil
-		nudDisp.mu.Unlock()
-		if diff != "" {
-			t.Fatalf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-		}
-	}
-
-	// Clear should remove both dynamic and static entries.
-	linkRes.neigh.clear()
-
-	// Remove events dispatched from clear() have no deterministic order so they
-	// need to be sorted before comparison.
-	wantUnorderedEvents := []testEntryEventInfo{
-		{
-			EventType: entryTestRemoved,
-			NICID:     1,
-			Entry: NeighborEntry{
-				Addr:           entry.Addr,
-				LinkAddr:       entry.LinkAddr,
-				State:          Reachable,
-				UpdatedAtNanos: clock.NowNanoseconds(),
-			},
-		},
-		{
-			EventType: entryTestRemoved,
-			NICID:     1,
-			Entry: NeighborEntry{
-				Addr:           entryTestAddr1,
-				LinkAddr:       entryTestLinkAddr1,
-				State:          Static,
-				UpdatedAtNanos: clock.NowNanoseconds(),
-			},
-		},
-	}
-	nudDisp.mu.Lock()
-	defer nudDisp.mu.Unlock()
-	if diff := cmp.Diff(wantUnorderedEvents, nudDisp.mu.events, unorderedEventsDiffOpts()...); diff != "" {
-		t.Errorf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-	}
-}
-
-// TestNeighborCacheClearThenOverflow verifies that the LRU cache eviction
-// strategy keeps count of the dynamic entry count when all entries are
-// cleared.
-func TestNeighborCacheClearThenOverflow(t *testing.T) {
-	config := DefaultNUDConfigurations()
-	// Stay in Reachable so the cache can overflow
-	config.BaseReachableTime = infiniteDuration
-	config.MinRandomFactor = 1
-	config.MaxRandomFactor = 1
-
-	c := newTestContext(config)
-
-	// Add a dynamic entry
-	entry, ok := c.linkRes.entries.entry(0)
-	if !ok {
-		t.Fatal("got c.linkRes.entries.entry(0) = _, false, want = true ")
-	}
-	if err := addReachableEntry(c.nudDisp, c.clock, c.linkRes, entry); err != nil {
-		t.Fatalf("addReachableEntry(...) = %s", err)
-	}
-
-	// Clear the cache.
-	c.linkRes.neigh.clear()
-
-	{
-		wantEvents := []testEntryEventInfo{
-			{
-				EventType: entryTestRemoved,
-				NICID:     1,
-				Entry: NeighborEntry{
-					Addr:           entry.Addr,
-					LinkAddr:       entry.LinkAddr,
-					State:          Reachable,
-					UpdatedAtNanos: c.clock.NowNanoseconds(),
-				},
-			},
-		}
-		c.nudDisp.mu.Lock()
-		diff := cmp.Diff(wantEvents, c.nudDisp.mu.events)
-		c.nudDisp.mu.events = nil
-		c.nudDisp.mu.Unlock()
-		if diff != "" {
-			t.Fatalf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-		}
-	}
-
-	opts := overflowOptions{
-		startAtEntryIndex: 0,
-	}
-	if err := c.overflowCache(opts); err != nil {
-		t.Errorf("c.overflowCache(%+v): %s", opts, err)
-	}
-}
-
-func TestNeighborCacheKeepFrequentlyUsed(t *testing.T) {
-	config := DefaultNUDConfigurations()
-	// Stay in Reachable so the cache can overflow
-	config.BaseReachableTime = infiniteDuration
-	config.MinRandomFactor = 1
-	config.MaxRandomFactor = 1
-
-	nudDisp := testNUDDispatcher{}
-	clock := faketime.NewManualClock()
-	linkRes := newTestNeighborResolver(&nudDisp, config, clock)
-
-	startedAt := clock.NowNanoseconds()
-
-	// The following logic is very similar to overflowCache, but
-	// periodically refreshes the frequently used entry.
-
-	// Fill the neighbor cache to capacity
-	for i := 0; i < neighborCacheSize; i++ {
-		entry, ok := linkRes.entries.entry(i)
-		if !ok {
-			t.Fatalf("got linkRes.entries.entry(%d) = _, false, want = true", i)
-		}
-		if err := addReachableEntry(&nudDisp, clock, linkRes, entry); err != nil {
-			t.Fatalf("addReachableEntry(...) = %s", err)
-		}
-	}
-
-	frequentlyUsedEntry, ok := linkRes.entries.entry(0)
-	if !ok {
-		t.Fatal("got linkRes.entries.entry(0) = _, false, want = true ")
-	}
-
-	// Keep adding more entries
-	for i := neighborCacheSize; i < linkRes.entries.size(); i++ {
-		// Periodically refresh the frequently used entry
-		if i%(neighborCacheSize/2) == 0 {
-			if _, _, err := linkRes.neigh.entry(frequentlyUsedEntry.Addr, "", nil); err != nil {
-				t.Errorf("unexpected error from linkRes.neigh.entry(%s, '', nil): %s", frequentlyUsedEntry.Addr, err)
-			}
-		}
-
-		entry, ok := linkRes.entries.entry(i)
-		if !ok {
-			t.Fatalf("got linkRes.entries.entry(%d) = _, false, want = true", i)
-		}
-
-		// An entry should have been removed, as per the LRU eviction strategy
-		removedEntry, ok := linkRes.entries.entry(i - neighborCacheSize + 1)
-		if !ok {
-			t.Fatalf("got linkRes.entries.entry(%d) = _, false, want = true", i-neighborCacheSize+1)
-		}
-
-		if err := addReachableEntryWithRemoved(&nudDisp, clock, linkRes, entry, []NeighborEntry{removedEntry}); err != nil {
-			t.Fatalf("addReachableEntryWithRemoved(...) = %s", err)
-		}
-	}
-
-	// Expect to find only the frequently used entry and the most recent entries.
-	// The order of entries reported by entries() is nondeterministic, so entries
-	// have to be sorted before comparison.
-	wantUnsortedEntries := []NeighborEntry{
-		{
-			Addr:     frequentlyUsedEntry.Addr,
-			LinkAddr: frequentlyUsedEntry.LinkAddr,
-			State:    Reachable,
-			// Can be inferred since the frequently used entry is the first to
-			// be created and transitioned to Reachable.
-			UpdatedAtNanos: startedAt + typicalLatency.Nanoseconds(),
-		},
-	}
-
-	for i := linkRes.entries.size() - neighborCacheSize + 1; i < linkRes.entries.size(); i++ {
-		entry, ok := linkRes.entries.entry(i)
-		if !ok {
-			t.Fatalf("got linkRes.entries.entry(%d) = _, false, want = true", i)
-		}
-		durationReachableNanos := int64(linkRes.entries.size()-i-1) * typicalLatency.Nanoseconds()
-		wantUnsortedEntries = append(wantUnsortedEntries, NeighborEntry{
-			Addr:           entry.Addr,
-			LinkAddr:       entry.LinkAddr,
-			State:          Reachable,
-			UpdatedAtNanos: clock.NowNanoseconds() - durationReachableNanos,
-		})
-	}
-
-	if diff := cmp.Diff(wantUnsortedEntries, linkRes.neigh.entries(), unorderedEntriesDiffOpts()...); diff != "" {
-		t.Errorf("neighbor entries mismatch (-want, +got):\n%s", diff)
-	}
-
-	// No more events should have been dispatched.
-	nudDisp.mu.Lock()
-	defer nudDisp.mu.Unlock()
-	if diff := cmp.Diff([]testEntryEventInfo(nil), nudDisp.mu.events); diff != "" {
-		t.Errorf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-	}
-}
-
-func TestNeighborCacheConcurrent(t *testing.T) {
-	const concurrentProcesses = 16
-
-	config := DefaultNUDConfigurations()
-
-	nudDisp := testNUDDispatcher{}
-	clock := faketime.NewManualClock()
-	linkRes := newTestNeighborResolver(&nudDisp, config, clock)
-
-	storeEntries := linkRes.entries.entries()
-	for _, entry := range storeEntries {
-		var wg sync.WaitGroup
-		for r := 0; r < concurrentProcesses; r++ {
-			wg.Add(1)
-			go func(entry NeighborEntry) {
-				defer wg.Done()
-				switch e, _, err := linkRes.neigh.entry(entry.Addr, "", nil); err.(type) {
-				case nil, *tcpip.ErrWouldBlock:
-				default:
-					t.Errorf("got linkRes.neigh.entry(%s, '', nil) = (%+v, _, %s), want (_, _, nil) or (_, _, %s)", entry.Addr, e, err, &tcpip.ErrWouldBlock{})
-				}
-			}(entry)
-		}
-
-		// Wait for all goroutines to send a request
-		wg.Wait()
-
-		// Process all the requests for a single entry concurrently
-		clock.Advance(typicalLatency)
-	}
-
-	// All goroutines add in the same order and add more values than can fit in
-	// the cache. Our eviction strategy requires that the last entries are
-	// present, up to the size of the neighbor cache, and the rest are missing.
-	// The order of entries reported by entries() is nondeterministic, so entries
-	// have to be sorted before comparison.
-	var wantUnsortedEntries []NeighborEntry
-	for i := linkRes.entries.size() - neighborCacheSize; i < linkRes.entries.size(); i++ {
-		entry, ok := linkRes.entries.entry(i)
-		if !ok {
-			t.Errorf("got linkRes.entries.entry(%d) = _, false, want = true", i)
-		}
-		durationReachableNanos := int64(linkRes.entries.size()-i-1) * typicalLatency.Nanoseconds()
-		wantUnsortedEntries = append(wantUnsortedEntries, NeighborEntry{
-			Addr:           entry.Addr,
-			LinkAddr:       entry.LinkAddr,
-			State:          Reachable,
-			UpdatedAtNanos: clock.NowNanoseconds() - durationReachableNanos,
-		})
-	}
-
-	if diff := cmp.Diff(wantUnsortedEntries, linkRes.neigh.entries(), unorderedEntriesDiffOpts()...); diff != "" {
-		t.Errorf("neighbor entries mismatch (-want, +got):\n%s", diff)
-	}
-}
-
-func TestNeighborCacheReplace(t *testing.T) {
-	config := DefaultNUDConfigurations()
-
-	nudDisp := testNUDDispatcher{}
-	clock := faketime.NewManualClock()
-	linkRes := newTestNeighborResolver(&nudDisp, config, clock)
-
-	entry, ok := linkRes.entries.entry(0)
-	if !ok {
-		t.Fatal("got linkRes.entries.entry(0) = _, false, want = true ")
-	}
-	if err := addReachableEntry(&nudDisp, clock, linkRes, entry); err != nil {
-		t.Fatalf("addReachableEntry(...) = %s", err)
-	}
-
-	// Notify of a link address change
-	var updatedLinkAddr tcpip.LinkAddress
-	{
-		entry, ok := linkRes.entries.entry(1)
-		if !ok {
-			t.Fatal("got linkRes.entries.entry(1) = _, false, want = true")
-		}
-		updatedLinkAddr = entry.LinkAddr
-	}
-	linkRes.entries.set(0, updatedLinkAddr)
-	linkRes.neigh.handleConfirmation(entry.Addr, updatedLinkAddr, ReachabilityConfirmationFlags{
-		Solicited: false,
-		Override:  true,
-		IsRouter:  false,
-	})
-
-	// Requesting the entry again should start neighbor reachability confirmation.
-	//
-	// Verify the entry's new link address and the new state.
-	{
-		e, _, err := linkRes.neigh.entry(entry.Addr, "", nil)
-		if err != nil {
-			t.Fatalf("linkRes.neigh.entry(%s, '', nil): %s", entry.Addr, err)
-		}
-		want := NeighborEntry{
-			Addr:           entry.Addr,
-			LinkAddr:       updatedLinkAddr,
-			State:          Delay,
-			UpdatedAtNanos: clock.NowNanoseconds(),
-		}
-		if diff := cmp.Diff(want, e); diff != "" {
-			t.Errorf("linkRes.neigh.entry(%s, '', nil) mismatch (-want, +got):\n%s", entry.Addr, diff)
-		}
-	}
-
-	clock.Advance(config.DelayFirstProbeTime + typicalLatency)
-
-	// Verify that the neighbor is now reachable.
-	{
-		e, _, err := linkRes.neigh.entry(entry.Addr, "", nil)
-		if err != nil {
-			t.Errorf("unexpected error from linkRes.neigh.entry(%s, '', nil): %s", entry.Addr, err)
-		}
-		want := NeighborEntry{
-			Addr:           entry.Addr,
-			LinkAddr:       updatedLinkAddr,
-			State:          Reachable,
-			UpdatedAtNanos: clock.NowNanoseconds(),
-		}
-		if diff := cmp.Diff(want, e); diff != "" {
-			t.Errorf("linkRes.neigh.entry(%s, '', nil) mismatch (-want, +got):\n%s", entry.Addr, diff)
-		}
-	}
-}
-
-func TestNeighborCacheResolutionFailed(t *testing.T) {
-	config := DefaultNUDConfigurations()
-
-	nudDisp := testNUDDispatcher{}
-	clock := faketime.NewManualClock()
-	linkRes := newTestNeighborResolver(&nudDisp, config, clock)
-
-	var requestCount uint32
-	linkRes.onLinkAddressRequest = func() {
-		atomic.AddUint32(&requestCount, 1)
-	}
-
-	entry, ok := linkRes.entries.entry(0)
-	if !ok {
-		t.Fatal("got linkRes.entries.entry(0) = _, false, want = true ")
-	}
-
-	// First, sanity check that resolution is working
-	if err := addReachableEntry(&nudDisp, clock, linkRes, entry); err != nil {
-		t.Fatalf("addReachableEntry(...) = %s", err)
-	}
-
-	got, _, err := linkRes.neigh.entry(entry.Addr, "", nil)
-	if err != nil {
-		t.Fatalf("unexpected error from linkRes.neigh.entry(%s, '', nil): %s", entry.Addr, err)
-	}
-	want := NeighborEntry{
-		Addr:           entry.Addr,
-		LinkAddr:       entry.LinkAddr,
-		State:          Reachable,
-		UpdatedAtNanos: clock.NowNanoseconds(),
-	}
-	if diff := cmp.Diff(want, got); diff != "" {
-		t.Errorf("linkRes.neigh.entry(%s, '', nil) mismatch (-want, +got):\n%s", entry.Addr, diff)
-	}
-
-	// Verify address resolution fails for an unknown address.
-	before := atomic.LoadUint32(&requestCount)
-
-	entry.Addr += "2"
-	{
-		_, ch, err := linkRes.neigh.entry(entry.Addr, "", func(r LinkResolutionResult) {
-			if diff := cmp.Diff(LinkResolutionResult{Err: &tcpip.ErrTimeout{}}, r); diff != "" {
-				t.Fatalf("got link resolution result mismatch (-want +got):\n%s", diff)
-			}
-		})
-		if _, ok := err.(*tcpip.ErrWouldBlock); !ok {
-			t.Fatalf("got linkRes.neigh.entry(%s, '', _) = %v, want = %s", entry.Addr, err, &tcpip.ErrWouldBlock{})
-		}
-		waitFor := config.DelayFirstProbeTime + typicalLatency*time.Duration(config.MaxMulticastProbes)
-		clock.Advance(waitFor)
-		select {
-		case <-ch:
-		default:
-			t.Fatalf("expected notification from done channel returned by linkRes.neigh.entry(%s, '', _)", entry.Addr)
-		}
-	}
-
-	maxAttempts := linkRes.neigh.config().MaxUnicastProbes
-	if got, want := atomic.LoadUint32(&requestCount)-before, maxAttempts; got != want {
-		t.Errorf("got link address request count = %d, want = %d", got, want)
-	}
-}
-
-// TestNeighborCacheResolutionTimeout simulates sending MaxMulticastProbes
-// probes and not retrieving a confirmation before the duration defined by
-// MaxMulticastProbes * RetransmitTimer.
-func TestNeighborCacheResolutionTimeout(t *testing.T) {
-	config := DefaultNUDConfigurations()
-	config.RetransmitTimer = time.Millisecond // small enough to cause timeout
-
-	clock := faketime.NewManualClock()
-	linkRes := newTestNeighborResolver(nil, config, clock)
-	// large enough to cause timeout
-	linkRes.delay = time.Minute
-
-	entry, ok := linkRes.entries.entry(0)
-	if !ok {
-		t.Fatal("got linkRes.entries.entry(0) = _, false, want = true ")
-	}
-
-	_, ch, err := linkRes.neigh.entry(entry.Addr, "", func(r LinkResolutionResult) {
-		if diff := cmp.Diff(LinkResolutionResult{Err: &tcpip.ErrTimeout{}}, r); diff != "" {
-			t.Fatalf("got link resolution result mismatch (-want +got):\n%s", diff)
-		}
-	})
-	if _, ok := err.(*tcpip.ErrWouldBlock); !ok {
-		t.Fatalf("got linkRes.neigh.entry(%s, '', _) = %v, want = %s", entry.Addr, err, &tcpip.ErrWouldBlock{})
-	}
-	waitFor := config.RetransmitTimer * time.Duration(config.MaxMulticastProbes)
-	clock.Advance(waitFor)
-
-	select {
-	case <-ch:
-	default:
-		t.Fatalf("expected notification from done channel returned by linkRes.neigh.entry(%s, '', _)", entry.Addr)
-	}
-}
-
-// TestNeighborCacheRetryResolution simulates retrying communication after
-// failing to perform address resolution.
-func TestNeighborCacheRetryResolution(t *testing.T) {
-	config := DefaultNUDConfigurations()
-	nudDisp := testNUDDispatcher{}
-	clock := faketime.NewManualClock()
-	linkRes := newTestNeighborResolver(&nudDisp, config, clock)
-	// Simulate a faulty link.
-	linkRes.dropReplies = true
-
-	entry, ok := linkRes.entries.entry(0)
-	if !ok {
-		t.Fatal("got linkRes.entries.entry(0) = _, false, want = true ")
-	}
-
-	// Perform address resolution with a faulty link, which will fail.
-	{
-		_, ch, err := linkRes.neigh.entry(entry.Addr, "", func(r LinkResolutionResult) {
-			if diff := cmp.Diff(LinkResolutionResult{Err: &tcpip.ErrTimeout{}}, r); diff != "" {
-				t.Fatalf("got link resolution result mismatch (-want +got):\n%s", diff)
-			}
-		})
-		if _, ok := err.(*tcpip.ErrWouldBlock); !ok {
-			t.Fatalf("got linkRes.neigh.entry(%s, '', _) = %v, want = %s", entry.Addr, err, &tcpip.ErrWouldBlock{})
-		}
-
-		{
-			wantEvents := []testEntryEventInfo{
-				{
-					EventType: entryTestAdded,
-					NICID:     1,
-					Entry: NeighborEntry{
-						Addr:           entry.Addr,
-						LinkAddr:       "",
-						State:          Incomplete,
-						UpdatedAtNanos: clock.NowNanoseconds(),
-					},
-				},
-			}
-			nudDisp.mu.Lock()
-			diff := cmp.Diff(wantEvents, nudDisp.mu.events)
-			nudDisp.mu.events = nil
-			nudDisp.mu.Unlock()
-			if diff != "" {
-				t.Fatalf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-			}
-		}
-
-		waitFor := config.RetransmitTimer * time.Duration(config.MaxMulticastProbes)
-		clock.Advance(waitFor)
-
-		select {
-		case <-ch:
-		default:
-			t.Fatalf("expected notification from done channel returned by linkRes.neigh.entry(%s, '', _)", entry.Addr)
-		}
-
-		{
-			wantEvents := []testEntryEventInfo{
-				{
-					EventType: entryTestChanged,
-					NICID:     1,
-					Entry: NeighborEntry{
-						Addr:           entry.Addr,
-						LinkAddr:       "",
-						State:          Unreachable,
-						UpdatedAtNanos: clock.NowNanoseconds(),
-					},
-				},
-			}
-			nudDisp.mu.Lock()
-			diff := cmp.Diff(wantEvents, nudDisp.mu.events)
-			nudDisp.mu.events = nil
-			nudDisp.mu.Unlock()
-			if diff != "" {
-				t.Fatalf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-			}
-		}
-
-		{
-			wantEntries := []NeighborEntry{
-				{
-					Addr:           entry.Addr,
-					LinkAddr:       "",
-					State:          Unreachable,
-					UpdatedAtNanos: clock.NowNanoseconds(),
-				},
-			}
-			if diff := cmp.Diff(linkRes.neigh.entries(), wantEntries, unorderedEntriesDiffOpts()...); diff != "" {
-				t.Fatalf("neighbor entries mismatch (-got, +want):\n%s", diff)
-			}
-		}
-	}
-
-	// Retry address resolution with a working link.
-	linkRes.dropReplies = false
-	{
-		incompleteEntry, ch, err := linkRes.neigh.entry(entry.Addr, "", func(r LinkResolutionResult) {
-			if diff := cmp.Diff(LinkResolutionResult{LinkAddress: entry.LinkAddr, Err: nil}, r); diff != "" {
-				t.Fatalf("got link resolution result mismatch (-want +got):\n%s", diff)
-			}
-		})
-		if _, ok := err.(*tcpip.ErrWouldBlock); !ok {
-			t.Fatalf("got linkRes.neigh.entry(%s, '', _) = %v, want = %s", entry.Addr, err, &tcpip.ErrWouldBlock{})
-		}
-		if incompleteEntry.State != Incomplete {
-			t.Fatalf("got entry.State = %s, want = %s", incompleteEntry.State, Incomplete)
-		}
-
-		{
-			wantEvents := []testEntryEventInfo{
-				{
-					EventType: entryTestChanged,
-					NICID:     1,
-					Entry: NeighborEntry{
-						Addr:           entry.Addr,
-						LinkAddr:       "",
-						State:          Incomplete,
-						UpdatedAtNanos: clock.NowNanoseconds(),
-					},
-				},
-			}
-			nudDisp.mu.Lock()
-			diff := cmp.Diff(wantEvents, nudDisp.mu.events)
-			nudDisp.mu.events = nil
-			nudDisp.mu.Unlock()
-			if diff != "" {
-				t.Fatalf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-			}
-		}
-
-		clock.Advance(typicalLatency)
-
-		select {
-		case <-ch:
-		default:
-			t.Fatalf("expected notification from done channel returned by linkRes.neigh.entry(%s, '', _)", entry.Addr)
-		}
-
-		{
-			wantEvents := []testEntryEventInfo{
-				{
-					EventType: entryTestChanged,
-					NICID:     1,
-					Entry: NeighborEntry{
-						Addr:           entry.Addr,
-						LinkAddr:       entry.LinkAddr,
-						State:          Reachable,
-						UpdatedAtNanos: clock.NowNanoseconds(),
-					},
-				},
-			}
-			nudDisp.mu.Lock()
-			diff := cmp.Diff(wantEvents, nudDisp.mu.events)
-			nudDisp.mu.events = nil
-			nudDisp.mu.Unlock()
-			if diff != "" {
-				t.Fatalf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-			}
-		}
-
-		{
-			gotEntry, _, err := linkRes.neigh.entry(entry.Addr, "", nil)
-			if err != nil {
-				t.Fatalf("linkRes.neigh.entry(%s, '', _): %s", entry.Addr, err)
-			}
-
-			wantEntry := NeighborEntry{
-				Addr:           entry.Addr,
-				LinkAddr:       entry.LinkAddr,
-				State:          Reachable,
-				UpdatedAtNanos: clock.NowNanoseconds(),
-			}
-			if diff := cmp.Diff(gotEntry, wantEntry); diff != "" {
-				t.Fatalf("neighbor entry mismatch (-got, +want):\n%s", diff)
-			}
-		}
-	}
-}
-
-func BenchmarkCacheClear(b *testing.B) {
-	b.StopTimer()
-	config := DefaultNUDConfigurations()
-	clock := &tcpip.StdClock{}
-	linkRes := newTestNeighborResolver(nil, config, clock)
-	linkRes.delay = 0
-
-	// Clear for every possible size of the cache
-	for cacheSize := 0; cacheSize < neighborCacheSize; cacheSize++ {
-		// Fill the neighbor cache to capacity.
-		for i := 0; i < cacheSize; i++ {
-			entry, ok := linkRes.entries.entry(i)
-			if !ok {
-				b.Fatalf("got linkRes.entries.entry(%d) = _, false, want = true", i)
-			}
-
-			_, ch, err := linkRes.neigh.entry(entry.Addr, "", func(r LinkResolutionResult) {
-				if diff := cmp.Diff(LinkResolutionResult{LinkAddress: entry.LinkAddr, Err: nil}, r); diff != "" {
-					b.Fatalf("got link resolution result mismatch (-want +got):\n%s", diff)
-				}
-			})
-			if _, ok := err.(*tcpip.ErrWouldBlock); !ok {
-				b.Fatalf("got linkRes.neigh.entry(%s, '', _) = %v, want = %s", entry.Addr, err, &tcpip.ErrWouldBlock{})
-			}
-
-			select {
-			case <-ch:
-			default:
-				b.Fatalf("expected notification from done channel returned by linkRes.neigh.entry(%s, '', _)", entry.Addr)
-			}
-		}
-
-		b.StartTimer()
-		linkRes.neigh.clear()
-		b.StopTimer()
-	}
-}
diff --git a/pkg/tcpip/stack/neighbor_entry_list.go b/pkg/tcpip/stack/neighbor_entry_list.go
new file mode 100644
index 0000000..d784300
--- /dev/null
+++ b/pkg/tcpip/stack/neighbor_entry_list.go
@@ -0,0 +1,221 @@
+package stack
+
+// ElementMapper provides an identity mapping by default.
+//
+// This can be replaced to provide a struct that maps elements to linker
+// objects, if they are not the same. An ElementMapper is not typically
+// required if: Linker is left as is, Element is left as is, or Linker and
+// Element are the same type.
+type neighborEntryElementMapper struct{}
+
+// linkerFor maps an Element to a Linker.
+//
+// This default implementation should be inlined.
+//
+//go:nosplit
+func (neighborEntryElementMapper) linkerFor(elem *neighborEntry) *neighborEntry { return elem }
+
+// List is an intrusive list. Entries can be added to or removed from the list
+// in O(1) time and with no additional memory allocations.
+//
+// The zero value for List is an empty list ready to use.
+//
+// To iterate over a list (where l is a List):
+//      for e := l.Front(); e != nil; e = e.Next() {
+// 		// do something with e.
+//      }
+//
+// +stateify savable
+type neighborEntryList struct {
+	head *neighborEntry
+	tail *neighborEntry
+}
+
+// Reset resets list l to the empty state.
+func (l *neighborEntryList) Reset() {
+	l.head = nil
+	l.tail = nil
+}
+
+// Empty returns true iff the list is empty.
+//
+//go:nosplit
+func (l *neighborEntryList) Empty() bool {
+	return l.head == nil
+}
+
+// Front returns the first element of list l or nil.
+//
+//go:nosplit
+func (l *neighborEntryList) Front() *neighborEntry {
+	return l.head
+}
+
+// Back returns the last element of list l or nil.
+//
+//go:nosplit
+func (l *neighborEntryList) Back() *neighborEntry {
+	return l.tail
+}
+
+// Len returns the number of elements in the list.
+//
+// NOTE: This is an O(n) operation.
+//
+//go:nosplit
+func (l *neighborEntryList) Len() (count int) {
+	for e := l.Front(); e != nil; e = (neighborEntryElementMapper{}.linkerFor(e)).Next() {
+		count++
+	}
+	return count
+}
+
+// PushFront inserts the element e at the front of list l.
+//
+//go:nosplit
+func (l *neighborEntryList) PushFront(e *neighborEntry) {
+	linker := neighborEntryElementMapper{}.linkerFor(e)
+	linker.SetNext(l.head)
+	linker.SetPrev(nil)
+	if l.head != nil {
+		neighborEntryElementMapper{}.linkerFor(l.head).SetPrev(e)
+	} else {
+		l.tail = e
+	}
+
+	l.head = e
+}
+
+// PushBack inserts the element e at the back of list l.
+//
+//go:nosplit
+func (l *neighborEntryList) PushBack(e *neighborEntry) {
+	linker := neighborEntryElementMapper{}.linkerFor(e)
+	linker.SetNext(nil)
+	linker.SetPrev(l.tail)
+	if l.tail != nil {
+		neighborEntryElementMapper{}.linkerFor(l.tail).SetNext(e)
+	} else {
+		l.head = e
+	}
+
+	l.tail = e
+}
+
+// PushBackList inserts list m at the end of list l, emptying m.
+//
+//go:nosplit
+func (l *neighborEntryList) PushBackList(m *neighborEntryList) {
+	if l.head == nil {
+		l.head = m.head
+		l.tail = m.tail
+	} else if m.head != nil {
+		neighborEntryElementMapper{}.linkerFor(l.tail).SetNext(m.head)
+		neighborEntryElementMapper{}.linkerFor(m.head).SetPrev(l.tail)
+
+		l.tail = m.tail
+	}
+	m.head = nil
+	m.tail = nil
+}
+
+// InsertAfter inserts e after b.
+//
+//go:nosplit
+func (l *neighborEntryList) InsertAfter(b, e *neighborEntry) {
+	bLinker := neighborEntryElementMapper{}.linkerFor(b)
+	eLinker := neighborEntryElementMapper{}.linkerFor(e)
+
+	a := bLinker.Next()
+
+	eLinker.SetNext(a)
+	eLinker.SetPrev(b)
+	bLinker.SetNext(e)
+
+	if a != nil {
+		neighborEntryElementMapper{}.linkerFor(a).SetPrev(e)
+	} else {
+		l.tail = e
+	}
+}
+
+// InsertBefore inserts e before a.
+//
+//go:nosplit
+func (l *neighborEntryList) InsertBefore(a, e *neighborEntry) {
+	aLinker := neighborEntryElementMapper{}.linkerFor(a)
+	eLinker := neighborEntryElementMapper{}.linkerFor(e)
+
+	b := aLinker.Prev()
+	eLinker.SetNext(a)
+	eLinker.SetPrev(b)
+	aLinker.SetPrev(e)
+
+	if b != nil {
+		neighborEntryElementMapper{}.linkerFor(b).SetNext(e)
+	} else {
+		l.head = e
+	}
+}
+
+// Remove removes e from l.
+//
+//go:nosplit
+func (l *neighborEntryList) Remove(e *neighborEntry) {
+	linker := neighborEntryElementMapper{}.linkerFor(e)
+	prev := linker.Prev()
+	next := linker.Next()
+
+	if prev != nil {
+		neighborEntryElementMapper{}.linkerFor(prev).SetNext(next)
+	} else if l.head == e {
+		l.head = next
+	}
+
+	if next != nil {
+		neighborEntryElementMapper{}.linkerFor(next).SetPrev(prev)
+	} else if l.tail == e {
+		l.tail = prev
+	}
+
+	linker.SetNext(nil)
+	linker.SetPrev(nil)
+}
+
+// Entry is a default implementation of Linker. Users can add anonymous fields
+// of this type to their structs to make them automatically implement the
+// methods needed by List.
+//
+// +stateify savable
+type neighborEntryEntry struct {
+	next *neighborEntry
+	prev *neighborEntry
+}
+
+// Next returns the entry that follows e in the list.
+//
+//go:nosplit
+func (e *neighborEntryEntry) Next() *neighborEntry {
+	return e.next
+}
+
+// Prev returns the entry that precedes e in the list.
+//
+//go:nosplit
+func (e *neighborEntryEntry) Prev() *neighborEntry {
+	return e.prev
+}
+
+// SetNext assigns 'entry' as the entry that follows e in the list.
+//
+//go:nosplit
+func (e *neighborEntryEntry) SetNext(elem *neighborEntry) {
+	e.next = elem
+}
+
+// SetPrev assigns 'entry' as the entry that precedes e in the list.
+//
+//go:nosplit
+func (e *neighborEntryEntry) SetPrev(elem *neighborEntry) {
+	e.prev = elem
+}
diff --git a/pkg/tcpip/stack/neighbor_entry_test.go b/pkg/tcpip/stack/neighbor_entry_test.go
deleted file mode 100644
index bb2b2d7..0000000
--- a/pkg/tcpip/stack/neighbor_entry_test.go
+++ /dev/null
@@ -1,2270 +0,0 @@
-// Copyright 2020 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
-
-import (
-	"fmt"
-	"math"
-	"math/rand"
-	"sync"
-	"testing"
-	"time"
-
-	"github.com/google/go-cmp/cmp"
-	"gvisor.dev/gvisor/pkg/tcpip"
-	"gvisor.dev/gvisor/pkg/tcpip/faketime"
-	"gvisor.dev/gvisor/pkg/tcpip/header"
-)
-
-const (
-	entryTestNetNumber tcpip.NetworkProtocolNumber = math.MaxUint32
-
-	entryTestNICID tcpip.NICID = 1
-	entryTestAddr1             = tcpip.Address("\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01")
-	entryTestAddr2             = tcpip.Address("\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02")
-
-	entryTestLinkAddr1 = tcpip.LinkAddress("\x0a\x00\x00\x00\x00\x01")
-	entryTestLinkAddr2 = tcpip.LinkAddress("\x0a\x00\x00\x00\x00\x02")
-
-	// entryTestNetDefaultMTU is the MTU, in bytes, used throughout the tests,
-	// except where another value is explicitly used. It is chosen to match the
-	// MTU of loopback interfaces on Linux systems.
-	entryTestNetDefaultMTU = 65536
-)
-
-// runImmediatelyScheduledJobs runs all jobs scheduled to run at the current
-// time.
-func runImmediatelyScheduledJobs(clock *faketime.ManualClock) {
-	clock.Advance(immediateDuration)
-}
-
-// The following unit tests exercise every state transition and verify its
-// behavior with RFC 4681 and RFC 7048.
-//
-// | From        | To          | Cause                                      | Update   | Action     | Event   |
-// | =========== | =========== | ========================================== | ======== | ===========| ======= |
-// | Unknown     | Unknown     | Confirmation w/ unknown address            |          |            | Added   |
-// | Unknown     | Incomplete  | Packet queued to unknown address           |          | Send probe | Added   |
-// | Unknown     | Stale       | Probe                                      |          |            | Added   |
-// | Incomplete  | Incomplete  | Retransmit timer expired                   |          | Send probe | Changed |
-// | Incomplete  | Reachable   | Solicited confirmation                     | LinkAddr | Notify     | Changed |
-// | Incomplete  | Stale       | Unsolicited confirmation                   | LinkAddr | Notify     | Changed |
-// | Incomplete  | Stale       | Probe                                      | LinkAddr | Notify     | Changed |
-// | Incomplete  | Unreachable | Max probes sent without reply              |          | Notify     | Changed |
-// | Reachable   | Reachable   | Confirmation w/ different isRouter flag    | IsRouter |            |         |
-// | Reachable   | Stale       | Reachable timer expired                    |          |            | Changed |
-// | Reachable   | Stale       | Probe or confirmation w/ different address |          |            | Changed |
-// | Stale       | Reachable   | Solicited override confirmation            | LinkAddr |            | Changed |
-// | Stale       | Reachable   | Solicited confirmation w/o address         |          | Notify     | Changed |
-// | Stale       | Stale       | Override confirmation                      | LinkAddr |            | Changed |
-// | Stale       | Stale       | Probe w/ different address                 | LinkAddr |            | Changed |
-// | Stale       | Delay       | Packet sent                                |          |            | Changed |
-// | Delay       | Reachable   | Upper-layer confirmation                   |          |            | Changed |
-// | Delay       | Reachable   | Solicited override confirmation            | LinkAddr |            | Changed |
-// | Delay       | Reachable   | Solicited confirmation w/o address         |          | Notify     | Changed |
-// | Delay       | Stale       | Probe or confirmation w/ different address |          |            | Changed |
-// | Delay       | Probe       | Delay timer expired                        |          | Send probe | Changed |
-// | Probe       | Reachable   | Solicited override confirmation            | LinkAddr |            | Changed |
-// | Probe       | Reachable   | Solicited confirmation w/ same address     |          | Notify     | Changed |
-// | Probe       | Reachable   | Solicited confirmation w/o address         |          | Notify     | Changed |
-// | Probe       | Stale       | Probe or confirmation w/ different address |          |            | Changed |
-// | Probe       | Probe       | Retransmit timer expired                   |          |            | Changed |
-// | Probe       | Unreachable | Max probes sent without reply              |          | Notify     | Changed |
-// | Unreachable | Incomplete  | Packet queued                              |          | Send probe | Changed |
-// | Unreachable | Stale       | Probe w/ different address                 | LinkAddr |            | Changed |
-
-type testEntryEventType uint8
-
-const (
-	entryTestAdded testEntryEventType = iota
-	entryTestChanged
-	entryTestRemoved
-)
-
-func (t testEntryEventType) String() string {
-	switch t {
-	case entryTestAdded:
-		return "add"
-	case entryTestChanged:
-		return "change"
-	case entryTestRemoved:
-		return "remove"
-	default:
-		return fmt.Sprintf("unknown (%d)", t)
-	}
-}
-
-// Fields are exported for use with cmp.Diff.
-type testEntryEventInfo struct {
-	EventType testEntryEventType
-	NICID     tcpip.NICID
-	Entry     NeighborEntry
-}
-
-func (e testEntryEventInfo) String() string {
-	return fmt.Sprintf("%s event for NIC #%d, %#v", e.EventType, e.NICID, e.Entry)
-}
-
-// testNUDDispatcher implements NUDDispatcher to validate the dispatching of
-// events upon certain NUD state machine events.
-type testNUDDispatcher struct {
-	mu struct {
-		sync.Mutex
-		events []testEntryEventInfo
-	}
-}
-
-var _ NUDDispatcher = (*testNUDDispatcher)(nil)
-
-func (d *testNUDDispatcher) queueEvent(e testEntryEventInfo) {
-	d.mu.Lock()
-	defer d.mu.Unlock()
-	d.mu.events = append(d.mu.events, e)
-}
-
-func (d *testNUDDispatcher) OnNeighborAdded(nicID tcpip.NICID, entry NeighborEntry) {
-	d.queueEvent(testEntryEventInfo{
-		EventType: entryTestAdded,
-		NICID:     nicID,
-		Entry:     entry,
-	})
-}
-
-func (d *testNUDDispatcher) OnNeighborChanged(nicID tcpip.NICID, entry NeighborEntry) {
-	d.queueEvent(testEntryEventInfo{
-		EventType: entryTestChanged,
-		NICID:     nicID,
-		Entry:     entry,
-	})
-}
-
-func (d *testNUDDispatcher) OnNeighborRemoved(nicID tcpip.NICID, entry NeighborEntry) {
-	d.queueEvent(testEntryEventInfo{
-		EventType: entryTestRemoved,
-		NICID:     nicID,
-		Entry:     entry,
-	})
-}
-
-type entryTestLinkResolver struct {
-	mu struct {
-		sync.Mutex
-		probes []entryTestProbeInfo
-	}
-}
-
-var _ LinkAddressResolver = (*entryTestLinkResolver)(nil)
-
-type entryTestProbeInfo struct {
-	RemoteAddress     tcpip.Address
-	RemoteLinkAddress tcpip.LinkAddress
-	LocalAddress      tcpip.Address
-}
-
-func (p entryTestProbeInfo) String() string {
-	return fmt.Sprintf("probe with RemoteAddress=%q, RemoteLinkAddress=%q, LocalAddress=%q", p.RemoteAddress, p.RemoteLinkAddress, p.LocalAddress)
-}
-
-// LinkAddressRequest sends a request for the LinkAddress of addr. Broadcasts
-// to the local network if linkAddr is the zero value.
-func (r *entryTestLinkResolver) LinkAddressRequest(targetAddr, localAddr tcpip.Address, linkAddr tcpip.LinkAddress) tcpip.Error {
-	r.mu.Lock()
-	defer r.mu.Unlock()
-	r.mu.probes = append(r.mu.probes, entryTestProbeInfo{
-		RemoteAddress:     targetAddr,
-		RemoteLinkAddress: linkAddr,
-		LocalAddress:      localAddr,
-	})
-	return nil
-}
-
-// ResolveStaticAddress attempts to resolve address without sending requests.
-// It either resolves the name immediately or returns the empty LinkAddress.
-func (r *entryTestLinkResolver) ResolveStaticAddress(addr tcpip.Address) (tcpip.LinkAddress, bool) {
-	return "", false
-}
-
-// LinkAddressProtocol returns the network protocol of the addresses this
-// resolver can resolve.
-func (r *entryTestLinkResolver) LinkAddressProtocol() tcpip.NetworkProtocolNumber {
-	return entryTestNetNumber
-}
-
-func entryTestSetup(c NUDConfigurations) (*neighborEntry, *testNUDDispatcher, *entryTestLinkResolver, *faketime.ManualClock) {
-	clock := faketime.NewManualClock()
-	disp := testNUDDispatcher{}
-	nic := nic{
-		LinkEndpoint: nil, // entryTestLinkResolver doesn't use a LinkEndpoint
-
-		id: entryTestNICID,
-		stack: &Stack{
-			clock:           clock,
-			nudDisp:         &disp,
-			nudConfigs:      c,
-			randomGenerator: rand.New(rand.NewSource(time.Now().UnixNano())),
-		},
-		stats: makeNICStats(),
-	}
-	netEP := (&testIPv6Protocol{}).NewEndpoint(&nic, nil)
-	nic.networkEndpoints = map[tcpip.NetworkProtocolNumber]NetworkEndpoint{
-		header.IPv6ProtocolNumber: netEP,
-	}
-
-	var linkRes entryTestLinkResolver
-	// Stub out the neighbor cache to verify deletion from the cache.
-	l := &linkResolver{
-		resolver: &linkRes,
-	}
-	l.neigh.init(&nic, &linkRes)
-
-	entry := newNeighborEntry(&l.neigh, entryTestAddr1 /* remoteAddr */, l.neigh.state)
-	l.neigh.mu.Lock()
-	l.neigh.mu.cache[entryTestAddr1] = entry
-	l.neigh.mu.Unlock()
-	nic.linkAddrResolvers = map[tcpip.NetworkProtocolNumber]*linkResolver{
-		header.IPv6ProtocolNumber: l,
-	}
-
-	return entry, &disp, &linkRes, clock
-}
-
-// TestEntryInitiallyUnknown verifies that the state of a newly created
-// neighborEntry is Unknown.
-func TestEntryInitiallyUnknown(t *testing.T) {
-	c := DefaultNUDConfigurations()
-	e, nudDisp, linkRes, clock := entryTestSetup(c)
-
-	e.mu.Lock()
-	if e.mu.neigh.State != Unknown {
-		t.Errorf("got e.mu.neigh.State = %q, want = %q", e.mu.neigh.State, Unknown)
-	}
-	e.mu.Unlock()
-
-	clock.Advance(c.RetransmitTimer)
-
-	// No probes should have been sent.
-	linkRes.mu.Lock()
-	diff := cmp.Diff([]entryTestProbeInfo(nil), linkRes.mu.probes)
-	linkRes.mu.Unlock()
-	if diff != "" {
-		t.Fatalf("link address resolver probes mismatch (-want, +got):\n%s", diff)
-	}
-
-	// No events should have been dispatched.
-	nudDisp.mu.Lock()
-	if diff := cmp.Diff([]testEntryEventInfo(nil), nudDisp.mu.events); diff != "" {
-		t.Errorf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-	}
-	nudDisp.mu.Unlock()
-}
-
-func TestEntryUnknownToUnknownWhenConfirmationWithUnknownAddress(t *testing.T) {
-	c := DefaultNUDConfigurations()
-	e, nudDisp, linkRes, clock := entryTestSetup(c)
-
-	e.mu.Lock()
-	e.handleConfirmationLocked(entryTestLinkAddr1, ReachabilityConfirmationFlags{
-		Solicited: false,
-		Override:  false,
-		IsRouter:  false,
-	})
-	if e.mu.neigh.State != Unknown {
-		t.Errorf("got e.mu.neigh.State = %q, want = %q", e.mu.neigh.State, Unknown)
-	}
-	e.mu.Unlock()
-
-	clock.Advance(time.Hour)
-
-	// No probes should have been sent.
-	linkRes.mu.Lock()
-	diff := cmp.Diff([]entryTestProbeInfo(nil), linkRes.mu.probes)
-	linkRes.mu.Unlock()
-	if diff != "" {
-		t.Fatalf("link address resolver probes mismatch (-want, +got):\n%s", diff)
-	}
-
-	// No events should have been dispatched.
-	nudDisp.mu.Lock()
-	if diff := cmp.Diff([]testEntryEventInfo(nil), nudDisp.mu.events); diff != "" {
-		t.Errorf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-	}
-	nudDisp.mu.Unlock()
-}
-
-func TestEntryUnknownToIncomplete(t *testing.T) {
-	c := DefaultNUDConfigurations()
-	e, nudDisp, linkRes, clock := entryTestSetup(c)
-
-	if err := unknownToIncomplete(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("unknownToIncomplete(...) = %s", err)
-	}
-}
-
-func unknownToIncomplete(e *neighborEntry, nudDisp *testNUDDispatcher, linkRes *entryTestLinkResolver, clock *faketime.ManualClock) error {
-	if err := func() error {
-		e.mu.Lock()
-		defer e.mu.Unlock()
-
-		if e.mu.neigh.State != Unknown {
-			return fmt.Errorf("got e.mu.neigh.State = %q, want = %q", e.mu.neigh.State, Unknown)
-		}
-		e.handlePacketQueuedLocked(entryTestAddr2)
-		if e.mu.neigh.State != Incomplete {
-			return fmt.Errorf("got e.mu.neigh.State = %q, want = %q", e.mu.neigh.State, Incomplete)
-		}
-		return nil
-	}(); err != nil {
-		return err
-	}
-
-	runImmediatelyScheduledJobs(clock)
-	wantProbes := []entryTestProbeInfo{
-		{
-			RemoteAddress:     entryTestAddr1,
-			RemoteLinkAddress: tcpip.LinkAddress(""),
-			LocalAddress:      entryTestAddr2,
-		},
-	}
-	linkRes.mu.Lock()
-	diff := cmp.Diff(wantProbes, linkRes.mu.probes)
-	linkRes.mu.probes = nil
-	linkRes.mu.Unlock()
-	if diff != "" {
-		return fmt.Errorf("link address resolver probes mismatch (-want, +got):\n%s", diff)
-	}
-
-	wantEvents := []testEntryEventInfo{
-		{
-			EventType: entryTestAdded,
-			NICID:     entryTestNICID,
-			Entry: NeighborEntry{
-				Addr:           entryTestAddr1,
-				LinkAddr:       tcpip.LinkAddress(""),
-				State:          Incomplete,
-				UpdatedAtNanos: clock.NowNanoseconds(),
-			},
-		},
-	}
-	{
-		nudDisp.mu.Lock()
-		diff := cmp.Diff(wantEvents, nudDisp.mu.events)
-		nudDisp.mu.events = nil
-		nudDisp.mu.Unlock()
-		if diff != "" {
-			return fmt.Errorf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-		}
-	}
-	return nil
-}
-
-func TestEntryUnknownToStale(t *testing.T) {
-	c := DefaultNUDConfigurations()
-	e, nudDisp, linkRes, clock := entryTestSetup(c)
-
-	if err := unknownToStale(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("unknownToStale(...) = %s", err)
-	}
-}
-
-func unknownToStale(e *neighborEntry, nudDisp *testNUDDispatcher, linkRes *entryTestLinkResolver, clock *faketime.ManualClock) error {
-	if err := func() error {
-		e.mu.Lock()
-		defer e.mu.Unlock()
-
-		if e.mu.neigh.State != Unknown {
-			return fmt.Errorf("got e.mu.neigh.State = %q, want = %q", e.mu.neigh.State, Unknown)
-		}
-		e.handleProbeLocked(entryTestLinkAddr1)
-		if e.mu.neigh.State != Stale {
-			return fmt.Errorf("got e.mu.neigh.State = %q, want = %q", e.mu.neigh.State, Stale)
-		}
-		return nil
-	}(); err != nil {
-		return err
-	}
-
-	// No probes should have been sent.
-	runImmediatelyScheduledJobs(clock)
-	{
-		linkRes.mu.Lock()
-		diff := cmp.Diff([]entryTestProbeInfo(nil), linkRes.mu.probes)
-		linkRes.mu.Unlock()
-		if diff != "" {
-			return fmt.Errorf("link address resolver probes mismatch (-want, +got):\n%s", diff)
-		}
-	}
-
-	wantEvents := []testEntryEventInfo{
-		{
-			EventType: entryTestAdded,
-			NICID:     entryTestNICID,
-			Entry: NeighborEntry{
-				Addr:           entryTestAddr1,
-				LinkAddr:       entryTestLinkAddr1,
-				State:          Stale,
-				UpdatedAtNanos: clock.NowNanoseconds(),
-			},
-		},
-	}
-	{
-		nudDisp.mu.Lock()
-		diff := cmp.Diff(wantEvents, nudDisp.mu.events)
-		nudDisp.mu.events = nil
-		nudDisp.mu.Unlock()
-		if diff != "" {
-			return fmt.Errorf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-		}
-	}
-
-	return nil
-}
-
-func TestEntryIncompleteToIncompleteDoesNotChangeUpdatedAt(t *testing.T) {
-	c := DefaultNUDConfigurations()
-	c.MaxMulticastProbes = 3
-	e, nudDisp, linkRes, clock := entryTestSetup(c)
-
-	if err := unknownToIncomplete(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("unknownToIncomplete(...) = %s", err)
-	}
-
-	// UpdatedAt should remain the same during address resolution.
-	e.mu.Lock()
-	startedAt := e.mu.neigh.UpdatedAtNanos
-	e.mu.Unlock()
-
-	// Wait for the rest of the reachability probe transmissions, signifying
-	// Incomplete to Incomplete transitions.
-	for i := uint32(1); i < c.MaxMulticastProbes; i++ {
-		clock.Advance(c.RetransmitTimer)
-
-		wantProbes := []entryTestProbeInfo{
-			{
-				RemoteAddress:     entryTestAddr1,
-				RemoteLinkAddress: tcpip.LinkAddress(""),
-				LocalAddress:      entryTestAddr2,
-			},
-		}
-		linkRes.mu.Lock()
-		diff := cmp.Diff(wantProbes, linkRes.mu.probes)
-		linkRes.mu.probes = nil
-		linkRes.mu.Unlock()
-		if diff != "" {
-			t.Fatalf("link address resolver probes mismatch (-want, +got):\n%s", diff)
-		}
-
-		e.mu.Lock()
-		if got, want := e.mu.neigh.UpdatedAtNanos, startedAt; got != want {
-			t.Errorf("got e.mu.neigh.UpdatedAt = %q, want = %q", got, want)
-		}
-		e.mu.Unlock()
-	}
-
-	// UpdatedAt should change after failing address resolution. Timing out after
-	// sending the last probe transitions the entry to Unreachable.
-	clock.Advance(c.RetransmitTimer)
-
-	wantEvents := []testEntryEventInfo{
-		{
-			EventType: entryTestChanged,
-			NICID:     entryTestNICID,
-			Entry: NeighborEntry{
-				Addr:           entryTestAddr1,
-				LinkAddr:       tcpip.LinkAddress(""),
-				State:          Unreachable,
-				UpdatedAtNanos: clock.NowNanoseconds(),
-			},
-		},
-	}
-	nudDisp.mu.Lock()
-	if diff := cmp.Diff(wantEvents, nudDisp.mu.events); diff != "" {
-		t.Errorf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-	}
-	nudDisp.mu.Unlock()
-}
-
-func TestEntryIncompleteToReachable(t *testing.T) {
-	c := DefaultNUDConfigurations()
-	e, nudDisp, linkRes, clock := entryTestSetup(c)
-
-	if err := unknownToIncomplete(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("unknownToIncomplete(...) = %s", err)
-	}
-	if err := incompleteToReachable(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("incompleteToReachable(...) = %s", err)
-	}
-}
-
-func incompleteToReachableWithFlags(e *neighborEntry, nudDisp *testNUDDispatcher, linkRes *entryTestLinkResolver, clock *faketime.ManualClock, flags ReachabilityConfirmationFlags) error {
-	if err := func() error {
-		e.mu.Lock()
-		defer e.mu.Unlock()
-
-		if e.mu.neigh.State != Incomplete {
-			return fmt.Errorf("got e.mu.neigh.State = %q, want = %q", e.mu.neigh.State, Incomplete)
-		}
-		e.handleConfirmationLocked(entryTestLinkAddr1, flags)
-		if e.mu.neigh.State != Reachable {
-			return fmt.Errorf("got e.mu.neigh.State = %q, want = %q", e.mu.neigh.State, Reachable)
-		}
-		if e.mu.neigh.LinkAddr != entryTestLinkAddr1 {
-			return fmt.Errorf("got e.mu.neigh.LinkAddr = %q, want = %q", e.mu.neigh.LinkAddr, entryTestLinkAddr1)
-		}
-		return nil
-	}(); err != nil {
-		return err
-	}
-
-	// No probes should have been sent.
-	runImmediatelyScheduledJobs(clock)
-	{
-		linkRes.mu.Lock()
-		diff := cmp.Diff([]entryTestProbeInfo(nil), linkRes.mu.probes)
-		linkRes.mu.Unlock()
-		if diff != "" {
-			return fmt.Errorf("link address resolver probes mismatch (-want, +got):\n%s", diff)
-		}
-	}
-
-	wantEvents := []testEntryEventInfo{
-		{
-			EventType: entryTestChanged,
-			NICID:     entryTestNICID,
-			Entry: NeighborEntry{
-				Addr:           entryTestAddr1,
-				LinkAddr:       entryTestLinkAddr1,
-				State:          Reachable,
-				UpdatedAtNanos: clock.NowNanoseconds(),
-			},
-		},
-	}
-	{
-		nudDisp.mu.Lock()
-		diff := cmp.Diff(wantEvents, nudDisp.mu.events)
-		nudDisp.mu.events = nil
-		nudDisp.mu.Unlock()
-		if diff != "" {
-			return fmt.Errorf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-		}
-	}
-
-	return nil
-}
-
-func incompleteToReachable(e *neighborEntry, nudDisp *testNUDDispatcher, linkRes *entryTestLinkResolver, clock *faketime.ManualClock) error {
-	if err := incompleteToReachableWithFlags(e, nudDisp, linkRes, clock, ReachabilityConfirmationFlags{
-		Solicited: true,
-		Override:  false,
-		IsRouter:  false,
-	}); err != nil {
-		return err
-	}
-
-	e.mu.Lock()
-	isRouter := e.mu.isRouter
-	e.mu.Unlock()
-	if isRouter {
-		return fmt.Errorf("got e.mu.isRouter = %t, want = false", isRouter)
-	}
-
-	return nil
-}
-
-func TestEntryIncompleteToReachableWithRouterFlag(t *testing.T) {
-	c := DefaultNUDConfigurations()
-	e, nudDisp, linkRes, clock := entryTestSetup(c)
-
-	if err := unknownToIncomplete(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("unknownToIncomplete(...) = %s", err)
-	}
-	if err := incompleteToReachableWithRouterFlag(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("incompleteToReachableWithRouterFlag(...) = %s", err)
-	}
-}
-
-func incompleteToReachableWithRouterFlag(e *neighborEntry, nudDisp *testNUDDispatcher, linkRes *entryTestLinkResolver, clock *faketime.ManualClock) error {
-	if err := incompleteToReachableWithFlags(e, nudDisp, linkRes, clock, ReachabilityConfirmationFlags{
-		Solicited: true,
-		Override:  false,
-		IsRouter:  true,
-	}); err != nil {
-		return err
-	}
-
-	e.mu.Lock()
-	isRouter := e.mu.isRouter
-	e.mu.Unlock()
-	if !isRouter {
-		return fmt.Errorf("got e.mu.isRouter = %t, want = true", isRouter)
-	}
-
-	return nil
-}
-
-func TestEntryIncompleteToStaleWhenUnsolicitedConfirmation(t *testing.T) {
-	c := DefaultNUDConfigurations()
-	e, nudDisp, linkRes, clock := entryTestSetup(c)
-
-	if err := unknownToIncomplete(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("unknownToIncomplete(...) = %s", err)
-	}
-
-	e.mu.Lock()
-	e.handleConfirmationLocked(entryTestLinkAddr1, ReachabilityConfirmationFlags{
-		Solicited: false,
-		Override:  false,
-		IsRouter:  false,
-	})
-	if e.mu.neigh.State != Stale {
-		t.Errorf("got e.mu.neigh.State = %q, want = %q", e.mu.neigh.State, Stale)
-	}
-	if e.mu.isRouter {
-		t.Errorf("got e.mu.isRouter = %t, want = false", e.mu.isRouter)
-	}
-	e.mu.Unlock()
-
-	wantEvents := []testEntryEventInfo{
-		{
-			EventType: entryTestChanged,
-			NICID:     entryTestNICID,
-			Entry: NeighborEntry{
-				Addr:           entryTestAddr1,
-				LinkAddr:       entryTestLinkAddr1,
-				State:          Stale,
-				UpdatedAtNanos: clock.NowNanoseconds(),
-			},
-		},
-	}
-	nudDisp.mu.Lock()
-	if diff := cmp.Diff(wantEvents, nudDisp.mu.events); diff != "" {
-		t.Errorf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-	}
-	nudDisp.mu.Unlock()
-}
-
-func TestEntryIncompleteToStaleWhenProbe(t *testing.T) {
-	c := DefaultNUDConfigurations()
-	e, nudDisp, linkRes, clock := entryTestSetup(c)
-
-	if err := unknownToIncomplete(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("unknownToIncomplete(...) = %s", err)
-	}
-
-	e.mu.Lock()
-	e.handleProbeLocked(entryTestLinkAddr1)
-	if e.mu.neigh.State != Stale {
-		t.Errorf("got e.mu.neigh.State = %q, want = %q", e.mu.neigh.State, Stale)
-	}
-	e.mu.Unlock()
-
-	wantEvents := []testEntryEventInfo{
-		{
-			EventType: entryTestChanged,
-			NICID:     entryTestNICID,
-			Entry: NeighborEntry{
-				Addr:           entryTestAddr1,
-				LinkAddr:       entryTestLinkAddr1,
-				State:          Stale,
-				UpdatedAtNanos: clock.NowNanoseconds(),
-			},
-		},
-	}
-	nudDisp.mu.Lock()
-	if diff := cmp.Diff(wantEvents, nudDisp.mu.events); diff != "" {
-		t.Errorf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-	}
-	nudDisp.mu.Unlock()
-}
-
-func TestEntryIncompleteToUnreachable(t *testing.T) {
-	c := DefaultNUDConfigurations()
-	c.MaxMulticastProbes = 3
-	e, nudDisp, linkRes, clock := entryTestSetup(c)
-
-	if err := unknownToIncomplete(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("unknownToIncomplete(...) = %s", err)
-	}
-	if err := incompleteToUnreachable(c, e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("incompleteToUnreachable(...) = %s", err)
-	}
-}
-
-func incompleteToUnreachable(c NUDConfigurations, e *neighborEntry, nudDisp *testNUDDispatcher, linkRes *entryTestLinkResolver, clock *faketime.ManualClock) error {
-	{
-		e.mu.Lock()
-		state := e.mu.neigh.State
-		e.mu.Unlock()
-		if state != Incomplete {
-			return fmt.Errorf("got e.mu.neigh.State = %q, want = %q", state, Incomplete)
-		}
-	}
-
-	// The first probe was sent in the transition from Unknown to Incomplete.
-	clock.Advance(c.RetransmitTimer)
-
-	// Observe each subsequent multicast probe transmitted.
-	for i := uint32(1); i < c.MaxMulticastProbes; i++ {
-		wantProbes := []entryTestProbeInfo{{
-			RemoteAddress:     entryTestAddr1,
-			RemoteLinkAddress: "",
-			LocalAddress:      entryTestAddr2,
-		}}
-		linkRes.mu.Lock()
-		diff := cmp.Diff(wantProbes, linkRes.mu.probes)
-		linkRes.mu.probes = nil
-		linkRes.mu.Unlock()
-		if diff != "" {
-			return fmt.Errorf("link address resolver probe #%d mismatch (-want, +got):\n%s", i+1, diff)
-		}
-
-		e.mu.Lock()
-		state := e.mu.neigh.State
-		e.mu.Unlock()
-		if state != Incomplete {
-			return fmt.Errorf("got e.mu.neigh.State = %q, want = %q", state, Incomplete)
-		}
-
-		clock.Advance(c.RetransmitTimer)
-	}
-
-	{
-		e.mu.Lock()
-		state := e.mu.neigh.State
-		e.mu.Unlock()
-		if state != Unreachable {
-			return fmt.Errorf("got e.mu.neigh.State = %q, want = %q", state, Unreachable)
-		}
-	}
-
-	wantEvents := []testEntryEventInfo{
-		{
-			EventType: entryTestChanged,
-			NICID:     entryTestNICID,
-			Entry: NeighborEntry{
-				Addr:           entryTestAddr1,
-				LinkAddr:       tcpip.LinkAddress(""),
-				State:          Unreachable,
-				UpdatedAtNanos: clock.NowNanoseconds(),
-			},
-		},
-	}
-	nudDisp.mu.Lock()
-	diff := cmp.Diff(wantEvents, nudDisp.mu.events)
-	nudDisp.mu.events = nil
-	nudDisp.mu.Unlock()
-	if diff != "" {
-		return fmt.Errorf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-	}
-
-	return nil
-}
-
-type testLocker struct{}
-
-var _ sync.Locker = (*testLocker)(nil)
-
-func (*testLocker) Lock()   {}
-func (*testLocker) Unlock() {}
-
-func TestEntryReachableToReachableClearsRouterWhenConfirmationWithoutRouter(t *testing.T) {
-	c := DefaultNUDConfigurations()
-	e, nudDisp, linkRes, clock := entryTestSetup(c)
-
-	if err := unknownToIncomplete(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("unknownToIncomplete(...) = %s", err)
-	}
-	if err := incompleteToReachableWithRouterFlag(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("incompleteToReachableWithRouterFlag(...) = %s", err)
-	}
-
-	e.mu.Lock()
-	e.handleConfirmationLocked(entryTestLinkAddr1, ReachabilityConfirmationFlags{
-		Solicited: false,
-		Override:  false,
-		IsRouter:  false,
-	})
-	if e.mu.neigh.State != Reachable {
-		t.Errorf("got e.mu.neigh.State = %q, want = %q", e.mu.neigh.State, Reachable)
-	}
-	if got, want := e.mu.isRouter, false; got != want {
-		t.Errorf("got e.mu.isRouter = %t, want = %t", got, want)
-	}
-	ipv6EP := e.cache.nic.networkEndpoints[header.IPv6ProtocolNumber].(*testIPv6Endpoint)
-	if ipv6EP.invalidatedRtr != e.mu.neigh.Addr {
-		t.Errorf("got ipv6EP.invalidatedRtr = %s, want = %s", ipv6EP.invalidatedRtr, e.mu.neigh.Addr)
-	}
-	e.mu.Unlock()
-
-	// No probes should have been sent.
-	runImmediatelyScheduledJobs(clock)
-	{
-		linkRes.mu.Lock()
-		diff := cmp.Diff([]entryTestProbeInfo(nil), linkRes.mu.probes)
-		linkRes.mu.Unlock()
-		if diff != "" {
-			t.Errorf("link address resolver probes mismatch (-want, +got):\n%s", diff)
-		}
-	}
-
-	// No events should have been dispatched.
-	nudDisp.mu.Lock()
-	diff := cmp.Diff([]testEntryEventInfo(nil), nudDisp.mu.events)
-	nudDisp.mu.Unlock()
-	if diff != "" {
-		t.Errorf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-	}
-}
-
-func TestEntryReachableToReachableWhenProbeWithSameAddress(t *testing.T) {
-	c := DefaultNUDConfigurations()
-	e, nudDisp, linkRes, clock := entryTestSetup(c)
-
-	if err := unknownToIncomplete(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("unknownToIncomplete(...) = %s", err)
-	}
-	if err := incompleteToReachable(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("incompleteToReachable(...) = %s", err)
-	}
-
-	e.mu.Lock()
-	e.handleProbeLocked(entryTestLinkAddr1)
-	if e.mu.neigh.State != Reachable {
-		t.Errorf("got e.mu.neigh.State = %q, want = %q", e.mu.neigh.State, Reachable)
-	}
-	if e.mu.neigh.LinkAddr != entryTestLinkAddr1 {
-		t.Errorf("got e.mu.neigh.LinkAddr = %q, want = %q", e.mu.neigh.LinkAddr, entryTestLinkAddr1)
-	}
-	e.mu.Unlock()
-
-	// No probes should have been sent.
-	runImmediatelyScheduledJobs(clock)
-	{
-		linkRes.mu.Lock()
-		diff := cmp.Diff([]entryTestProbeInfo(nil), linkRes.mu.probes)
-		linkRes.mu.Unlock()
-		if diff != "" {
-			t.Errorf("link address resolver probes mismatch (-want, +got):\n%s", diff)
-		}
-	}
-
-	// No events should have been dispatched.
-	nudDisp.mu.Lock()
-	diff := cmp.Diff([]testEntryEventInfo(nil), nudDisp.mu.events)
-	nudDisp.mu.Unlock()
-	if diff != "" {
-		t.Errorf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-	}
-}
-
-func TestEntryReachableToStaleWhenTimeout(t *testing.T) {
-	c := DefaultNUDConfigurations()
-	// Eliminate random factors from ReachableTime computation so the transition
-	// from Stale to Reachable will only take BaseReachableTime duration.
-	c.MinRandomFactor = 1
-	c.MaxRandomFactor = 1
-
-	e, nudDisp, linkRes, clock := entryTestSetup(c)
-
-	if err := unknownToIncomplete(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("unknownToIncomplete(...) = %s", err)
-	}
-	if err := incompleteToReachable(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("incompleteToReachable(...) = %s", err)
-	}
-	if err := reachableToStale(c, e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("reachableToStale(...) = %s", err)
-	}
-}
-
-// reachableToStale transitions a neighborEntry in Reachable state to Stale
-// state. Depends on the elimination of random factors in the ReachableTime
-// computation.
-//
-//	c.MinRandomFactor = 1
-//	c.MaxRandomFactor = 1
-func reachableToStale(c NUDConfigurations, e *neighborEntry, nudDisp *testNUDDispatcher, linkRes *entryTestLinkResolver, clock *faketime.ManualClock) error {
-	// Ensure there are no random factors in the ReachableTime computation.
-	if c.MinRandomFactor != 1 {
-		return fmt.Errorf("got c.MinRandomFactor = %f, want = 1", c.MinRandomFactor)
-	}
-	if c.MaxRandomFactor != 1 {
-		return fmt.Errorf("got c.MaxRandomFactor = %f, want = 1", c.MaxRandomFactor)
-	}
-
-	{
-		e.mu.Lock()
-		state := e.mu.neigh.State
-		e.mu.Unlock()
-		if state != Reachable {
-			return fmt.Errorf("got e.mu.neigh.State = %q, want = %q", state, Reachable)
-		}
-	}
-
-	clock.Advance(c.BaseReachableTime)
-
-	{
-		e.mu.Lock()
-		state := e.mu.neigh.State
-		e.mu.Unlock()
-		if state != Stale {
-			return fmt.Errorf("got e.mu.neigh.State = %q, want = %q", state, Stale)
-		}
-	}
-
-	// No probes should have been sent.
-	runImmediatelyScheduledJobs(clock)
-	{
-		linkRes.mu.Lock()
-		diff := cmp.Diff([]entryTestProbeInfo(nil), linkRes.mu.probes)
-		linkRes.mu.Unlock()
-		if diff != "" {
-			return fmt.Errorf("link address resolver probes mismatch (-want, +got):\n%s", diff)
-		}
-	}
-
-	wantEvents := []testEntryEventInfo{
-		{
-			EventType: entryTestChanged,
-			NICID:     entryTestNICID,
-			Entry: NeighborEntry{
-				Addr:           entryTestAddr1,
-				LinkAddr:       entryTestLinkAddr1,
-				State:          Stale,
-				UpdatedAtNanos: clock.NowNanoseconds(),
-			},
-		},
-	}
-	{
-
-		nudDisp.mu.Lock()
-		diff := cmp.Diff(wantEvents, nudDisp.mu.events)
-		nudDisp.mu.events = nil
-		nudDisp.mu.Unlock()
-		if diff != "" {
-			return fmt.Errorf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-		}
-	}
-
-	return nil
-}
-
-func TestEntryReachableToStaleWhenProbeWithDifferentAddress(t *testing.T) {
-	c := DefaultNUDConfigurations()
-	e, nudDisp, linkRes, clock := entryTestSetup(c)
-
-	if err := unknownToIncomplete(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("unknownToIncomplete(...) = %s", err)
-	}
-	if err := incompleteToReachable(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("incompleteToReachable(...) = %s", err)
-	}
-
-	e.mu.Lock()
-	e.handleProbeLocked(entryTestLinkAddr2)
-	if e.mu.neigh.State != Stale {
-		t.Errorf("got e.mu.neigh.State = %q, want = %q", e.mu.neigh.State, Stale)
-	}
-	e.mu.Unlock()
-
-	// No probes should have been sent.
-	runImmediatelyScheduledJobs(clock)
-	{
-		linkRes.mu.Lock()
-		diff := cmp.Diff([]entryTestProbeInfo(nil), linkRes.mu.probes)
-		linkRes.mu.Unlock()
-		if diff != "" {
-			t.Errorf("link address resolver probes mismatch (-want, +got):\n%s", diff)
-		}
-	}
-
-	wantEvents := []testEntryEventInfo{
-		{
-			EventType: entryTestChanged,
-			NICID:     entryTestNICID,
-			Entry: NeighborEntry{
-				Addr:           entryTestAddr1,
-				LinkAddr:       entryTestLinkAddr2,
-				State:          Stale,
-				UpdatedAtNanos: clock.NowNanoseconds(),
-			},
-		},
-	}
-	nudDisp.mu.Lock()
-	if diff := cmp.Diff(wantEvents, nudDisp.mu.events); diff != "" {
-		t.Errorf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-	}
-	nudDisp.mu.Unlock()
-}
-
-func TestEntryReachableToStaleWhenConfirmationWithDifferentAddress(t *testing.T) {
-	c := DefaultNUDConfigurations()
-	e, nudDisp, linkRes, clock := entryTestSetup(c)
-
-	if err := unknownToIncomplete(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("unknownToIncomplete(...) = %s", err)
-	}
-	if err := incompleteToReachable(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("incompleteToReachable(...) = %s", err)
-	}
-
-	e.mu.Lock()
-	e.handleConfirmationLocked(entryTestLinkAddr2, ReachabilityConfirmationFlags{
-		Solicited: false,
-		Override:  false,
-		IsRouter:  false,
-	})
-	if e.mu.neigh.State != Stale {
-		t.Errorf("got e.mu.neigh.State = %q, want = %q", e.mu.neigh.State, Stale)
-	}
-	e.mu.Unlock()
-
-	// No probes should have been sent.
-	runImmediatelyScheduledJobs(clock)
-	{
-		linkRes.mu.Lock()
-		diff := cmp.Diff([]entryTestProbeInfo(nil), linkRes.mu.probes)
-		linkRes.mu.Unlock()
-		if diff != "" {
-			t.Errorf("link address resolver probes mismatch (-want, +got):\n%s", diff)
-		}
-	}
-
-	wantEvents := []testEntryEventInfo{
-		{
-			EventType: entryTestChanged,
-			NICID:     entryTestNICID,
-			Entry: NeighborEntry{
-				Addr:           entryTestAddr1,
-				LinkAddr:       entryTestLinkAddr1,
-				State:          Stale,
-				UpdatedAtNanos: clock.NowNanoseconds(),
-			},
-		},
-	}
-	nudDisp.mu.Lock()
-	if diff := cmp.Diff(wantEvents, nudDisp.mu.events); diff != "" {
-		t.Errorf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-	}
-	nudDisp.mu.Unlock()
-}
-
-func TestEntryReachableToStaleWhenConfirmationWithDifferentAddressAndOverride(t *testing.T) {
-	c := DefaultNUDConfigurations()
-	e, nudDisp, linkRes, clock := entryTestSetup(c)
-
-	if err := unknownToIncomplete(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("unknownToIncomplete(...) = %s", err)
-	}
-	if err := incompleteToReachable(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("incompleteToReachable(...) = %s", err)
-	}
-
-	e.mu.Lock()
-	e.handleConfirmationLocked(entryTestLinkAddr2, ReachabilityConfirmationFlags{
-		Solicited: false,
-		Override:  true,
-		IsRouter:  false,
-	})
-	if e.mu.neigh.State != Stale {
-		t.Errorf("got e.mu.neigh.State = %q, want = %q", e.mu.neigh.State, Stale)
-	}
-	e.mu.Unlock()
-
-	// No probes should have been sent.
-	runImmediatelyScheduledJobs(clock)
-	{
-		linkRes.mu.Lock()
-		diff := cmp.Diff([]entryTestProbeInfo(nil), linkRes.mu.probes)
-		linkRes.mu.Unlock()
-		if diff != "" {
-			t.Errorf("link address resolver probes mismatch (-want, +got):\n%s", diff)
-		}
-	}
-
-	wantEvents := []testEntryEventInfo{
-		{
-			EventType: entryTestChanged,
-			NICID:     entryTestNICID,
-			Entry: NeighborEntry{
-				Addr:           entryTestAddr1,
-				LinkAddr:       entryTestLinkAddr2,
-				State:          Stale,
-				UpdatedAtNanos: clock.NowNanoseconds(),
-			},
-		},
-	}
-	nudDisp.mu.Lock()
-	if diff := cmp.Diff(wantEvents, nudDisp.mu.events); diff != "" {
-		t.Errorf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-	}
-	nudDisp.mu.Unlock()
-}
-
-func TestEntryStaleToStaleWhenProbeWithSameAddress(t *testing.T) {
-	c := DefaultNUDConfigurations()
-	e, nudDisp, linkRes, clock := entryTestSetup(c)
-
-	if err := unknownToStale(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("unknownToStale(...) = %s", err)
-	}
-
-	e.mu.Lock()
-	e.handleProbeLocked(entryTestLinkAddr1)
-	if e.mu.neigh.State != Stale {
-		t.Errorf("got e.mu.neigh.State = %q, want = %q", e.mu.neigh.State, Stale)
-	}
-	if e.mu.neigh.LinkAddr != entryTestLinkAddr1 {
-		t.Errorf("got e.mu.neigh.LinkAddr = %q, want = %q", e.mu.neigh.LinkAddr, entryTestLinkAddr1)
-	}
-	e.mu.Unlock()
-
-	// No probes should have been sent.
-	runImmediatelyScheduledJobs(clock)
-	{
-		linkRes.mu.Lock()
-		diff := cmp.Diff([]entryTestProbeInfo(nil), linkRes.mu.probes)
-		linkRes.mu.Unlock()
-		if diff != "" {
-			t.Errorf("link address resolver probes mismatch (-want, +got):\n%s", diff)
-		}
-	}
-
-	// No events should have been dispatched.
-	nudDisp.mu.Lock()
-	if diff := cmp.Diff([]testEntryEventInfo(nil), nudDisp.mu.events); diff != "" {
-		t.Errorf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-	}
-	nudDisp.mu.Unlock()
-}
-
-func TestEntryStaleToReachableWhenSolicitedOverrideConfirmation(t *testing.T) {
-	c := DefaultNUDConfigurations()
-	e, nudDisp, linkRes, clock := entryTestSetup(c)
-
-	if err := unknownToStale(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("unknownToStale(...) = %s", err)
-	}
-
-	e.mu.Lock()
-	e.handleConfirmationLocked(entryTestLinkAddr2, ReachabilityConfirmationFlags{
-		Solicited: true,
-		Override:  true,
-		IsRouter:  false,
-	})
-	if e.mu.neigh.State != Reachable {
-		t.Errorf("got e.mu.neigh.State = %q, want = %q", e.mu.neigh.State, Reachable)
-	}
-	if e.mu.neigh.LinkAddr != entryTestLinkAddr2 {
-		t.Errorf("got e.mu.neigh.LinkAddr = %q, want = %q", e.mu.neigh.LinkAddr, entryTestLinkAddr2)
-	}
-	e.mu.Unlock()
-
-	// No probes should have been sent.
-	runImmediatelyScheduledJobs(clock)
-	{
-		linkRes.mu.Lock()
-		diff := cmp.Diff([]entryTestProbeInfo(nil), linkRes.mu.probes)
-		linkRes.mu.Unlock()
-		if diff != "" {
-			t.Errorf("link address resolver probes mismatch (-want, +got):\n%s", diff)
-		}
-	}
-
-	wantEvents := []testEntryEventInfo{
-		{
-			EventType: entryTestChanged,
-			NICID:     entryTestNICID,
-			Entry: NeighborEntry{
-				Addr:           entryTestAddr1,
-				LinkAddr:       entryTestLinkAddr2,
-				State:          Reachable,
-				UpdatedAtNanos: clock.NowNanoseconds(),
-			},
-		},
-	}
-	nudDisp.mu.Lock()
-	if diff := cmp.Diff(wantEvents, nudDisp.mu.events); diff != "" {
-		t.Errorf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-	}
-	nudDisp.mu.Unlock()
-}
-
-func TestEntryStaleToReachableWhenSolicitedConfirmationWithoutAddress(t *testing.T) {
-	c := DefaultNUDConfigurations()
-	e, nudDisp, linkRes, clock := entryTestSetup(c)
-
-	if err := unknownToStale(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("unknownToStale(...) = %s", err)
-	}
-
-	e.mu.Lock()
-	e.handleConfirmationLocked("" /* linkAddr */, ReachabilityConfirmationFlags{
-		Solicited: true,
-		Override:  false,
-		IsRouter:  false,
-	})
-	if e.mu.neigh.State != Reachable {
-		t.Errorf("got e.mu.neigh.State = %q, want = %q", e.mu.neigh.State, Reachable)
-	}
-	if e.mu.neigh.LinkAddr != entryTestLinkAddr1 {
-		t.Errorf("got e.mu.neigh.LinkAddr = %q, want = %q", e.mu.neigh.LinkAddr, entryTestLinkAddr1)
-	}
-	e.mu.Unlock()
-
-	// No probes should have been sent.
-	runImmediatelyScheduledJobs(clock)
-	{
-		linkRes.mu.Lock()
-		diff := cmp.Diff([]entryTestProbeInfo(nil), linkRes.mu.probes)
-		linkRes.mu.Unlock()
-		if diff != "" {
-			t.Errorf("link address resolver probes mismatch (-want, +got):\n%s", diff)
-		}
-	}
-
-	wantEvents := []testEntryEventInfo{
-		{
-			EventType: entryTestChanged,
-			NICID:     entryTestNICID,
-			Entry: NeighborEntry{
-				Addr:           entryTestAddr1,
-				LinkAddr:       entryTestLinkAddr1,
-				State:          Reachable,
-				UpdatedAtNanos: clock.NowNanoseconds(),
-			},
-		},
-	}
-	nudDisp.mu.Lock()
-	if diff := cmp.Diff(wantEvents, nudDisp.mu.events); diff != "" {
-		t.Errorf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-	}
-	nudDisp.mu.Unlock()
-}
-
-func TestEntryStaleToStaleWhenOverrideConfirmation(t *testing.T) {
-	c := DefaultNUDConfigurations()
-	e, nudDisp, linkRes, clock := entryTestSetup(c)
-
-	if err := unknownToStale(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("unknownToStale(...) = %s", err)
-	}
-
-	e.mu.Lock()
-	e.handleConfirmationLocked(entryTestLinkAddr2, ReachabilityConfirmationFlags{
-		Solicited: false,
-		Override:  true,
-		IsRouter:  false,
-	})
-	if e.mu.neigh.State != Stale {
-		t.Errorf("got e.mu.neigh.State = %q, want = %q", e.mu.neigh.State, Stale)
-	}
-	if e.mu.neigh.LinkAddr != entryTestLinkAddr2 {
-		t.Errorf("got e.mu.neigh.LinkAddr = %q, want = %q", e.mu.neigh.LinkAddr, entryTestLinkAddr2)
-	}
-	e.mu.Unlock()
-
-	wantEvents := []testEntryEventInfo{
-		{
-			EventType: entryTestChanged,
-			NICID:     entryTestNICID,
-			Entry: NeighborEntry{
-				Addr:           entryTestAddr1,
-				LinkAddr:       entryTestLinkAddr2,
-				State:          Stale,
-				UpdatedAtNanos: clock.NowNanoseconds(),
-			},
-		},
-	}
-	nudDisp.mu.Lock()
-	if diff := cmp.Diff(wantEvents, nudDisp.mu.events); diff != "" {
-		t.Errorf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-	}
-	nudDisp.mu.Unlock()
-}
-
-func TestEntryStaleToStaleWhenProbeUpdateAddress(t *testing.T) {
-	c := DefaultNUDConfigurations()
-	e, nudDisp, linkRes, clock := entryTestSetup(c)
-
-	if err := unknownToStale(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("unknownToStale(...) = %s", err)
-	}
-
-	e.mu.Lock()
-	e.handleProbeLocked(entryTestLinkAddr2)
-	if e.mu.neigh.State != Stale {
-		t.Errorf("got e.mu.neigh.State = %q, want = %q", e.mu.neigh.State, Stale)
-	}
-	if e.mu.neigh.LinkAddr != entryTestLinkAddr2 {
-		t.Errorf("got e.mu.neigh.LinkAddr = %q, want = %q", e.mu.neigh.LinkAddr, entryTestLinkAddr2)
-	}
-	e.mu.Unlock()
-
-	// No probes should have been sent.
-	runImmediatelyScheduledJobs(clock)
-	{
-		linkRes.mu.Lock()
-		diff := cmp.Diff([]entryTestProbeInfo(nil), linkRes.mu.probes)
-		linkRes.mu.Unlock()
-		if diff != "" {
-			t.Errorf("link address resolver probes mismatch (-want, +got):\n%s", diff)
-		}
-	}
-
-	wantEvents := []testEntryEventInfo{
-		{
-			EventType: entryTestChanged,
-			NICID:     entryTestNICID,
-			Entry: NeighborEntry{
-				Addr:           entryTestAddr1,
-				LinkAddr:       entryTestLinkAddr2,
-				State:          Stale,
-				UpdatedAtNanos: clock.NowNanoseconds(),
-			},
-		},
-	}
-	nudDisp.mu.Lock()
-	if diff := cmp.Diff(wantEvents, nudDisp.mu.events); diff != "" {
-		t.Errorf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-	}
-	nudDisp.mu.Unlock()
-}
-
-func TestEntryStaleToDelay(t *testing.T) {
-	c := DefaultNUDConfigurations()
-	e, nudDisp, linkRes, clock := entryTestSetup(c)
-
-	if err := unknownToStale(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("unknownToStale(...) = %s", err)
-	}
-	if err := staleToDelay(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("staleToDelay(...) = %s", err)
-	}
-}
-
-func staleToDelay(e *neighborEntry, nudDisp *testNUDDispatcher, linkRes *entryTestLinkResolver, clock *faketime.ManualClock) error {
-	if err := func() error {
-		e.mu.Lock()
-		defer e.mu.Unlock()
-
-		if e.mu.neigh.State != Stale {
-			return fmt.Errorf("got e.mu.neigh.State = %q, want = %q", e.mu.neigh.State, Stale)
-		}
-		e.handlePacketQueuedLocked(entryTestAddr2)
-		if e.mu.neigh.State != Delay {
-			return fmt.Errorf("got e.mu.neigh.State = %q, want = %q", e.mu.neigh.State, Delay)
-		}
-		return nil
-	}(); err != nil {
-		return err
-	}
-
-	// No probes should have been sent.
-	runImmediatelyScheduledJobs(clock)
-	{
-		linkRes.mu.Lock()
-		diff := cmp.Diff([]entryTestProbeInfo(nil), linkRes.mu.probes)
-		linkRes.mu.Unlock()
-		if diff != "" {
-			return fmt.Errorf("link address resolver probes mismatch (-want, +got):\n%s", diff)
-		}
-	}
-
-	wantEvents := []testEntryEventInfo{
-		{
-			EventType: entryTestChanged,
-			NICID:     entryTestNICID,
-			Entry: NeighborEntry{
-				Addr:           entryTestAddr1,
-				LinkAddr:       entryTestLinkAddr1,
-				State:          Delay,
-				UpdatedAtNanos: clock.NowNanoseconds(),
-			},
-		},
-	}
-	nudDisp.mu.Lock()
-	diff := cmp.Diff(wantEvents, nudDisp.mu.events)
-	nudDisp.mu.events = nil
-	nudDisp.mu.Unlock()
-	if diff != "" {
-		return fmt.Errorf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-	}
-
-	return nil
-}
-
-func TestEntryDelayToReachableWhenUpperLevelConfirmation(t *testing.T) {
-	c := DefaultNUDConfigurations()
-	e, nudDisp, linkRes, clock := entryTestSetup(c)
-
-	if err := unknownToStale(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("unknownToStale(...) = %s", err)
-	}
-	if err := staleToDelay(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("staleToDelay(...) = %s", err)
-	}
-
-	e.mu.Lock()
-	e.handleUpperLevelConfirmationLocked()
-	if e.mu.neigh.State != Reachable {
-		t.Errorf("got e.mu.neigh.State = %q, want = %q", e.mu.neigh.State, Reachable)
-	}
-	e.mu.Unlock()
-
-	// No probes should have been sent.
-	runImmediatelyScheduledJobs(clock)
-	{
-		linkRes.mu.Lock()
-		diff := cmp.Diff([]entryTestProbeInfo(nil), linkRes.mu.probes)
-		linkRes.mu.Unlock()
-		if diff != "" {
-			t.Errorf("link address resolver probes mismatch (-want, +got):\n%s", diff)
-		}
-	}
-
-	wantEvents := []testEntryEventInfo{
-		{
-			EventType: entryTestChanged,
-			NICID:     entryTestNICID,
-			Entry: NeighborEntry{
-				Addr:           entryTestAddr1,
-				LinkAddr:       entryTestLinkAddr1,
-				State:          Reachable,
-				UpdatedAtNanos: clock.NowNanoseconds(),
-			},
-		},
-	}
-	nudDisp.mu.Lock()
-	if diff := cmp.Diff(wantEvents, nudDisp.mu.events); diff != "" {
-		t.Errorf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-	}
-	nudDisp.mu.Unlock()
-}
-
-func TestEntryDelayToReachableWhenSolicitedOverrideConfirmation(t *testing.T) {
-	c := DefaultNUDConfigurations()
-	e, nudDisp, linkRes, clock := entryTestSetup(c)
-
-	if err := unknownToStale(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("unknownToStale(...) = %s", err)
-	}
-	if err := staleToDelay(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("staleToDelay(...) = %s", err)
-	}
-
-	e.mu.Lock()
-	e.handleConfirmationLocked(entryTestLinkAddr2, ReachabilityConfirmationFlags{
-		Solicited: true,
-		Override:  true,
-		IsRouter:  false,
-	})
-	if e.mu.neigh.State != Reachable {
-		t.Errorf("got e.mu.neigh.State = %q, want = %q", e.mu.neigh.State, Reachable)
-	}
-	if e.mu.neigh.LinkAddr != entryTestLinkAddr2 {
-		t.Errorf("got e.mu.neigh.LinkAddr = %q, want = %q", e.mu.neigh.LinkAddr, entryTestLinkAddr2)
-	}
-	e.mu.Unlock()
-
-	// No probes should have been sent.
-	runImmediatelyScheduledJobs(clock)
-	{
-		linkRes.mu.Lock()
-		diff := cmp.Diff([]entryTestProbeInfo(nil), linkRes.mu.probes)
-		linkRes.mu.Unlock()
-		if diff != "" {
-			t.Errorf("link address resolver probes mismatch (-want, +got):\n%s", diff)
-		}
-	}
-
-	wantEvents := []testEntryEventInfo{
-		{
-			EventType: entryTestChanged,
-			NICID:     entryTestNICID,
-			Entry: NeighborEntry{
-				Addr:           entryTestAddr1,
-				LinkAddr:       entryTestLinkAddr2,
-				State:          Reachable,
-				UpdatedAtNanos: clock.NowNanoseconds(),
-			},
-		},
-	}
-	nudDisp.mu.Lock()
-	if diff := cmp.Diff(wantEvents, nudDisp.mu.events); diff != "" {
-		t.Errorf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-	}
-	nudDisp.mu.Unlock()
-}
-
-func TestEntryDelayToReachableWhenSolicitedConfirmationWithoutAddress(t *testing.T) {
-	c := DefaultNUDConfigurations()
-	e, nudDisp, linkRes, clock := entryTestSetup(c)
-
-	if err := unknownToStale(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("unknownToStale(...) = %s", err)
-	}
-	if err := staleToDelay(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("staleToDelay(...) = %s", err)
-	}
-
-	e.mu.Lock()
-	e.handleConfirmationLocked("" /* linkAddr */, ReachabilityConfirmationFlags{
-		Solicited: true,
-		Override:  false,
-		IsRouter:  false,
-	})
-	if e.mu.neigh.State != Reachable {
-		t.Errorf("got e.mu.neigh.State = %q, want = %q", e.mu.neigh.State, Reachable)
-	}
-	if e.mu.neigh.LinkAddr != entryTestLinkAddr1 {
-		t.Errorf("got e.mu.neigh.LinkAddr = %q, want = %q", e.mu.neigh.LinkAddr, entryTestLinkAddr1)
-	}
-	e.mu.Unlock()
-
-	// No probes should have been sent.
-	runImmediatelyScheduledJobs(clock)
-	{
-		linkRes.mu.Lock()
-		diff := cmp.Diff([]entryTestProbeInfo(nil), linkRes.mu.probes)
-		linkRes.mu.Unlock()
-		if diff != "" {
-			t.Errorf("link address resolver probes mismatch (-want, +got):\n%s", diff)
-		}
-	}
-
-	wantEvents := []testEntryEventInfo{
-		{
-			EventType: entryTestChanged,
-			NICID:     entryTestNICID,
-			Entry: NeighborEntry{
-				Addr:           entryTestAddr1,
-				LinkAddr:       entryTestLinkAddr1,
-				State:          Reachable,
-				UpdatedAtNanos: clock.NowNanoseconds(),
-			},
-		},
-	}
-	nudDisp.mu.Lock()
-	if diff := cmp.Diff(wantEvents, nudDisp.mu.events); diff != "" {
-		t.Errorf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-	}
-	nudDisp.mu.Unlock()
-}
-
-func TestEntryDelayToDelayWhenOverrideConfirmationWithSameAddress(t *testing.T) {
-	c := DefaultNUDConfigurations()
-	e, nudDisp, linkRes, clock := entryTestSetup(c)
-
-	if err := unknownToStale(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("unknownToStale(...) = %s", err)
-	}
-	if err := staleToDelay(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("staleToDelay(...) = %s", err)
-	}
-
-	e.mu.Lock()
-	e.handleConfirmationLocked(entryTestLinkAddr1, ReachabilityConfirmationFlags{
-		Solicited: false,
-		Override:  true,
-		IsRouter:  false,
-	})
-	if e.mu.neigh.State != Delay {
-		t.Errorf("got e.mu.neigh.State = %q, want = %q", e.mu.neigh.State, Delay)
-	}
-	if e.mu.neigh.LinkAddr != entryTestLinkAddr1 {
-		t.Errorf("got e.mu.neigh.LinkAddr = %q, want = %q", e.mu.neigh.LinkAddr, entryTestLinkAddr1)
-	}
-	e.mu.Unlock()
-
-	// No probes should have been sent.
-	runImmediatelyScheduledJobs(clock)
-	{
-		linkRes.mu.Lock()
-		diff := cmp.Diff([]entryTestProbeInfo(nil), linkRes.mu.probes)
-		linkRes.mu.Unlock()
-		if diff != "" {
-			t.Errorf("link address resolver probes mismatch (-want, +got):\n%s", diff)
-		}
-	}
-
-	// No events should have been dispatched.
-	nudDisp.mu.Lock()
-	if diff := cmp.Diff([]testEntryEventInfo(nil), nudDisp.mu.events); diff != "" {
-		t.Errorf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-	}
-	nudDisp.mu.Unlock()
-}
-
-func TestEntryDelayToStaleWhenProbeWithDifferentAddress(t *testing.T) {
-	c := DefaultNUDConfigurations()
-	e, nudDisp, linkRes, clock := entryTestSetup(c)
-
-	if err := unknownToStale(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("unknownToStale(...) = %s", err)
-	}
-	if err := staleToDelay(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("staleToDelay(...) = %s", err)
-	}
-
-	e.mu.Lock()
-	e.handleProbeLocked(entryTestLinkAddr2)
-	if e.mu.neigh.State != Stale {
-		t.Errorf("got e.mu.neigh.State = %q, want = %q", e.mu.neigh.State, Stale)
-	}
-	e.mu.Unlock()
-
-	// No probes should have been sent.
-	runImmediatelyScheduledJobs(clock)
-	{
-		linkRes.mu.Lock()
-		diff := cmp.Diff([]entryTestProbeInfo(nil), linkRes.mu.probes)
-		linkRes.mu.Unlock()
-		if diff != "" {
-			t.Errorf("link address resolver probes mismatch (-want, +got):\n%s", diff)
-		}
-	}
-
-	wantEvents := []testEntryEventInfo{
-		{
-			EventType: entryTestChanged,
-			NICID:     entryTestNICID,
-			Entry: NeighborEntry{
-				Addr:           entryTestAddr1,
-				LinkAddr:       entryTestLinkAddr2,
-				State:          Stale,
-				UpdatedAtNanos: clock.NowNanoseconds(),
-			},
-		},
-	}
-	nudDisp.mu.Lock()
-	if diff := cmp.Diff(wantEvents, nudDisp.mu.events); diff != "" {
-		t.Errorf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-	}
-	nudDisp.mu.Unlock()
-}
-
-func TestEntryDelayToStaleWhenConfirmationWithDifferentAddress(t *testing.T) {
-	c := DefaultNUDConfigurations()
-	e, nudDisp, linkRes, clock := entryTestSetup(c)
-
-	if err := unknownToStale(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("unknownToStale(...) = %s", err)
-	}
-	if err := staleToDelay(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("staleToDelay(...) = %s", err)
-	}
-
-	e.mu.Lock()
-	e.handleConfirmationLocked(entryTestLinkAddr2, ReachabilityConfirmationFlags{
-		Solicited: false,
-		Override:  true,
-		IsRouter:  false,
-	})
-	if e.mu.neigh.State != Stale {
-		t.Errorf("got e.mu.neigh.State = %q, want = %q", e.mu.neigh.State, Stale)
-	}
-	e.mu.Unlock()
-
-	// No probes should have been sent.
-	runImmediatelyScheduledJobs(clock)
-	{
-		linkRes.mu.Lock()
-		diff := cmp.Diff([]entryTestProbeInfo(nil), linkRes.mu.probes)
-		linkRes.mu.Unlock()
-		if diff != "" {
-			t.Errorf("link address resolver probes mismatch (-want, +got):\n%s", diff)
-		}
-	}
-
-	wantEvents := []testEntryEventInfo{
-		{
-			EventType: entryTestChanged,
-			NICID:     entryTestNICID,
-			Entry: NeighborEntry{
-				Addr:           entryTestAddr1,
-				LinkAddr:       entryTestLinkAddr2,
-				State:          Stale,
-				UpdatedAtNanos: clock.NowNanoseconds(),
-			},
-		},
-	}
-	nudDisp.mu.Lock()
-	if diff := cmp.Diff(wantEvents, nudDisp.mu.events); diff != "" {
-		t.Errorf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-	}
-	nudDisp.mu.Unlock()
-}
-
-func TestEntryDelayToProbe(t *testing.T) {
-	c := DefaultNUDConfigurations()
-	e, nudDisp, linkRes, clock := entryTestSetup(c)
-
-	if err := unknownToStale(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("unknownToStale(...) = %s", err)
-	}
-	if err := staleToDelay(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("staleToDelay(...) = %s", err)
-	}
-	if err := delayToProbe(c, e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("delayToProbe(...) = %s", err)
-	}
-}
-
-func delayToProbe(c NUDConfigurations, e *neighborEntry, nudDisp *testNUDDispatcher, linkRes *entryTestLinkResolver, clock *faketime.ManualClock) error {
-	{
-		e.mu.Lock()
-		state := e.mu.neigh.State
-		e.mu.Unlock()
-		if state != Delay {
-			return fmt.Errorf("got e.mu.neigh.State = %q, want = %q", state, Delay)
-		}
-	}
-
-	// Wait for the first unicast probe to be transmitted, marking the
-	// transition from Delay to Probe.
-	clock.Advance(c.DelayFirstProbeTime)
-
-	{
-		e.mu.Lock()
-		state := e.mu.neigh.State
-		e.mu.Unlock()
-		if state != Probe {
-			return fmt.Errorf("got e.mu.neigh.State = %q, want = %q", state, Probe)
-		}
-	}
-
-	wantProbes := []entryTestProbeInfo{
-		{
-			RemoteAddress:     entryTestAddr1,
-			RemoteLinkAddress: entryTestLinkAddr1,
-		},
-	}
-	{
-		linkRes.mu.Lock()
-		diff := cmp.Diff(wantProbes, linkRes.mu.probes)
-		linkRes.mu.probes = nil
-		linkRes.mu.Unlock()
-		if diff != "" {
-			return fmt.Errorf("link address resolver probes mismatch (-want, +got):\n%s", diff)
-		}
-	}
-
-	wantEvents := []testEntryEventInfo{
-		{
-			EventType: entryTestChanged,
-			NICID:     entryTestNICID,
-			Entry: NeighborEntry{
-				Addr:           entryTestAddr1,
-				LinkAddr:       entryTestLinkAddr1,
-				State:          Probe,
-				UpdatedAtNanos: clock.NowNanoseconds(),
-			},
-		},
-	}
-	{
-		nudDisp.mu.Lock()
-		diff := cmp.Diff(wantEvents, nudDisp.mu.events)
-		nudDisp.mu.events = nil
-		nudDisp.mu.Unlock()
-		if diff != "" {
-			return fmt.Errorf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-		}
-	}
-
-	return nil
-}
-
-func TestEntryProbeToStaleWhenProbeWithDifferentAddress(t *testing.T) {
-	c := DefaultNUDConfigurations()
-	e, nudDisp, linkRes, clock := entryTestSetup(c)
-
-	if err := unknownToStale(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("unknownToStale(...) = %s", err)
-	}
-	if err := staleToDelay(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("staleToDelay(...) = %s", err)
-	}
-	if err := delayToProbe(c, e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("delayToProbe(...) = %s", err)
-	}
-
-	e.mu.Lock()
-	e.handleProbeLocked(entryTestLinkAddr2)
-	if e.mu.neigh.State != Stale {
-		t.Errorf("got e.mu.neigh.State = %q, want = %q", e.mu.neigh.State, Stale)
-	}
-	e.mu.Unlock()
-
-	// No probes should have been sent.
-	runImmediatelyScheduledJobs(clock)
-	{
-		linkRes.mu.Lock()
-		diff := cmp.Diff([]entryTestProbeInfo(nil), linkRes.mu.probes)
-		linkRes.mu.Unlock()
-		if diff != "" {
-			t.Errorf("link address resolver probes mismatch (-want, +got):\n%s", diff)
-		}
-	}
-
-	wantEvents := []testEntryEventInfo{
-		{
-			EventType: entryTestChanged,
-			NICID:     entryTestNICID,
-			Entry: NeighborEntry{
-				Addr:           entryTestAddr1,
-				LinkAddr:       entryTestLinkAddr2,
-				State:          Stale,
-				UpdatedAtNanos: clock.NowNanoseconds(),
-			},
-		},
-	}
-	nudDisp.mu.Lock()
-	if diff := cmp.Diff(wantEvents, nudDisp.mu.events); diff != "" {
-		t.Errorf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-	}
-	nudDisp.mu.Unlock()
-}
-
-func TestEntryProbeToStaleWhenConfirmationWithDifferentAddress(t *testing.T) {
-	c := DefaultNUDConfigurations()
-	e, nudDisp, linkRes, clock := entryTestSetup(c)
-
-	if err := unknownToStale(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("unknownToStale(...) = %s", err)
-	}
-	if err := staleToDelay(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("staleToDelay(...) = %s", err)
-	}
-	if err := delayToProbe(c, e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("delayToProbe(...) = %s", err)
-	}
-
-	e.mu.Lock()
-	e.handleConfirmationLocked(entryTestLinkAddr2, ReachabilityConfirmationFlags{
-		Solicited: false,
-		Override:  true,
-		IsRouter:  false,
-	})
-	if e.mu.neigh.State != Stale {
-		t.Errorf("got e.mu.neigh.State = %q, want = %q", e.mu.neigh.State, Stale)
-	}
-	e.mu.Unlock()
-
-	// No probes should have been sent.
-	runImmediatelyScheduledJobs(clock)
-	{
-		linkRes.mu.Lock()
-		diff := cmp.Diff([]entryTestProbeInfo(nil), linkRes.mu.probes)
-		linkRes.mu.Unlock()
-		if diff != "" {
-			t.Errorf("link address resolver probes mismatch (-want, +got):\n%s", diff)
-		}
-	}
-
-	wantEvents := []testEntryEventInfo{
-		{
-			EventType: entryTestChanged,
-			NICID:     entryTestNICID,
-			Entry: NeighborEntry{
-				Addr:           entryTestAddr1,
-				LinkAddr:       entryTestLinkAddr2,
-				State:          Stale,
-				UpdatedAtNanos: clock.NowNanoseconds(),
-			},
-		},
-	}
-	nudDisp.mu.Lock()
-	if diff := cmp.Diff(wantEvents, nudDisp.mu.events); diff != "" {
-		t.Errorf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-	}
-	nudDisp.mu.Unlock()
-}
-
-func TestEntryProbeToProbeWhenOverrideConfirmationWithSameAddress(t *testing.T) {
-	c := DefaultNUDConfigurations()
-	e, nudDisp, linkRes, clock := entryTestSetup(c)
-
-	if err := unknownToStale(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("unknownToStale(...) = %s", err)
-	}
-	if err := staleToDelay(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("staleToDelay(...) = %s", err)
-	}
-	if err := delayToProbe(c, e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("delayToProbe(...) = %s", err)
-	}
-
-	e.mu.Lock()
-	e.handleConfirmationLocked(entryTestLinkAddr1, ReachabilityConfirmationFlags{
-		Solicited: false,
-		Override:  true,
-		IsRouter:  false,
-	})
-	if e.mu.neigh.State != Probe {
-		t.Errorf("got e.mu.neigh.State = %q, want = %q", e.mu.neigh.State, Probe)
-	}
-	if got, want := e.mu.neigh.LinkAddr, entryTestLinkAddr1; got != want {
-		t.Errorf("got e.mu.neigh.LinkAddr = %q, want = %q", got, want)
-	}
-	e.mu.Unlock()
-
-	// No probes should have been sent.
-	runImmediatelyScheduledJobs(clock)
-	{
-		linkRes.mu.Lock()
-		diff := cmp.Diff([]entryTestProbeInfo(nil), linkRes.mu.probes)
-		linkRes.mu.Unlock()
-		if diff != "" {
-			t.Errorf("link address resolver probes mismatch (-want, +got):\n%s", diff)
-		}
-	}
-
-	// No events should have been dispatched.
-	nudDisp.mu.Lock()
-	diff := cmp.Diff([]testEntryEventInfo(nil), nudDisp.mu.events)
-	nudDisp.mu.Unlock()
-	if diff != "" {
-		t.Errorf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-	}
-}
-
-func TestEntryProbeToReachableWhenSolicitedOverrideConfirmation(t *testing.T) {
-	c := DefaultNUDConfigurations()
-	e, nudDisp, linkRes, clock := entryTestSetup(c)
-
-	if err := unknownToStale(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("unknownToStale(...) = %s", err)
-	}
-	if err := staleToDelay(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("staleToDelay(...) = %s", err)
-	}
-	if err := delayToProbe(c, e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("delayToProbe(...) = %s", err)
-	}
-	if err := probeToReachableWithOverride(e, nudDisp, linkRes, clock, entryTestLinkAddr2); err != nil {
-		t.Fatalf("probeToReachableWithOverride(...) = %s", err)
-	}
-}
-
-func probeToReachableWithFlags(e *neighborEntry, nudDisp *testNUDDispatcher, linkRes *entryTestLinkResolver, clock *faketime.ManualClock, linkAddr tcpip.LinkAddress, flags ReachabilityConfirmationFlags) error {
-	if err := func() error {
-		e.mu.Lock()
-		defer e.mu.Unlock()
-
-		prevLinkAddr := e.mu.neigh.LinkAddr
-		if e.mu.neigh.State != Probe {
-			return fmt.Errorf("got e.mu.neigh.State = %q, want = %q", e.mu.neigh.State, Probe)
-		}
-		e.handleConfirmationLocked(linkAddr, flags)
-
-		if e.mu.neigh.State != Reachable {
-			return fmt.Errorf("got e.mu.neigh.State = %q, want = %q", e.mu.neigh.State, Reachable)
-		}
-		if linkAddr == "" {
-			linkAddr = prevLinkAddr
-		}
-		if e.mu.neigh.LinkAddr != linkAddr {
-			return fmt.Errorf("got e.mu.neigh.LinkAddr = %q, want = %q", e.mu.neigh.LinkAddr, linkAddr)
-		}
-		return nil
-	}(); err != nil {
-		return err
-	}
-
-	// No probes should have been sent.
-	runImmediatelyScheduledJobs(clock)
-	{
-		linkRes.mu.Lock()
-		diff := cmp.Diff([]entryTestProbeInfo(nil), linkRes.mu.probes)
-		linkRes.mu.Unlock()
-		if diff != "" {
-			return fmt.Errorf("link address resolver probes mismatch (-want, +got):\n%s", diff)
-		}
-	}
-
-	wantEvents := []testEntryEventInfo{
-		{
-			EventType: entryTestChanged,
-			NICID:     entryTestNICID,
-			Entry: NeighborEntry{
-				Addr:           entryTestAddr1,
-				LinkAddr:       linkAddr,
-				State:          Reachable,
-				UpdatedAtNanos: clock.NowNanoseconds(),
-			},
-		},
-	}
-	{
-		nudDisp.mu.Lock()
-		diff := cmp.Diff(wantEvents, nudDisp.mu.events)
-		nudDisp.mu.events = nil
-		nudDisp.mu.Unlock()
-		if diff != "" {
-			return fmt.Errorf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-		}
-	}
-
-	return nil
-}
-
-func probeToReachableWithOverride(e *neighborEntry, nudDisp *testNUDDispatcher, linkRes *entryTestLinkResolver, clock *faketime.ManualClock, linkAddr tcpip.LinkAddress) error {
-	return probeToReachableWithFlags(e, nudDisp, linkRes, clock, linkAddr, ReachabilityConfirmationFlags{
-		Solicited: true,
-		Override:  true,
-		IsRouter:  false,
-	})
-}
-
-func TestEntryProbeToReachableWhenSolicitedConfirmationWithSameAddress(t *testing.T) {
-	c := DefaultNUDConfigurations()
-	e, nudDisp, linkRes, clock := entryTestSetup(c)
-
-	if err := unknownToStale(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("unknownToStale(...) = %s", err)
-	}
-	if err := staleToDelay(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("staleToDelay(...) = %s", err)
-	}
-	if err := delayToProbe(c, e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("delayToProbe(...) = %s", err)
-	}
-	if err := probeToReachable(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("probeToReachable(...) = %s", err)
-	}
-}
-
-func probeToReachable(e *neighborEntry, nudDisp *testNUDDispatcher, linkRes *entryTestLinkResolver, clock *faketime.ManualClock) error {
-	return probeToReachableWithFlags(e, nudDisp, linkRes, clock, entryTestLinkAddr1, ReachabilityConfirmationFlags{
-		Solicited: true,
-		Override:  false,
-		IsRouter:  false,
-	})
-}
-
-func TestEntryProbeToReachableWhenSolicitedConfirmationWithoutAddress(t *testing.T) {
-	c := DefaultNUDConfigurations()
-	e, nudDisp, linkRes, clock := entryTestSetup(c)
-
-	if err := unknownToStale(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("unknownToStale(...) = %s", err)
-	}
-	if err := staleToDelay(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("staleToDelay(...) = %s", err)
-	}
-	if err := delayToProbe(c, e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("delayToProbe(...) = %s", err)
-	}
-	if err := probeToReachableWithoutAddress(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("probeToReachableWithoutAddress(...) = %s", err)
-	}
-}
-
-func probeToReachableWithoutAddress(e *neighborEntry, nudDisp *testNUDDispatcher, linkRes *entryTestLinkResolver, clock *faketime.ManualClock) error {
-	return probeToReachableWithFlags(e, nudDisp, linkRes, clock, "" /* linkAddr */, ReachabilityConfirmationFlags{
-		Solicited: true,
-		Override:  false,
-		IsRouter:  false,
-	})
-}
-
-func TestEntryProbeToUnreachable(t *testing.T) {
-	c := DefaultNUDConfigurations()
-	c.MaxMulticastProbes = 3
-	c.MaxUnicastProbes = 3
-	c.DelayFirstProbeTime = c.RetransmitTimer
-	e, nudDisp, linkRes, clock := entryTestSetup(c)
-
-	if err := unknownToStale(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("unknownToStale(...) = %s", err)
-	}
-	if err := staleToDelay(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("staleToDelay(...) = %s", err)
-	}
-	if err := delayToProbe(c, e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("delayToProbe(...) = %s", err)
-	}
-	if err := probeToUnreachable(c, e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("probeToUnreachable(...) = %s", err)
-	}
-}
-
-func probeToUnreachable(c NUDConfigurations, e *neighborEntry, nudDisp *testNUDDispatcher, linkRes *entryTestLinkResolver, clock *faketime.ManualClock) error {
-	{
-		e.mu.Lock()
-		state := e.mu.neigh.State
-		e.mu.Unlock()
-		if state != Probe {
-			return fmt.Errorf("got e.mu.neigh.State = %q, want = %q", state, Probe)
-		}
-	}
-
-	// The first probe was sent in the transition from Delay to Probe.
-	clock.Advance(c.RetransmitTimer)
-
-	// Observe each subsequent unicast probe transmitted.
-	for i := uint32(1); i < c.MaxUnicastProbes; i++ {
-		wantProbes := []entryTestProbeInfo{{
-			RemoteAddress:     entryTestAddr1,
-			RemoteLinkAddress: entryTestLinkAddr1,
-		}}
-		linkRes.mu.Lock()
-		diff := cmp.Diff(wantProbes, linkRes.mu.probes)
-		linkRes.mu.probes = nil
-		linkRes.mu.Unlock()
-		if diff != "" {
-			return fmt.Errorf("link address resolver probe #%d mismatch (-want, +got):\n%s", i+1, diff)
-		}
-
-		e.mu.Lock()
-		state := e.mu.neigh.State
-		e.mu.Unlock()
-		if state != Probe {
-			return fmt.Errorf("got e.mu.neigh.State = %q, want = %q", state, Probe)
-		}
-
-		clock.Advance(c.RetransmitTimer)
-	}
-
-	{
-		e.mu.Lock()
-		state := e.mu.neigh.State
-		e.mu.Unlock()
-		if state != Unreachable {
-			return fmt.Errorf("got e.mu.neigh.State = %q, want = %q", state, Unreachable)
-		}
-	}
-
-	wantEvents := []testEntryEventInfo{
-		{
-			EventType: entryTestChanged,
-			NICID:     entryTestNICID,
-			Entry: NeighborEntry{
-				Addr:           entryTestAddr1,
-				LinkAddr:       entryTestLinkAddr1,
-				State:          Unreachable,
-				UpdatedAtNanos: clock.NowNanoseconds(),
-			},
-		},
-	}
-	nudDisp.mu.Lock()
-	diff := cmp.Diff(wantEvents, nudDisp.mu.events)
-	nudDisp.mu.events = nil
-	nudDisp.mu.Unlock()
-	if diff != "" {
-		return fmt.Errorf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-	}
-
-	return nil
-}
-
-func TestEntryUnreachableToIncomplete(t *testing.T) {
-	c := DefaultNUDConfigurations()
-	c.MaxMulticastProbes = 3
-	e, nudDisp, linkRes, clock := entryTestSetup(c)
-
-	if err := unknownToIncomplete(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("unknownToIncomplete(...) = %s", err)
-	}
-	if err := incompleteToUnreachable(c, e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("incompleteToUnreachable(...) = %s", err)
-	}
-	if err := unreachableToIncomplete(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("unreachableToIncomplete(...) = %s", err)
-	}
-}
-
-func unreachableToIncomplete(e *neighborEntry, nudDisp *testNUDDispatcher, linkRes *entryTestLinkResolver, clock *faketime.ManualClock) error {
-	if err := func() error {
-		e.mu.Lock()
-		defer e.mu.Unlock()
-
-		if e.mu.neigh.State != Unreachable {
-			return fmt.Errorf("got e.mu.neigh.State = %q, want = %q", e.mu.neigh.State, Unreachable)
-		}
-		e.handlePacketQueuedLocked(entryTestAddr2)
-		if e.mu.neigh.State != Incomplete {
-			return fmt.Errorf("got e.mu.neigh.State = %q, want = %q", e.mu.neigh.State, Incomplete)
-		}
-		return nil
-	}(); err != nil {
-		return err
-	}
-
-	runImmediatelyScheduledJobs(clock)
-	wantProbes := []entryTestProbeInfo{
-		{
-			RemoteAddress:     entryTestAddr1,
-			RemoteLinkAddress: tcpip.LinkAddress(""),
-			LocalAddress:      entryTestAddr2,
-		},
-	}
-	linkRes.mu.Lock()
-	diff := cmp.Diff(wantProbes, linkRes.mu.probes)
-	linkRes.mu.probes = nil
-	linkRes.mu.Unlock()
-	if diff != "" {
-		return fmt.Errorf("link address resolver probes mismatch (-want, +got):\n%s", diff)
-	}
-
-	wantEvents := []testEntryEventInfo{
-		{
-			EventType: entryTestChanged,
-			NICID:     entryTestNICID,
-			Entry: NeighborEntry{
-				Addr:           entryTestAddr1,
-				LinkAddr:       tcpip.LinkAddress(""),
-				State:          Incomplete,
-				UpdatedAtNanos: clock.NowNanoseconds(),
-			},
-		},
-	}
-	{
-		nudDisp.mu.Lock()
-		diff := cmp.Diff(wantEvents, nudDisp.mu.events)
-		nudDisp.mu.events = nil
-		nudDisp.mu.Unlock()
-		if diff != "" {
-			return fmt.Errorf("nud dispatcher events mismatch (-want, +got):\n%s", diff)
-		}
-	}
-	return nil
-}
-
-func TestEntryUnreachableToStale(t *testing.T) {
-	c := DefaultNUDConfigurations()
-	c.MaxMulticastProbes = 3
-	// Eliminate random factors from ReachableTime computation so the transition
-	// from Stale to Reachable will only take BaseReachableTime duration.
-	c.MinRandomFactor = 1
-	c.MaxRandomFactor = 1
-
-	e, nudDisp, linkRes, clock := entryTestSetup(c)
-
-	if err := unknownToIncomplete(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("unknownToIncomplete(...) = %s", err)
-	}
-	if err := incompleteToUnreachable(c, e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("incompleteToUnreachable(...) = %s", err)
-	}
-	if err := unreachableToIncomplete(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("unreachableToIncomplete(...) = %s", err)
-	}
-	if err := incompleteToReachable(e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("incompleteToReachable(...) = %s", err)
-	}
-	if err := reachableToStale(c, e, nudDisp, linkRes, clock); err != nil {
-		t.Fatalf("reachableToStale(...) = %s", err)
-	}
-}
diff --git a/pkg/tcpip/stack/nic_test.go b/pkg/tcpip/stack/nic_test.go
deleted file mode 100644
index c0f956e..0000000
--- a/pkg/tcpip/stack/nic_test.go
+++ /dev/null
@@ -1,210 +0,0 @@
-// Copyright 2020 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
-
-import (
-	"testing"
-
-	"gvisor.dev/gvisor/pkg/tcpip"
-	"gvisor.dev/gvisor/pkg/tcpip/buffer"
-	"gvisor.dev/gvisor/pkg/tcpip/header"
-)
-
-var _ AddressableEndpoint = (*testIPv6Endpoint)(nil)
-var _ NetworkEndpoint = (*testIPv6Endpoint)(nil)
-var _ NDPEndpoint = (*testIPv6Endpoint)(nil)
-
-// An IPv6 NetworkEndpoint that throws away outgoing packets.
-//
-// We use this instead of ipv6.endpoint because the ipv6 package depends on
-// the stack package which this test lives in, causing a cyclic dependency.
-type testIPv6Endpoint struct {
-	AddressableEndpointState
-
-	nic      NetworkInterface
-	protocol *testIPv6Protocol
-
-	invalidatedRtr tcpip.Address
-}
-
-func (*testIPv6Endpoint) Enable() tcpip.Error {
-	return nil
-}
-
-func (*testIPv6Endpoint) Enabled() bool {
-	return true
-}
-
-func (*testIPv6Endpoint) Disable() {}
-
-// DefaultTTL implements NetworkEndpoint.DefaultTTL.
-func (*testIPv6Endpoint) DefaultTTL() uint8 {
-	return 0
-}
-
-// MTU implements NetworkEndpoint.MTU.
-func (e *testIPv6Endpoint) MTU() uint32 {
-	return e.nic.MTU() - header.IPv6MinimumSize
-}
-
-// MaxHeaderLength implements NetworkEndpoint.MaxHeaderLength.
-func (e *testIPv6Endpoint) MaxHeaderLength() uint16 {
-	return e.nic.MaxHeaderLength() + header.IPv6MinimumSize
-}
-
-// WritePacket implements NetworkEndpoint.WritePacket.
-func (*testIPv6Endpoint) WritePacket(*Route, *GSO, NetworkHeaderParams, *PacketBuffer) tcpip.Error {
-	return nil
-}
-
-// WritePackets implements NetworkEndpoint.WritePackets.
-func (*testIPv6Endpoint) WritePackets(*Route, *GSO, PacketBufferList, NetworkHeaderParams) (int, tcpip.Error) {
-	// Our tests don't use this so we don't support it.
-	return 0, &tcpip.ErrNotSupported{}
-}
-
-// WriteHeaderIncludedPacket implements
-// NetworkEndpoint.WriteHeaderIncludedPacket.
-func (*testIPv6Endpoint) WriteHeaderIncludedPacket(*Route, *PacketBuffer) tcpip.Error {
-	// Our tests don't use this so we don't support it.
-	return &tcpip.ErrNotSupported{}
-}
-
-// HandlePacket implements NetworkEndpoint.HandlePacket.
-func (*testIPv6Endpoint) HandlePacket(*PacketBuffer) {}
-
-// Close implements NetworkEndpoint.Close.
-func (e *testIPv6Endpoint) Close() {
-	e.AddressableEndpointState.Cleanup()
-}
-
-// NetworkProtocolNumber implements NetworkEndpoint.NetworkProtocolNumber.
-func (*testIPv6Endpoint) NetworkProtocolNumber() tcpip.NetworkProtocolNumber {
-	return header.IPv6ProtocolNumber
-}
-
-func (e *testIPv6Endpoint) InvalidateDefaultRouter(rtr tcpip.Address) {
-	e.invalidatedRtr = rtr
-}
-
-// Stats implements NetworkEndpoint.
-func (*testIPv6Endpoint) Stats() NetworkEndpointStats {
-	return &testIPv6EndpointStats{}
-}
-
-var _ NetworkEndpointStats = (*testIPv6EndpointStats)(nil)
-
-type testIPv6EndpointStats struct{}
-
-// IsNetworkEndpointStats implements stack.NetworkEndpointStats.
-func (*testIPv6EndpointStats) IsNetworkEndpointStats() {}
-
-// We use this instead of ipv6.protocol because the ipv6 package depends on
-// the stack package which this test lives in, causing a cyclic dependency.
-type testIPv6Protocol struct{}
-
-// Number implements NetworkProtocol.Number.
-func (*testIPv6Protocol) Number() tcpip.NetworkProtocolNumber {
-	return header.IPv6ProtocolNumber
-}
-
-// MinimumPacketSize implements NetworkProtocol.MinimumPacketSize.
-func (*testIPv6Protocol) MinimumPacketSize() int {
-	return header.IPv6MinimumSize
-}
-
-// DefaultPrefixLen implements NetworkProtocol.DefaultPrefixLen.
-func (*testIPv6Protocol) DefaultPrefixLen() int {
-	return header.IPv6AddressSize * 8
-}
-
-// ParseAddresses implements NetworkProtocol.ParseAddresses.
-func (*testIPv6Protocol) ParseAddresses(v buffer.View) (src, dst tcpip.Address) {
-	h := header.IPv6(v)
-	return h.SourceAddress(), h.DestinationAddress()
-}
-
-// NewEndpoint implements NetworkProtocol.NewEndpoint.
-func (p *testIPv6Protocol) NewEndpoint(nic NetworkInterface, _ TransportDispatcher) NetworkEndpoint {
-	e := &testIPv6Endpoint{
-		nic:      nic,
-		protocol: p,
-	}
-	e.AddressableEndpointState.Init(e)
-	return e
-}
-
-// SetOption implements NetworkProtocol.SetOption.
-func (*testIPv6Protocol) SetOption(tcpip.SettableNetworkProtocolOption) tcpip.Error {
-	return nil
-}
-
-// Option implements NetworkProtocol.Option.
-func (*testIPv6Protocol) Option(tcpip.GettableNetworkProtocolOption) tcpip.Error {
-	return nil
-}
-
-// Close implements NetworkProtocol.Close.
-func (*testIPv6Protocol) Close() {}
-
-// Wait implements NetworkProtocol.Wait.
-func (*testIPv6Protocol) Wait() {}
-
-// Parse implements NetworkProtocol.Parse.
-func (*testIPv6Protocol) Parse(*PacketBuffer) (tcpip.TransportProtocolNumber, bool, bool) {
-	return 0, false, false
-}
-
-func TestDisabledRxStatsWhenNICDisabled(t *testing.T) {
-	// When the NIC is disabled, the only field that matters is the stats field.
-	// This test is limited to stats counter checks.
-	nic := nic{
-		stats: makeNICStats(),
-	}
-
-	if got := nic.stats.DisabledRx.Packets.Value(); got != 0 {
-		t.Errorf("got DisabledRx.Packets = %d, want = 0", got)
-	}
-	if got := nic.stats.DisabledRx.Bytes.Value(); got != 0 {
-		t.Errorf("got DisabledRx.Bytes = %d, want = 0", got)
-	}
-	if got := nic.stats.Rx.Packets.Value(); got != 0 {
-		t.Errorf("got Rx.Packets = %d, want = 0", got)
-	}
-	if got := nic.stats.Rx.Bytes.Value(); got != 0 {
-		t.Errorf("got Rx.Bytes = %d, want = 0", got)
-	}
-
-	if t.Failed() {
-		t.FailNow()
-	}
-
-	nic.DeliverNetworkPacket("", "", 0, NewPacketBuffer(PacketBufferOptions{
-		Data: buffer.View([]byte{1, 2, 3, 4}).ToVectorisedView(),
-	}))
-
-	if got := nic.stats.DisabledRx.Packets.Value(); got != 1 {
-		t.Errorf("got DisabledRx.Packets = %d, want = 1", got)
-	}
-	if got := nic.stats.DisabledRx.Bytes.Value(); got != 4 {
-		t.Errorf("got DisabledRx.Bytes = %d, want = 4", got)
-	}
-	if got := nic.stats.Rx.Packets.Value(); got != 0 {
-		t.Errorf("got Rx.Packets = %d, want = 0", got)
-	}
-	if got := nic.stats.Rx.Bytes.Value(); got != 0 {
-		t.Errorf("got Rx.Bytes = %d, want = 0", got)
-	}
-}
diff --git a/pkg/tcpip/stack/nud_test.go b/pkg/tcpip/stack/nud_test.go
deleted file mode 100644
index e1253f3..0000000
--- a/pkg/tcpip/stack/nud_test.go
+++ /dev/null
@@ -1,813 +0,0 @@
-// Copyright 2020 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 (
-	"math"
-	"testing"
-	"time"
-
-	"github.com/google/go-cmp/cmp"
-	"gvisor.dev/gvisor/pkg/tcpip"
-	"gvisor.dev/gvisor/pkg/tcpip/faketime"
-	"gvisor.dev/gvisor/pkg/tcpip/link/channel"
-	"gvisor.dev/gvisor/pkg/tcpip/network/ipv6"
-	"gvisor.dev/gvisor/pkg/tcpip/stack"
-)
-
-const (
-	defaultBaseReachableTime           = 30 * time.Second
-	minimumBaseReachableTime           = time.Millisecond
-	defaultMinRandomFactor             = 0.5
-	defaultMaxRandomFactor             = 1.5
-	defaultRetransmitTimer             = time.Second
-	minimumRetransmitTimer             = time.Millisecond
-	defaultDelayFirstProbeTime         = 5 * time.Second
-	defaultMaxMulticastProbes          = 3
-	defaultMaxUnicastProbes            = 3
-	defaultMaxAnycastDelayTime         = time.Second
-	defaultMaxReachbilityConfirmations = 3
-
-	defaultFakeRandomNum = 0.5
-)
-
-// fakeRand is a deterministic random number generator.
-type fakeRand struct {
-	num float32
-}
-
-var _ stack.Rand = (*fakeRand)(nil)
-
-func (f *fakeRand) Float32() float32 {
-	return f.num
-}
-
-func TestNUDFunctions(t *testing.T) {
-	const nicID = 1
-
-	tests := []struct {
-		name                  string
-		nicID                 tcpip.NICID
-		netProtoFactory       []stack.NetworkProtocolFactory
-		extraLinkCapabilities stack.LinkEndpointCapabilities
-		expectedErr           tcpip.Error
-	}{
-		{
-			name:                  "Invalid NICID",
-			nicID:                 nicID + 1,
-			netProtoFactory:       []stack.NetworkProtocolFactory{ipv6.NewProtocol},
-			extraLinkCapabilities: stack.CapabilityResolutionRequired,
-			expectedErr:           &tcpip.ErrUnknownNICID{},
-		},
-		{
-			name:        "No network protocol",
-			nicID:       nicID,
-			expectedErr: &tcpip.ErrNotSupported{},
-		},
-		{
-			name:            "With IPv6",
-			nicID:           nicID,
-			netProtoFactory: []stack.NetworkProtocolFactory{ipv6.NewProtocol},
-			expectedErr:     &tcpip.ErrNotSupported{},
-		},
-		{
-			name:                  "With resolution capability",
-			nicID:                 nicID,
-			extraLinkCapabilities: stack.CapabilityResolutionRequired,
-			expectedErr:           &tcpip.ErrNotSupported{},
-		},
-		{
-			name:                  "With IPv6 and resolution capability",
-			nicID:                 nicID,
-			netProtoFactory:       []stack.NetworkProtocolFactory{ipv6.NewProtocol},
-			extraLinkCapabilities: stack.CapabilityResolutionRequired,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			clock := faketime.NewManualClock()
-			s := stack.New(stack.Options{
-				NUDConfigs:       stack.DefaultNUDConfigurations(),
-				NetworkProtocols: test.netProtoFactory,
-				Clock:            clock,
-			})
-
-			e := channel.New(0, 0, linkAddr1)
-			e.LinkEPCapabilities &^= stack.CapabilityResolutionRequired
-			e.LinkEPCapabilities |= test.extraLinkCapabilities
-
-			if err := s.CreateNIC(nicID, e); err != nil {
-				t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
-			}
-
-			configs := stack.DefaultNUDConfigurations()
-			configs.BaseReachableTime = time.Hour
-
-			{
-				err := s.SetNUDConfigurations(test.nicID, ipv6.ProtocolNumber, configs)
-				if diff := cmp.Diff(test.expectedErr, err); diff != "" {
-					t.Errorf("s.SetNUDConfigurations(%d, %d, _) error mismatch (-want +got):\n%s", test.nicID, ipv6.ProtocolNumber, diff)
-				}
-			}
-
-			{
-				gotConfigs, err := s.NUDConfigurations(test.nicID, ipv6.ProtocolNumber)
-				if diff := cmp.Diff(test.expectedErr, err); diff != "" {
-					t.Errorf("s.NUDConfigurations(%d, %d) error mismatch (-want +got):\n%s", test.nicID, ipv6.ProtocolNumber, diff)
-				} else if test.expectedErr == nil {
-					if diff := cmp.Diff(configs, gotConfigs); diff != "" {
-						t.Errorf("got configs mismatch (-want +got):\n%s", diff)
-					}
-				}
-			}
-
-			for _, addr := range []tcpip.Address{llAddr1, llAddr2} {
-				{
-					err := s.AddStaticNeighbor(test.nicID, ipv6.ProtocolNumber, addr, linkAddr1)
-					if diff := cmp.Diff(test.expectedErr, err); diff != "" {
-						t.Errorf("s.AddStaticNeighbor(%d, %d, %s, %s) error mismatch (-want +got):\n%s", test.nicID, ipv6.ProtocolNumber, addr, linkAddr1, diff)
-					}
-				}
-			}
-
-			{
-				wantErr := test.expectedErr
-				for i := 0; i < 2; i++ {
-					{
-						err := s.RemoveNeighbor(test.nicID, ipv6.ProtocolNumber, llAddr1)
-						if diff := cmp.Diff(wantErr, err); diff != "" {
-							t.Errorf("s.RemoveNeighbor(%d, %d, '') error mismatch (-want +got):\n%s", test.nicID, ipv6.ProtocolNumber, diff)
-						}
-					}
-
-					if test.expectedErr != nil {
-						break
-					}
-
-					// Removing a neighbor that does not exist should give us a bad address
-					// error.
-					wantErr = &tcpip.ErrBadAddress{}
-				}
-			}
-
-			{
-				neighbors, err := s.Neighbors(test.nicID, ipv6.ProtocolNumber)
-				if diff := cmp.Diff(test.expectedErr, err); diff != "" {
-					t.Errorf("s.Neigbors(%d, %d) error mismatch (-want +got):\n%s", test.nicID, ipv6.ProtocolNumber, diff)
-				} else if test.expectedErr == nil {
-					if diff := cmp.Diff(
-						[]stack.NeighborEntry{{Addr: llAddr2, LinkAddr: linkAddr1, State: stack.Static, UpdatedAtNanos: clock.NowNanoseconds()}},
-						neighbors,
-					); diff != "" {
-						t.Errorf("neighbors mismatch (-want +got):\n%s", diff)
-					}
-				}
-			}
-
-			{
-				err := s.ClearNeighbors(test.nicID, ipv6.ProtocolNumber)
-				if diff := cmp.Diff(test.expectedErr, err); diff != "" {
-					t.Errorf("s.ClearNeigbors(%d, %d) error mismatch (-want +got):\n%s", test.nicID, ipv6.ProtocolNumber, diff)
-				} else if test.expectedErr == nil {
-					if neighbors, err := s.Neighbors(test.nicID, ipv6.ProtocolNumber); err != nil {
-						t.Errorf("s.Neighbors(%d, %d): %s", test.nicID, ipv6.ProtocolNumber, err)
-					} else if len(neighbors) != 0 {
-						t.Errorf("got len(neighbors) = %d, want = 0; neighbors = %#v", len(neighbors), neighbors)
-					}
-				}
-			}
-		})
-	}
-}
-
-func TestDefaultNUDConfigurations(t *testing.T) {
-	const nicID = 1
-
-	e := channel.New(0, 1280, linkAddr1)
-	e.LinkEPCapabilities |= stack.CapabilityResolutionRequired
-
-	s := stack.New(stack.Options{
-		// A neighbor cache is required to store NUDConfigurations. The networking
-		// stack will only allocate neighbor caches if a protocol providing link
-		// address resolution is specified (e.g. ARP or IPv6).
-		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocol},
-		NUDConfigs:       stack.DefaultNUDConfigurations(),
-	})
-	if err := s.CreateNIC(nicID, e); err != nil {
-		t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
-	}
-	c, err := s.NUDConfigurations(nicID, ipv6.ProtocolNumber)
-	if err != nil {
-		t.Fatalf("got stack.NUDConfigurations(%d, %d) = %s", nicID, ipv6.ProtocolNumber, err)
-	}
-	if got, want := c, stack.DefaultNUDConfigurations(); got != want {
-		t.Errorf("got stack.NUDConfigurations(%d, %d) = %+v, want = %+v", nicID, ipv6.ProtocolNumber, got, want)
-	}
-}
-
-func TestNUDConfigurationsBaseReachableTime(t *testing.T) {
-	tests := []struct {
-		name              string
-		baseReachableTime time.Duration
-		want              time.Duration
-	}{
-		// Invalid cases
-		{
-			name:              "EqualToZero",
-			baseReachableTime: 0,
-			want:              defaultBaseReachableTime,
-		},
-		// Valid cases
-		{
-			name:              "MoreThanZero",
-			baseReachableTime: time.Millisecond,
-			want:              time.Millisecond,
-		},
-		{
-			name:              "MoreThanDefaultBaseReachableTime",
-			baseReachableTime: 2 * defaultBaseReachableTime,
-			want:              2 * defaultBaseReachableTime,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			const nicID = 1
-
-			c := stack.DefaultNUDConfigurations()
-			c.BaseReachableTime = test.baseReachableTime
-
-			e := channel.New(0, 1280, linkAddr1)
-			e.LinkEPCapabilities |= stack.CapabilityResolutionRequired
-
-			s := stack.New(stack.Options{
-				// A neighbor cache is required to store NUDConfigurations. The
-				// networking stack will only allocate neighbor caches if a protocol
-				// providing link address resolution is specified (e.g. ARP or IPv6).
-				NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocol},
-				NUDConfigs:       c,
-			})
-			if err := s.CreateNIC(nicID, e); err != nil {
-				t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
-			}
-			sc, err := s.NUDConfigurations(nicID, ipv6.ProtocolNumber)
-			if err != nil {
-				t.Fatalf("got stack.NUDConfigurations(%d, %d) = %s", nicID, ipv6.ProtocolNumber, err)
-			}
-			if got := sc.BaseReachableTime; got != test.want {
-				t.Errorf("got BaseReachableTime = %q, want = %q", got, test.want)
-			}
-		})
-	}
-}
-
-func TestNUDConfigurationsMinRandomFactor(t *testing.T) {
-	tests := []struct {
-		name            string
-		minRandomFactor float32
-		want            float32
-	}{
-		// Invalid cases
-		{
-			name:            "LessThanZero",
-			minRandomFactor: -1,
-			want:            defaultMinRandomFactor,
-		},
-		{
-			name:            "EqualToZero",
-			minRandomFactor: 0,
-			want:            defaultMinRandomFactor,
-		},
-		// Valid cases
-		{
-			name:            "MoreThanZero",
-			minRandomFactor: 1,
-			want:            1,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			const nicID = 1
-
-			c := stack.DefaultNUDConfigurations()
-			c.MinRandomFactor = test.minRandomFactor
-
-			e := channel.New(0, 1280, linkAddr1)
-			e.LinkEPCapabilities |= stack.CapabilityResolutionRequired
-
-			s := stack.New(stack.Options{
-				// A neighbor cache is required to store NUDConfigurations. The
-				// networking stack will only allocate neighbor caches if a protocol
-				// providing link address resolution is specified (e.g. ARP or IPv6).
-				NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocol},
-				NUDConfigs:       c,
-			})
-			if err := s.CreateNIC(nicID, e); err != nil {
-				t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
-			}
-			sc, err := s.NUDConfigurations(nicID, ipv6.ProtocolNumber)
-			if err != nil {
-				t.Fatalf("got stack.NUDConfigurations(%d, %d) = %s", nicID, ipv6.ProtocolNumber, err)
-			}
-			if got := sc.MinRandomFactor; got != test.want {
-				t.Errorf("got MinRandomFactor = %f, want = %f", got, test.want)
-			}
-		})
-	}
-}
-
-func TestNUDConfigurationsMaxRandomFactor(t *testing.T) {
-	tests := []struct {
-		name            string
-		minRandomFactor float32
-		maxRandomFactor float32
-		want            float32
-	}{
-		// Invalid cases
-		{
-			name:            "LessThanZero",
-			minRandomFactor: defaultMinRandomFactor,
-			maxRandomFactor: -1,
-			want:            defaultMaxRandomFactor,
-		},
-		{
-			name:            "EqualToZero",
-			minRandomFactor: defaultMinRandomFactor,
-			maxRandomFactor: 0,
-			want:            defaultMaxRandomFactor,
-		},
-		{
-			name:            "LessThanMinRandomFactor",
-			minRandomFactor: defaultMinRandomFactor,
-			maxRandomFactor: defaultMinRandomFactor * 0.99,
-			want:            defaultMaxRandomFactor,
-		},
-		{
-			name:            "MoreThanMinRandomFactorWhenMinRandomFactorIsLargerThanMaxRandomFactorDefault",
-			minRandomFactor: defaultMaxRandomFactor * 2,
-			maxRandomFactor: defaultMaxRandomFactor,
-			want:            defaultMaxRandomFactor * 6,
-		},
-		// Valid cases
-		{
-			name:            "EqualToMinRandomFactor",
-			minRandomFactor: defaultMinRandomFactor,
-			maxRandomFactor: defaultMinRandomFactor,
-			want:            defaultMinRandomFactor,
-		},
-		{
-			name:            "MoreThanMinRandomFactor",
-			minRandomFactor: defaultMinRandomFactor,
-			maxRandomFactor: defaultMinRandomFactor * 1.1,
-			want:            defaultMinRandomFactor * 1.1,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			const nicID = 1
-
-			c := stack.DefaultNUDConfigurations()
-			c.MinRandomFactor = test.minRandomFactor
-			c.MaxRandomFactor = test.maxRandomFactor
-
-			e := channel.New(0, 1280, linkAddr1)
-			e.LinkEPCapabilities |= stack.CapabilityResolutionRequired
-
-			s := stack.New(stack.Options{
-				// A neighbor cache is required to store NUDConfigurations. The
-				// networking stack will only allocate neighbor caches if a protocol
-				// providing link address resolution is specified (e.g. ARP or IPv6).
-				NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocol},
-				NUDConfigs:       c,
-			})
-			if err := s.CreateNIC(nicID, e); err != nil {
-				t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
-			}
-			sc, err := s.NUDConfigurations(nicID, ipv6.ProtocolNumber)
-			if err != nil {
-				t.Fatalf("got stack.NUDConfigurations(%d, %d) = %s", nicID, ipv6.ProtocolNumber, err)
-			}
-			if got := sc.MaxRandomFactor; got != test.want {
-				t.Errorf("got MaxRandomFactor = %f, want = %f", got, test.want)
-			}
-		})
-	}
-}
-
-func TestNUDConfigurationsRetransmitTimer(t *testing.T) {
-	tests := []struct {
-		name            string
-		retransmitTimer time.Duration
-		want            time.Duration
-	}{
-		// Invalid cases
-		{
-			name:            "EqualToZero",
-			retransmitTimer: 0,
-			want:            defaultRetransmitTimer,
-		},
-		{
-			name:            "LessThanMinimumRetransmitTimer",
-			retransmitTimer: minimumRetransmitTimer - time.Nanosecond,
-			want:            defaultRetransmitTimer,
-		},
-		// Valid cases
-		{
-			name:            "EqualToMinimumRetransmitTimer",
-			retransmitTimer: minimumRetransmitTimer,
-			want:            minimumBaseReachableTime,
-		},
-		{
-			name:            "LargetThanMinimumRetransmitTimer",
-			retransmitTimer: 2 * minimumBaseReachableTime,
-			want:            2 * minimumBaseReachableTime,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			const nicID = 1
-
-			c := stack.DefaultNUDConfigurations()
-			c.RetransmitTimer = test.retransmitTimer
-
-			e := channel.New(0, 1280, linkAddr1)
-			e.LinkEPCapabilities |= stack.CapabilityResolutionRequired
-
-			s := stack.New(stack.Options{
-				// A neighbor cache is required to store NUDConfigurations. The
-				// networking stack will only allocate neighbor caches if a protocol
-				// providing link address resolution is specified (e.g. ARP or IPv6).
-				NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocol},
-				NUDConfigs:       c,
-			})
-			if err := s.CreateNIC(nicID, e); err != nil {
-				t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
-			}
-			sc, err := s.NUDConfigurations(nicID, ipv6.ProtocolNumber)
-			if err != nil {
-				t.Fatalf("got stack.NUDConfigurations(%d, %d) = %s", nicID, ipv6.ProtocolNumber, err)
-			}
-			if got := sc.RetransmitTimer; got != test.want {
-				t.Errorf("got RetransmitTimer = %q, want = %q", got, test.want)
-			}
-		})
-	}
-}
-
-func TestNUDConfigurationsDelayFirstProbeTime(t *testing.T) {
-	tests := []struct {
-		name                string
-		delayFirstProbeTime time.Duration
-		want                time.Duration
-	}{
-		// Invalid cases
-		{
-			name:                "EqualToZero",
-			delayFirstProbeTime: 0,
-			want:                defaultDelayFirstProbeTime,
-		},
-		// Valid cases
-		{
-			name:                "MoreThanZero",
-			delayFirstProbeTime: time.Millisecond,
-			want:                time.Millisecond,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			const nicID = 1
-
-			c := stack.DefaultNUDConfigurations()
-			c.DelayFirstProbeTime = test.delayFirstProbeTime
-
-			e := channel.New(0, 1280, linkAddr1)
-			e.LinkEPCapabilities |= stack.CapabilityResolutionRequired
-
-			s := stack.New(stack.Options{
-				// A neighbor cache is required to store NUDConfigurations. The
-				// networking stack will only allocate neighbor caches if a protocol
-				// providing link address resolution is specified (e.g. ARP or IPv6).
-				NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocol},
-				NUDConfigs:       c,
-			})
-			if err := s.CreateNIC(nicID, e); err != nil {
-				t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
-			}
-			sc, err := s.NUDConfigurations(nicID, ipv6.ProtocolNumber)
-			if err != nil {
-				t.Fatalf("got stack.NUDConfigurations(%d, %d) = %s", nicID, ipv6.ProtocolNumber, err)
-			}
-			if got := sc.DelayFirstProbeTime; got != test.want {
-				t.Errorf("got DelayFirstProbeTime = %q, want = %q", got, test.want)
-			}
-		})
-	}
-}
-
-func TestNUDConfigurationsMaxMulticastProbes(t *testing.T) {
-	tests := []struct {
-		name               string
-		maxMulticastProbes uint32
-		want               uint32
-	}{
-		// Invalid cases
-		{
-			name:               "EqualToZero",
-			maxMulticastProbes: 0,
-			want:               defaultMaxMulticastProbes,
-		},
-		// Valid cases
-		{
-			name:               "MoreThanZero",
-			maxMulticastProbes: 1,
-			want:               1,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			const nicID = 1
-
-			c := stack.DefaultNUDConfigurations()
-			c.MaxMulticastProbes = test.maxMulticastProbes
-
-			e := channel.New(0, 1280, linkAddr1)
-			e.LinkEPCapabilities |= stack.CapabilityResolutionRequired
-
-			s := stack.New(stack.Options{
-				// A neighbor cache is required to store NUDConfigurations. The
-				// networking stack will only allocate neighbor caches if a protocol
-				// providing link address resolution is specified (e.g. ARP or IPv6).
-				NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocol},
-				NUDConfigs:       c,
-			})
-			if err := s.CreateNIC(nicID, e); err != nil {
-				t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
-			}
-			sc, err := s.NUDConfigurations(nicID, ipv6.ProtocolNumber)
-			if err != nil {
-				t.Fatalf("got stack.NUDConfigurations(%d, %d) = %s", nicID, ipv6.ProtocolNumber, err)
-			}
-			if got := sc.MaxMulticastProbes; got != test.want {
-				t.Errorf("got MaxMulticastProbes = %q, want = %q", got, test.want)
-			}
-		})
-	}
-}
-
-func TestNUDConfigurationsMaxUnicastProbes(t *testing.T) {
-	tests := []struct {
-		name             string
-		maxUnicastProbes uint32
-		want             uint32
-	}{
-		// Invalid cases
-		{
-			name:             "EqualToZero",
-			maxUnicastProbes: 0,
-			want:             defaultMaxUnicastProbes,
-		},
-		// Valid cases
-		{
-			name:             "MoreThanZero",
-			maxUnicastProbes: 1,
-			want:             1,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			const nicID = 1
-
-			c := stack.DefaultNUDConfigurations()
-			c.MaxUnicastProbes = test.maxUnicastProbes
-
-			e := channel.New(0, 1280, linkAddr1)
-			e.LinkEPCapabilities |= stack.CapabilityResolutionRequired
-
-			s := stack.New(stack.Options{
-				// A neighbor cache is required to store NUDConfigurations. The
-				// networking stack will only allocate neighbor caches if a protocol
-				// providing link address resolution is specified (e.g. ARP or IPv6).
-				NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocol},
-				NUDConfigs:       c,
-			})
-			if err := s.CreateNIC(nicID, e); err != nil {
-				t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
-			}
-			sc, err := s.NUDConfigurations(nicID, ipv6.ProtocolNumber)
-			if err != nil {
-				t.Fatalf("got stack.NUDConfigurations(%d, %d) = %s", nicID, ipv6.ProtocolNumber, err)
-			}
-			if got := sc.MaxUnicastProbes; got != test.want {
-				t.Errorf("got MaxUnicastProbes = %q, want = %q", got, test.want)
-			}
-		})
-	}
-}
-
-// TestNUDStateReachableTime verifies the correctness of the ReachableTime
-// computation.
-func TestNUDStateReachableTime(t *testing.T) {
-	tests := []struct {
-		name              string
-		baseReachableTime time.Duration
-		minRandomFactor   float32
-		maxRandomFactor   float32
-		want              time.Duration
-	}{
-		{
-			name:              "AllZeros",
-			baseReachableTime: 0,
-			minRandomFactor:   0,
-			maxRandomFactor:   0,
-			want:              0,
-		},
-		{
-			name:              "ZeroMaxRandomFactor",
-			baseReachableTime: time.Second,
-			minRandomFactor:   0,
-			maxRandomFactor:   0,
-			want:              0,
-		},
-		{
-			name:              "ZeroMinRandomFactor",
-			baseReachableTime: time.Second,
-			minRandomFactor:   0,
-			maxRandomFactor:   1,
-			want:              time.Duration(defaultFakeRandomNum * float32(time.Second)),
-		},
-		{
-			name:              "FractionalRandomFactor",
-			baseReachableTime: time.Duration(math.MaxInt64),
-			minRandomFactor:   0.001,
-			maxRandomFactor:   0.002,
-			want:              time.Duration((0.001 + (0.001 * defaultFakeRandomNum)) * float32(math.MaxInt64)),
-		},
-		{
-			name:              "MinAndMaxRandomFactorsEqual",
-			baseReachableTime: time.Second,
-			minRandomFactor:   1,
-			maxRandomFactor:   1,
-			want:              time.Second,
-		},
-		{
-			name:              "MinAndMaxRandomFactorsDifferent",
-			baseReachableTime: time.Second,
-			minRandomFactor:   1,
-			maxRandomFactor:   2,
-			want:              time.Duration((1.0 + defaultFakeRandomNum) * float32(time.Second)),
-		},
-		{
-			name:              "MaxInt64",
-			baseReachableTime: time.Duration(math.MaxInt64),
-			minRandomFactor:   1,
-			maxRandomFactor:   1,
-			want:              time.Duration(math.MaxInt64),
-		},
-		{
-			name:              "Overflow",
-			baseReachableTime: time.Duration(math.MaxInt64),
-			minRandomFactor:   1.5,
-			maxRandomFactor:   1.5,
-			want:              time.Duration(math.MaxInt64),
-		},
-		{
-			name:              "DoubleOverflow",
-			baseReachableTime: time.Duration(math.MaxInt64),
-			minRandomFactor:   2.5,
-			maxRandomFactor:   2.5,
-			want:              time.Duration(math.MaxInt64),
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			c := stack.NUDConfigurations{
-				BaseReachableTime: test.baseReachableTime,
-				MinRandomFactor:   test.minRandomFactor,
-				MaxRandomFactor:   test.maxRandomFactor,
-			}
-			// A fake random number generator is used to ensure deterministic
-			// results.
-			rng := fakeRand{
-				num: defaultFakeRandomNum,
-			}
-			s := stack.NewNUDState(c, &rng)
-			if got, want := s.ReachableTime(), test.want; got != want {
-				t.Errorf("got ReachableTime = %q, want = %q", got, want)
-			}
-		})
-	}
-}
-
-// TestNUDStateRecomputeReachableTime exercises the ReachableTime function
-// twice to verify recomputation of reachable time when the min random factor,
-// max random factor, or base reachable time changes.
-func TestNUDStateRecomputeReachableTime(t *testing.T) {
-	const defaultBase = time.Second
-	const defaultMin = 2.0 * defaultMaxRandomFactor
-	const defaultMax = 3.0 * defaultMaxRandomFactor
-
-	tests := []struct {
-		name              string
-		baseReachableTime time.Duration
-		minRandomFactor   float32
-		maxRandomFactor   float32
-		want              time.Duration
-	}{
-		{
-			name:              "BaseReachableTime",
-			baseReachableTime: 2 * defaultBase,
-			minRandomFactor:   defaultMin,
-			maxRandomFactor:   defaultMax,
-			want:              time.Duration((defaultMin + (defaultMax-defaultMin)*defaultFakeRandomNum) * float32(2*defaultBase)),
-		},
-		{
-			name:              "MinRandomFactor",
-			baseReachableTime: defaultBase,
-			minRandomFactor:   defaultMax,
-			maxRandomFactor:   defaultMax,
-			want:              time.Duration(defaultMax * float32(defaultBase)),
-		},
-		{
-			name:              "MaxRandomFactor",
-			baseReachableTime: defaultBase,
-			minRandomFactor:   defaultMin,
-			maxRandomFactor:   defaultMin,
-			want:              time.Duration(defaultMin * float32(defaultBase)),
-		},
-		{
-			name:              "BothRandomFactor",
-			baseReachableTime: defaultBase,
-			minRandomFactor:   2 * defaultMin,
-			maxRandomFactor:   2 * defaultMax,
-			want:              time.Duration((2*defaultMin + (2*defaultMax-2*defaultMin)*defaultFakeRandomNum) * float32(defaultBase)),
-		},
-		{
-			name:              "BaseReachableTimeAndBothRandomFactors",
-			baseReachableTime: 2 * defaultBase,
-			minRandomFactor:   2 * defaultMin,
-			maxRandomFactor:   2 * defaultMax,
-			want:              time.Duration((2*defaultMin + (2*defaultMax-2*defaultMin)*defaultFakeRandomNum) * float32(2*defaultBase)),
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			c := stack.DefaultNUDConfigurations()
-			c.BaseReachableTime = defaultBase
-			c.MinRandomFactor = defaultMin
-			c.MaxRandomFactor = defaultMax
-
-			// A fake random number generator is used to ensure deterministic
-			// results.
-			rng := fakeRand{
-				num: defaultFakeRandomNum,
-			}
-			s := stack.NewNUDState(c, &rng)
-			old := s.ReachableTime()
-
-			if got, want := s.ReachableTime(), old; got != want {
-				t.Errorf("got ReachableTime = %q, want = %q", got, want)
-			}
-
-			// Check for recomputation when changing the min random factor, the max
-			// random factor, the base reachability time, or any permutation of those
-			// three options.
-			c.BaseReachableTime = test.baseReachableTime
-			c.MinRandomFactor = test.minRandomFactor
-			c.MaxRandomFactor = test.maxRandomFactor
-			s.SetConfig(c)
-
-			if got, want := s.ReachableTime(), test.want; got != want {
-				t.Errorf("got ReachableTime = %q, want = %q", got, want)
-			}
-
-			// Verify that ReachableTime isn't recomputed when none of the
-			// configuration options change. The random factor is changed so that if
-			// a recompution were to occur, ReachableTime would change.
-			rng.num = defaultFakeRandomNum / 2.0
-			if got, want := s.ReachableTime(), test.want; got != want {
-				t.Errorf("got ReachableTime = %q, want = %q", got, want)
-			}
-		})
-	}
-}
diff --git a/pkg/tcpip/stack/packet_buffer_list.go b/pkg/tcpip/stack/packet_buffer_list.go
new file mode 100644
index 0000000..ce7057d
--- /dev/null
+++ b/pkg/tcpip/stack/packet_buffer_list.go
@@ -0,0 +1,221 @@
+package stack
+
+// ElementMapper provides an identity mapping by default.
+//
+// This can be replaced to provide a struct that maps elements to linker
+// objects, if they are not the same. An ElementMapper is not typically
+// required if: Linker is left as is, Element is left as is, or Linker and
+// Element are the same type.
+type PacketBufferElementMapper struct{}
+
+// linkerFor maps an Element to a Linker.
+//
+// This default implementation should be inlined.
+//
+//go:nosplit
+func (PacketBufferElementMapper) linkerFor(elem *PacketBuffer) *PacketBuffer { return elem }
+
+// List is an intrusive list. Entries can be added to or removed from the list
+// in O(1) time and with no additional memory allocations.
+//
+// The zero value for List is an empty list ready to use.
+//
+// To iterate over a list (where l is a List):
+//      for e := l.Front(); e != nil; e = e.Next() {
+// 		// do something with e.
+//      }
+//
+// +stateify savable
+type PacketBufferList struct {
+	head *PacketBuffer
+	tail *PacketBuffer
+}
+
+// Reset resets list l to the empty state.
+func (l *PacketBufferList) Reset() {
+	l.head = nil
+	l.tail = nil
+}
+
+// Empty returns true iff the list is empty.
+//
+//go:nosplit
+func (l *PacketBufferList) Empty() bool {
+	return l.head == nil
+}
+
+// Front returns the first element of list l or nil.
+//
+//go:nosplit
+func (l *PacketBufferList) Front() *PacketBuffer {
+	return l.head
+}
+
+// Back returns the last element of list l or nil.
+//
+//go:nosplit
+func (l *PacketBufferList) Back() *PacketBuffer {
+	return l.tail
+}
+
+// Len returns the number of elements in the list.
+//
+// NOTE: This is an O(n) operation.
+//
+//go:nosplit
+func (l *PacketBufferList) Len() (count int) {
+	for e := l.Front(); e != nil; e = (PacketBufferElementMapper{}.linkerFor(e)).Next() {
+		count++
+	}
+	return count
+}
+
+// PushFront inserts the element e at the front of list l.
+//
+//go:nosplit
+func (l *PacketBufferList) PushFront(e *PacketBuffer) {
+	linker := PacketBufferElementMapper{}.linkerFor(e)
+	linker.SetNext(l.head)
+	linker.SetPrev(nil)
+	if l.head != nil {
+		PacketBufferElementMapper{}.linkerFor(l.head).SetPrev(e)
+	} else {
+		l.tail = e
+	}
+
+	l.head = e
+}
+
+// PushBack inserts the element e at the back of list l.
+//
+//go:nosplit
+func (l *PacketBufferList) PushBack(e *PacketBuffer) {
+	linker := PacketBufferElementMapper{}.linkerFor(e)
+	linker.SetNext(nil)
+	linker.SetPrev(l.tail)
+	if l.tail != nil {
+		PacketBufferElementMapper{}.linkerFor(l.tail).SetNext(e)
+	} else {
+		l.head = e
+	}
+
+	l.tail = e
+}
+
+// PushBackList inserts list m at the end of list l, emptying m.
+//
+//go:nosplit
+func (l *PacketBufferList) PushBackList(m *PacketBufferList) {
+	if l.head == nil {
+		l.head = m.head
+		l.tail = m.tail
+	} else if m.head != nil {
+		PacketBufferElementMapper{}.linkerFor(l.tail).SetNext(m.head)
+		PacketBufferElementMapper{}.linkerFor(m.head).SetPrev(l.tail)
+
+		l.tail = m.tail
+	}
+	m.head = nil
+	m.tail = nil
+}
+
+// InsertAfter inserts e after b.
+//
+//go:nosplit
+func (l *PacketBufferList) InsertAfter(b, e *PacketBuffer) {
+	bLinker := PacketBufferElementMapper{}.linkerFor(b)
+	eLinker := PacketBufferElementMapper{}.linkerFor(e)
+
+	a := bLinker.Next()
+
+	eLinker.SetNext(a)
+	eLinker.SetPrev(b)
+	bLinker.SetNext(e)
+
+	if a != nil {
+		PacketBufferElementMapper{}.linkerFor(a).SetPrev(e)
+	} else {
+		l.tail = e
+	}
+}
+
+// InsertBefore inserts e before a.
+//
+//go:nosplit
+func (l *PacketBufferList) InsertBefore(a, e *PacketBuffer) {
+	aLinker := PacketBufferElementMapper{}.linkerFor(a)
+	eLinker := PacketBufferElementMapper{}.linkerFor(e)
+
+	b := aLinker.Prev()
+	eLinker.SetNext(a)
+	eLinker.SetPrev(b)
+	aLinker.SetPrev(e)
+
+	if b != nil {
+		PacketBufferElementMapper{}.linkerFor(b).SetNext(e)
+	} else {
+		l.head = e
+	}
+}
+
+// Remove removes e from l.
+//
+//go:nosplit
+func (l *PacketBufferList) Remove(e *PacketBuffer) {
+	linker := PacketBufferElementMapper{}.linkerFor(e)
+	prev := linker.Prev()
+	next := linker.Next()
+
+	if prev != nil {
+		PacketBufferElementMapper{}.linkerFor(prev).SetNext(next)
+	} else if l.head == e {
+		l.head = next
+	}
+
+	if next != nil {
+		PacketBufferElementMapper{}.linkerFor(next).SetPrev(prev)
+	} else if l.tail == e {
+		l.tail = prev
+	}
+
+	linker.SetNext(nil)
+	linker.SetPrev(nil)
+}
+
+// Entry is a default implementation of Linker. Users can add anonymous fields
+// of this type to their structs to make them automatically implement the
+// methods needed by List.
+//
+// +stateify savable
+type PacketBufferEntry struct {
+	next *PacketBuffer
+	prev *PacketBuffer
+}
+
+// Next returns the entry that follows e in the list.
+//
+//go:nosplit
+func (e *PacketBufferEntry) Next() *PacketBuffer {
+	return e.next
+}
+
+// Prev returns the entry that precedes e in the list.
+//
+//go:nosplit
+func (e *PacketBufferEntry) Prev() *PacketBuffer {
+	return e.prev
+}
+
+// SetNext assigns 'entry' as the entry that follows e in the list.
+//
+//go:nosplit
+func (e *PacketBufferEntry) SetNext(elem *PacketBuffer) {
+	e.next = elem
+}
+
+// SetPrev assigns 'entry' as the entry that precedes e in the list.
+//
+//go:nosplit
+func (e *PacketBufferEntry) SetPrev(elem *PacketBuffer) {
+	e.prev = elem
+}
diff --git a/pkg/tcpip/stack/packet_buffer_test.go b/pkg/tcpip/stack/packet_buffer_test.go
deleted file mode 100644
index 6728370..0000000
--- a/pkg/tcpip/stack/packet_buffer_test.go
+++ /dev/null
@@ -1,615 +0,0 @@
-// Copyright 2020 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
-
-import (
-	"bytes"
-	"fmt"
-	"testing"
-
-	"gvisor.dev/gvisor/pkg/tcpip/buffer"
-	"gvisor.dev/gvisor/pkg/tcpip/header"
-)
-
-func TestPacketHeaderPush(t *testing.T) {
-	for _, test := range []struct {
-		name      string
-		reserved  int
-		link      []byte
-		network   []byte
-		transport []byte
-		data      []byte
-	}{
-		{
-			name: "construct empty packet",
-		},
-		{
-			name:     "construct link header only packet",
-			reserved: 60,
-			link:     makeView(10),
-		},
-		{
-			name:     "construct link and network header only packet",
-			reserved: 60,
-			link:     makeView(10),
-			network:  makeView(20),
-		},
-		{
-			name:      "construct header only packet",
-			reserved:  60,
-			link:      makeView(10),
-			network:   makeView(20),
-			transport: makeView(30),
-		},
-		{
-			name: "construct data only packet",
-			data: makeView(40),
-		},
-		{
-			name:      "construct L3 packet",
-			reserved:  60,
-			network:   makeView(20),
-			transport: makeView(30),
-			data:      makeView(40),
-		},
-		{
-			name:      "construct L2 packet",
-			reserved:  60,
-			link:      makeView(10),
-			network:   makeView(20),
-			transport: makeView(30),
-			data:      makeView(40),
-		},
-	} {
-		t.Run(test.name, func(t *testing.T) {
-			pk := NewPacketBuffer(PacketBufferOptions{
-				ReserveHeaderBytes: test.reserved,
-				// Make a copy of data to make sure our truth data won't be taint by
-				// PacketBuffer.
-				Data: buffer.NewViewFromBytes(test.data).ToVectorisedView(),
-			})
-
-			allHdrSize := len(test.link) + len(test.network) + len(test.transport)
-
-			// Check the initial values for packet.
-			checkInitialPacketBuffer(t, pk, PacketBufferOptions{
-				ReserveHeaderBytes: test.reserved,
-				Data:               buffer.View(test.data).ToVectorisedView(),
-			})
-
-			// Push headers.
-			if v := test.transport; len(v) > 0 {
-				copy(pk.TransportHeader().Push(len(v)), v)
-			}
-			if v := test.network; len(v) > 0 {
-				copy(pk.NetworkHeader().Push(len(v)), v)
-			}
-			if v := test.link; len(v) > 0 {
-				copy(pk.LinkHeader().Push(len(v)), v)
-			}
-
-			// Check the after values for packet.
-			if got, want := pk.ReservedHeaderBytes(), test.reserved; got != want {
-				t.Errorf("After pk.ReservedHeaderBytes() = %d, want %d", got, want)
-			}
-			if got, want := pk.AvailableHeaderBytes(), test.reserved-allHdrSize; got != want {
-				t.Errorf("After pk.AvailableHeaderBytes() = %d, want %d", got, want)
-			}
-			if got, want := pk.HeaderSize(), allHdrSize; got != want {
-				t.Errorf("After pk.HeaderSize() = %d, want %d", got, want)
-			}
-			if got, want := pk.Size(), allHdrSize+len(test.data); got != want {
-				t.Errorf("After pk.Size() = %d, want %d", got, want)
-			}
-			checkData(t, pk, test.data)
-			checkViewEqual(t, "After pk.Views()", concatViews(pk.Views()...),
-				concatViews(test.link, test.network, test.transport, test.data))
-			// Check the after values for each header.
-			checkPacketHeader(t, "After pk.LinkHeader", pk.LinkHeader(), test.link)
-			checkPacketHeader(t, "After pk.NetworkHeader", pk.NetworkHeader(), test.network)
-			checkPacketHeader(t, "After pk.TransportHeader", pk.TransportHeader(), test.transport)
-			// Check the after values for PayloadSince.
-			checkViewEqual(t, "After PayloadSince(LinkHeader)",
-				PayloadSince(pk.LinkHeader()),
-				concatViews(test.link, test.network, test.transport, test.data))
-			checkViewEqual(t, "After PayloadSince(NetworkHeader)",
-				PayloadSince(pk.NetworkHeader()),
-				concatViews(test.network, test.transport, test.data))
-			checkViewEqual(t, "After PayloadSince(TransportHeader)",
-				PayloadSince(pk.TransportHeader()),
-				concatViews(test.transport, test.data))
-		})
-	}
-}
-
-func TestPacketHeaderConsume(t *testing.T) {
-	for _, test := range []struct {
-		name      string
-		data      []byte
-		link      int
-		network   int
-		transport int
-	}{
-		{
-			name:      "parse L2 packet",
-			data:      concatViews(makeView(10), makeView(20), makeView(30), makeView(40)),
-			link:      10,
-			network:   20,
-			transport: 30,
-		},
-		{
-			name:      "parse L3 packet",
-			data:      concatViews(makeView(20), makeView(30), makeView(40)),
-			network:   20,
-			transport: 30,
-		},
-	} {
-		t.Run(test.name, func(t *testing.T) {
-			pk := NewPacketBuffer(PacketBufferOptions{
-				// Make a copy of data to make sure our truth data won't be taint by
-				// PacketBuffer.
-				Data: buffer.NewViewFromBytes(test.data).ToVectorisedView(),
-			})
-
-			// Check the initial values for packet.
-			checkInitialPacketBuffer(t, pk, PacketBufferOptions{
-				Data: buffer.View(test.data).ToVectorisedView(),
-			})
-
-			// Consume headers.
-			if size := test.link; size > 0 {
-				if _, ok := pk.LinkHeader().Consume(size); !ok {
-					t.Fatalf("pk.LinkHeader().Consume() = false, want true")
-				}
-			}
-			if size := test.network; size > 0 {
-				if _, ok := pk.NetworkHeader().Consume(size); !ok {
-					t.Fatalf("pk.NetworkHeader().Consume() = false, want true")
-				}
-			}
-			if size := test.transport; size > 0 {
-				if _, ok := pk.TransportHeader().Consume(size); !ok {
-					t.Fatalf("pk.TransportHeader().Consume() = false, want true")
-				}
-			}
-
-			allHdrSize := test.link + test.network + test.transport
-
-			// Check the after values for packet.
-			if got, want := pk.ReservedHeaderBytes(), 0; got != want {
-				t.Errorf("After pk.ReservedHeaderBytes() = %d, want %d", got, want)
-			}
-			if got, want := pk.AvailableHeaderBytes(), 0; got != want {
-				t.Errorf("After pk.AvailableHeaderBytes() = %d, want %d", got, want)
-			}
-			if got, want := pk.HeaderSize(), allHdrSize; got != want {
-				t.Errorf("After pk.HeaderSize() = %d, want %d", got, want)
-			}
-			if got, want := pk.Size(), len(test.data); got != want {
-				t.Errorf("After pk.Size() = %d, want %d", got, want)
-			}
-			// After state of pk.
-			var (
-				link      = test.data[:test.link]
-				network   = test.data[test.link:][:test.network]
-				transport = test.data[test.link+test.network:][:test.transport]
-				payload   = test.data[allHdrSize:]
-			)
-			checkData(t, pk, payload)
-			checkViewEqual(t, "After pk.Views()", concatViews(pk.Views()...), test.data)
-			// Check the after values for each header.
-			checkPacketHeader(t, "After pk.LinkHeader", pk.LinkHeader(), link)
-			checkPacketHeader(t, "After pk.NetworkHeader", pk.NetworkHeader(), network)
-			checkPacketHeader(t, "After pk.TransportHeader", pk.TransportHeader(), transport)
-			// Check the after values for PayloadSince.
-			checkViewEqual(t, "After PayloadSince(LinkHeader)",
-				PayloadSince(pk.LinkHeader()),
-				concatViews(link, network, transport, payload))
-			checkViewEqual(t, "After PayloadSince(NetworkHeader)",
-				PayloadSince(pk.NetworkHeader()),
-				concatViews(network, transport, payload))
-			checkViewEqual(t, "After PayloadSince(TransportHeader)",
-				PayloadSince(pk.TransportHeader()),
-				concatViews(transport, payload))
-		})
-	}
-}
-
-func TestPacketHeaderConsumeDataTooShort(t *testing.T) {
-	data := makeView(10)
-
-	pk := NewPacketBuffer(PacketBufferOptions{
-		// Make a copy of data to make sure our truth data won't be taint by
-		// PacketBuffer.
-		Data: buffer.NewViewFromBytes(data).ToVectorisedView(),
-	})
-
-	// Consume should fail if pkt.Data is too short.
-	if _, ok := pk.LinkHeader().Consume(11); ok {
-		t.Fatalf("pk.LinkHeader().Consume() = _, true; want _, false")
-	}
-	if _, ok := pk.NetworkHeader().Consume(11); ok {
-		t.Fatalf("pk.NetworkHeader().Consume() = _, true; want _, false")
-	}
-	if _, ok := pk.TransportHeader().Consume(11); ok {
-		t.Fatalf("pk.TransportHeader().Consume() = _, true; want _, false")
-	}
-
-	// Check packet should look the same as initial packet.
-	checkInitialPacketBuffer(t, pk, PacketBufferOptions{
-		Data: buffer.View(data).ToVectorisedView(),
-	})
-}
-
-func TestPacketHeaderPushCalledAtMostOnce(t *testing.T) {
-	const headerSize = 10
-
-	pk := NewPacketBuffer(PacketBufferOptions{
-		ReserveHeaderBytes: headerSize * int(numHeaderType),
-	})
-
-	for _, h := range []PacketHeader{
-		pk.TransportHeader(),
-		pk.NetworkHeader(),
-		pk.LinkHeader(),
-	} {
-		t.Run("PushedTwice/"+h.typ.String(), func(t *testing.T) {
-			h.Push(headerSize)
-
-			defer func() { recover() }()
-			h.Push(headerSize)
-			t.Fatal("Second push should have panicked")
-		})
-	}
-}
-
-func TestPacketHeaderConsumeCalledAtMostOnce(t *testing.T) {
-	const headerSize = 10
-
-	pk := NewPacketBuffer(PacketBufferOptions{
-		Data: makeView(headerSize * int(numHeaderType)).ToVectorisedView(),
-	})
-
-	for _, h := range []PacketHeader{
-		pk.LinkHeader(),
-		pk.NetworkHeader(),
-		pk.TransportHeader(),
-	} {
-		t.Run("ConsumedTwice/"+h.typ.String(), func(t *testing.T) {
-			if _, ok := h.Consume(headerSize); !ok {
-				t.Fatal("First consume should succeed")
-			}
-
-			defer func() { recover() }()
-			h.Consume(headerSize)
-			t.Fatal("Second consume should have panicked")
-		})
-	}
-}
-
-func TestPacketHeaderPushThenConsumePanics(t *testing.T) {
-	const headerSize = 10
-
-	pk := NewPacketBuffer(PacketBufferOptions{
-		ReserveHeaderBytes: headerSize * int(numHeaderType),
-	})
-
-	for _, h := range []PacketHeader{
-		pk.TransportHeader(),
-		pk.NetworkHeader(),
-		pk.LinkHeader(),
-	} {
-		t.Run(h.typ.String(), func(t *testing.T) {
-			h.Push(headerSize)
-
-			defer func() { recover() }()
-			h.Consume(headerSize)
-			t.Fatal("Consume should have panicked")
-		})
-	}
-}
-
-func TestPacketHeaderConsumeThenPushPanics(t *testing.T) {
-	const headerSize = 10
-
-	pk := NewPacketBuffer(PacketBufferOptions{
-		Data: makeView(headerSize * int(numHeaderType)).ToVectorisedView(),
-	})
-
-	for _, h := range []PacketHeader{
-		pk.LinkHeader(),
-		pk.NetworkHeader(),
-		pk.TransportHeader(),
-	} {
-		t.Run(h.typ.String(), func(t *testing.T) {
-			h.Consume(headerSize)
-
-			defer func() { recover() }()
-			h.Push(headerSize)
-			t.Fatal("Push should have panicked")
-		})
-	}
-}
-
-func TestPacketBufferData(t *testing.T) {
-	for _, tc := range []struct {
-		name    string
-		makePkt func(*testing.T) *PacketBuffer
-		data    string
-	}{
-		{
-			name: "inbound packet",
-			makePkt: func(*testing.T) *PacketBuffer {
-				pkt := NewPacketBuffer(PacketBufferOptions{
-					Data: vv("aabbbbccccccDATA"),
-				})
-				pkt.LinkHeader().Consume(2)
-				pkt.NetworkHeader().Consume(4)
-				pkt.TransportHeader().Consume(6)
-				return pkt
-			},
-			data: "DATA",
-		},
-		{
-			name: "outbound packet",
-			makePkt: func(*testing.T) *PacketBuffer {
-				pkt := NewPacketBuffer(PacketBufferOptions{
-					ReserveHeaderBytes: 12,
-					Data:               vv("DATA"),
-				})
-				copy(pkt.TransportHeader().Push(6), []byte("cccccc"))
-				copy(pkt.NetworkHeader().Push(4), []byte("bbbb"))
-				copy(pkt.LinkHeader().Push(2), []byte("aa"))
-				return pkt
-			},
-			data: "DATA",
-		},
-	} {
-		t.Run(tc.name, func(t *testing.T) {
-			// PullUp
-			for _, n := range []int{1, len(tc.data)} {
-				t.Run(fmt.Sprintf("PullUp%d", n), func(t *testing.T) {
-					pkt := tc.makePkt(t)
-					v, ok := pkt.Data().PullUp(n)
-					wantV := []byte(tc.data)[:n]
-					if !ok || !bytes.Equal(v, wantV) {
-						t.Errorf("pkt.Data().PullUp(%d) = %q, %t; want %q, true", n, v, ok, wantV)
-					}
-				})
-			}
-			t.Run("PullUpOutOfBounds", func(t *testing.T) {
-				n := len(tc.data) + 1
-				pkt := tc.makePkt(t)
-				v, ok := pkt.Data().PullUp(n)
-				if ok || v != nil {
-					t.Errorf("pkt.Data().PullUp(%d) = %q, %t; want nil, false", n, v, ok)
-				}
-			})
-
-			// TrimFront
-			for _, n := range []int{1, len(tc.data)} {
-				t.Run(fmt.Sprintf("TrimFront%d", n), func(t *testing.T) {
-					pkt := tc.makePkt(t)
-					pkt.Data().TrimFront(n)
-
-					checkData(t, pkt, []byte(tc.data)[n:])
-				})
-			}
-
-			// CapLength
-			for _, n := range []int{0, 1, len(tc.data)} {
-				t.Run(fmt.Sprintf("CapLength%d", n), func(t *testing.T) {
-					pkt := tc.makePkt(t)
-					pkt.Data().CapLength(n)
-
-					want := []byte(tc.data)
-					if n < len(want) {
-						want = want[:n]
-					}
-					checkData(t, pkt, want)
-				})
-			}
-
-			// Views
-			t.Run("Views", func(t *testing.T) {
-				pkt := tc.makePkt(t)
-				checkData(t, pkt, []byte(tc.data))
-			})
-
-			// AppendView
-			t.Run("AppendView", func(t *testing.T) {
-				s := "APPEND"
-
-				pkt := tc.makePkt(t)
-				pkt.Data().AppendView(buffer.View(s))
-
-				checkData(t, pkt, []byte(tc.data+s))
-			})
-
-			// ReadFromData/VV
-			for _, n := range []int{0, 1, 2, 7, 10, 14, 20} {
-				t.Run(fmt.Sprintf("ReadFromData%d", n), func(t *testing.T) {
-					s := "TO READ"
-					otherPkt := NewPacketBuffer(PacketBufferOptions{
-						Data: vv(s, s),
-					})
-					s += s
-
-					pkt := tc.makePkt(t)
-					pkt.Data().ReadFromData(otherPkt.Data(), n)
-
-					if n < len(s) {
-						s = s[:n]
-					}
-					checkData(t, pkt, []byte(tc.data+s))
-				})
-				t.Run(fmt.Sprintf("ReadFromVV%d", n), func(t *testing.T) {
-					s := "TO READ"
-					srcVV := vv(s, s)
-					s += s
-
-					pkt := tc.makePkt(t)
-					pkt.Data().ReadFromVV(&srcVV, n)
-
-					if n < len(s) {
-						s = s[:n]
-					}
-					checkData(t, pkt, []byte(tc.data+s))
-				})
-			}
-
-			// ExtractVV
-			t.Run("ExtractVV", func(t *testing.T) {
-				pkt := tc.makePkt(t)
-				extractedVV := pkt.Data().ExtractVV()
-
-				got := extractedVV.ToOwnedView()
-				want := []byte(tc.data)
-				if !bytes.Equal(got, want) {
-					t.Errorf("pkt.Data().ExtractVV().ToOwnedView() = %q, want %q", got, want)
-				}
-			})
-
-			// Replace
-			t.Run("Replace", func(t *testing.T) {
-				s := "REPLACED"
-
-				pkt := tc.makePkt(t)
-				pkt.Data().Replace(vv(s))
-
-				checkData(t, pkt, []byte(s))
-			})
-		})
-	}
-}
-
-func checkInitialPacketBuffer(t *testing.T, pk *PacketBuffer, opts PacketBufferOptions) {
-	t.Helper()
-	reserved := opts.ReserveHeaderBytes
-	if got, want := pk.ReservedHeaderBytes(), reserved; got != want {
-		t.Errorf("Initial pk.ReservedHeaderBytes() = %d, want %d", got, want)
-	}
-	if got, want := pk.AvailableHeaderBytes(), reserved; got != want {
-		t.Errorf("Initial pk.AvailableHeaderBytes() = %d, want %d", got, want)
-	}
-	if got, want := pk.HeaderSize(), 0; got != want {
-		t.Errorf("Initial pk.HeaderSize() = %d, want %d", got, want)
-	}
-	data := opts.Data.ToView()
-	if got, want := pk.Size(), len(data); got != want {
-		t.Errorf("Initial pk.Size() = %d, want %d", got, want)
-	}
-	checkData(t, pk, data)
-	checkViewEqual(t, "Initial pk.Views()", concatViews(pk.Views()...), data)
-	// Check the initial values for each header.
-	checkPacketHeader(t, "Initial pk.LinkHeader", pk.LinkHeader(), nil)
-	checkPacketHeader(t, "Initial pk.NetworkHeader", pk.NetworkHeader(), nil)
-	checkPacketHeader(t, "Initial pk.TransportHeader", pk.TransportHeader(), nil)
-	// Check the initial valies for PayloadSince.
-	checkViewEqual(t, "Initial PayloadSince(LinkHeader)",
-		PayloadSince(pk.LinkHeader()), data)
-	checkViewEqual(t, "Initial PayloadSince(NetworkHeader)",
-		PayloadSince(pk.NetworkHeader()), data)
-	checkViewEqual(t, "Initial PayloadSince(TransportHeader)",
-		PayloadSince(pk.TransportHeader()), data)
-}
-
-func checkPacketHeader(t *testing.T, name string, h PacketHeader, want []byte) {
-	t.Helper()
-	checkViewEqual(t, name+".View()", h.View(), want)
-}
-
-func checkViewEqual(t *testing.T, what string, got, want buffer.View) {
-	t.Helper()
-	if !bytes.Equal(got, want) {
-		t.Errorf("%s = %x, want %x", what, got, want)
-	}
-}
-
-func checkData(t *testing.T, pkt *PacketBuffer, want []byte) {
-	t.Helper()
-	if got := concatViews(pkt.Data().Views()...); !bytes.Equal(got, want) {
-		t.Errorf("pkt.Data().Views() = %x, want %x", got, want)
-	}
-	if got := pkt.Data().Size(); got != len(want) {
-		t.Errorf("pkt.Data().Size() = %d, want %d", got, len(want))
-	}
-
-	t.Run("AsRange", func(t *testing.T) {
-		// Full range
-		checkRange(t, pkt.Data().AsRange(), want)
-
-		// SubRange
-		for _, off := range []int{0, 1, len(want), len(want) + 1} {
-			t.Run(fmt.Sprintf("SubRange%d", off), func(t *testing.T) {
-				// Empty when off is greater than the size of range.
-				var sub []byte
-				if off < len(want) {
-					sub = want[off:]
-				}
-				checkRange(t, pkt.Data().AsRange().SubRange(off), sub)
-			})
-		}
-
-		// Capped
-		for _, n := range []int{0, 1, len(want), len(want) + 1} {
-			t.Run(fmt.Sprintf("Capped%d", n), func(t *testing.T) {
-				sub := want
-				if n < len(sub) {
-					sub = sub[:n]
-				}
-				checkRange(t, pkt.Data().AsRange().Capped(n), sub)
-			})
-		}
-	})
-}
-
-func checkRange(t *testing.T, r Range, data []byte) {
-	if got, want := r.Size(), len(data); got != want {
-		t.Errorf("r.Size() = %d, want %d", got, want)
-	}
-	if got := r.AsView(); !bytes.Equal(got, data) {
-		t.Errorf("r.AsView() = %x, want %x", got, data)
-	}
-	if got := r.ToOwnedView(); !bytes.Equal(got, data) {
-		t.Errorf("r.ToOwnedView() = %x, want %x", got, data)
-	}
-	if got, want := r.Checksum(), header.Checksum(data, 0 /* initial */); got != want {
-		t.Errorf("r.Checksum() = %x, want %x", got, want)
-	}
-}
-
-func vv(pieces ...string) buffer.VectorisedView {
-	var views []buffer.View
-	var size int
-	for _, p := range pieces {
-		v := buffer.View([]byte(p))
-		size += len(v)
-		views = append(views, v)
-	}
-	return buffer.NewVectorisedView(size, views)
-}
-
-func makeView(size int) buffer.View {
-	b := byte(size)
-	return bytes.Repeat([]byte{b}, size)
-}
-
-func concatViews(views ...buffer.View) buffer.View {
-	var all buffer.View
-	for _, v := range views {
-		all = append(all, v...)
-	}
-	return all
-}
diff --git a/pkg/tcpip/stack/stack_state_autogen.go b/pkg/tcpip/stack/stack_state_autogen.go
new file mode 100644
index 0000000..6b10c1e
--- /dev/null
+++ b/pkg/tcpip/stack/stack_state_autogen.go
@@ -0,0 +1,718 @@
+// automatically generated by stateify.
+
+package stack
+
+import (
+	"gvisor.dev/gvisor/pkg/state"
+)
+
+func (t *tuple) StateTypeName() string {
+	return "pkg/tcpip/stack.tuple"
+}
+
+func (t *tuple) StateFields() []string {
+	return []string{
+		"tupleEntry",
+		"tupleID",
+		"conn",
+		"direction",
+	}
+}
+
+func (t *tuple) beforeSave() {}
+
+// +checklocksignore
+func (t *tuple) StateSave(stateSinkObject state.Sink) {
+	t.beforeSave()
+	stateSinkObject.Save(0, &t.tupleEntry)
+	stateSinkObject.Save(1, &t.tupleID)
+	stateSinkObject.Save(2, &t.conn)
+	stateSinkObject.Save(3, &t.direction)
+}
+
+func (t *tuple) afterLoad() {}
+
+// +checklocksignore
+func (t *tuple) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &t.tupleEntry)
+	stateSourceObject.Load(1, &t.tupleID)
+	stateSourceObject.Load(2, &t.conn)
+	stateSourceObject.Load(3, &t.direction)
+}
+
+func (ti *tupleID) StateTypeName() string {
+	return "pkg/tcpip/stack.tupleID"
+}
+
+func (ti *tupleID) StateFields() []string {
+	return []string{
+		"srcAddr",
+		"srcPort",
+		"dstAddr",
+		"dstPort",
+		"transProto",
+		"netProto",
+	}
+}
+
+func (ti *tupleID) beforeSave() {}
+
+// +checklocksignore
+func (ti *tupleID) StateSave(stateSinkObject state.Sink) {
+	ti.beforeSave()
+	stateSinkObject.Save(0, &ti.srcAddr)
+	stateSinkObject.Save(1, &ti.srcPort)
+	stateSinkObject.Save(2, &ti.dstAddr)
+	stateSinkObject.Save(3, &ti.dstPort)
+	stateSinkObject.Save(4, &ti.transProto)
+	stateSinkObject.Save(5, &ti.netProto)
+}
+
+func (ti *tupleID) afterLoad() {}
+
+// +checklocksignore
+func (ti *tupleID) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &ti.srcAddr)
+	stateSourceObject.Load(1, &ti.srcPort)
+	stateSourceObject.Load(2, &ti.dstAddr)
+	stateSourceObject.Load(3, &ti.dstPort)
+	stateSourceObject.Load(4, &ti.transProto)
+	stateSourceObject.Load(5, &ti.netProto)
+}
+
+func (cn *conn) StateTypeName() string {
+	return "pkg/tcpip/stack.conn"
+}
+
+func (cn *conn) StateFields() []string {
+	return []string{
+		"original",
+		"reply",
+		"manip",
+		"tcbHook",
+		"tcb",
+		"lastUsed",
+	}
+}
+
+func (cn *conn) beforeSave() {}
+
+// +checklocksignore
+func (cn *conn) StateSave(stateSinkObject state.Sink) {
+	cn.beforeSave()
+	var lastUsedValue unixTime = cn.saveLastUsed()
+	stateSinkObject.SaveValue(5, lastUsedValue)
+	stateSinkObject.Save(0, &cn.original)
+	stateSinkObject.Save(1, &cn.reply)
+	stateSinkObject.Save(2, &cn.manip)
+	stateSinkObject.Save(3, &cn.tcbHook)
+	stateSinkObject.Save(4, &cn.tcb)
+}
+
+func (cn *conn) afterLoad() {}
+
+// +checklocksignore
+func (cn *conn) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &cn.original)
+	stateSourceObject.Load(1, &cn.reply)
+	stateSourceObject.Load(2, &cn.manip)
+	stateSourceObject.Load(3, &cn.tcbHook)
+	stateSourceObject.Load(4, &cn.tcb)
+	stateSourceObject.LoadValue(5, new(unixTime), func(y interface{}) { cn.loadLastUsed(y.(unixTime)) })
+}
+
+func (ct *ConnTrack) StateTypeName() string {
+	return "pkg/tcpip/stack.ConnTrack"
+}
+
+func (ct *ConnTrack) StateFields() []string {
+	return []string{
+		"seed",
+		"buckets",
+	}
+}
+
+// +checklocksignore
+func (ct *ConnTrack) StateSave(stateSinkObject state.Sink) {
+	ct.beforeSave()
+	stateSinkObject.Save(0, &ct.seed)
+	stateSinkObject.Save(1, &ct.buckets)
+}
+
+func (ct *ConnTrack) afterLoad() {}
+
+// +checklocksignore
+func (ct *ConnTrack) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &ct.seed)
+	stateSourceObject.Load(1, &ct.buckets)
+}
+
+func (b *bucket) StateTypeName() string {
+	return "pkg/tcpip/stack.bucket"
+}
+
+func (b *bucket) StateFields() []string {
+	return []string{
+		"tuples",
+	}
+}
+
+func (b *bucket) beforeSave() {}
+
+// +checklocksignore
+func (b *bucket) StateSave(stateSinkObject state.Sink) {
+	b.beforeSave()
+	stateSinkObject.Save(0, &b.tuples)
+}
+
+func (b *bucket) afterLoad() {}
+
+// +checklocksignore
+func (b *bucket) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &b.tuples)
+}
+
+func (u *unixTime) StateTypeName() string {
+	return "pkg/tcpip/stack.unixTime"
+}
+
+func (u *unixTime) StateFields() []string {
+	return []string{
+		"second",
+		"nano",
+	}
+}
+
+func (u *unixTime) beforeSave() {}
+
+// +checklocksignore
+func (u *unixTime) StateSave(stateSinkObject state.Sink) {
+	u.beforeSave()
+	stateSinkObject.Save(0, &u.second)
+	stateSinkObject.Save(1, &u.nano)
+}
+
+func (u *unixTime) afterLoad() {}
+
+// +checklocksignore
+func (u *unixTime) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &u.second)
+	stateSourceObject.Load(1, &u.nano)
+}
+
+func (it *IPTables) StateTypeName() string {
+	return "pkg/tcpip/stack.IPTables"
+}
+
+func (it *IPTables) StateFields() []string {
+	return []string{
+		"mu",
+		"v4Tables",
+		"v6Tables",
+		"modified",
+		"priorities",
+		"connections",
+		"reaperDone",
+	}
+}
+
+// +checklocksignore
+func (it *IPTables) StateSave(stateSinkObject state.Sink) {
+	it.beforeSave()
+	stateSinkObject.Save(0, &it.mu)
+	stateSinkObject.Save(1, &it.v4Tables)
+	stateSinkObject.Save(2, &it.v6Tables)
+	stateSinkObject.Save(3, &it.modified)
+	stateSinkObject.Save(4, &it.priorities)
+	stateSinkObject.Save(5, &it.connections)
+	stateSinkObject.Save(6, &it.reaperDone)
+}
+
+// +checklocksignore
+func (it *IPTables) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &it.mu)
+	stateSourceObject.Load(1, &it.v4Tables)
+	stateSourceObject.Load(2, &it.v6Tables)
+	stateSourceObject.Load(3, &it.modified)
+	stateSourceObject.Load(4, &it.priorities)
+	stateSourceObject.Load(5, &it.connections)
+	stateSourceObject.Load(6, &it.reaperDone)
+	stateSourceObject.AfterLoad(it.afterLoad)
+}
+
+func (table *Table) StateTypeName() string {
+	return "pkg/tcpip/stack.Table"
+}
+
+func (table *Table) StateFields() []string {
+	return []string{
+		"Rules",
+		"BuiltinChains",
+		"Underflows",
+	}
+}
+
+func (table *Table) beforeSave() {}
+
+// +checklocksignore
+func (table *Table) StateSave(stateSinkObject state.Sink) {
+	table.beforeSave()
+	stateSinkObject.Save(0, &table.Rules)
+	stateSinkObject.Save(1, &table.BuiltinChains)
+	stateSinkObject.Save(2, &table.Underflows)
+}
+
+func (table *Table) afterLoad() {}
+
+// +checklocksignore
+func (table *Table) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &table.Rules)
+	stateSourceObject.Load(1, &table.BuiltinChains)
+	stateSourceObject.Load(2, &table.Underflows)
+}
+
+func (r *Rule) StateTypeName() string {
+	return "pkg/tcpip/stack.Rule"
+}
+
+func (r *Rule) StateFields() []string {
+	return []string{
+		"Filter",
+		"Matchers",
+		"Target",
+	}
+}
+
+func (r *Rule) beforeSave() {}
+
+// +checklocksignore
+func (r *Rule) StateSave(stateSinkObject state.Sink) {
+	r.beforeSave()
+	stateSinkObject.Save(0, &r.Filter)
+	stateSinkObject.Save(1, &r.Matchers)
+	stateSinkObject.Save(2, &r.Target)
+}
+
+func (r *Rule) afterLoad() {}
+
+// +checklocksignore
+func (r *Rule) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &r.Filter)
+	stateSourceObject.Load(1, &r.Matchers)
+	stateSourceObject.Load(2, &r.Target)
+}
+
+func (fl *IPHeaderFilter) StateTypeName() string {
+	return "pkg/tcpip/stack.IPHeaderFilter"
+}
+
+func (fl *IPHeaderFilter) StateFields() []string {
+	return []string{
+		"Protocol",
+		"CheckProtocol",
+		"Dst",
+		"DstMask",
+		"DstInvert",
+		"Src",
+		"SrcMask",
+		"SrcInvert",
+		"InputInterface",
+		"InputInterfaceMask",
+		"InputInterfaceInvert",
+		"OutputInterface",
+		"OutputInterfaceMask",
+		"OutputInterfaceInvert",
+	}
+}
+
+func (fl *IPHeaderFilter) beforeSave() {}
+
+// +checklocksignore
+func (fl *IPHeaderFilter) StateSave(stateSinkObject state.Sink) {
+	fl.beforeSave()
+	stateSinkObject.Save(0, &fl.Protocol)
+	stateSinkObject.Save(1, &fl.CheckProtocol)
+	stateSinkObject.Save(2, &fl.Dst)
+	stateSinkObject.Save(3, &fl.DstMask)
+	stateSinkObject.Save(4, &fl.DstInvert)
+	stateSinkObject.Save(5, &fl.Src)
+	stateSinkObject.Save(6, &fl.SrcMask)
+	stateSinkObject.Save(7, &fl.SrcInvert)
+	stateSinkObject.Save(8, &fl.InputInterface)
+	stateSinkObject.Save(9, &fl.InputInterfaceMask)
+	stateSinkObject.Save(10, &fl.InputInterfaceInvert)
+	stateSinkObject.Save(11, &fl.OutputInterface)
+	stateSinkObject.Save(12, &fl.OutputInterfaceMask)
+	stateSinkObject.Save(13, &fl.OutputInterfaceInvert)
+}
+
+func (fl *IPHeaderFilter) afterLoad() {}
+
+// +checklocksignore
+func (fl *IPHeaderFilter) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &fl.Protocol)
+	stateSourceObject.Load(1, &fl.CheckProtocol)
+	stateSourceObject.Load(2, &fl.Dst)
+	stateSourceObject.Load(3, &fl.DstMask)
+	stateSourceObject.Load(4, &fl.DstInvert)
+	stateSourceObject.Load(5, &fl.Src)
+	stateSourceObject.Load(6, &fl.SrcMask)
+	stateSourceObject.Load(7, &fl.SrcInvert)
+	stateSourceObject.Load(8, &fl.InputInterface)
+	stateSourceObject.Load(9, &fl.InputInterfaceMask)
+	stateSourceObject.Load(10, &fl.InputInterfaceInvert)
+	stateSourceObject.Load(11, &fl.OutputInterface)
+	stateSourceObject.Load(12, &fl.OutputInterfaceMask)
+	stateSourceObject.Load(13, &fl.OutputInterfaceInvert)
+}
+
+func (l *neighborEntryList) StateTypeName() string {
+	return "pkg/tcpip/stack.neighborEntryList"
+}
+
+func (l *neighborEntryList) StateFields() []string {
+	return []string{
+		"head",
+		"tail",
+	}
+}
+
+func (l *neighborEntryList) beforeSave() {}
+
+// +checklocksignore
+func (l *neighborEntryList) StateSave(stateSinkObject state.Sink) {
+	l.beforeSave()
+	stateSinkObject.Save(0, &l.head)
+	stateSinkObject.Save(1, &l.tail)
+}
+
+func (l *neighborEntryList) afterLoad() {}
+
+// +checklocksignore
+func (l *neighborEntryList) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &l.head)
+	stateSourceObject.Load(1, &l.tail)
+}
+
+func (e *neighborEntryEntry) StateTypeName() string {
+	return "pkg/tcpip/stack.neighborEntryEntry"
+}
+
+func (e *neighborEntryEntry) StateFields() []string {
+	return []string{
+		"next",
+		"prev",
+	}
+}
+
+func (e *neighborEntryEntry) beforeSave() {}
+
+// +checklocksignore
+func (e *neighborEntryEntry) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+	stateSinkObject.Save(0, &e.next)
+	stateSinkObject.Save(1, &e.prev)
+}
+
+func (e *neighborEntryEntry) afterLoad() {}
+
+// +checklocksignore
+func (e *neighborEntryEntry) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &e.next)
+	stateSourceObject.Load(1, &e.prev)
+}
+
+func (p *PacketBufferList) StateTypeName() string {
+	return "pkg/tcpip/stack.PacketBufferList"
+}
+
+func (p *PacketBufferList) StateFields() []string {
+	return []string{
+		"head",
+		"tail",
+	}
+}
+
+func (p *PacketBufferList) beforeSave() {}
+
+// +checklocksignore
+func (p *PacketBufferList) StateSave(stateSinkObject state.Sink) {
+	p.beforeSave()
+	stateSinkObject.Save(0, &p.head)
+	stateSinkObject.Save(1, &p.tail)
+}
+
+func (p *PacketBufferList) afterLoad() {}
+
+// +checklocksignore
+func (p *PacketBufferList) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &p.head)
+	stateSourceObject.Load(1, &p.tail)
+}
+
+func (e *PacketBufferEntry) StateTypeName() string {
+	return "pkg/tcpip/stack.PacketBufferEntry"
+}
+
+func (e *PacketBufferEntry) StateFields() []string {
+	return []string{
+		"next",
+		"prev",
+	}
+}
+
+func (e *PacketBufferEntry) beforeSave() {}
+
+// +checklocksignore
+func (e *PacketBufferEntry) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+	stateSinkObject.Save(0, &e.next)
+	stateSinkObject.Save(1, &e.prev)
+}
+
+func (e *PacketBufferEntry) afterLoad() {}
+
+// +checklocksignore
+func (e *PacketBufferEntry) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &e.next)
+	stateSourceObject.Load(1, &e.prev)
+}
+
+func (t *TransportEndpointID) StateTypeName() string {
+	return "pkg/tcpip/stack.TransportEndpointID"
+}
+
+func (t *TransportEndpointID) StateFields() []string {
+	return []string{
+		"LocalPort",
+		"LocalAddress",
+		"RemotePort",
+		"RemoteAddress",
+	}
+}
+
+func (t *TransportEndpointID) beforeSave() {}
+
+// +checklocksignore
+func (t *TransportEndpointID) StateSave(stateSinkObject state.Sink) {
+	t.beforeSave()
+	stateSinkObject.Save(0, &t.LocalPort)
+	stateSinkObject.Save(1, &t.LocalAddress)
+	stateSinkObject.Save(2, &t.RemotePort)
+	stateSinkObject.Save(3, &t.RemoteAddress)
+}
+
+func (t *TransportEndpointID) afterLoad() {}
+
+// +checklocksignore
+func (t *TransportEndpointID) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &t.LocalPort)
+	stateSourceObject.Load(1, &t.LocalAddress)
+	stateSourceObject.Load(2, &t.RemotePort)
+	stateSourceObject.Load(3, &t.RemoteAddress)
+}
+
+func (g *GSOType) StateTypeName() string {
+	return "pkg/tcpip/stack.GSOType"
+}
+
+func (g *GSOType) StateFields() []string {
+	return nil
+}
+
+func (g *GSO) StateTypeName() string {
+	return "pkg/tcpip/stack.GSO"
+}
+
+func (g *GSO) StateFields() []string {
+	return []string{
+		"Type",
+		"NeedsCsum",
+		"CsumOffset",
+		"MSS",
+		"L3HdrLen",
+		"MaxSize",
+	}
+}
+
+func (g *GSO) beforeSave() {}
+
+// +checklocksignore
+func (g *GSO) StateSave(stateSinkObject state.Sink) {
+	g.beforeSave()
+	stateSinkObject.Save(0, &g.Type)
+	stateSinkObject.Save(1, &g.NeedsCsum)
+	stateSinkObject.Save(2, &g.CsumOffset)
+	stateSinkObject.Save(3, &g.MSS)
+	stateSinkObject.Save(4, &g.L3HdrLen)
+	stateSinkObject.Save(5, &g.MaxSize)
+}
+
+func (g *GSO) afterLoad() {}
+
+// +checklocksignore
+func (g *GSO) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &g.Type)
+	stateSourceObject.Load(1, &g.NeedsCsum)
+	stateSourceObject.Load(2, &g.CsumOffset)
+	stateSourceObject.Load(3, &g.MSS)
+	stateSourceObject.Load(4, &g.L3HdrLen)
+	stateSourceObject.Load(5, &g.MaxSize)
+}
+
+func (t *TransportEndpointInfo) StateTypeName() string {
+	return "pkg/tcpip/stack.TransportEndpointInfo"
+}
+
+func (t *TransportEndpointInfo) StateFields() []string {
+	return []string{
+		"NetProto",
+		"TransProto",
+		"ID",
+		"BindNICID",
+		"BindAddr",
+		"RegisterNICID",
+	}
+}
+
+func (t *TransportEndpointInfo) beforeSave() {}
+
+// +checklocksignore
+func (t *TransportEndpointInfo) StateSave(stateSinkObject state.Sink) {
+	t.beforeSave()
+	stateSinkObject.Save(0, &t.NetProto)
+	stateSinkObject.Save(1, &t.TransProto)
+	stateSinkObject.Save(2, &t.ID)
+	stateSinkObject.Save(3, &t.BindNICID)
+	stateSinkObject.Save(4, &t.BindAddr)
+	stateSinkObject.Save(5, &t.RegisterNICID)
+}
+
+func (t *TransportEndpointInfo) afterLoad() {}
+
+// +checklocksignore
+func (t *TransportEndpointInfo) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &t.NetProto)
+	stateSourceObject.Load(1, &t.TransProto)
+	stateSourceObject.Load(2, &t.ID)
+	stateSourceObject.Load(3, &t.BindNICID)
+	stateSourceObject.Load(4, &t.BindAddr)
+	stateSourceObject.Load(5, &t.RegisterNICID)
+}
+
+func (ep *multiPortEndpoint) StateTypeName() string {
+	return "pkg/tcpip/stack.multiPortEndpoint"
+}
+
+func (ep *multiPortEndpoint) StateFields() []string {
+	return []string{
+		"demux",
+		"netProto",
+		"transProto",
+		"endpoints",
+		"flags",
+	}
+}
+
+func (ep *multiPortEndpoint) beforeSave() {}
+
+// +checklocksignore
+func (ep *multiPortEndpoint) StateSave(stateSinkObject state.Sink) {
+	ep.beforeSave()
+	stateSinkObject.Save(0, &ep.demux)
+	stateSinkObject.Save(1, &ep.netProto)
+	stateSinkObject.Save(2, &ep.transProto)
+	stateSinkObject.Save(3, &ep.endpoints)
+	stateSinkObject.Save(4, &ep.flags)
+}
+
+func (ep *multiPortEndpoint) afterLoad() {}
+
+// +checklocksignore
+func (ep *multiPortEndpoint) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &ep.demux)
+	stateSourceObject.Load(1, &ep.netProto)
+	stateSourceObject.Load(2, &ep.transProto)
+	stateSourceObject.Load(3, &ep.endpoints)
+	stateSourceObject.Load(4, &ep.flags)
+}
+
+func (l *tupleList) StateTypeName() string {
+	return "pkg/tcpip/stack.tupleList"
+}
+
+func (l *tupleList) StateFields() []string {
+	return []string{
+		"head",
+		"tail",
+	}
+}
+
+func (l *tupleList) beforeSave() {}
+
+// +checklocksignore
+func (l *tupleList) StateSave(stateSinkObject state.Sink) {
+	l.beforeSave()
+	stateSinkObject.Save(0, &l.head)
+	stateSinkObject.Save(1, &l.tail)
+}
+
+func (l *tupleList) afterLoad() {}
+
+// +checklocksignore
+func (l *tupleList) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &l.head)
+	stateSourceObject.Load(1, &l.tail)
+}
+
+func (e *tupleEntry) StateTypeName() string {
+	return "pkg/tcpip/stack.tupleEntry"
+}
+
+func (e *tupleEntry) StateFields() []string {
+	return []string{
+		"next",
+		"prev",
+	}
+}
+
+func (e *tupleEntry) beforeSave() {}
+
+// +checklocksignore
+func (e *tupleEntry) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+	stateSinkObject.Save(0, &e.next)
+	stateSinkObject.Save(1, &e.prev)
+}
+
+func (e *tupleEntry) afterLoad() {}
+
+// +checklocksignore
+func (e *tupleEntry) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &e.next)
+	stateSourceObject.Load(1, &e.prev)
+}
+
+func init() {
+	state.Register((*tuple)(nil))
+	state.Register((*tupleID)(nil))
+	state.Register((*conn)(nil))
+	state.Register((*ConnTrack)(nil))
+	state.Register((*bucket)(nil))
+	state.Register((*unixTime)(nil))
+	state.Register((*IPTables)(nil))
+	state.Register((*Table)(nil))
+	state.Register((*Rule)(nil))
+	state.Register((*IPHeaderFilter)(nil))
+	state.Register((*neighborEntryList)(nil))
+	state.Register((*neighborEntryEntry)(nil))
+	state.Register((*PacketBufferList)(nil))
+	state.Register((*PacketBufferEntry)(nil))
+	state.Register((*TransportEndpointID)(nil))
+	state.Register((*GSOType)(nil))
+	state.Register((*GSO)(nil))
+	state.Register((*TransportEndpointInfo)(nil))
+	state.Register((*multiPortEndpoint)(nil))
+	state.Register((*tupleList)(nil))
+	state.Register((*tupleEntry)(nil))
+}
diff --git a/pkg/tcpip/stack/stack_test.go b/pkg/tcpip/stack/stack_test.go
deleted file mode 100644
index 7ddf7a0..0000000
--- a/pkg/tcpip/stack/stack_test.go
+++ /dev/null
@@ -1,4513 +0,0 @@
-// 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 stack_test contains tests for the stack. It is in its own package so
-// that the tests can also validate that all definitions needed to implement
-// transport and network protocols are properly exported by the stack package.
-package stack_test
-
-import (
-	"bytes"
-	"fmt"
-	"math"
-	"net"
-	"sort"
-	"testing"
-	"time"
-
-	"github.com/google/go-cmp/cmp"
-	"gvisor.dev/gvisor/pkg/rand"
-	"gvisor.dev/gvisor/pkg/sync"
-	"gvisor.dev/gvisor/pkg/tcpip"
-	"gvisor.dev/gvisor/pkg/tcpip/buffer"
-	"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/arp"
-	"gvisor.dev/gvisor/pkg/tcpip/network/ipv4"
-	"gvisor.dev/gvisor/pkg/tcpip/network/ipv6"
-	"gvisor.dev/gvisor/pkg/tcpip/stack"
-	"gvisor.dev/gvisor/pkg/tcpip/transport/udp"
-)
-
-const (
-	fakeNetNumber        tcpip.NetworkProtocolNumber = math.MaxUint32
-	fakeNetHeaderLen                                 = 12
-	fakeDefaultPrefixLen                             = 8
-
-	// fakeControlProtocol is used for control packets that represent
-	// destination port unreachable.
-	fakeControlProtocol tcpip.TransportProtocolNumber = 2
-
-	// defaultMTU is the MTU, in bytes, used throughout the tests, except
-	// where another value is explicitly used. It is chosen to match the MTU
-	// of loopback interfaces on linux systems.
-	defaultMTU = 65536
-
-	dstAddrOffset        = 0
-	srcAddrOffset        = 1
-	protocolNumberOffset = 2
-)
-
-func checkGetMainNICAddress(s *stack.Stack, nicID tcpip.NICID, proto tcpip.NetworkProtocolNumber, want tcpip.AddressWithPrefix) error {
-	if addr, err := s.GetMainNICAddress(nicID, proto); err != nil {
-		return fmt.Errorf("stack.GetMainNICAddress(%d, %d): %s", nicID, proto, err)
-	} else if addr != want {
-		return fmt.Errorf("got stack.GetMainNICAddress(%d, %d) = %s, want = %s", nicID, proto, addr, want)
-	}
-	return nil
-}
-
-// fakeNetworkEndpoint is a network-layer protocol endpoint. It counts sent and
-// received packets; the counts of all endpoints are aggregated in the protocol
-// descriptor.
-//
-// Headers of this protocol are fakeNetHeaderLen bytes, but we currently only
-// use the first three: destination address, source address, and transport
-// protocol. They're all one byte fields to simplify parsing.
-type fakeNetworkEndpoint struct {
-	stack.AddressableEndpointState
-
-	mu struct {
-		sync.RWMutex
-
-		enabled bool
-	}
-
-	nic        stack.NetworkInterface
-	proto      *fakeNetworkProtocol
-	dispatcher stack.TransportDispatcher
-}
-
-func (f *fakeNetworkEndpoint) Enable() tcpip.Error {
-	f.mu.Lock()
-	defer f.mu.Unlock()
-	f.mu.enabled = true
-	return nil
-}
-
-func (f *fakeNetworkEndpoint) Enabled() bool {
-	f.mu.RLock()
-	defer f.mu.RUnlock()
-	return f.mu.enabled
-}
-
-func (f *fakeNetworkEndpoint) Disable() {
-	f.mu.Lock()
-	defer f.mu.Unlock()
-	f.mu.enabled = false
-}
-
-func (f *fakeNetworkEndpoint) MTU() uint32 {
-	return f.nic.MTU() - uint32(f.MaxHeaderLength())
-}
-
-func (*fakeNetworkEndpoint) DefaultTTL() uint8 {
-	return 123
-}
-
-func (f *fakeNetworkEndpoint) HandlePacket(pkt *stack.PacketBuffer) {
-	if _, _, ok := f.proto.Parse(pkt); !ok {
-		return
-	}
-
-	// Increment the received packet count in the protocol descriptor.
-	netHdr := pkt.NetworkHeader().View()
-
-	dst := tcpip.Address(netHdr[dstAddrOffset:][:1])
-	addressEndpoint := f.AcquireAssignedAddress(dst, f.nic.Promiscuous(), stack.CanBePrimaryEndpoint)
-	if addressEndpoint == nil {
-		return
-	}
-	addressEndpoint.DecRef()
-
-	f.proto.packetCount[int(dst[0])%len(f.proto.packetCount)]++
-
-	// Handle control packets.
-	if netHdr[protocolNumberOffset] == uint8(fakeControlProtocol) {
-		nb, ok := pkt.Data().PullUp(fakeNetHeaderLen)
-		if !ok {
-			return
-		}
-		pkt.Data().TrimFront(fakeNetHeaderLen)
-		f.dispatcher.DeliverTransportError(
-			tcpip.Address(nb[srcAddrOffset:srcAddrOffset+1]),
-			tcpip.Address(nb[dstAddrOffset:dstAddrOffset+1]),
-			fakeNetNumber,
-			tcpip.TransportProtocolNumber(nb[protocolNumberOffset]),
-			// Nothing checks the error.
-			nil, /* transport error */
-			pkt,
-		)
-		return
-	}
-
-	// Dispatch the packet to the transport protocol.
-	f.dispatcher.DeliverTransportPacket(tcpip.TransportProtocolNumber(pkt.NetworkHeader().View()[protocolNumberOffset]), pkt)
-}
-
-func (f *fakeNetworkEndpoint) MaxHeaderLength() uint16 {
-	return f.nic.MaxHeaderLength() + fakeNetHeaderLen
-}
-
-func (*fakeNetworkEndpoint) PseudoHeaderChecksum(protocol tcpip.TransportProtocolNumber, dstAddr tcpip.Address) uint16 {
-	return 0
-}
-
-func (f *fakeNetworkEndpoint) NetworkProtocolNumber() tcpip.NetworkProtocolNumber {
-	return f.proto.Number()
-}
-
-func (f *fakeNetworkEndpoint) WritePacket(r *stack.Route, gso *stack.GSO, params stack.NetworkHeaderParams, pkt *stack.PacketBuffer) tcpip.Error {
-	// Increment the sent packet count in the protocol descriptor.
-	f.proto.sendPacketCount[int(r.RemoteAddress[0])%len(f.proto.sendPacketCount)]++
-
-	// Add the protocol's header to the packet and send it to the link
-	// endpoint.
-	hdr := pkt.NetworkHeader().Push(fakeNetHeaderLen)
-	pkt.NetworkProtocolNumber = fakeNetNumber
-	hdr[dstAddrOffset] = r.RemoteAddress[0]
-	hdr[srcAddrOffset] = r.LocalAddress[0]
-	hdr[protocolNumberOffset] = byte(params.Protocol)
-
-	if r.Loop&stack.PacketLoop != 0 {
-		f.HandlePacket(pkt.Clone())
-	}
-	if r.Loop&stack.PacketOut == 0 {
-		return nil
-	}
-
-	return f.nic.WritePacket(r, gso, fakeNetNumber, pkt)
-}
-
-// WritePackets implements stack.LinkEndpoint.WritePackets.
-func (*fakeNetworkEndpoint) WritePackets(r *stack.Route, gso *stack.GSO, pkts stack.PacketBufferList, params stack.NetworkHeaderParams) (int, tcpip.Error) {
-	panic("not implemented")
-}
-
-func (*fakeNetworkEndpoint) WriteHeaderIncludedPacket(r *stack.Route, pkt *stack.PacketBuffer) tcpip.Error {
-	return &tcpip.ErrNotSupported{}
-}
-
-func (f *fakeNetworkEndpoint) Close() {
-	f.AddressableEndpointState.Cleanup()
-}
-
-// Stats implements NetworkEndpoint.
-func (*fakeNetworkEndpoint) Stats() stack.NetworkEndpointStats {
-	return &fakeNetworkEndpointStats{}
-}
-
-var _ stack.NetworkEndpointStats = (*fakeNetworkEndpointStats)(nil)
-
-type fakeNetworkEndpointStats struct{}
-
-// IsNetworkEndpointStats implements stack.NetworkEndpointStats.
-func (*fakeNetworkEndpointStats) IsNetworkEndpointStats() {}
-
-// fakeNetworkProtocol is a network-layer protocol descriptor. It aggregates the
-// number of packets sent and received via endpoints of this protocol. The index
-// where packets are added is given by the packet's destination address MOD 10.
-type fakeNetworkProtocol struct {
-	packetCount     [10]int
-	sendPacketCount [10]int
-	defaultTTL      uint8
-
-	mu struct {
-		sync.RWMutex
-		forwarding bool
-	}
-}
-
-func (*fakeNetworkProtocol) Number() tcpip.NetworkProtocolNumber {
-	return fakeNetNumber
-}
-
-func (*fakeNetworkProtocol) MinimumPacketSize() int {
-	return fakeNetHeaderLen
-}
-
-func (*fakeNetworkProtocol) DefaultPrefixLen() int {
-	return fakeDefaultPrefixLen
-}
-
-func (f *fakeNetworkProtocol) PacketCount(intfAddr byte) int {
-	return f.packetCount[int(intfAddr)%len(f.packetCount)]
-}
-
-func (*fakeNetworkProtocol) ParseAddresses(v buffer.View) (src, dst tcpip.Address) {
-	return tcpip.Address(v[srcAddrOffset : srcAddrOffset+1]), tcpip.Address(v[dstAddrOffset : dstAddrOffset+1])
-}
-
-func (f *fakeNetworkProtocol) NewEndpoint(nic stack.NetworkInterface, dispatcher stack.TransportDispatcher) stack.NetworkEndpoint {
-	e := &fakeNetworkEndpoint{
-		nic:        nic,
-		proto:      f,
-		dispatcher: dispatcher,
-	}
-	e.AddressableEndpointState.Init(e)
-	return e
-}
-
-func (f *fakeNetworkProtocol) SetOption(option tcpip.SettableNetworkProtocolOption) tcpip.Error {
-	switch v := option.(type) {
-	case *tcpip.DefaultTTLOption:
-		f.defaultTTL = uint8(*v)
-		return nil
-	default:
-		return &tcpip.ErrUnknownProtocolOption{}
-	}
-}
-
-func (f *fakeNetworkProtocol) Option(option tcpip.GettableNetworkProtocolOption) tcpip.Error {
-	switch v := option.(type) {
-	case *tcpip.DefaultTTLOption:
-		*v = tcpip.DefaultTTLOption(f.defaultTTL)
-		return nil
-	default:
-		return &tcpip.ErrUnknownProtocolOption{}
-	}
-}
-
-// Close implements NetworkProtocol.Close.
-func (*fakeNetworkProtocol) Close() {}
-
-// Wait implements NetworkProtocol.Wait.
-func (*fakeNetworkProtocol) Wait() {}
-
-// Parse implements NetworkProtocol.Parse.
-func (*fakeNetworkProtocol) Parse(pkt *stack.PacketBuffer) (tcpip.TransportProtocolNumber, bool, bool) {
-	hdr, ok := pkt.NetworkHeader().Consume(fakeNetHeaderLen)
-	if !ok {
-		return 0, false, false
-	}
-	pkt.NetworkProtocolNumber = fakeNetNumber
-	return tcpip.TransportProtocolNumber(hdr[protocolNumberOffset]), true, true
-}
-
-// Forwarding implements stack.ForwardingNetworkProtocol.
-func (f *fakeNetworkProtocol) Forwarding() bool {
-	f.mu.RLock()
-	defer f.mu.RUnlock()
-	return f.mu.forwarding
-}
-
-// SetForwarding implements stack.ForwardingNetworkProtocol.
-func (f *fakeNetworkProtocol) SetForwarding(v bool) {
-	f.mu.Lock()
-	defer f.mu.Unlock()
-	f.mu.forwarding = v
-}
-
-func fakeNetFactory(*stack.Stack) stack.NetworkProtocol {
-	return &fakeNetworkProtocol{}
-}
-
-// linkEPWithMockedAttach is a stack.LinkEndpoint that tests can use to verify
-// that LinkEndpoint.Attach was called.
-type linkEPWithMockedAttach struct {
-	stack.LinkEndpoint
-	attached bool
-}
-
-// Attach implements stack.LinkEndpoint.Attach.
-func (l *linkEPWithMockedAttach) Attach(d stack.NetworkDispatcher) {
-	l.LinkEndpoint.Attach(d)
-	l.attached = d != nil
-}
-
-func (l *linkEPWithMockedAttach) isAttached() bool {
-	return l.attached
-}
-
-// Checks to see if list contains an address.
-func containsAddr(list []tcpip.ProtocolAddress, item tcpip.ProtocolAddress) bool {
-	for _, i := range list {
-		if i == item {
-			return true
-		}
-	}
-
-	return false
-}
-
-func TestNetworkReceive(t *testing.T) {
-	// Create a stack with the fake network protocol, one nic, and two
-	// addresses attached to it: 1 & 2.
-	ep := channel.New(10, defaultMTU, "")
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
-	})
-	if err := s.CreateNIC(1, ep); err != nil {
-		t.Fatal("CreateNIC failed:", err)
-	}
-
-	if err := s.AddAddress(1, fakeNetNumber, "\x01"); err != nil {
-		t.Fatal("AddAddress failed:", err)
-	}
-
-	if err := s.AddAddress(1, fakeNetNumber, "\x02"); err != nil {
-		t.Fatal("AddAddress failed:", err)
-	}
-
-	fakeNet := s.NetworkProtocolInstance(fakeNetNumber).(*fakeNetworkProtocol)
-
-	buf := buffer.NewView(30)
-
-	// Make sure packet with wrong address is not delivered.
-	buf[dstAddrOffset] = 3
-	ep.InjectInbound(fakeNetNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
-		Data: buf.ToVectorisedView(),
-	}))
-	if fakeNet.packetCount[1] != 0 {
-		t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 0)
-	}
-	if fakeNet.packetCount[2] != 0 {
-		t.Errorf("packetCount[2] = %d, want %d", fakeNet.packetCount[2], 0)
-	}
-
-	// Make sure packet is delivered to first endpoint.
-	buf[dstAddrOffset] = 1
-	ep.InjectInbound(fakeNetNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
-		Data: buf.ToVectorisedView(),
-	}))
-	if fakeNet.packetCount[1] != 1 {
-		t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 1)
-	}
-	if fakeNet.packetCount[2] != 0 {
-		t.Errorf("packetCount[2] = %d, want %d", fakeNet.packetCount[2], 0)
-	}
-
-	// Make sure packet is delivered to second endpoint.
-	buf[dstAddrOffset] = 2
-	ep.InjectInbound(fakeNetNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
-		Data: buf.ToVectorisedView(),
-	}))
-	if fakeNet.packetCount[1] != 1 {
-		t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 1)
-	}
-	if fakeNet.packetCount[2] != 1 {
-		t.Errorf("packetCount[2] = %d, want %d", fakeNet.packetCount[2], 1)
-	}
-
-	// Make sure packet is not delivered if protocol number is wrong.
-	ep.InjectInbound(fakeNetNumber-1, stack.NewPacketBuffer(stack.PacketBufferOptions{
-		Data: buf.ToVectorisedView(),
-	}))
-	if fakeNet.packetCount[1] != 1 {
-		t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 1)
-	}
-	if fakeNet.packetCount[2] != 1 {
-		t.Errorf("packetCount[2] = %d, want %d", fakeNet.packetCount[2], 1)
-	}
-
-	// Make sure packet that is too small is dropped.
-	buf.CapLength(2)
-	ep.InjectInbound(fakeNetNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
-		Data: buf.ToVectorisedView(),
-	}))
-	if fakeNet.packetCount[1] != 1 {
-		t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 1)
-	}
-	if fakeNet.packetCount[2] != 1 {
-		t.Errorf("packetCount[2] = %d, want %d", fakeNet.packetCount[2], 1)
-	}
-}
-
-func sendTo(s *stack.Stack, addr tcpip.Address, payload buffer.View) tcpip.Error {
-	r, err := s.FindRoute(0, "", addr, fakeNetNumber, false /* multicastLoop */)
-	if err != nil {
-		return err
-	}
-	defer r.Release()
-	return send(r, payload)
-}
-
-func send(r *stack.Route, payload buffer.View) tcpip.Error {
-	return r.WritePacket(nil /* gso */, stack.NetworkHeaderParams{Protocol: fakeTransNumber, TTL: 123, TOS: stack.DefaultTOS}, stack.NewPacketBuffer(stack.PacketBufferOptions{
-		ReserveHeaderBytes: int(r.MaxHeaderLength()),
-		Data:               payload.ToVectorisedView(),
-	}))
-}
-
-func testSendTo(t *testing.T, s *stack.Stack, addr tcpip.Address, ep *channel.Endpoint, payload buffer.View) {
-	t.Helper()
-	ep.Drain()
-	if err := sendTo(s, addr, payload); err != nil {
-		t.Error("sendTo failed:", err)
-	}
-	if got, want := ep.Drain(), 1; got != want {
-		t.Errorf("sendTo packet count: got = %d, want %d", got, want)
-	}
-}
-
-func testSend(t *testing.T, r *stack.Route, ep *channel.Endpoint, payload buffer.View) {
-	t.Helper()
-	ep.Drain()
-	if err := send(r, payload); err != nil {
-		t.Error("send failed:", err)
-	}
-	if got, want := ep.Drain(), 1; got != want {
-		t.Errorf("send packet count: got = %d, want %d", got, want)
-	}
-}
-
-func testFailingSend(t *testing.T, r *stack.Route, ep *channel.Endpoint, payload buffer.View, wantErr tcpip.Error) {
-	t.Helper()
-	if gotErr := send(r, payload); gotErr != wantErr {
-		t.Errorf("send failed: got = %s, want = %s ", gotErr, wantErr)
-	}
-}
-
-func testFailingSendTo(t *testing.T, s *stack.Stack, addr tcpip.Address, ep *channel.Endpoint, payload buffer.View, wantErr tcpip.Error) {
-	t.Helper()
-	if gotErr := sendTo(s, addr, payload); gotErr != wantErr {
-		t.Errorf("sendto failed: got = %s, want = %s ", gotErr, wantErr)
-	}
-}
-
-func testRecv(t *testing.T, fakeNet *fakeNetworkProtocol, localAddrByte byte, ep *channel.Endpoint, buf buffer.View) {
-	t.Helper()
-	// testRecvInternal injects one packet, and we expect to receive it.
-	want := fakeNet.PacketCount(localAddrByte) + 1
-	testRecvInternal(t, fakeNet, localAddrByte, ep, buf, want)
-}
-
-func testFailingRecv(t *testing.T, fakeNet *fakeNetworkProtocol, localAddrByte byte, ep *channel.Endpoint, buf buffer.View) {
-	t.Helper()
-	// testRecvInternal injects one packet, and we do NOT expect to receive it.
-	want := fakeNet.PacketCount(localAddrByte)
-	testRecvInternal(t, fakeNet, localAddrByte, ep, buf, want)
-}
-
-func testRecvInternal(t *testing.T, fakeNet *fakeNetworkProtocol, localAddrByte byte, ep *channel.Endpoint, buf buffer.View, want int) {
-	t.Helper()
-	ep.InjectInbound(fakeNetNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
-		Data: buf.ToVectorisedView(),
-	}))
-	if got := fakeNet.PacketCount(localAddrByte); got != want {
-		t.Errorf("receive packet count: got = %d, want %d", got, want)
-	}
-}
-
-func TestNetworkSend(t *testing.T) {
-	// Create a stack with the fake network protocol, one nic, and one
-	// address: 1. The route table sends all packets through the only
-	// existing nic.
-	ep := channel.New(10, defaultMTU, "")
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
-	})
-	if err := s.CreateNIC(1, ep); err != nil {
-		t.Fatal("NewNIC failed:", err)
-	}
-
-	{
-		subnet, err := tcpip.NewSubnet("\x00", "\x00")
-		if err != nil {
-			t.Fatal(err)
-		}
-		s.SetRouteTable([]tcpip.Route{{Destination: subnet, Gateway: "\x00", NIC: 1}})
-	}
-
-	if err := s.AddAddress(1, fakeNetNumber, "\x01"); err != nil {
-		t.Fatal("AddAddress failed:", err)
-	}
-
-	// Make sure that the link-layer endpoint received the outbound packet.
-	testSendTo(t, s, "\x03", ep, nil)
-}
-
-func TestNetworkSendMultiRoute(t *testing.T) {
-	// Create a stack with the fake network protocol, two nics, and two
-	// addresses per nic, the first nic has odd address, the second one has
-	// even addresses.
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
-	})
-
-	ep1 := channel.New(10, defaultMTU, "")
-	if err := s.CreateNIC(1, ep1); err != nil {
-		t.Fatal("CreateNIC failed:", err)
-	}
-
-	if err := s.AddAddress(1, fakeNetNumber, "\x01"); err != nil {
-		t.Fatal("AddAddress failed:", err)
-	}
-
-	if err := s.AddAddress(1, fakeNetNumber, "\x03"); err != nil {
-		t.Fatal("AddAddress failed:", err)
-	}
-
-	ep2 := channel.New(10, defaultMTU, "")
-	if err := s.CreateNIC(2, ep2); err != nil {
-		t.Fatal("CreateNIC failed:", err)
-	}
-
-	if err := s.AddAddress(2, fakeNetNumber, "\x02"); err != nil {
-		t.Fatal("AddAddress failed:", err)
-	}
-
-	if err := s.AddAddress(2, fakeNetNumber, "\x04"); err != nil {
-		t.Fatal("AddAddress failed:", err)
-	}
-
-	// Set a route table that sends all packets with odd destination
-	// addresses through the first NIC, and all even destination address
-	// through the second one.
-	{
-		subnet0, err := tcpip.NewSubnet("\x00", "\x01")
-		if err != nil {
-			t.Fatal(err)
-		}
-		subnet1, err := tcpip.NewSubnet("\x01", "\x01")
-		if err != nil {
-			t.Fatal(err)
-		}
-		s.SetRouteTable([]tcpip.Route{
-			{Destination: subnet1, Gateway: "\x00", NIC: 1},
-			{Destination: subnet0, Gateway: "\x00", NIC: 2},
-		})
-	}
-
-	// Send a packet to an odd destination.
-	testSendTo(t, s, "\x05", ep1, nil)
-
-	// Send a packet to an even destination.
-	testSendTo(t, s, "\x06", ep2, nil)
-}
-
-func testRoute(t *testing.T, s *stack.Stack, nic tcpip.NICID, srcAddr, dstAddr, expectedSrcAddr tcpip.Address) {
-	r, err := s.FindRoute(nic, srcAddr, dstAddr, fakeNetNumber, false /* multicastLoop */)
-	if err != nil {
-		t.Fatal("FindRoute failed:", err)
-	}
-
-	defer r.Release()
-
-	if r.LocalAddress != expectedSrcAddr {
-		t.Fatalf("Bad source address: expected %v, got %v", expectedSrcAddr, r.LocalAddress)
-	}
-
-	if r.RemoteAddress != dstAddr {
-		t.Fatalf("Bad destination address: expected %v, got %v", dstAddr, r.RemoteAddress)
-	}
-}
-
-func testNoRoute(t *testing.T, s *stack.Stack, nic tcpip.NICID, srcAddr, dstAddr tcpip.Address) {
-	_, err := s.FindRoute(nic, srcAddr, dstAddr, fakeNetNumber, false /* multicastLoop */)
-	if _, ok := err.(*tcpip.ErrNoRoute); !ok {
-		t.Fatalf("FindRoute returned unexpected error, got = %v, want = %s", err, &tcpip.ErrNoRoute{})
-	}
-}
-
-// TestAttachToLinkEndpointImmediately tests that a LinkEndpoint is attached to
-// a NetworkDispatcher when the NIC is created.
-func TestAttachToLinkEndpointImmediately(t *testing.T) {
-	const nicID = 1
-
-	tests := []struct {
-		name    string
-		nicOpts stack.NICOptions
-	}{
-		{
-			name:    "Create enabled NIC",
-			nicOpts: stack.NICOptions{Disabled: false},
-		},
-		{
-			name:    "Create disabled NIC",
-			nicOpts: stack.NICOptions{Disabled: true},
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			s := stack.New(stack.Options{
-				NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
-			})
-
-			e := linkEPWithMockedAttach{
-				LinkEndpoint: loopback.New(),
-			}
-
-			if err := s.CreateNICWithOptions(nicID, &e, test.nicOpts); err != nil {
-				t.Fatalf("CreateNICWithOptions(%d, _, %+v) = %s", nicID, test.nicOpts, err)
-			}
-			if !e.isAttached() {
-				t.Fatal("link endpoint not attached to a network dispatcher")
-			}
-		})
-	}
-}
-
-func TestDisableUnknownNIC(t *testing.T) {
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
-	})
-
-	err := s.DisableNIC(1)
-	if _, ok := err.(*tcpip.ErrUnknownNICID); !ok {
-		t.Fatalf("got s.DisableNIC(1) = %v, want = %s", err, &tcpip.ErrUnknownNICID{})
-	}
-}
-
-func TestDisabledNICsNICInfoAndCheckNIC(t *testing.T) {
-	const nicID = 1
-
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
-	})
-
-	e := loopback.New()
-	nicOpts := stack.NICOptions{Disabled: true}
-	if err := s.CreateNICWithOptions(nicID, e, nicOpts); err != nil {
-		t.Fatalf("CreateNICWithOptions(%d, _, %+v) = %s", nicID, nicOpts, err)
-	}
-
-	checkNIC := func(enabled bool) {
-		t.Helper()
-
-		allNICInfo := s.NICInfo()
-		nicInfo, ok := allNICInfo[nicID]
-		if !ok {
-			t.Errorf("entry for %d missing from allNICInfo = %+v", nicID, allNICInfo)
-		} else if nicInfo.Flags.Running != enabled {
-			t.Errorf("got nicInfo.Flags.Running = %t, want = %t", nicInfo.Flags.Running, enabled)
-		}
-
-		if got := s.CheckNIC(nicID); got != enabled {
-			t.Errorf("got s.CheckNIC(%d) = %t, want = %t", nicID, got, enabled)
-		}
-	}
-
-	// NIC should initially report itself as disabled.
-	checkNIC(false)
-
-	if err := s.EnableNIC(nicID); err != nil {
-		t.Fatalf("s.EnableNIC(%d): %s", nicID, err)
-	}
-	checkNIC(true)
-
-	// If the NIC is not reporting a correct enabled status, we cannot trust the
-	// next check so end the test here.
-	if t.Failed() {
-		t.FailNow()
-	}
-
-	if err := s.DisableNIC(nicID); err != nil {
-		t.Fatalf("s.DisableNIC(%d): %s", nicID, err)
-	}
-	checkNIC(false)
-}
-
-func TestRemoveUnknownNIC(t *testing.T) {
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
-	})
-
-	err := s.RemoveNIC(1)
-	if _, ok := err.(*tcpip.ErrUnknownNICID); !ok {
-		t.Fatalf("got s.RemoveNIC(1) = %v, want = %s", err, &tcpip.ErrUnknownNICID{})
-	}
-}
-
-func TestRemoveNIC(t *testing.T) {
-	const nicID = 1
-
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
-	})
-
-	e := linkEPWithMockedAttach{
-		LinkEndpoint: loopback.New(),
-	}
-	if err := s.CreateNIC(nicID, &e); err != nil {
-		t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
-	}
-
-	// NIC should be present in NICInfo and attached to a NetworkDispatcher.
-	allNICInfo := s.NICInfo()
-	if _, ok := allNICInfo[nicID]; !ok {
-		t.Errorf("entry for %d missing from allNICInfo = %+v", nicID, allNICInfo)
-	}
-	if !e.isAttached() {
-		t.Fatal("link endpoint not attached to a network dispatcher")
-	}
-
-	// Removing a NIC should remove it from NICInfo and e should be detached from
-	// the NetworkDispatcher.
-	if err := s.RemoveNIC(nicID); err != nil {
-		t.Fatalf("s.RemoveNIC(%d): %s", nicID, err)
-	}
-	if nicInfo, ok := s.NICInfo()[nicID]; ok {
-		t.Errorf("got unexpected NICInfo entry for deleted NIC %d = %+v", nicID, nicInfo)
-	}
-	if e.isAttached() {
-		t.Error("link endpoint for removed NIC still attached to a network dispatcher")
-	}
-}
-
-func TestRouteWithDownNIC(t *testing.T) {
-	tests := []struct {
-		name   string
-		downFn func(s *stack.Stack, nicID tcpip.NICID) tcpip.Error
-		upFn   func(s *stack.Stack, nicID tcpip.NICID) tcpip.Error
-	}{
-		{
-			name:   "Disabled NIC",
-			downFn: (*stack.Stack).DisableNIC,
-			upFn:   (*stack.Stack).EnableNIC,
-		},
-
-		// Once a NIC is removed, it cannot be brought up.
-		{
-			name:   "Removed NIC",
-			downFn: (*stack.Stack).RemoveNIC,
-		},
-	}
-
-	const unspecifiedNIC = 0
-	const nicID1 = 1
-	const nicID2 = 2
-	const addr1 = tcpip.Address("\x01")
-	const addr2 = tcpip.Address("\x02")
-	const nic1Dst = tcpip.Address("\x05")
-	const nic2Dst = tcpip.Address("\x06")
-
-	setup := func(t *testing.T) (*stack.Stack, *channel.Endpoint, *channel.Endpoint) {
-		s := stack.New(stack.Options{
-			NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
-		})
-
-		ep1 := channel.New(1, defaultMTU, "")
-		if err := s.CreateNIC(nicID1, ep1); err != nil {
-			t.Fatalf("CreateNIC(%d, _): %s", nicID1, err)
-		}
-
-		if err := s.AddAddress(nicID1, fakeNetNumber, addr1); err != nil {
-			t.Fatalf("AddAddress(%d, %d, %s): %s", nicID1, fakeNetNumber, addr1, err)
-		}
-
-		ep2 := channel.New(1, defaultMTU, "")
-		if err := s.CreateNIC(nicID2, ep2); err != nil {
-			t.Fatalf("CreateNIC(%d, _): %s", nicID2, err)
-		}
-
-		if err := s.AddAddress(nicID2, fakeNetNumber, addr2); err != nil {
-			t.Fatalf("AddAddress(%d, %d, %s): %s", nicID2, fakeNetNumber, addr2, err)
-		}
-
-		// Set a route table that sends all packets with odd destination
-		// addresses through the first NIC, and all even destination address
-		// through the second one.
-		{
-			subnet0, err := tcpip.NewSubnet("\x00", "\x01")
-			if err != nil {
-				t.Fatal(err)
-			}
-			subnet1, err := tcpip.NewSubnet("\x01", "\x01")
-			if err != nil {
-				t.Fatal(err)
-			}
-			s.SetRouteTable([]tcpip.Route{
-				{Destination: subnet1, Gateway: "\x00", NIC: nicID1},
-				{Destination: subnet0, Gateway: "\x00", NIC: nicID2},
-			})
-		}
-
-		return s, ep1, ep2
-	}
-
-	// Tests that routes through a down NIC are not used when looking up a route
-	// for a destination.
-	t.Run("Find", func(t *testing.T) {
-		for _, test := range tests {
-			t.Run(test.name, func(t *testing.T) {
-				s, _, _ := setup(t)
-
-				// Test routes to odd address.
-				testRoute(t, s, unspecifiedNIC, "", "\x05", addr1)
-				testRoute(t, s, unspecifiedNIC, addr1, "\x05", addr1)
-				testRoute(t, s, nicID1, addr1, "\x05", addr1)
-
-				// Test routes to even address.
-				testRoute(t, s, unspecifiedNIC, "", "\x06", addr2)
-				testRoute(t, s, unspecifiedNIC, addr2, "\x06", addr2)
-				testRoute(t, s, nicID2, addr2, "\x06", addr2)
-
-				// Bringing NIC1 down should result in no routes to odd addresses. Routes to
-				// even addresses should continue to be available as NIC2 is still up.
-				if err := test.downFn(s, nicID1); err != nil {
-					t.Fatalf("test.downFn(_, %d): %s", nicID1, err)
-				}
-				testNoRoute(t, s, unspecifiedNIC, "", nic1Dst)
-				testNoRoute(t, s, unspecifiedNIC, addr1, nic1Dst)
-				testNoRoute(t, s, nicID1, addr1, nic1Dst)
-				testRoute(t, s, unspecifiedNIC, "", nic2Dst, addr2)
-				testRoute(t, s, unspecifiedNIC, addr2, nic2Dst, addr2)
-				testRoute(t, s, nicID2, addr2, nic2Dst, addr2)
-
-				// Bringing NIC2 down should result in no routes to even addresses. No
-				// route should be available to any address as routes to odd addresses
-				// were made unavailable by bringing NIC1 down above.
-				if err := test.downFn(s, nicID2); err != nil {
-					t.Fatalf("test.downFn(_, %d): %s", nicID2, err)
-				}
-				testNoRoute(t, s, unspecifiedNIC, "", nic1Dst)
-				testNoRoute(t, s, unspecifiedNIC, addr1, nic1Dst)
-				testNoRoute(t, s, nicID1, addr1, nic1Dst)
-				testNoRoute(t, s, unspecifiedNIC, "", nic2Dst)
-				testNoRoute(t, s, unspecifiedNIC, addr2, nic2Dst)
-				testNoRoute(t, s, nicID2, addr2, nic2Dst)
-
-				if upFn := test.upFn; upFn != nil {
-					// Bringing NIC1 up should make routes to odd addresses available
-					// again. Routes to even addresses should continue to be unavailable
-					// as NIC2 is still down.
-					if err := upFn(s, nicID1); err != nil {
-						t.Fatalf("test.upFn(_, %d): %s", nicID1, err)
-					}
-					testRoute(t, s, unspecifiedNIC, "", nic1Dst, addr1)
-					testRoute(t, s, unspecifiedNIC, addr1, nic1Dst, addr1)
-					testRoute(t, s, nicID1, addr1, nic1Dst, addr1)
-					testNoRoute(t, s, unspecifiedNIC, "", nic2Dst)
-					testNoRoute(t, s, unspecifiedNIC, addr2, nic2Dst)
-					testNoRoute(t, s, nicID2, addr2, nic2Dst)
-				}
-			})
-		}
-	})
-
-	// Tests that writing a packet using a Route through a down NIC fails.
-	t.Run("WritePacket", func(t *testing.T) {
-		for _, test := range tests {
-			t.Run(test.name, func(t *testing.T) {
-				s, ep1, ep2 := setup(t)
-
-				r1, err := s.FindRoute(nicID1, addr1, nic1Dst, fakeNetNumber, false /* multicastLoop */)
-				if err != nil {
-					t.Errorf("FindRoute(%d, %s, %s, %d, false): %s", nicID1, addr1, nic1Dst, fakeNetNumber, err)
-				}
-				defer r1.Release()
-
-				r2, err := s.FindRoute(nicID2, addr2, nic2Dst, fakeNetNumber, false /* multicastLoop */)
-				if err != nil {
-					t.Errorf("FindRoute(%d, %s, %s, %d, false): %s", nicID2, addr2, nic2Dst, fakeNetNumber, err)
-				}
-				defer r2.Release()
-
-				// If we failed to get routes r1 or r2, we cannot proceed with the test.
-				if t.Failed() {
-					t.FailNow()
-				}
-
-				buf := buffer.View([]byte{1})
-				testSend(t, r1, ep1, buf)
-				testSend(t, r2, ep2, buf)
-
-				// Writes with Routes that use NIC1 after being brought down should fail.
-				if err := test.downFn(s, nicID1); err != nil {
-					t.Fatalf("test.downFn(_, %d): %s", nicID1, err)
-				}
-				testFailingSend(t, r1, ep1, buf, &tcpip.ErrInvalidEndpointState{})
-				testSend(t, r2, ep2, buf)
-
-				// Writes with Routes that use NIC2 after being brought down should fail.
-				if err := test.downFn(s, nicID2); err != nil {
-					t.Fatalf("test.downFn(_, %d): %s", nicID2, err)
-				}
-				testFailingSend(t, r1, ep1, buf, &tcpip.ErrInvalidEndpointState{})
-				testFailingSend(t, r2, ep2, buf, &tcpip.ErrInvalidEndpointState{})
-
-				if upFn := test.upFn; upFn != nil {
-					// Writes with Routes that use NIC1 after being brought up should
-					// succeed.
-					//
-					// TODO(gvisor.dev/issue/1491): Should we instead completely
-					// invalidate all Routes that were bound to a NIC that was brought
-					// down at some point?
-					if err := upFn(s, nicID1); err != nil {
-						t.Fatalf("test.upFn(_, %d): %s", nicID1, err)
-					}
-					testSend(t, r1, ep1, buf)
-					testFailingSend(t, r2, ep2, buf, &tcpip.ErrInvalidEndpointState{})
-				}
-			})
-		}
-	})
-}
-
-func TestRoutes(t *testing.T) {
-	// Create a stack with the fake network protocol, two nics, and two
-	// addresses per nic, the first nic has odd address, the second one has
-	// even addresses.
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
-	})
-
-	ep1 := channel.New(10, defaultMTU, "")
-	if err := s.CreateNIC(1, ep1); err != nil {
-		t.Fatal("CreateNIC failed:", err)
-	}
-
-	if err := s.AddAddress(1, fakeNetNumber, "\x01"); err != nil {
-		t.Fatal("AddAddress failed:", err)
-	}
-
-	if err := s.AddAddress(1, fakeNetNumber, "\x03"); err != nil {
-		t.Fatal("AddAddress failed:", err)
-	}
-
-	ep2 := channel.New(10, defaultMTU, "")
-	if err := s.CreateNIC(2, ep2); err != nil {
-		t.Fatal("CreateNIC failed:", err)
-	}
-
-	if err := s.AddAddress(2, fakeNetNumber, "\x02"); err != nil {
-		t.Fatal("AddAddress failed:", err)
-	}
-
-	if err := s.AddAddress(2, fakeNetNumber, "\x04"); err != nil {
-		t.Fatal("AddAddress failed:", err)
-	}
-
-	// Set a route table that sends all packets with odd destination
-	// addresses through the first NIC, and all even destination address
-	// through the second one.
-	{
-		subnet0, err := tcpip.NewSubnet("\x00", "\x01")
-		if err != nil {
-			t.Fatal(err)
-		}
-		subnet1, err := tcpip.NewSubnet("\x01", "\x01")
-		if err != nil {
-			t.Fatal(err)
-		}
-		s.SetRouteTable([]tcpip.Route{
-			{Destination: subnet1, Gateway: "\x00", NIC: 1},
-			{Destination: subnet0, Gateway: "\x00", NIC: 2},
-		})
-	}
-
-	// Test routes to odd address.
-	testRoute(t, s, 0, "", "\x05", "\x01")
-	testRoute(t, s, 0, "\x01", "\x05", "\x01")
-	testRoute(t, s, 1, "\x01", "\x05", "\x01")
-	testRoute(t, s, 0, "\x03", "\x05", "\x03")
-	testRoute(t, s, 1, "\x03", "\x05", "\x03")
-
-	// Test routes to even address.
-	testRoute(t, s, 0, "", "\x06", "\x02")
-	testRoute(t, s, 0, "\x02", "\x06", "\x02")
-	testRoute(t, s, 2, "\x02", "\x06", "\x02")
-	testRoute(t, s, 0, "\x04", "\x06", "\x04")
-	testRoute(t, s, 2, "\x04", "\x06", "\x04")
-
-	// Try to send to odd numbered address from even numbered ones, then
-	// vice-versa.
-	testNoRoute(t, s, 0, "\x02", "\x05")
-	testNoRoute(t, s, 2, "\x02", "\x05")
-	testNoRoute(t, s, 0, "\x04", "\x05")
-	testNoRoute(t, s, 2, "\x04", "\x05")
-
-	testNoRoute(t, s, 0, "\x01", "\x06")
-	testNoRoute(t, s, 1, "\x01", "\x06")
-	testNoRoute(t, s, 0, "\x03", "\x06")
-	testNoRoute(t, s, 1, "\x03", "\x06")
-}
-
-func TestAddressRemoval(t *testing.T) {
-	const localAddrByte byte = 0x01
-	localAddr := tcpip.Address([]byte{localAddrByte})
-	remoteAddr := tcpip.Address("\x02")
-
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
-	})
-
-	ep := channel.New(10, defaultMTU, "")
-	if err := s.CreateNIC(1, ep); err != nil {
-		t.Fatal("CreateNIC failed:", err)
-	}
-
-	if err := s.AddAddress(1, fakeNetNumber, localAddr); err != nil {
-		t.Fatal("AddAddress failed:", err)
-	}
-	{
-		subnet, err := tcpip.NewSubnet("\x00", "\x00")
-		if err != nil {
-			t.Fatal(err)
-		}
-		s.SetRouteTable([]tcpip.Route{{Destination: subnet, Gateway: "\x00", NIC: 1}})
-	}
-
-	fakeNet := s.NetworkProtocolInstance(fakeNetNumber).(*fakeNetworkProtocol)
-
-	buf := buffer.NewView(30)
-
-	// Send and receive packets, and verify they are received.
-	buf[dstAddrOffset] = localAddrByte
-	testRecv(t, fakeNet, localAddrByte, ep, buf)
-	testSendTo(t, s, remoteAddr, ep, nil)
-
-	// Remove the address, then check that send/receive doesn't work anymore.
-	if err := s.RemoveAddress(1, localAddr); err != nil {
-		t.Fatal("RemoveAddress failed:", err)
-	}
-	testFailingRecv(t, fakeNet, localAddrByte, ep, buf)
-	testFailingSendTo(t, s, remoteAddr, ep, nil, &tcpip.ErrNoRoute{})
-
-	// Check that removing the same address fails.
-	err := s.RemoveAddress(1, localAddr)
-	if _, ok := err.(*tcpip.ErrBadLocalAddress); !ok {
-		t.Fatalf("RemoveAddress returned unexpected error, got = %v, want = %s", err, &tcpip.ErrBadLocalAddress{})
-	}
-}
-
-func TestAddressRemovalWithRouteHeld(t *testing.T) {
-	const localAddrByte byte = 0x01
-	localAddr := tcpip.Address([]byte{localAddrByte})
-	remoteAddr := tcpip.Address("\x02")
-
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
-	})
-
-	ep := channel.New(10, defaultMTU, "")
-	if err := s.CreateNIC(1, ep); err != nil {
-		t.Fatalf("CreateNIC failed: %v", err)
-	}
-	fakeNet := s.NetworkProtocolInstance(fakeNetNumber).(*fakeNetworkProtocol)
-	buf := buffer.NewView(30)
-
-	if err := s.AddAddress(1, fakeNetNumber, localAddr); err != nil {
-		t.Fatal("AddAddress failed:", err)
-	}
-	{
-		subnet, err := tcpip.NewSubnet("\x00", "\x00")
-		if err != nil {
-			t.Fatal(err)
-		}
-		s.SetRouteTable([]tcpip.Route{{Destination: subnet, Gateway: "\x00", NIC: 1}})
-	}
-
-	r, err := s.FindRoute(0, "", remoteAddr, fakeNetNumber, false /* multicastLoop */)
-	if err != nil {
-		t.Fatal("FindRoute failed:", err)
-	}
-
-	// Send and receive packets, and verify they are received.
-	buf[dstAddrOffset] = localAddrByte
-	testRecv(t, fakeNet, localAddrByte, ep, buf)
-	testSend(t, r, ep, nil)
-	testSendTo(t, s, remoteAddr, ep, nil)
-
-	// Remove the address, then check that send/receive doesn't work anymore.
-	if err := s.RemoveAddress(1, localAddr); err != nil {
-		t.Fatal("RemoveAddress failed:", err)
-	}
-	testFailingRecv(t, fakeNet, localAddrByte, ep, buf)
-	testFailingSend(t, r, ep, nil, &tcpip.ErrInvalidEndpointState{})
-	testFailingSendTo(t, s, remoteAddr, ep, nil, &tcpip.ErrNoRoute{})
-
-	// Check that removing the same address fails.
-	{
-		err := s.RemoveAddress(1, localAddr)
-		if _, ok := err.(*tcpip.ErrBadLocalAddress); !ok {
-			t.Fatalf("RemoveAddress returned unexpected error, got = %v, want = %s", err, &tcpip.ErrBadLocalAddress{})
-		}
-	}
-}
-
-func verifyAddress(t *testing.T, s *stack.Stack, nicID tcpip.NICID, addr tcpip.Address) {
-	t.Helper()
-	info, ok := s.NICInfo()[nicID]
-	if !ok {
-		t.Fatalf("NICInfo() failed to find nicID=%d", nicID)
-	}
-	if len(addr) == 0 {
-		// No address given, verify that there is no address assigned to the NIC.
-		for _, a := range info.ProtocolAddresses {
-			if a.Protocol == fakeNetNumber && a.AddressWithPrefix != (tcpip.AddressWithPrefix{}) {
-				t.Errorf("verify no-address: got = %s, want = %s", a.AddressWithPrefix, (tcpip.AddressWithPrefix{}))
-			}
-		}
-		return
-	}
-	// Address given, verify the address is assigned to the NIC and no other
-	// address is.
-	found := false
-	for _, a := range info.ProtocolAddresses {
-		if a.Protocol == fakeNetNumber {
-			if a.AddressWithPrefix.Address == addr {
-				found = true
-			} else {
-				t.Errorf("verify address: got = %s, want = %s", a.AddressWithPrefix.Address, addr)
-			}
-		}
-	}
-	if !found {
-		t.Errorf("verify address: couldn't find %s on the NIC", addr)
-	}
-}
-
-func TestEndpointExpiration(t *testing.T) {
-	const (
-		localAddrByte byte          = 0x01
-		remoteAddr    tcpip.Address = "\x03"
-		noAddr        tcpip.Address = ""
-		nicID         tcpip.NICID   = 1
-	)
-	localAddr := tcpip.Address([]byte{localAddrByte})
-
-	for _, promiscuous := range []bool{true, false} {
-		for _, spoofing := range []bool{true, false} {
-			t.Run(fmt.Sprintf("promiscuous=%t spoofing=%t", promiscuous, spoofing), func(t *testing.T) {
-				s := stack.New(stack.Options{
-					NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
-				})
-
-				ep := channel.New(10, defaultMTU, "")
-				if err := s.CreateNIC(nicID, ep); err != nil {
-					t.Fatal("CreateNIC failed:", err)
-				}
-
-				{
-					subnet, err := tcpip.NewSubnet("\x00", "\x00")
-					if err != nil {
-						t.Fatal(err)
-					}
-					s.SetRouteTable([]tcpip.Route{{Destination: subnet, Gateway: "\x00", NIC: 1}})
-				}
-
-				fakeNet := s.NetworkProtocolInstance(fakeNetNumber).(*fakeNetworkProtocol)
-				buf := buffer.NewView(30)
-				buf[dstAddrOffset] = localAddrByte
-
-				if promiscuous {
-					if err := s.SetPromiscuousMode(nicID, true); err != nil {
-						t.Fatal("SetPromiscuousMode failed:", err)
-					}
-				}
-
-				if spoofing {
-					if err := s.SetSpoofing(nicID, true); err != nil {
-						t.Fatal("SetSpoofing failed:", err)
-					}
-				}
-
-				// 1. No Address yet, send should only work for spoofing, receive for
-				// promiscuous mode.
-				//-----------------------
-				verifyAddress(t, s, nicID, noAddr)
-				if promiscuous {
-					testRecv(t, fakeNet, localAddrByte, ep, buf)
-				} else {
-					testFailingRecv(t, fakeNet, localAddrByte, ep, buf)
-				}
-				if spoofing {
-					// FIXME(b/139841518):Spoofing doesn't work if there is no primary address.
-					// testSendTo(t, s, remoteAddr, ep, nil)
-				} else {
-					testFailingSendTo(t, s, remoteAddr, ep, nil, &tcpip.ErrNoRoute{})
-				}
-
-				// 2. Add Address, everything should work.
-				//-----------------------
-				if err := s.AddAddress(nicID, fakeNetNumber, localAddr); err != nil {
-					t.Fatal("AddAddress failed:", err)
-				}
-				verifyAddress(t, s, nicID, localAddr)
-				testRecv(t, fakeNet, localAddrByte, ep, buf)
-				testSendTo(t, s, remoteAddr, ep, nil)
-
-				// 3. Remove the address, send should only work for spoofing, receive
-				// for promiscuous mode.
-				//-----------------------
-				if err := s.RemoveAddress(nicID, localAddr); err != nil {
-					t.Fatal("RemoveAddress failed:", err)
-				}
-				verifyAddress(t, s, nicID, noAddr)
-				if promiscuous {
-					testRecv(t, fakeNet, localAddrByte, ep, buf)
-				} else {
-					testFailingRecv(t, fakeNet, localAddrByte, ep, buf)
-				}
-				if spoofing {
-					// FIXME(b/139841518):Spoofing doesn't work if there is no primary address.
-					// testSendTo(t, s, remoteAddr, ep, nil)
-				} else {
-					testFailingSendTo(t, s, remoteAddr, ep, nil, &tcpip.ErrNoRoute{})
-				}
-
-				// 4. Add Address back, everything should work again.
-				//-----------------------
-				if err := s.AddAddress(nicID, fakeNetNumber, localAddr); err != nil {
-					t.Fatal("AddAddress failed:", err)
-				}
-				verifyAddress(t, s, nicID, localAddr)
-				testRecv(t, fakeNet, localAddrByte, ep, buf)
-				testSendTo(t, s, remoteAddr, ep, nil)
-
-				// 5. Take a reference to the endpoint by getting a route. Verify that
-				// we can still send/receive, including sending using the route.
-				//-----------------------
-				r, err := s.FindRoute(0, "", remoteAddr, fakeNetNumber, false /* multicastLoop */)
-				if err != nil {
-					t.Fatal("FindRoute failed:", err)
-				}
-				testRecv(t, fakeNet, localAddrByte, ep, buf)
-				testSendTo(t, s, remoteAddr, ep, nil)
-				testSend(t, r, ep, nil)
-
-				// 6. Remove the address. Send should only work for spoofing, receive
-				// for promiscuous mode.
-				//-----------------------
-				if err := s.RemoveAddress(nicID, localAddr); err != nil {
-					t.Fatal("RemoveAddress failed:", err)
-				}
-				verifyAddress(t, s, nicID, noAddr)
-				if promiscuous {
-					testRecv(t, fakeNet, localAddrByte, ep, buf)
-				} else {
-					testFailingRecv(t, fakeNet, localAddrByte, ep, buf)
-				}
-				if spoofing {
-					testSend(t, r, ep, nil)
-					testSendTo(t, s, remoteAddr, ep, nil)
-				} else {
-					testFailingSend(t, r, ep, nil, &tcpip.ErrInvalidEndpointState{})
-					testFailingSendTo(t, s, remoteAddr, ep, nil, &tcpip.ErrNoRoute{})
-				}
-
-				// 7. Add Address back, everything should work again.
-				//-----------------------
-				if err := s.AddAddress(nicID, fakeNetNumber, localAddr); err != nil {
-					t.Fatal("AddAddress failed:", err)
-				}
-				verifyAddress(t, s, nicID, localAddr)
-				testRecv(t, fakeNet, localAddrByte, ep, buf)
-				testSendTo(t, s, remoteAddr, ep, nil)
-				testSend(t, r, ep, nil)
-
-				// 8. Remove the route, sendTo/recv should still work.
-				//-----------------------
-				r.Release()
-				verifyAddress(t, s, nicID, localAddr)
-				testRecv(t, fakeNet, localAddrByte, ep, buf)
-				testSendTo(t, s, remoteAddr, ep, nil)
-
-				// 9. Remove the address. Send should only work for spoofing, receive
-				// for promiscuous mode.
-				//-----------------------
-				if err := s.RemoveAddress(nicID, localAddr); err != nil {
-					t.Fatal("RemoveAddress failed:", err)
-				}
-				verifyAddress(t, s, nicID, noAddr)
-				if promiscuous {
-					testRecv(t, fakeNet, localAddrByte, ep, buf)
-				} else {
-					testFailingRecv(t, fakeNet, localAddrByte, ep, buf)
-				}
-				if spoofing {
-					// FIXME(b/139841518):Spoofing doesn't work if there is no primary address.
-					// testSendTo(t, s, remoteAddr, ep, nil)
-				} else {
-					testFailingSendTo(t, s, remoteAddr, ep, nil, &tcpip.ErrNoRoute{})
-				}
-			})
-		}
-	}
-}
-
-func TestPromiscuousMode(t *testing.T) {
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
-	})
-
-	ep := channel.New(10, defaultMTU, "")
-	if err := s.CreateNIC(1, ep); err != nil {
-		t.Fatal("CreateNIC failed:", err)
-	}
-
-	{
-		subnet, err := tcpip.NewSubnet("\x00", "\x00")
-		if err != nil {
-			t.Fatal(err)
-		}
-		s.SetRouteTable([]tcpip.Route{{Destination: subnet, Gateway: "\x00", NIC: 1}})
-	}
-
-	fakeNet := s.NetworkProtocolInstance(fakeNetNumber).(*fakeNetworkProtocol)
-
-	buf := buffer.NewView(30)
-
-	// Write a packet, and check that it doesn't get delivered as we don't
-	// have a matching endpoint.
-	const localAddrByte byte = 0x01
-	buf[dstAddrOffset] = localAddrByte
-	testFailingRecv(t, fakeNet, localAddrByte, ep, buf)
-
-	// Set promiscuous mode, then check that packet is delivered.
-	if err := s.SetPromiscuousMode(1, true); err != nil {
-		t.Fatal("SetPromiscuousMode failed:", err)
-	}
-	testRecv(t, fakeNet, localAddrByte, ep, buf)
-
-	// Check that we can't get a route as there is no local address.
-	_, err := s.FindRoute(0, "", "\x02", fakeNetNumber, false /* multicastLoop */)
-	if _, ok := err.(*tcpip.ErrNoRoute); !ok {
-		t.Fatalf("FindRoute returned unexpected error: got = %v, want = %s", err, &tcpip.ErrNoRoute{})
-	}
-
-	// Set promiscuous mode to false, then check that packet can't be
-	// delivered anymore.
-	if err := s.SetPromiscuousMode(1, false); err != nil {
-		t.Fatal("SetPromiscuousMode failed:", err)
-	}
-	testFailingRecv(t, fakeNet, localAddrByte, ep, buf)
-}
-
-// TestExternalSendWithHandleLocal tests that the stack creates a non-local
-// route when spoofing or promiscuous mode are enabled.
-//
-// This test makes sure that packets are transmitted from the stack.
-func TestExternalSendWithHandleLocal(t *testing.T) {
-	const (
-		unspecifiedNICID = 0
-		nicID            = 1
-
-		localAddr = tcpip.Address("\x01")
-		dstAddr   = tcpip.Address("\x03")
-	)
-
-	subnet, err := tcpip.NewSubnet("\x00", "\x00")
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	tests := []struct {
-		name           string
-		configureStack func(*testing.T, *stack.Stack)
-	}{
-		{
-			name:           "Default",
-			configureStack: func(*testing.T, *stack.Stack) {},
-		},
-		{
-			name: "Spoofing",
-			configureStack: func(t *testing.T, s *stack.Stack) {
-				if err := s.SetSpoofing(nicID, true); err != nil {
-					t.Fatalf("s.SetSpoofing(%d, true): %s", nicID, err)
-				}
-			},
-		},
-		{
-			name: "Promiscuous",
-			configureStack: func(t *testing.T, s *stack.Stack) {
-				if err := s.SetPromiscuousMode(nicID, true); err != nil {
-					t.Fatalf("s.SetPromiscuousMode(%d, true): %s", nicID, err)
-				}
-			},
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			for _, handleLocal := range []bool{true, false} {
-				t.Run(fmt.Sprintf("HandleLocal=%t", handleLocal), func(t *testing.T) {
-					s := stack.New(stack.Options{
-						NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
-						HandleLocal:      handleLocal,
-					})
-
-					ep := channel.New(1, defaultMTU, "")
-					if err := s.CreateNIC(nicID, ep); err != nil {
-						t.Fatalf("s.CreateNIC(%d, _): %s", nicID, err)
-					}
-					if err := s.AddAddress(nicID, fakeNetNumber, localAddr); err != nil {
-						t.Fatalf("s.AddAddress(%d, %d, %s): %s", nicID, fakeNetNumber, localAddr, err)
-					}
-
-					s.SetRouteTable([]tcpip.Route{{Destination: subnet, NIC: nicID}})
-
-					test.configureStack(t, s)
-
-					r, err := s.FindRoute(unspecifiedNICID, localAddr, dstAddr, fakeNetNumber, false /* multicastLoop */)
-					if err != nil {
-						t.Fatalf("s.FindRoute(%d, %s, %s, %d, false): %s", unspecifiedNICID, localAddr, dstAddr, fakeNetNumber, err)
-					}
-					defer r.Release()
-
-					if r.LocalAddress != localAddr {
-						t.Errorf("got r.LocalAddress = %s, want = %s", r.LocalAddress, localAddr)
-					}
-					if r.RemoteAddress != dstAddr {
-						t.Errorf("got r.RemoteAddress = %s, want = %s", r.RemoteAddress, dstAddr)
-					}
-
-					if n := ep.Drain(); n != 0 {
-						t.Fatalf("got ep.Drain() = %d, want = 0", n)
-					}
-					if err := r.WritePacket(nil /* gso */, stack.NetworkHeaderParams{
-						Protocol: fakeTransNumber,
-						TTL:      123,
-						TOS:      stack.DefaultTOS,
-					}, stack.NewPacketBuffer(stack.PacketBufferOptions{
-						ReserveHeaderBytes: int(r.MaxHeaderLength()),
-						Data:               buffer.NewView(10).ToVectorisedView(),
-					})); err != nil {
-						t.Fatalf("r.WritePacket(nil, _, _): %s", err)
-					}
-					if n := ep.Drain(); n != 1 {
-						t.Fatalf("got ep.Drain() = %d, want = 1", n)
-					}
-				})
-			}
-		})
-	}
-}
-
-func TestSpoofingWithAddress(t *testing.T) {
-	localAddr := tcpip.Address("\x01")
-	nonExistentLocalAddr := tcpip.Address("\x02")
-	dstAddr := tcpip.Address("\x03")
-
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
-	})
-
-	ep := channel.New(10, defaultMTU, "")
-	if err := s.CreateNIC(1, ep); err != nil {
-		t.Fatal("CreateNIC failed:", err)
-	}
-
-	if err := s.AddAddress(1, fakeNetNumber, localAddr); err != nil {
-		t.Fatal("AddAddress failed:", err)
-	}
-
-	{
-		subnet, err := tcpip.NewSubnet("\x00", "\x00")
-		if err != nil {
-			t.Fatal(err)
-		}
-		s.SetRouteTable([]tcpip.Route{{Destination: subnet, Gateway: "\x00", NIC: 1}})
-	}
-
-	// With address spoofing disabled, FindRoute does not permit an address
-	// that was not added to the NIC to be used as the source.
-	r, err := s.FindRoute(0, nonExistentLocalAddr, dstAddr, fakeNetNumber, false /* multicastLoop */)
-	if err == nil {
-		t.Errorf("FindRoute succeeded with route %+v when it should have failed", r)
-	}
-
-	// With address spoofing enabled, FindRoute permits any address to be used
-	// as the source.
-	if err := s.SetSpoofing(1, true); err != nil {
-		t.Fatal("SetSpoofing failed:", err)
-	}
-	r, err = s.FindRoute(0, nonExistentLocalAddr, dstAddr, fakeNetNumber, false /* multicastLoop */)
-	if err != nil {
-		t.Fatal("FindRoute failed:", err)
-	}
-	if r.LocalAddress != nonExistentLocalAddr {
-		t.Errorf("got Route.LocalAddress = %s, want = %s", r.LocalAddress, nonExistentLocalAddr)
-	}
-	if r.RemoteAddress != dstAddr {
-		t.Errorf("got Route.RemoteAddress = %s, want = %s", r.RemoteAddress, dstAddr)
-	}
-	// Sending a packet works.
-	testSendTo(t, s, dstAddr, ep, nil)
-	testSend(t, r, ep, nil)
-
-	// FindRoute should also work with a local address that exists on the NIC.
-	r, err = s.FindRoute(0, localAddr, dstAddr, fakeNetNumber, false /* multicastLoop */)
-	if err != nil {
-		t.Fatal("FindRoute failed:", err)
-	}
-	if r.LocalAddress != localAddr {
-		t.Errorf("got Route.LocalAddress = %s, want = %s", r.LocalAddress, nonExistentLocalAddr)
-	}
-	if r.RemoteAddress != dstAddr {
-		t.Errorf("got Route.RemoteAddress = %s, want = %s", r.RemoteAddress, dstAddr)
-	}
-	// Sending a packet using the route works.
-	testSend(t, r, ep, nil)
-}
-
-func TestSpoofingNoAddress(t *testing.T) {
-	nonExistentLocalAddr := tcpip.Address("\x01")
-	dstAddr := tcpip.Address("\x02")
-
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
-	})
-
-	ep := channel.New(10, defaultMTU, "")
-	if err := s.CreateNIC(1, ep); err != nil {
-		t.Fatal("CreateNIC failed:", err)
-	}
-
-	{
-		subnet, err := tcpip.NewSubnet("\x00", "\x00")
-		if err != nil {
-			t.Fatal(err)
-		}
-		s.SetRouteTable([]tcpip.Route{{Destination: subnet, Gateway: "\x00", NIC: 1}})
-	}
-
-	// With address spoofing disabled, FindRoute does not permit an address
-	// that was not added to the NIC to be used as the source.
-	r, err := s.FindRoute(0, nonExistentLocalAddr, dstAddr, fakeNetNumber, false /* multicastLoop */)
-	if err == nil {
-		t.Errorf("FindRoute succeeded with route %+v when it should have failed", r)
-	}
-	// Sending a packet fails.
-	testFailingSendTo(t, s, dstAddr, ep, nil, &tcpip.ErrNoRoute{})
-
-	// With address spoofing enabled, FindRoute permits any address to be used
-	// as the source.
-	if err := s.SetSpoofing(1, true); err != nil {
-		t.Fatal("SetSpoofing failed:", err)
-	}
-	r, err = s.FindRoute(0, nonExistentLocalAddr, dstAddr, fakeNetNumber, false /* multicastLoop */)
-	if err != nil {
-		t.Fatal("FindRoute failed:", err)
-	}
-	if r.LocalAddress != nonExistentLocalAddr {
-		t.Errorf("got Route.LocalAddress = %s, want = %s", r.LocalAddress, nonExistentLocalAddr)
-	}
-	if r.RemoteAddress != dstAddr {
-		t.Errorf("got Route.RemoteAddress = %s, want = %s", r.RemoteAddress, dstAddr)
-	}
-	// Sending a packet works.
-	// FIXME(b/139841518):Spoofing doesn't work if there is no primary address.
-	// testSendTo(t, s, remoteAddr, ep, nil)
-}
-
-func verifyRoute(gotRoute, wantRoute *stack.Route) error {
-	if gotRoute.LocalAddress != wantRoute.LocalAddress {
-		return fmt.Errorf("bad local address: got %s, want = %s", gotRoute.LocalAddress, wantRoute.LocalAddress)
-	}
-	if gotRoute.RemoteAddress != wantRoute.RemoteAddress {
-		return fmt.Errorf("bad remote address: got %s, want = %s", gotRoute.RemoteAddress, wantRoute.RemoteAddress)
-	}
-	if got, want := gotRoute.RemoteLinkAddress(), wantRoute.RemoteLinkAddress(); got != want {
-		return fmt.Errorf("bad remote link address: got %s, want = %s", got, want)
-	}
-	if gotRoute.NextHop != wantRoute.NextHop {
-		return fmt.Errorf("bad next-hop address: got %s, want = %s", gotRoute.NextHop, wantRoute.NextHop)
-	}
-	return nil
-}
-
-func TestOutgoingBroadcastWithEmptyRouteTable(t *testing.T) {
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
-	})
-
-	ep := channel.New(10, defaultMTU, "")
-	if err := s.CreateNIC(1, ep); err != nil {
-		t.Fatal("CreateNIC failed:", err)
-	}
-	s.SetRouteTable([]tcpip.Route{})
-
-	// If there is no endpoint, it won't work.
-	{
-		_, err := s.FindRoute(1, header.IPv4Any, header.IPv4Broadcast, fakeNetNumber, false /* multicastLoop */)
-		if _, ok := err.(*tcpip.ErrNetworkUnreachable); !ok {
-			t.Fatalf("got FindRoute(1, %s, %s, %d) = %s, want = %s", header.IPv4Any, header.IPv4Broadcast, fakeNetNumber, err, &tcpip.ErrNetworkUnreachable{})
-		}
-	}
-
-	protoAddr := tcpip.ProtocolAddress{Protocol: fakeNetNumber, AddressWithPrefix: tcpip.AddressWithPrefix{header.IPv4Any, 0}}
-	if err := s.AddProtocolAddress(1, protoAddr); err != nil {
-		t.Fatalf("AddProtocolAddress(1, %v) failed: %v", protoAddr, err)
-	}
-	r, err := s.FindRoute(1, header.IPv4Any, header.IPv4Broadcast, fakeNetNumber, false /* multicastLoop */)
-	if err != nil {
-		t.Fatalf("FindRoute(1, %v, %v, %d) failed: %v", header.IPv4Any, header.IPv4Broadcast, fakeNetNumber, err)
-	}
-	var wantRoute stack.Route
-	wantRoute.LocalAddress = header.IPv4Any
-	wantRoute.RemoteAddress = header.IPv4Broadcast
-	if err := verifyRoute(r, &wantRoute); err != nil {
-		t.Errorf("FindRoute(1, %v, %v, %d) returned unexpected Route: %v", header.IPv4Any, header.IPv4Broadcast, fakeNetNumber, err)
-	}
-
-	// If the NIC doesn't exist, it won't work.
-	{
-		_, err := s.FindRoute(2, header.IPv4Any, header.IPv4Broadcast, fakeNetNumber, false /* multicastLoop */)
-		if _, ok := err.(*tcpip.ErrNetworkUnreachable); !ok {
-			t.Fatalf("got FindRoute(2, %v, %v, %d) = %v want = %v", header.IPv4Any, header.IPv4Broadcast, fakeNetNumber, err, &tcpip.ErrNetworkUnreachable{})
-		}
-	}
-}
-
-func TestOutgoingBroadcastWithRouteTable(t *testing.T) {
-	defaultAddr := tcpip.AddressWithPrefix{header.IPv4Any, 0}
-	// Local subnet on NIC1: 192.168.1.58/24, gateway 192.168.1.1.
-	nic1Addr := tcpip.AddressWithPrefix{"\xc0\xa8\x01\x3a", 24}
-	nic1Gateway := tcpip.Address("\xc0\xa8\x01\x01")
-	// Local subnet on NIC2: 10.10.10.5/24, gateway 10.10.10.1.
-	nic2Addr := tcpip.AddressWithPrefix{"\x0a\x0a\x0a\x05", 24}
-	nic2Gateway := tcpip.Address("\x0a\x0a\x0a\x01")
-
-	// Create a new stack with two NICs.
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
-	})
-	ep := channel.New(10, defaultMTU, "")
-	if err := s.CreateNIC(1, ep); err != nil {
-		t.Fatalf("CreateNIC failed: %s", err)
-	}
-	if err := s.CreateNIC(2, ep); err != nil {
-		t.Fatalf("CreateNIC failed: %s", err)
-	}
-	nic1ProtoAddr := tcpip.ProtocolAddress{fakeNetNumber, nic1Addr}
-	if err := s.AddProtocolAddress(1, nic1ProtoAddr); err != nil {
-		t.Fatalf("AddProtocolAddress(1, %v) failed: %v", nic1ProtoAddr, err)
-	}
-
-	nic2ProtoAddr := tcpip.ProtocolAddress{fakeNetNumber, nic2Addr}
-	if err := s.AddProtocolAddress(2, nic2ProtoAddr); err != nil {
-		t.Fatalf("AddAddress(2, %v) failed: %v", nic2ProtoAddr, err)
-	}
-
-	// Set the initial route table.
-	rt := []tcpip.Route{
-		{Destination: nic1Addr.Subnet(), NIC: 1},
-		{Destination: nic2Addr.Subnet(), NIC: 2},
-		{Destination: defaultAddr.Subnet(), Gateway: nic2Gateway, NIC: 2},
-		{Destination: defaultAddr.Subnet(), Gateway: nic1Gateway, NIC: 1},
-	}
-	s.SetRouteTable(rt)
-
-	// When an interface is given, the route for a broadcast goes through it.
-	r, err := s.FindRoute(1, nic1Addr.Address, header.IPv4Broadcast, fakeNetNumber, false /* multicastLoop */)
-	if err != nil {
-		t.Fatalf("FindRoute(1, %v, %v, %d) failed: %v", nic1Addr.Address, header.IPv4Broadcast, fakeNetNumber, err)
-	}
-	var wantRoute stack.Route
-	wantRoute.LocalAddress = nic1Addr.Address
-	wantRoute.RemoteAddress = header.IPv4Broadcast
-	if err := verifyRoute(r, &wantRoute); err != nil {
-		t.Errorf("FindRoute(1, %v, %v, %d) returned unexpected Route: %v", nic1Addr.Address, header.IPv4Broadcast, fakeNetNumber, err)
-	}
-
-	// When an interface is not given, it consults the route table.
-	// 1. Case: Using the default route.
-	r, err = s.FindRoute(0, "", header.IPv4Broadcast, fakeNetNumber, false /* multicastLoop */)
-	if err != nil {
-		t.Fatalf("FindRoute(0, \"\", %s, %d) failed: %s", header.IPv4Broadcast, fakeNetNumber, err)
-	}
-	wantRoute = stack.Route{}
-	wantRoute.LocalAddress = nic2Addr.Address
-	wantRoute.RemoteAddress = header.IPv4Broadcast
-	if err := verifyRoute(r, &wantRoute); err != nil {
-		t.Errorf("FindRoute(0, \"\", %s, %d) returned unexpected Route: %s)", header.IPv4Broadcast, fakeNetNumber, err)
-	}
-
-	// 2. Case: Having an explicit route for broadcast will select that one.
-	rt = append(
-		[]tcpip.Route{
-			{Destination: tcpip.AddressWithPrefix{header.IPv4Broadcast, 8 * header.IPv4AddressSize}.Subnet(), NIC: 1},
-		},
-		rt...,
-	)
-	s.SetRouteTable(rt)
-	r, err = s.FindRoute(0, "", header.IPv4Broadcast, fakeNetNumber, false /* multicastLoop */)
-	if err != nil {
-		t.Fatalf("FindRoute(0, \"\", %s, %d) failed: %s", header.IPv4Broadcast, fakeNetNumber, err)
-	}
-	wantRoute = stack.Route{}
-	wantRoute.LocalAddress = nic1Addr.Address
-	wantRoute.RemoteAddress = header.IPv4Broadcast
-	if err := verifyRoute(r, &wantRoute); err != nil {
-		t.Errorf("FindRoute(0, \"\", %s, %d) returned unexpected Route: %s)", header.IPv4Broadcast, fakeNetNumber, err)
-	}
-}
-
-func TestMulticastOrIPv6LinkLocalNeedsNoRoute(t *testing.T) {
-	for _, tc := range []struct {
-		name        string
-		routeNeeded bool
-		address     tcpip.Address
-	}{
-		// IPv4 multicast address range: 224.0.0.0 - 239.255.255.255
-		//                <=>  0xe0.0x00.0x00.0x00 - 0xef.0xff.0xff.0xff
-		{"IPv4 Multicast 1", false, "\xe0\x00\x00\x00"},
-		{"IPv4 Multicast 2", false, "\xef\xff\xff\xff"},
-		{"IPv4 Unicast 1", true, "\xdf\xff\xff\xff"},
-		{"IPv4 Unicast 2", true, "\xf0\x00\x00\x00"},
-		{"IPv4 Unicast 3", true, "\x00\x00\x00\x00"},
-
-		// IPv6 multicast address is 0xff[8] + flags[4] + scope[4] + groupId[112]
-		{"IPv6 Multicast 1", false, "\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
-		{"IPv6 Multicast 2", false, "\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
-		{"IPv6 Multicast 3", false, "\xff\x0f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"},
-
-		// IPv6 link-local address starts with fe80::/10.
-		{"IPv6 Unicast Link-Local 1", false, "\xfe\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
-		{"IPv6 Unicast Link-Local 2", false, "\xfe\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"},
-		{"IPv6 Unicast Link-Local 3", false, "\xfe\x80\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff"},
-		{"IPv6 Unicast Link-Local 4", false, "\xfe\xbf\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
-		{"IPv6 Unicast Link-Local 5", false, "\xfe\xbf\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"},
-
-		// IPv6 addresses that are neither multicast nor link-local.
-		{"IPv6 Unicast Not Link-Local 1", true, "\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
-		{"IPv6 Unicast Not Link-Local 2", true, "\xf0\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"},
-		{"IPv6 Unicast Not Link-local 3", true, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
-		{"IPv6 Unicast Not Link-Local 4", true, "\xfe\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
-		{"IPv6 Unicast Not Link-Local 5", true, "\xfe\xdf\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
-		{"IPv6 Unicast Not Link-Local 6", true, "\xfd\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
-		{"IPv6 Unicast Not Link-Local 7", true, "\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
-	} {
-		t.Run(tc.name, func(t *testing.T) {
-			s := stack.New(stack.Options{
-				NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
-			})
-
-			ep := channel.New(10, defaultMTU, "")
-			if err := s.CreateNIC(1, ep); err != nil {
-				t.Fatal("CreateNIC failed:", err)
-			}
-
-			s.SetRouteTable([]tcpip.Route{})
-
-			var anyAddr tcpip.Address
-			if len(tc.address) == header.IPv4AddressSize {
-				anyAddr = header.IPv4Any
-			} else {
-				anyAddr = header.IPv6Any
-			}
-
-			var want tcpip.Error = &tcpip.ErrNetworkUnreachable{}
-			if tc.routeNeeded {
-				want = &tcpip.ErrNoRoute{}
-			}
-
-			// If there is no endpoint, it won't work.
-			if _, err := s.FindRoute(1, anyAddr, tc.address, fakeNetNumber, false /* multicastLoop */); err != want {
-				t.Fatalf("got FindRoute(1, %v, %v, %v) = %v, want = %v", anyAddr, tc.address, fakeNetNumber, err, want)
-			}
-
-			if err := s.AddAddress(1, fakeNetNumber, anyAddr); err != nil {
-				t.Fatalf("AddAddress(%v, %v) failed: %v", fakeNetNumber, anyAddr, err)
-			}
-
-			if r, err := s.FindRoute(1, anyAddr, tc.address, fakeNetNumber, false /* multicastLoop */); tc.routeNeeded {
-				// Route table is empty but we need a route, this should cause an error.
-				if _, ok := err.(*tcpip.ErrNoRoute); !ok {
-					t.Fatalf("got FindRoute(1, %v, %v, %v) = %v, want = %v", anyAddr, tc.address, fakeNetNumber, err, &tcpip.ErrNoRoute{})
-				}
-			} else {
-				if err != nil {
-					t.Fatalf("FindRoute(1, %v, %v, %v) failed: %v", anyAddr, tc.address, fakeNetNumber, err)
-				}
-				if r.LocalAddress != anyAddr {
-					t.Errorf("Bad local address: got %v, want = %v", r.LocalAddress, anyAddr)
-				}
-				if r.RemoteAddress != tc.address {
-					t.Errorf("Bad remote address: got %v, want = %v", r.RemoteAddress, tc.address)
-				}
-			}
-			// If the NIC doesn't exist, it won't work.
-			if _, err := s.FindRoute(2, anyAddr, tc.address, fakeNetNumber, false /* multicastLoop */); err != want {
-				t.Fatalf("got FindRoute(2, %v, %v, %v) = %v want = %v", anyAddr, tc.address, fakeNetNumber, err, want)
-			}
-		})
-	}
-}
-
-func TestNetworkOption(t *testing.T) {
-	s := stack.New(stack.Options{
-		NetworkProtocols:   []stack.NetworkProtocolFactory{fakeNetFactory},
-		TransportProtocols: []stack.TransportProtocolFactory{},
-	})
-
-	opt := tcpip.DefaultTTLOption(5)
-	if err := s.SetNetworkProtocolOption(fakeNetNumber, &opt); err != nil {
-		t.Fatalf("s.SetNetworkProtocolOption(%d, &%T(%d)): %s", fakeNetNumber, opt, opt, err)
-	}
-
-	var optGot tcpip.DefaultTTLOption
-	if err := s.NetworkProtocolOption(fakeNetNumber, &optGot); err != nil {
-		t.Fatalf("s.NetworkProtocolOption(%d, &%T): %s", fakeNetNumber, optGot, err)
-	}
-
-	if opt != optGot {
-		t.Errorf("got optGot = %d, want = %d", optGot, opt)
-	}
-}
-
-func TestGetMainNICAddressAddPrimaryNonPrimary(t *testing.T) {
-	const nicID = 1
-
-	for _, addrLen := range []int{4, 16} {
-		t.Run(fmt.Sprintf("addrLen=%d", addrLen), func(t *testing.T) {
-			for canBe := 0; canBe < 3; canBe++ {
-				t.Run(fmt.Sprintf("canBe=%d", canBe), func(t *testing.T) {
-					for never := 0; never < 3; never++ {
-						t.Run(fmt.Sprintf("never=%d", never), func(t *testing.T) {
-							s := stack.New(stack.Options{
-								NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
-							})
-							ep := channel.New(10, defaultMTU, "")
-							if err := s.CreateNIC(nicID, ep); err != nil {
-								t.Fatalf("CreateNIC(%d, _): %s", nicID, err)
-							}
-							// Insert <canBe> primary and <never> never-primary addresses.
-							// Each one will add a network endpoint to the NIC.
-							primaryAddrAdded := make(map[tcpip.AddressWithPrefix]struct{})
-							for i := 0; i < canBe+never; i++ {
-								var behavior stack.PrimaryEndpointBehavior
-								if i < canBe {
-									behavior = stack.CanBePrimaryEndpoint
-								} else {
-									behavior = stack.NeverPrimaryEndpoint
-								}
-								// Add an address and in case of a primary one include a
-								// prefixLen.
-								address := tcpip.Address(bytes.Repeat([]byte{byte(i)}, addrLen))
-								if behavior == stack.CanBePrimaryEndpoint {
-									protocolAddress := tcpip.ProtocolAddress{
-										Protocol: fakeNetNumber,
-										AddressWithPrefix: tcpip.AddressWithPrefix{
-											Address:   address,
-											PrefixLen: addrLen * 8,
-										},
-									}
-									if err := s.AddProtocolAddressWithOptions(nicID, protocolAddress, behavior); err != nil {
-										t.Fatalf("AddProtocolAddressWithOptions(%d, %#v, %d): %s", nicID, protocolAddress, behavior, err)
-									}
-									// Remember the address/prefix.
-									primaryAddrAdded[protocolAddress.AddressWithPrefix] = struct{}{}
-								} else {
-									if err := s.AddAddressWithOptions(nicID, fakeNetNumber, address, behavior); err != nil {
-										t.Fatalf("AddAddressWithOptions(%d, %d, %s, %d): %s:", nicID, fakeNetNumber, address, behavior, err)
-									}
-								}
-							}
-							// Check that GetMainNICAddress returns an address if at least
-							// one primary address was added. In that case make sure the
-							// address/prefixLen matches what we added.
-							gotAddr, err := s.GetMainNICAddress(nicID, fakeNetNumber)
-							if err != nil {
-								t.Fatalf("GetMainNICAddress(%d, %d): %s", nicID, fakeNetNumber, err)
-							}
-							if len(primaryAddrAdded) == 0 {
-								// No primary addresses present.
-								if wantAddr := (tcpip.AddressWithPrefix{}); gotAddr != wantAddr {
-									t.Fatalf("got GetMainNICAddress(%d, %d) = %s, want = %s", nicID, fakeNetNumber, gotAddr, wantAddr)
-								}
-							} else {
-								// At least one primary address was added, verify the returned
-								// address is in the list of primary addresses we added.
-								if _, ok := primaryAddrAdded[gotAddr]; !ok {
-									t.Fatalf("got GetMainNICAddress(%d, %d) = %s, want = %s", nicID, fakeNetNumber, gotAddr, primaryAddrAdded)
-								}
-							}
-						})
-					}
-				})
-			}
-		})
-	}
-}
-
-func TestGetMainNICAddressErrors(t *testing.T) {
-	const nicID = 1
-
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol, arp.NewProtocol},
-	})
-	if err := s.CreateNIC(nicID, loopback.New()); err != nil {
-		t.Fatalf("CreateNIC(%d, _): %s", nicID, err)
-	}
-
-	// Sanity check with a successful call.
-	if addr, err := s.GetMainNICAddress(nicID, ipv4.ProtocolNumber); err != nil {
-		t.Errorf("s.GetMainNICAddress(%d, %d): %s", nicID, ipv4.ProtocolNumber, err)
-	} else if want := (tcpip.AddressWithPrefix{}); addr != want {
-		t.Errorf("got s.GetMainNICAddress(%d, %d) = %s, want = %s", nicID, ipv4.ProtocolNumber, addr, want)
-	}
-
-	const unknownNICID = nicID + 1
-	switch addr, err := s.GetMainNICAddress(unknownNICID, ipv4.ProtocolNumber); err.(type) {
-	case *tcpip.ErrUnknownNICID:
-	default:
-		t.Errorf("got s.GetMainNICAddress(%d, %d) = (%s, %T), want = (_, tcpip.ErrUnknownNICID)", unknownNICID, ipv4.ProtocolNumber, addr, err)
-	}
-
-	// ARP is not an addressable network endpoint.
-	switch addr, err := s.GetMainNICAddress(nicID, arp.ProtocolNumber); err.(type) {
-	case *tcpip.ErrNotSupported:
-	default:
-		t.Errorf("got s.GetMainNICAddress(%d, %d) = (%s, %T), want = (_, tcpip.ErrNotSupported)", nicID, arp.ProtocolNumber, addr, err)
-	}
-
-	const unknownProtocolNumber = 1234
-	switch addr, err := s.GetMainNICAddress(nicID, unknownProtocolNumber); err.(type) {
-	case *tcpip.ErrUnknownProtocol:
-	default:
-		t.Errorf("got s.GetMainNICAddress(%d, %d) = (%s, %T), want = (_, tcpip.ErrUnknownProtocol)", nicID, unknownProtocolNumber, addr, err)
-	}
-}
-
-func TestGetMainNICAddressAddRemove(t *testing.T) {
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
-	})
-	ep := channel.New(10, defaultMTU, "")
-	if err := s.CreateNIC(1, ep); err != nil {
-		t.Fatal("CreateNIC failed:", err)
-	}
-
-	for _, tc := range []struct {
-		name      string
-		address   tcpip.Address
-		prefixLen int
-	}{
-		{"IPv4", "\x01\x01\x01\x01", 24},
-		{"IPv6", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", 116},
-	} {
-		t.Run(tc.name, func(t *testing.T) {
-			protocolAddress := tcpip.ProtocolAddress{
-				Protocol: fakeNetNumber,
-				AddressWithPrefix: tcpip.AddressWithPrefix{
-					Address:   tc.address,
-					PrefixLen: tc.prefixLen,
-				},
-			}
-			if err := s.AddProtocolAddress(1, protocolAddress); err != nil {
-				t.Fatal("AddProtocolAddress failed:", err)
-			}
-
-			// Check that we get the right initial address and prefix length.
-			if err := checkGetMainNICAddress(s, 1, fakeNetNumber, protocolAddress.AddressWithPrefix); err != nil {
-				t.Fatal(err)
-			}
-
-			if err := s.RemoveAddress(1, protocolAddress.AddressWithPrefix.Address); err != nil {
-				t.Fatal("RemoveAddress failed:", err)
-			}
-
-			// Check that we get no address after removal.
-			if err := checkGetMainNICAddress(s, 1, fakeNetNumber, tcpip.AddressWithPrefix{}); err != nil {
-				t.Fatal(err)
-			}
-		})
-	}
-}
-
-// Simple network address generator. Good for 255 addresses.
-type addressGenerator struct{ cnt byte }
-
-func (g *addressGenerator) next(addrLen int) tcpip.Address {
-	g.cnt++
-	return tcpip.Address(bytes.Repeat([]byte{g.cnt}, addrLen))
-}
-
-func verifyAddresses(t *testing.T, expectedAddresses, gotAddresses []tcpip.ProtocolAddress) {
-	t.Helper()
-
-	if len(gotAddresses) != len(expectedAddresses) {
-		t.Fatalf("got len(addresses) = %d, want = %d", len(gotAddresses), len(expectedAddresses))
-	}
-
-	sort.Slice(gotAddresses, func(i, j int) bool {
-		return gotAddresses[i].AddressWithPrefix.Address < gotAddresses[j].AddressWithPrefix.Address
-	})
-	sort.Slice(expectedAddresses, func(i, j int) bool {
-		return expectedAddresses[i].AddressWithPrefix.Address < expectedAddresses[j].AddressWithPrefix.Address
-	})
-
-	for i, gotAddr := range gotAddresses {
-		expectedAddr := expectedAddresses[i]
-		if gotAddr != expectedAddr {
-			t.Errorf("got address = %+v, wanted = %+v", gotAddr, expectedAddr)
-		}
-	}
-}
-
-func TestAddAddress(t *testing.T) {
-	const nicID = 1
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
-	})
-	ep := channel.New(10, defaultMTU, "")
-	if err := s.CreateNIC(nicID, ep); err != nil {
-		t.Fatal("CreateNIC failed:", err)
-	}
-
-	var addrGen addressGenerator
-	expectedAddresses := make([]tcpip.ProtocolAddress, 0, 2)
-	for _, addrLen := range []int{4, 16} {
-		address := addrGen.next(addrLen)
-		if err := s.AddAddress(nicID, fakeNetNumber, address); err != nil {
-			t.Fatalf("AddAddress(address=%s) failed: %s", address, err)
-		}
-		expectedAddresses = append(expectedAddresses, tcpip.ProtocolAddress{
-			Protocol:          fakeNetNumber,
-			AddressWithPrefix: tcpip.AddressWithPrefix{address, fakeDefaultPrefixLen},
-		})
-	}
-
-	gotAddresses := s.AllAddresses()[nicID]
-	verifyAddresses(t, expectedAddresses, gotAddresses)
-}
-
-func TestAddProtocolAddress(t *testing.T) {
-	const nicID = 1
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
-	})
-	ep := channel.New(10, defaultMTU, "")
-	if err := s.CreateNIC(nicID, ep); err != nil {
-		t.Fatal("CreateNIC failed:", err)
-	}
-
-	var addrGen addressGenerator
-	addrLenRange := []int{4, 16}
-	prefixLenRange := []int{8, 13, 20, 32}
-	expectedAddresses := make([]tcpip.ProtocolAddress, 0, len(addrLenRange)*len(prefixLenRange))
-	for _, addrLen := range addrLenRange {
-		for _, prefixLen := range prefixLenRange {
-			protocolAddress := tcpip.ProtocolAddress{
-				Protocol: fakeNetNumber,
-				AddressWithPrefix: tcpip.AddressWithPrefix{
-					Address:   addrGen.next(addrLen),
-					PrefixLen: prefixLen,
-				},
-			}
-			if err := s.AddProtocolAddress(nicID, protocolAddress); err != nil {
-				t.Errorf("AddProtocolAddress(%+v) failed: %s", protocolAddress, err)
-			}
-			expectedAddresses = append(expectedAddresses, protocolAddress)
-		}
-	}
-
-	gotAddresses := s.AllAddresses()[nicID]
-	verifyAddresses(t, expectedAddresses, gotAddresses)
-}
-
-func TestAddAddressWithOptions(t *testing.T) {
-	const nicID = 1
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
-	})
-	ep := channel.New(10, defaultMTU, "")
-	if err := s.CreateNIC(nicID, ep); err != nil {
-		t.Fatal("CreateNIC failed:", err)
-	}
-
-	addrLenRange := []int{4, 16}
-	behaviorRange := []stack.PrimaryEndpointBehavior{stack.CanBePrimaryEndpoint, stack.FirstPrimaryEndpoint, stack.NeverPrimaryEndpoint}
-	expectedAddresses := make([]tcpip.ProtocolAddress, 0, len(addrLenRange)*len(behaviorRange))
-	var addrGen addressGenerator
-	for _, addrLen := range addrLenRange {
-		for _, behavior := range behaviorRange {
-			address := addrGen.next(addrLen)
-			if err := s.AddAddressWithOptions(nicID, fakeNetNumber, address, behavior); err != nil {
-				t.Fatalf("AddAddressWithOptions(address=%s, behavior=%d) failed: %s", address, behavior, err)
-			}
-			expectedAddresses = append(expectedAddresses, tcpip.ProtocolAddress{
-				Protocol:          fakeNetNumber,
-				AddressWithPrefix: tcpip.AddressWithPrefix{address, fakeDefaultPrefixLen},
-			})
-		}
-	}
-
-	gotAddresses := s.AllAddresses()[nicID]
-	verifyAddresses(t, expectedAddresses, gotAddresses)
-}
-
-func TestAddProtocolAddressWithOptions(t *testing.T) {
-	const nicID = 1
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
-	})
-	ep := channel.New(10, defaultMTU, "")
-	if err := s.CreateNIC(nicID, ep); err != nil {
-		t.Fatal("CreateNIC failed:", err)
-	}
-
-	addrLenRange := []int{4, 16}
-	prefixLenRange := []int{8, 13, 20, 32}
-	behaviorRange := []stack.PrimaryEndpointBehavior{stack.CanBePrimaryEndpoint, stack.FirstPrimaryEndpoint, stack.NeverPrimaryEndpoint}
-	expectedAddresses := make([]tcpip.ProtocolAddress, 0, len(addrLenRange)*len(prefixLenRange)*len(behaviorRange))
-	var addrGen addressGenerator
-	for _, addrLen := range addrLenRange {
-		for _, prefixLen := range prefixLenRange {
-			for _, behavior := range behaviorRange {
-				protocolAddress := tcpip.ProtocolAddress{
-					Protocol: fakeNetNumber,
-					AddressWithPrefix: tcpip.AddressWithPrefix{
-						Address:   addrGen.next(addrLen),
-						PrefixLen: prefixLen,
-					},
-				}
-				if err := s.AddProtocolAddressWithOptions(nicID, protocolAddress, behavior); err != nil {
-					t.Fatalf("AddProtocolAddressWithOptions(%+v, %d) failed: %s", protocolAddress, behavior, err)
-				}
-				expectedAddresses = append(expectedAddresses, protocolAddress)
-			}
-		}
-	}
-
-	gotAddresses := s.AllAddresses()[nicID]
-	verifyAddresses(t, expectedAddresses, gotAddresses)
-}
-
-func TestCreateNICWithOptions(t *testing.T) {
-	type callArgsAndExpect struct {
-		nicID tcpip.NICID
-		opts  stack.NICOptions
-		err   tcpip.Error
-	}
-
-	tests := []struct {
-		desc  string
-		calls []callArgsAndExpect
-	}{
-		{
-			desc: "DuplicateNICID",
-			calls: []callArgsAndExpect{
-				{
-					nicID: tcpip.NICID(1),
-					opts:  stack.NICOptions{Name: "eth1"},
-					err:   nil,
-				},
-				{
-					nicID: tcpip.NICID(1),
-					opts:  stack.NICOptions{Name: "eth2"},
-					err:   &tcpip.ErrDuplicateNICID{},
-				},
-			},
-		},
-		{
-			desc: "DuplicateName",
-			calls: []callArgsAndExpect{
-				{
-					nicID: tcpip.NICID(1),
-					opts:  stack.NICOptions{Name: "lo"},
-					err:   nil,
-				},
-				{
-					nicID: tcpip.NICID(2),
-					opts:  stack.NICOptions{Name: "lo"},
-					err:   &tcpip.ErrDuplicateNICID{},
-				},
-			},
-		},
-		{
-			desc: "Unnamed",
-			calls: []callArgsAndExpect{
-				{
-					nicID: tcpip.NICID(1),
-					opts:  stack.NICOptions{},
-					err:   nil,
-				},
-				{
-					nicID: tcpip.NICID(2),
-					opts:  stack.NICOptions{},
-					err:   nil,
-				},
-			},
-		},
-		{
-			desc: "UnnamedDuplicateNICID",
-			calls: []callArgsAndExpect{
-				{
-					nicID: tcpip.NICID(1),
-					opts:  stack.NICOptions{},
-					err:   nil,
-				},
-				{
-					nicID: tcpip.NICID(1),
-					opts:  stack.NICOptions{},
-					err:   &tcpip.ErrDuplicateNICID{},
-				},
-			},
-		},
-	}
-	for _, test := range tests {
-		t.Run(test.desc, func(t *testing.T) {
-			s := stack.New(stack.Options{})
-			ep := channel.New(0, 0, tcpip.LinkAddress("\x00\x00\x00\x00\x00\x00"))
-			for _, call := range test.calls {
-				if got, want := s.CreateNICWithOptions(call.nicID, ep, call.opts), call.err; got != want {
-					t.Fatalf("CreateNICWithOptions(%v, _, %+v) = %v, want %v", call.nicID, call.opts, got, want)
-				}
-			}
-		})
-	}
-}
-
-func TestNICStats(t *testing.T) {
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
-	})
-	ep1 := channel.New(10, defaultMTU, "")
-	if err := s.CreateNIC(1, ep1); err != nil {
-		t.Fatal("CreateNIC failed: ", err)
-	}
-	if err := s.AddAddress(1, fakeNetNumber, "\x01"); err != nil {
-		t.Fatal("AddAddress failed:", err)
-	}
-	// Route all packets for address \x01 to NIC 1.
-	{
-		subnet, err := tcpip.NewSubnet("\x01", "\xff")
-		if err != nil {
-			t.Fatal(err)
-		}
-		s.SetRouteTable([]tcpip.Route{{Destination: subnet, Gateway: "\x00", NIC: 1}})
-	}
-
-	// Send a packet to address 1.
-	buf := buffer.NewView(30)
-	ep1.InjectInbound(fakeNetNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
-		Data: buf.ToVectorisedView(),
-	}))
-	if got, want := s.NICInfo()[1].Stats.Rx.Packets.Value(), uint64(1); got != want {
-		t.Errorf("got Rx.Packets.Value() = %d, want = %d", got, want)
-	}
-
-	if got, want := s.NICInfo()[1].Stats.Rx.Bytes.Value(), uint64(len(buf)); got != want {
-		t.Errorf("got Rx.Bytes.Value() = %d, want = %d", got, want)
-	}
-
-	payload := buffer.NewView(10)
-	// Write a packet out via the address for NIC 1
-	if err := sendTo(s, "\x01", payload); err != nil {
-		t.Fatal("sendTo failed: ", err)
-	}
-	want := uint64(ep1.Drain())
-	if got := s.NICInfo()[1].Stats.Tx.Packets.Value(); got != want {
-		t.Errorf("got Tx.Packets.Value() = %d, ep1.Drain() = %d", got, want)
-	}
-
-	if got, want := s.NICInfo()[1].Stats.Tx.Bytes.Value(), uint64(len(payload)+fakeNetHeaderLen); got != want {
-		t.Errorf("got Tx.Bytes.Value() = %d, want = %d", got, want)
-	}
-}
-
-// TestNICContextPreservation tests that you can read out via stack.NICInfo the
-// Context data you pass via NICContext.Context in stack.CreateNICWithOptions.
-func TestNICContextPreservation(t *testing.T) {
-	var ctx *int
-	tests := []struct {
-		name string
-		opts stack.NICOptions
-		want stack.NICContext
-	}{
-		{
-			"context_set",
-			stack.NICOptions{Context: ctx},
-			ctx,
-		},
-		{
-			"context_not_set",
-			stack.NICOptions{},
-			nil,
-		},
-	}
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			s := stack.New(stack.Options{})
-			id := tcpip.NICID(1)
-			ep := channel.New(0, 0, tcpip.LinkAddress("\x00\x00\x00\x00\x00\x00"))
-			if err := s.CreateNICWithOptions(id, ep, test.opts); err != nil {
-				t.Fatalf("got stack.CreateNICWithOptions(%d, %+v, %+v) = %s, want nil", id, ep, test.opts, err)
-			}
-			nicinfos := s.NICInfo()
-			nicinfo, ok := nicinfos[id]
-			if !ok {
-				t.Fatalf("got nicinfos[%d] = _, %t, want _, true; nicinfos = %+v", id, ok, nicinfos)
-			}
-			if got, want := nicinfo.Context == test.want, true; got != want {
-				t.Fatalf("got nicinfo.Context == ctx = %t, want %t; nicinfo.Context = %p, ctx = %p", got, want, nicinfo.Context, test.want)
-			}
-		})
-	}
-}
-
-// TestNICAutoGenLinkLocalAddr tests the auto-generation of IPv6 link-local
-// addresses.
-func TestNICAutoGenLinkLocalAddr(t *testing.T) {
-	const nicID = 1
-
-	var secretKey [header.OpaqueIIDSecretKeyMinBytes]byte
-	n, err := rand.Read(secretKey[:])
-	if err != nil {
-		t.Fatalf("rand.Read(_): %s", err)
-	}
-	if n != header.OpaqueIIDSecretKeyMinBytes {
-		t.Fatalf("expected rand.Read to read %d bytes, read %d bytes", header.OpaqueIIDSecretKeyMinBytes, n)
-	}
-
-	nicNameFunc := func(_ tcpip.NICID, name string) string {
-		return name
-	}
-
-	tests := []struct {
-		name         string
-		nicName      string
-		autoGen      bool
-		linkAddr     tcpip.LinkAddress
-		iidOpts      ipv6.OpaqueInterfaceIdentifierOptions
-		shouldGen    bool
-		expectedAddr tcpip.Address
-	}{
-		{
-			name:      "Disabled",
-			nicName:   "nic1",
-			autoGen:   false,
-			linkAddr:  linkAddr1,
-			shouldGen: false,
-		},
-		{
-			name:     "Disabled without OIID options",
-			nicName:  "nic1",
-			autoGen:  false,
-			linkAddr: linkAddr1,
-			iidOpts: ipv6.OpaqueInterfaceIdentifierOptions{
-				NICNameFromID: nicNameFunc,
-				SecretKey:     secretKey[:],
-			},
-			shouldGen: false,
-		},
-
-		// Tests for EUI64 based addresses.
-		{
-			name:         "EUI64 Enabled",
-			autoGen:      true,
-			linkAddr:     linkAddr1,
-			shouldGen:    true,
-			expectedAddr: header.LinkLocalAddr(linkAddr1),
-		},
-		{
-			name:      "EUI64 Empty MAC",
-			autoGen:   true,
-			shouldGen: false,
-		},
-		{
-			name:      "EUI64 Invalid MAC",
-			autoGen:   true,
-			linkAddr:  "\x01\x02\x03",
-			shouldGen: false,
-		},
-		{
-			name:      "EUI64 Multicast MAC",
-			autoGen:   true,
-			linkAddr:  "\x01\x02\x03\x04\x05\x06",
-			shouldGen: false,
-		},
-		{
-			name:      "EUI64 Unspecified MAC",
-			autoGen:   true,
-			linkAddr:  "\x00\x00\x00\x00\x00\x00",
-			shouldGen: false,
-		},
-
-		// Tests for Opaque IID based addresses.
-		{
-			name:     "OIID Enabled",
-			nicName:  "nic1",
-			autoGen:  true,
-			linkAddr: linkAddr1,
-			iidOpts: ipv6.OpaqueInterfaceIdentifierOptions{
-				NICNameFromID: nicNameFunc,
-				SecretKey:     secretKey[:],
-			},
-			shouldGen:    true,
-			expectedAddr: header.LinkLocalAddrWithOpaqueIID("nic1", 0, secretKey[:]),
-		},
-		// These are all cases where we would not have generated a
-		// link-local address if opaque IIDs were disabled.
-		{
-			name:    "OIID Empty MAC and empty nicName",
-			autoGen: true,
-			iidOpts: ipv6.OpaqueInterfaceIdentifierOptions{
-				NICNameFromID: nicNameFunc,
-				SecretKey:     secretKey[:1],
-			},
-			shouldGen:    true,
-			expectedAddr: header.LinkLocalAddrWithOpaqueIID("", 0, secretKey[:1]),
-		},
-		{
-			name:     "OIID Invalid MAC",
-			nicName:  "test",
-			autoGen:  true,
-			linkAddr: "\x01\x02\x03",
-			iidOpts: ipv6.OpaqueInterfaceIdentifierOptions{
-				NICNameFromID: nicNameFunc,
-				SecretKey:     secretKey[:2],
-			},
-			shouldGen:    true,
-			expectedAddr: header.LinkLocalAddrWithOpaqueIID("test", 0, secretKey[:2]),
-		},
-		{
-			name:     "OIID Multicast MAC",
-			nicName:  "test2",
-			autoGen:  true,
-			linkAddr: "\x01\x02\x03\x04\x05\x06",
-			iidOpts: ipv6.OpaqueInterfaceIdentifierOptions{
-				NICNameFromID: nicNameFunc,
-				SecretKey:     secretKey[:3],
-			},
-			shouldGen:    true,
-			expectedAddr: header.LinkLocalAddrWithOpaqueIID("test2", 0, secretKey[:3]),
-		},
-		{
-			name:     "OIID Unspecified MAC and nil SecretKey",
-			nicName:  "test3",
-			autoGen:  true,
-			linkAddr: "\x00\x00\x00\x00\x00\x00",
-			iidOpts: ipv6.OpaqueInterfaceIdentifierOptions{
-				NICNameFromID: nicNameFunc,
-			},
-			shouldGen:    true,
-			expectedAddr: header.LinkLocalAddrWithOpaqueIID("test3", 0, nil),
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			ndpDisp := ndpDispatcher{
-				autoGenAddrC: make(chan ndpAutoGenAddrEvent, 1),
-			}
-			opts := stack.Options{
-				NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
-					AutoGenLinkLocal: test.autoGen,
-					NDPDisp:          &ndpDisp,
-					OpaqueIIDOpts:    test.iidOpts,
-				})},
-			}
-
-			e := channel.New(0, 1280, test.linkAddr)
-			s := stack.New(opts)
-			nicOpts := stack.NICOptions{Name: test.nicName, Disabled: true}
-			if err := s.CreateNICWithOptions(nicID, e, nicOpts); err != nil {
-				t.Fatalf("CreateNICWithOptions(%d, _, %+v) = %s", nicID, opts, err)
-			}
-
-			// A new disabled NIC should not have any address, even if auto generation
-			// was enabled.
-			allStackAddrs := s.AllAddresses()
-			allNICAddrs, ok := allStackAddrs[nicID]
-			if !ok {
-				t.Fatalf("entry for %d missing from allStackAddrs = %+v", nicID, allStackAddrs)
-			}
-			if l := len(allNICAddrs); l != 0 {
-				t.Fatalf("got len(allNICAddrs) = %d, want = 0", l)
-			}
-
-			// Enabling the NIC should attempt auto-generation of a link-local
-			// address.
-			if err := s.EnableNIC(nicID); err != nil {
-				t.Fatalf("s.EnableNIC(%d): %s", nicID, err)
-			}
-
-			var expectedMainAddr tcpip.AddressWithPrefix
-			if test.shouldGen {
-				expectedMainAddr = tcpip.AddressWithPrefix{
-					Address:   test.expectedAddr,
-					PrefixLen: header.IPv6LinkLocalPrefix.PrefixLen,
-				}
-
-				// Should have auto-generated an address and resolved immediately (DAD
-				// is disabled).
-				select {
-				case e := <-ndpDisp.autoGenAddrC:
-					if diff := checkAutoGenAddrEvent(e, expectedMainAddr, newAddr); diff != "" {
-						t.Errorf("auto-gen addr event mismatch (-want +got):\n%s", diff)
-					}
-				default:
-					t.Fatal("expected addr auto gen event")
-				}
-			} else {
-				// Should not have auto-generated an address.
-				select {
-				case <-ndpDisp.autoGenAddrC:
-					t.Fatal("unexpectedly auto-generated an address")
-				default:
-				}
-			}
-
-			if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, expectedMainAddr); err != nil {
-				t.Fatal(err)
-			}
-
-			// Disabling the NIC should remove the auto-generated address.
-			if err := s.DisableNIC(nicID); err != nil {
-				t.Fatalf("s.DisableNIC(%d): %s", nicID, err)
-			}
-			if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil {
-				t.Fatal(err)
-			}
-		})
-	}
-}
-
-// TestNoLinkLocalAutoGenForLoopbackNIC tests that IPv6 link-local addresses are
-// not auto-generated for loopback NICs.
-func TestNoLinkLocalAutoGenForLoopbackNIC(t *testing.T) {
-	const nicID = 1
-	const nicName = "nicName"
-
-	tests := []struct {
-		name          string
-		opaqueIIDOpts ipv6.OpaqueInterfaceIdentifierOptions
-	}{
-		{
-			name:          "IID From MAC",
-			opaqueIIDOpts: ipv6.OpaqueInterfaceIdentifierOptions{},
-		},
-		{
-			name: "Opaque IID",
-			opaqueIIDOpts: ipv6.OpaqueInterfaceIdentifierOptions{
-				NICNameFromID: func(_ tcpip.NICID, nicName string) string {
-					return nicName
-				},
-			},
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			opts := stack.Options{
-				NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
-					AutoGenLinkLocal: true,
-					OpaqueIIDOpts:    test.opaqueIIDOpts,
-				})},
-			}
-
-			e := loopback.New()
-			s := stack.New(opts)
-			nicOpts := stack.NICOptions{Name: nicName}
-			if err := s.CreateNICWithOptions(nicID, e, nicOpts); err != nil {
-				t.Fatalf("CreateNICWithOptions(%d, _, %+v) = %s", nicID, nicOpts, err)
-			}
-
-			if err := checkGetMainNICAddress(s, 1, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil {
-				t.Fatal(err)
-			}
-		})
-	}
-}
-
-// TestNICAutoGenAddrDoesDAD tests that the successful auto-generation of IPv6
-// link-local addresses will only be assigned after the DAD process resolves.
-func TestNICAutoGenAddrDoesDAD(t *testing.T) {
-	const nicID = 1
-
-	ndpDisp := ndpDispatcher{
-		dadC: make(chan ndpDADEvent),
-	}
-	dadConfigs := stack.DefaultDADConfigurations()
-	opts := stack.Options{
-		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
-			AutoGenLinkLocal: true,
-			NDPDisp:          &ndpDisp,
-			DADConfigs:       dadConfigs,
-		})},
-	}
-
-	e := channel.New(int(dadConfigs.DupAddrDetectTransmits), 1280, linkAddr1)
-	s := stack.New(opts)
-	if err := s.CreateNIC(nicID, e); err != nil {
-		t.Fatalf("CreateNIC(%d, _) = %s", nicID, 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)
-	}
-
-	linkLocalAddr := header.LinkLocalAddr(linkAddr1)
-
-	// Wait for DAD to resolve.
-	select {
-	case <-time.After(time.Duration(dadConfigs.DupAddrDetectTransmits)*dadConfigs.RetransmitTimer + time.Second):
-		// We should get a resolution event after 1s (default time to
-		// resolve as per default NDP configurations). Waiting for that
-		// resolution time + an extra 1s without a resolution event
-		// means something is wrong.
-		t.Fatal("timed out waiting for DAD resolution")
-	case e := <-ndpDisp.dadC:
-		if diff := checkDADEvent(e, nicID, linkLocalAddr, &stack.DADSucceeded{}); diff != "" {
-			t.Errorf("dad event mismatch (-want +got):\n%s", diff)
-		}
-	}
-	if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{Address: linkLocalAddr, PrefixLen: header.IPv6LinkLocalPrefix.PrefixLen}); err != nil {
-		t.Fatal(err)
-	}
-}
-
-// TestNewPEB tests that a new PrimaryEndpointBehavior value (peb) is respected
-// when an address's kind gets "promoted" to permanent from permanentExpired.
-func TestNewPEBOnPromotionToPermanent(t *testing.T) {
-	const nicID = 1
-
-	pebs := []stack.PrimaryEndpointBehavior{
-		stack.NeverPrimaryEndpoint,
-		stack.CanBePrimaryEndpoint,
-		stack.FirstPrimaryEndpoint,
-	}
-
-	for _, pi := range pebs {
-		for _, ps := range pebs {
-			t.Run(fmt.Sprintf("%d-to-%d", pi, ps), func(t *testing.T) {
-				s := stack.New(stack.Options{
-					NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
-				})
-				ep1 := channel.New(10, defaultMTU, "")
-				if err := s.CreateNIC(nicID, ep1); err != nil {
-					t.Fatalf("CreateNIC(%d, _): %s", nicID, err)
-				}
-
-				// Add a permanent address with initial
-				// PrimaryEndpointBehavior (peb), pi. If pi is
-				// NeverPrimaryEndpoint, the address should not
-				// be returned by a call to GetMainNICAddress;
-				// else, it should.
-				const address1 = tcpip.Address("\x01")
-				if err := s.AddAddressWithOptions(nicID, fakeNetNumber, address1, pi); err != nil {
-					t.Fatalf("AddAddressWithOptions(%d, %d, %s, %d): %s", nicID, fakeNetNumber, address1, pi, err)
-				}
-				addr, err := s.GetMainNICAddress(nicID, fakeNetNumber)
-				if err != nil {
-					t.Fatalf("GetMainNICAddress(%d, %d): %s", nicID, fakeNetNumber, err)
-				}
-				if pi == stack.NeverPrimaryEndpoint {
-					if want := (tcpip.AddressWithPrefix{}); addr != want {
-						t.Fatalf("got GetMainNICAddress(%d, %d) = %s, want = %s", nicID, fakeNetNumber, addr, want)
-
-					}
-				} else if addr.Address != address1 {
-					t.Fatalf("got GetMainNICAddress(%d, %d) = %s, want = %s", nicID, fakeNetNumber, addr.Address, address1)
-				}
-
-				{
-					subnet, err := tcpip.NewSubnet("\x00", "\x00")
-					if err != nil {
-						t.Fatalf("NewSubnet failed: %v", err)
-					}
-					s.SetRouteTable([]tcpip.Route{{Destination: subnet, Gateway: "\x00", NIC: 1}})
-				}
-
-				// Take a route through the address so its ref
-				// count gets incremented and does not actually
-				// get deleted when RemoveAddress is called
-				// below. This is because we want to test that a
-				// new peb is respected when an address gets
-				// "promoted" to permanent from a
-				// permanentExpired kind.
-				const address2 = tcpip.Address("\x02")
-				r, err := s.FindRoute(nicID, address1, address2, fakeNetNumber, false)
-				if err != nil {
-					t.Fatalf("FindRoute(%d, %s, %s, %d, false): %s", nicID, address1, address2, fakeNetNumber, err)
-				}
-				defer r.Release()
-				if err := s.RemoveAddress(nicID, address1); err != nil {
-					t.Fatalf("RemoveAddress(%d, %s): %s", nicID, address1, err)
-				}
-
-				//
-				// At this point, the address should still be
-				// known by the NIC, but have its
-				// kind = permanentExpired.
-				//
-
-				// Add some other address with peb set to
-				// FirstPrimaryEndpoint.
-				const address3 = tcpip.Address("\x03")
-				if err := s.AddAddressWithOptions(nicID, fakeNetNumber, address3, stack.FirstPrimaryEndpoint); err != nil {
-					t.Fatalf("AddAddressWithOptions(%d, %d, %s, %d): %s", nicID, fakeNetNumber, address3, stack.FirstPrimaryEndpoint, err)
-
-				}
-
-				// Add back the address we removed earlier and
-				// make sure the new peb was respected.
-				// (The address should just be promoted now).
-				if err := s.AddAddressWithOptions(nicID, fakeNetNumber, address1, ps); err != nil {
-					t.Fatalf("AddAddressWithOptions(%d, %d, %s, %d): %s", nicID, fakeNetNumber, address1, pi, err)
-				}
-				var primaryAddrs []tcpip.Address
-				for _, pa := range s.NICInfo()[nicID].ProtocolAddresses {
-					primaryAddrs = append(primaryAddrs, pa.AddressWithPrefix.Address)
-				}
-				var expectedList []tcpip.Address
-				switch ps {
-				case stack.FirstPrimaryEndpoint:
-					expectedList = []tcpip.Address{
-						"\x01",
-						"\x03",
-					}
-				case stack.CanBePrimaryEndpoint:
-					expectedList = []tcpip.Address{
-						"\x03",
-						"\x01",
-					}
-				case stack.NeverPrimaryEndpoint:
-					expectedList = []tcpip.Address{
-						"\x03",
-					}
-				}
-				if !cmp.Equal(primaryAddrs, expectedList) {
-					t.Fatalf("got NIC's primary addresses = %v, want = %v", primaryAddrs, expectedList)
-				}
-
-				// Once we remove the other address, if the new
-				// peb, ps, was NeverPrimaryEndpoint, no address
-				// should be returned by a call to
-				// GetMainNICAddress; else, our original address
-				// should be returned.
-				if err := s.RemoveAddress(nicID, address3); err != nil {
-					t.Fatalf("RemoveAddress(%d, %s): %s", nicID, address3, err)
-				}
-				addr, err = s.GetMainNICAddress(nicID, fakeNetNumber)
-				if err != nil {
-					t.Fatalf("GetMainNICAddress(%d, %d): %s", nicID, fakeNetNumber, err)
-				}
-				if ps == stack.NeverPrimaryEndpoint {
-					if want := (tcpip.AddressWithPrefix{}); addr != want {
-						t.Fatalf("got GetMainNICAddress(%d, %d) = %s, want = %s", nicID, fakeNetNumber, addr, want)
-					}
-				} else {
-					if addr.Address != address1 {
-						t.Fatalf("got GetMainNICAddress(%d, %d) = %s, want = %s", nicID, fakeNetNumber, addr.Address, address1)
-					}
-				}
-			})
-		}
-	}
-}
-
-func TestIPv6SourceAddressSelectionScopeAndSameAddress(t *testing.T) {
-	const (
-		linkLocalAddr1         = tcpip.Address("\xfe\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01")
-		linkLocalAddr2         = tcpip.Address("\xfe\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02")
-		linkLocalMulticastAddr = tcpip.Address("\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01")
-		uniqueLocalAddr1       = tcpip.Address("\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01")
-		uniqueLocalAddr2       = tcpip.Address("\xfd\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02")
-		globalAddr1            = tcpip.Address("\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01")
-		globalAddr2            = tcpip.Address("\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02")
-		globalAddr3            = tcpip.Address("\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03")
-		ipv4MappedIPv6Addr1    = tcpip.Address("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00\x00\x01")
-		ipv4MappedIPv6Addr2    = tcpip.Address("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00\x00\x02")
-		toredoAddr1            = tcpip.Address("\x20\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01")
-		toredoAddr2            = tcpip.Address("\x20\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02")
-		ipv6ToIPv4Addr1        = tcpip.Address("\x20\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01")
-		ipv6ToIPv4Addr2        = tcpip.Address("\x20\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02")
-
-		nicID           = 1
-		lifetimeSeconds = 9999
-	)
-
-	prefix1, _, stableGlobalAddr1 := prefixSubnetAddr(0, linkAddr1)
-	prefix2, _, stableGlobalAddr2 := prefixSubnetAddr(1, linkAddr1)
-
-	var tempIIDHistory [header.IIDSize]byte
-	header.InitialTempIID(tempIIDHistory[:], nil, nicID)
-	tempGlobalAddr1 := header.GenerateTempIPv6SLAACAddr(tempIIDHistory[:], stableGlobalAddr1.Address).Address
-	tempGlobalAddr2 := header.GenerateTempIPv6SLAACAddr(tempIIDHistory[:], stableGlobalAddr2.Address).Address
-
-	// Rule 3 is not tested here, and is instead tested by NDP's AutoGenAddr test.
-	tests := []struct {
-		name                                   string
-		slaacPrefixForTempAddrBeforeNICAddrAdd tcpip.AddressWithPrefix
-		nicAddrs                               []tcpip.Address
-		slaacPrefixForTempAddrAfterNICAddrAdd  tcpip.AddressWithPrefix
-		remoteAddr                             tcpip.Address
-		expectedLocalAddr                      tcpip.Address
-	}{
-		// Test Rule 1 of RFC 6724 section 5 (prefer same address).
-		{
-			name:              "Same Global most preferred (last address)",
-			nicAddrs:          []tcpip.Address{linkLocalAddr1, globalAddr1},
-			remoteAddr:        globalAddr1,
-			expectedLocalAddr: globalAddr1,
-		},
-		{
-			name:              "Same Global most preferred (first address)",
-			nicAddrs:          []tcpip.Address{globalAddr1, uniqueLocalAddr1},
-			remoteAddr:        globalAddr1,
-			expectedLocalAddr: globalAddr1,
-		},
-		{
-			name:              "Same Link Local most preferred (last address)",
-			nicAddrs:          []tcpip.Address{globalAddr1, linkLocalAddr1},
-			remoteAddr:        linkLocalAddr1,
-			expectedLocalAddr: linkLocalAddr1,
-		},
-		{
-			name:              "Same Link Local most preferred (first address)",
-			nicAddrs:          []tcpip.Address{linkLocalAddr1, globalAddr1},
-			remoteAddr:        linkLocalAddr1,
-			expectedLocalAddr: linkLocalAddr1,
-		},
-		{
-			name:              "Same Unique Local most preferred (last address)",
-			nicAddrs:          []tcpip.Address{uniqueLocalAddr1, globalAddr1},
-			remoteAddr:        uniqueLocalAddr1,
-			expectedLocalAddr: uniqueLocalAddr1,
-		},
-		{
-			name:              "Same Unique Local most preferred (first address)",
-			nicAddrs:          []tcpip.Address{globalAddr1, uniqueLocalAddr1},
-			remoteAddr:        uniqueLocalAddr1,
-			expectedLocalAddr: uniqueLocalAddr1,
-		},
-
-		// Test Rule 2 of RFC 6724 section 5 (prefer appropriate scope).
-		{
-			name:              "Global most preferred (last address)",
-			nicAddrs:          []tcpip.Address{linkLocalAddr1, globalAddr1},
-			remoteAddr:        globalAddr2,
-			expectedLocalAddr: globalAddr1,
-		},
-		{
-			name:              "Global most preferred (first address)",
-			nicAddrs:          []tcpip.Address{globalAddr1, linkLocalAddr1},
-			remoteAddr:        globalAddr2,
-			expectedLocalAddr: globalAddr1,
-		},
-		{
-			name:              "Link Local most preferred (last address)",
-			nicAddrs:          []tcpip.Address{globalAddr1, linkLocalAddr1},
-			remoteAddr:        linkLocalAddr2,
-			expectedLocalAddr: linkLocalAddr1,
-		},
-		{
-			name:              "Link Local most preferred (first address)",
-			nicAddrs:          []tcpip.Address{linkLocalAddr1, globalAddr1},
-			remoteAddr:        linkLocalAddr2,
-			expectedLocalAddr: linkLocalAddr1,
-		},
-		{
-			name:              "Link Local most preferred for link local multicast (last address)",
-			nicAddrs:          []tcpip.Address{globalAddr1, linkLocalAddr1},
-			remoteAddr:        linkLocalMulticastAddr,
-			expectedLocalAddr: linkLocalAddr1,
-		},
-		{
-			name:              "Link Local most preferred for link local multicast (first address)",
-			nicAddrs:          []tcpip.Address{linkLocalAddr1, globalAddr1},
-			remoteAddr:        linkLocalMulticastAddr,
-			expectedLocalAddr: linkLocalAddr1,
-		},
-
-		// Test Rule 6 of 6724 section 5 (prefer matching label).
-		{
-			name:              "Unique Local most preferred (last address)",
-			nicAddrs:          []tcpip.Address{uniqueLocalAddr1, globalAddr1, ipv4MappedIPv6Addr1, toredoAddr1, ipv6ToIPv4Addr1},
-			remoteAddr:        uniqueLocalAddr2,
-			expectedLocalAddr: uniqueLocalAddr1,
-		},
-		{
-			name:              "Unique Local most preferred (first address)",
-			nicAddrs:          []tcpip.Address{globalAddr1, ipv4MappedIPv6Addr1, toredoAddr1, ipv6ToIPv4Addr1, uniqueLocalAddr1},
-			remoteAddr:        uniqueLocalAddr2,
-			expectedLocalAddr: uniqueLocalAddr1,
-		},
-		{
-			name:              "Toredo most preferred (first address)",
-			nicAddrs:          []tcpip.Address{toredoAddr1, uniqueLocalAddr1, globalAddr1, ipv4MappedIPv6Addr1, ipv6ToIPv4Addr1},
-			remoteAddr:        toredoAddr2,
-			expectedLocalAddr: toredoAddr1,
-		},
-		{
-			name:              "Toredo most preferred (last address)",
-			nicAddrs:          []tcpip.Address{globalAddr1, ipv4MappedIPv6Addr1, ipv6ToIPv4Addr1, uniqueLocalAddr1, toredoAddr1},
-			remoteAddr:        toredoAddr2,
-			expectedLocalAddr: toredoAddr1,
-		},
-		{
-			name:              "6To4 most preferred (first address)",
-			nicAddrs:          []tcpip.Address{ipv6ToIPv4Addr1, toredoAddr1, uniqueLocalAddr1, globalAddr1, ipv4MappedIPv6Addr1},
-			remoteAddr:        ipv6ToIPv4Addr2,
-			expectedLocalAddr: ipv6ToIPv4Addr1,
-		},
-		{
-			name:              "6To4 most preferred (last address)",
-			nicAddrs:          []tcpip.Address{globalAddr1, ipv4MappedIPv6Addr1, uniqueLocalAddr1, toredoAddr1, ipv6ToIPv4Addr1},
-			remoteAddr:        ipv6ToIPv4Addr2,
-			expectedLocalAddr: ipv6ToIPv4Addr1,
-		},
-		{
-			name:              "IPv4 mapped IPv6 most preferred (first address)",
-			nicAddrs:          []tcpip.Address{ipv4MappedIPv6Addr1, ipv6ToIPv4Addr1, toredoAddr1, uniqueLocalAddr1, globalAddr1},
-			remoteAddr:        ipv4MappedIPv6Addr2,
-			expectedLocalAddr: ipv4MappedIPv6Addr1,
-		},
-		{
-			name:              "IPv4 mapped IPv6 most preferred (last address)",
-			nicAddrs:          []tcpip.Address{globalAddr1, ipv6ToIPv4Addr1, uniqueLocalAddr1, toredoAddr1, ipv4MappedIPv6Addr1},
-			remoteAddr:        ipv4MappedIPv6Addr2,
-			expectedLocalAddr: ipv4MappedIPv6Addr1,
-		},
-
-		// Test Rule 7 of RFC 6724 section 5 (prefer temporary addresses).
-		{
-			name:                                   "Temp Global most preferred (last address)",
-			slaacPrefixForTempAddrBeforeNICAddrAdd: prefix1,
-			nicAddrs:                               []tcpip.Address{linkLocalAddr1, uniqueLocalAddr1, globalAddr1},
-			remoteAddr:                             globalAddr2,
-			expectedLocalAddr:                      tempGlobalAddr1,
-		},
-		{
-			name:                                  "Temp Global most preferred (first address)",
-			nicAddrs:                              []tcpip.Address{linkLocalAddr1, uniqueLocalAddr1, globalAddr1},
-			slaacPrefixForTempAddrAfterNICAddrAdd: prefix1,
-			remoteAddr:                            globalAddr2,
-			expectedLocalAddr:                     tempGlobalAddr1,
-		},
-
-		// Test Rule 8 of RFC 6724 section 5 (use longest matching prefix).
-		{
-			name:              "Longest prefix matched most preferred (first address)",
-			nicAddrs:          []tcpip.Address{globalAddr2, globalAddr1},
-			remoteAddr:        globalAddr3,
-			expectedLocalAddr: globalAddr2,
-		},
-		{
-			name:              "Longest prefix matched most preferred (last address)",
-			nicAddrs:          []tcpip.Address{globalAddr1, globalAddr2},
-			remoteAddr:        globalAddr3,
-			expectedLocalAddr: globalAddr2,
-		},
-
-		// Test returning the endpoint that is closest to the front when
-		// candidate addresses are "equal" from the perspective of RFC 6724
-		// section 5.
-		{
-			name:              "Unique Local for Global",
-			nicAddrs:          []tcpip.Address{linkLocalAddr1, uniqueLocalAddr1, uniqueLocalAddr2},
-			remoteAddr:        globalAddr2,
-			expectedLocalAddr: uniqueLocalAddr1,
-		},
-		{
-			name:              "Link Local for Global",
-			nicAddrs:          []tcpip.Address{linkLocalAddr1, linkLocalAddr2},
-			remoteAddr:        globalAddr2,
-			expectedLocalAddr: linkLocalAddr1,
-		},
-		{
-			name:              "Link Local for Unique Local",
-			nicAddrs:          []tcpip.Address{linkLocalAddr1, linkLocalAddr2},
-			remoteAddr:        uniqueLocalAddr2,
-			expectedLocalAddr: linkLocalAddr1,
-		},
-		{
-			name:                                   "Temp Global for Global",
-			slaacPrefixForTempAddrBeforeNICAddrAdd: prefix1,
-			slaacPrefixForTempAddrAfterNICAddrAdd:  prefix2,
-			remoteAddr:                             globalAddr1,
-			expectedLocalAddr:                      tempGlobalAddr2,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			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,
-						AutoGenTempGlobalAddresses: true,
-					},
-					NDPDisp: &ndpDispatcher{},
-				})},
-				TransportProtocols: []stack.TransportProtocolFactory{udp.NewProtocol},
-			})
-			if err := s.CreateNIC(nicID, e); err != nil {
-				t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
-			}
-
-			if test.slaacPrefixForTempAddrBeforeNICAddrAdd != (tcpip.AddressWithPrefix{}) {
-				e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr3, 0, test.slaacPrefixForTempAddrBeforeNICAddrAdd, true, true, lifetimeSeconds, lifetimeSeconds))
-			}
-
-			for _, a := range test.nicAddrs {
-				if err := s.AddAddress(nicID, ipv6.ProtocolNumber, a); err != nil {
-					t.Errorf("s.AddAddress(%d, %d, %s): %s", nicID, ipv6.ProtocolNumber, a, err)
-				}
-			}
-
-			if test.slaacPrefixForTempAddrAfterNICAddrAdd != (tcpip.AddressWithPrefix{}) {
-				e.InjectInbound(header.IPv6ProtocolNumber, raBufWithPI(llAddr3, 0, test.slaacPrefixForTempAddrAfterNICAddrAdd, true, true, lifetimeSeconds, lifetimeSeconds))
-			}
-
-			if t.Failed() {
-				t.FailNow()
-			}
-
-			netEP, err := s.GetNetworkEndpoint(nicID, header.IPv6ProtocolNumber)
-			if err != nil {
-				t.Fatalf("s.GetNetworkEndpoint(%d, %d): %s", nicID, header.IPv6ProtocolNumber, err)
-			}
-
-			addressableEndpoint, ok := netEP.(stack.AddressableEndpoint)
-			if !ok {
-				t.Fatal("network endpoint is not addressable")
-			}
-
-			addressEP := addressableEndpoint.AcquireOutgoingPrimaryAddress(test.remoteAddr, false /* allowExpired */)
-			if addressEP == nil {
-				t.Fatal("expected a non-nil address endpoint")
-			}
-			defer addressEP.DecRef()
-
-			if got := addressEP.AddressWithPrefix().Address; got != test.expectedLocalAddr {
-				t.Errorf("got local address = %s, want = %s", got, test.expectedLocalAddr)
-			}
-		})
-	}
-}
-
-func TestAddRemoveIPv4BroadcastAddressOnNICEnableDisable(t *testing.T) {
-	const nicID = 1
-	broadcastAddr := tcpip.ProtocolAddress{
-		Protocol: header.IPv4ProtocolNumber,
-		AddressWithPrefix: tcpip.AddressWithPrefix{
-			Address:   header.IPv4Broadcast,
-			PrefixLen: 32,
-		},
-	}
-
-	e := loopback.New()
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol},
-	})
-	nicOpts := stack.NICOptions{Disabled: true}
-	if err := s.CreateNICWithOptions(nicID, e, nicOpts); err != nil {
-		t.Fatalf("CreateNIC(%d, _, %+v) = %s", nicID, nicOpts, err)
-	}
-
-	{
-		allStackAddrs := s.AllAddresses()
-		if allNICAddrs, ok := allStackAddrs[nicID]; !ok {
-			t.Fatalf("entry for %d missing from allStackAddrs = %+v", nicID, allStackAddrs)
-		} else if containsAddr(allNICAddrs, broadcastAddr) {
-			t.Fatalf("got allNICAddrs = %+v, don't want = %+v", allNICAddrs, broadcastAddr)
-		}
-	}
-
-	// Enabling the NIC should add the IPv4 broadcast address.
-	if err := s.EnableNIC(nicID); err != nil {
-		t.Fatalf("s.EnableNIC(%d): %s", nicID, err)
-	}
-
-	{
-		allStackAddrs := s.AllAddresses()
-		if allNICAddrs, ok := allStackAddrs[nicID]; !ok {
-			t.Fatalf("entry for %d missing from allStackAddrs = %+v", nicID, allStackAddrs)
-		} else if !containsAddr(allNICAddrs, broadcastAddr) {
-			t.Fatalf("got allNICAddrs = %+v, want = %+v", allNICAddrs, broadcastAddr)
-		}
-	}
-
-	// Disabling the NIC should remove the IPv4 broadcast address.
-	if err := s.DisableNIC(nicID); err != nil {
-		t.Fatalf("s.DisableNIC(%d): %s", nicID, err)
-	}
-
-	{
-		allStackAddrs := s.AllAddresses()
-		if allNICAddrs, ok := allStackAddrs[nicID]; !ok {
-			t.Fatalf("entry for %d missing from allStackAddrs = %+v", nicID, allStackAddrs)
-		} else if containsAddr(allNICAddrs, broadcastAddr) {
-			t.Fatalf("got allNICAddrs = %+v, don't want = %+v", allNICAddrs, broadcastAddr)
-		}
-	}
-}
-
-// TestLeaveIPv6SolicitedNodeAddrBeforeAddrRemoval tests that removing an IPv6
-// address after leaving its solicited node multicast address does not result in
-// an error.
-func TestLeaveIPv6SolicitedNodeAddrBeforeAddrRemoval(t *testing.T) {
-	const nicID = 1
-
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocol},
-	})
-	e := channel.New(10, 1280, linkAddr1)
-	if err := s.CreateNIC(1, e); err != nil {
-		t.Fatalf("CreateNIC(%d, _): %s", nicID, err)
-	}
-
-	if err := s.AddAddress(nicID, ipv6.ProtocolNumber, addr1); err != nil {
-		t.Fatalf("AddAddress(%d, %d, %s): %s", nicID, ipv6.ProtocolNumber, addr1, err)
-	}
-
-	// The NIC should have joined addr1's solicited node multicast address.
-	snmc := header.SolicitedNodeAddr(addr1)
-	in, err := s.IsInGroup(nicID, snmc)
-	if err != nil {
-		t.Fatalf("IsInGroup(%d, %s): %s", nicID, snmc, err)
-	}
-	if !in {
-		t.Fatalf("got IsInGroup(%d, %s) = false, want = true", nicID, snmc)
-	}
-
-	if err := s.LeaveGroup(ipv6.ProtocolNumber, nicID, snmc); err != nil {
-		t.Fatalf("LeaveGroup(%d, %d, %s): %s", ipv6.ProtocolNumber, nicID, snmc, err)
-	}
-	in, err = s.IsInGroup(nicID, snmc)
-	if err != nil {
-		t.Fatalf("IsInGroup(%d, %s): %s", nicID, snmc, err)
-	}
-	if in {
-		t.Fatalf("got IsInGroup(%d, %s) = true, want = false", nicID, snmc)
-	}
-
-	if err := s.RemoveAddress(nicID, addr1); err != nil {
-		t.Fatalf("RemoveAddress(%d, %s) = %s", nicID, addr1, err)
-	}
-}
-
-func TestJoinLeaveMulticastOnNICEnableDisable(t *testing.T) {
-	const nicID = 1
-
-	tests := []struct {
-		name  string
-		proto tcpip.NetworkProtocolNumber
-		addr  tcpip.Address
-	}{
-		{
-			name:  "IPv6 All-Nodes",
-			proto: header.IPv6ProtocolNumber,
-			addr:  header.IPv6AllNodesMulticastAddress,
-		},
-		{
-			name:  "IPv4 All-Systems",
-			proto: header.IPv4ProtocolNumber,
-			addr:  header.IPv4AllSystems,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			e := loopback.New()
-			s := stack.New(stack.Options{
-				NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol, ipv6.NewProtocol},
-			})
-			nicOpts := stack.NICOptions{Disabled: true}
-			if err := s.CreateNICWithOptions(nicID, e, nicOpts); err != nil {
-				t.Fatalf("CreateNIC(%d, _, %+v) = %s", nicID, nicOpts, err)
-			}
-
-			// Should not be in the multicast group yet because the NIC has not been
-			// enabled yet.
-			if isInGroup, err := s.IsInGroup(nicID, test.addr); err != nil {
-				t.Fatalf("IsInGroup(%d, %s): %s", nicID, test.addr, err)
-			} else if isInGroup {
-				t.Fatalf("got IsInGroup(%d, %s) = true, want = false", nicID, test.addr)
-			}
-
-			// The all-nodes multicast group should be joined when the NIC is enabled.
-			if err := s.EnableNIC(nicID); err != nil {
-				t.Fatalf("s.EnableNIC(%d): %s", nicID, err)
-			}
-
-			if isInGroup, err := s.IsInGroup(nicID, test.addr); err != nil {
-				t.Fatalf("IsInGroup(%d, %s): %s", nicID, test.addr, err)
-			} else if !isInGroup {
-				t.Fatalf("got IsInGroup(%d, %s) = false, want = true", nicID, test.addr)
-			}
-
-			// The multicast group should be left when the NIC is disabled.
-			if err := s.DisableNIC(nicID); err != nil {
-				t.Fatalf("s.DisableNIC(%d): %s", nicID, err)
-			}
-
-			if isInGroup, err := s.IsInGroup(nicID, test.addr); err != nil {
-				t.Fatalf("IsInGroup(%d, %s): %s", nicID, test.addr, err)
-			} else if isInGroup {
-				t.Fatalf("got IsInGroup(%d, %s) = true, want = false", nicID, test.addr)
-			}
-
-			// The all-nodes multicast group should be joined when the NIC is enabled.
-			if err := s.EnableNIC(nicID); err != nil {
-				t.Fatalf("s.EnableNIC(%d): %s", nicID, err)
-			}
-
-			if isInGroup, err := s.IsInGroup(nicID, test.addr); err != nil {
-				t.Fatalf("IsInGroup(%d, %s): %s", nicID, test.addr, err)
-			} else if !isInGroup {
-				t.Fatalf("got IsInGroup(%d, %s) = false, want = true", nicID, test.addr)
-			}
-
-			// Leaving the group before disabling the NIC should not cause an error.
-			if err := s.LeaveGroup(test.proto, nicID, test.addr); err != nil {
-				t.Fatalf("s.LeaveGroup(%d, %d, %s): %s", test.proto, nicID, test.addr, err)
-			}
-
-			if err := s.DisableNIC(nicID); err != nil {
-				t.Fatalf("s.DisableNIC(%d): %s", nicID, err)
-			}
-
-			if isInGroup, err := s.IsInGroup(nicID, test.addr); err != nil {
-				t.Fatalf("IsInGroup(%d, %s): %s", nicID, test.addr, err)
-			} else if isInGroup {
-				t.Fatalf("got IsInGroup(%d, %s) = true, want = false", nicID, test.addr)
-			}
-		})
-	}
-}
-
-// TestDoDADWhenNICEnabled tests that IPv6 endpoints that were added while a NIC
-// was disabled have DAD performed on them when the NIC is enabled.
-func TestDoDADWhenNICEnabled(t *testing.T) {
-	const dadTransmits = 1
-	const retransmitTimer = time.Second
-	const nicID = 1
-
-	ndpDisp := ndpDispatcher{
-		dadC: make(chan ndpDADEvent),
-	}
-	opts := stack.Options{
-		NetworkProtocols: []stack.NetworkProtocolFactory{ipv6.NewProtocolWithOptions(ipv6.Options{
-			DADConfigs: stack.DADConfigurations{
-				DupAddrDetectTransmits: dadTransmits,
-				RetransmitTimer:        retransmitTimer,
-			},
-			NDPDisp: &ndpDisp,
-		})},
-	}
-
-	e := channel.New(dadTransmits, 1280, linkAddr1)
-	s := stack.New(opts)
-	nicOpts := stack.NICOptions{Disabled: true}
-	if err := s.CreateNICWithOptions(nicID, e, nicOpts); err != nil {
-		t.Fatalf("CreateNIC(%d, _, %+v) = %s", nicID, nicOpts, err)
-	}
-
-	addr := tcpip.ProtocolAddress{
-		Protocol: header.IPv6ProtocolNumber,
-		AddressWithPrefix: tcpip.AddressWithPrefix{
-			Address:   llAddr1,
-			PrefixLen: 128,
-		},
-	}
-	if err := s.AddProtocolAddress(nicID, addr); err != nil {
-		t.Fatalf("AddProtocolAddress(%d, %+v): %s", nicID, addr, err)
-	}
-
-	// Address should be in the list of all addresses.
-	if addrs := s.AllAddresses()[nicID]; !containsV6Addr(addrs, addr.AddressWithPrefix) {
-		t.Fatalf("got s.AllAddresses()[%d] = %+v, want = %+v", nicID, addrs, addr)
-	}
-
-	// Address should be tentative so it should not be a main address.
-	if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, tcpip.AddressWithPrefix{}); err != nil {
-		t.Fatal(err)
-	}
-
-	// Enabling the NIC should start DAD for the address.
-	if err := s.EnableNIC(nicID); err != nil {
-		t.Fatalf("s.EnableNIC(%d): %s", nicID, err)
-	}
-	if addrs := s.AllAddresses()[nicID]; !containsV6Addr(addrs, addr.AddressWithPrefix) {
-		t.Fatalf("got s.AllAddresses()[%d] = %+v, want = %+v", nicID, addrs, addr)
-	}
-
-	// 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)
-	}
-
-	// Wait for DAD to resolve.
-	select {
-	case <-time.After(dadTransmits*retransmitTimer + defaultAsyncPositiveEventTimeout):
-		t.Fatal("timed out waiting for DAD resolution")
-	case e := <-ndpDisp.dadC:
-		if diff := checkDADEvent(e, nicID, addr.AddressWithPrefix.Address, &stack.DADSucceeded{}); diff != "" {
-			t.Errorf("dad event mismatch (-want +got):\n%s", diff)
-		}
-	}
-	if addrs := s.AllAddresses()[nicID]; !containsV6Addr(addrs, addr.AddressWithPrefix) {
-		t.Fatalf("got s.AllAddresses()[%d] = %+v, want = %+v", nicID, addrs, addr)
-	}
-	if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, addr.AddressWithPrefix); err != nil {
-		t.Fatal(err)
-	}
-
-	// Enabling the NIC again should be a no-op.
-	if err := s.EnableNIC(nicID); err != nil {
-		t.Fatalf("s.EnableNIC(%d): %s", nicID, err)
-	}
-	if addrs := s.AllAddresses()[nicID]; !containsV6Addr(addrs, addr.AddressWithPrefix) {
-		t.Fatalf("got s.AllAddresses()[%d] = %+v, want = %+v", nicID, addrs, addr)
-	}
-	if err := checkGetMainNICAddress(s, nicID, header.IPv6ProtocolNumber, addr.AddressWithPrefix); err != nil {
-		t.Fatal(err)
-	}
-}
-
-func TestStackReceiveBufferSizeOption(t *testing.T) {
-	const sMin = stack.MinBufferSize
-	testCases := []struct {
-		name string
-		rs   stack.ReceiveBufferSizeOption
-		err  tcpip.Error
-	}{
-		// Invalid configurations.
-		{"min_below_zero", stack.ReceiveBufferSizeOption{Min: -1, Default: sMin, Max: sMin}, &tcpip.ErrInvalidOptionValue{}},
-		{"min_zero", stack.ReceiveBufferSizeOption{Min: 0, Default: sMin, Max: sMin}, &tcpip.ErrInvalidOptionValue{}},
-		{"default_below_min", stack.ReceiveBufferSizeOption{Min: sMin, Default: sMin - 1, Max: sMin - 1}, &tcpip.ErrInvalidOptionValue{}},
-		{"default_above_max", stack.ReceiveBufferSizeOption{Min: sMin, Default: sMin + 1, Max: sMin}, &tcpip.ErrInvalidOptionValue{}},
-		{"max_below_min", stack.ReceiveBufferSizeOption{Min: sMin, Default: sMin + 1, Max: sMin - 1}, &tcpip.ErrInvalidOptionValue{}},
-
-		// Valid Configurations
-		{"in_ascending_order", stack.ReceiveBufferSizeOption{Min: sMin, Default: sMin + 1, Max: sMin + 2}, nil},
-		{"all_equal", stack.ReceiveBufferSizeOption{Min: sMin, Default: sMin, Max: sMin}, nil},
-		{"min_default_equal", stack.ReceiveBufferSizeOption{Min: sMin, Default: sMin, Max: sMin + 1}, nil},
-		{"default_max_equal", stack.ReceiveBufferSizeOption{Min: sMin, Default: sMin + 1, Max: sMin + 1}, nil},
-	}
-	for _, tc := range testCases {
-		t.Run(tc.name, func(t *testing.T) {
-			s := stack.New(stack.Options{})
-			defer s.Close()
-			if err := s.SetOption(tc.rs); err != tc.err {
-				t.Fatalf("s.SetOption(%#v) = %v, want: %v", tc.rs, err, tc.err)
-			}
-			var rs stack.ReceiveBufferSizeOption
-			if tc.err == nil {
-				if err := s.Option(&rs); err != nil {
-					t.Fatalf("s.Option(%#v) = %v, want: nil", rs, err)
-				}
-				if got, want := rs, tc.rs; got != want {
-					t.Fatalf("s.Option(..) returned unexpected value got: %#v, want: %#v", got, want)
-				}
-			}
-		})
-	}
-}
-
-func TestStackSendBufferSizeOption(t *testing.T) {
-	const sMin = stack.MinBufferSize
-	testCases := []struct {
-		name string
-		ss   tcpip.SendBufferSizeOption
-		err  tcpip.Error
-	}{
-		// Invalid configurations.
-		{"min_below_zero", tcpip.SendBufferSizeOption{Min: -1, Default: sMin, Max: sMin}, &tcpip.ErrInvalidOptionValue{}},
-		{"min_zero", tcpip.SendBufferSizeOption{Min: 0, Default: sMin, Max: sMin}, &tcpip.ErrInvalidOptionValue{}},
-		{"default_below_min", tcpip.SendBufferSizeOption{Min: 0, Default: sMin - 1, Max: sMin - 1}, &tcpip.ErrInvalidOptionValue{}},
-		{"default_above_max", tcpip.SendBufferSizeOption{Min: 0, Default: sMin + 1, Max: sMin}, &tcpip.ErrInvalidOptionValue{}},
-		{"max_below_min", tcpip.SendBufferSizeOption{Min: sMin, Default: sMin + 1, Max: sMin - 1}, &tcpip.ErrInvalidOptionValue{}},
-
-		// Valid Configurations
-		{"in_ascending_order", tcpip.SendBufferSizeOption{Min: sMin, Default: sMin + 1, Max: sMin + 2}, nil},
-		{"all_equal", tcpip.SendBufferSizeOption{Min: sMin, Default: sMin, Max: sMin}, nil},
-		{"min_default_equal", tcpip.SendBufferSizeOption{Min: sMin, Default: sMin, Max: sMin + 1}, nil},
-		{"default_max_equal", tcpip.SendBufferSizeOption{Min: sMin, Default: sMin + 1, Max: sMin + 1}, nil},
-	}
-	for _, tc := range testCases {
-		t.Run(tc.name, func(t *testing.T) {
-			s := stack.New(stack.Options{})
-			defer s.Close()
-			err := s.SetOption(tc.ss)
-			if diff := cmp.Diff(tc.err, err); diff != "" {
-				t.Fatalf("unexpected error from s.SetOption(%+v), (-want, +got):\n%s", tc.ss, diff)
-			}
-			if tc.err == nil {
-				var ss tcpip.SendBufferSizeOption
-				if err := s.Option(&ss); err != nil {
-					t.Fatalf("s.Option(%+v) = %v, want: nil", ss, err)
-				}
-				if got, want := ss, tc.ss; got != want {
-					t.Fatalf("s.Option(..) returned unexpected value got: %#v, want: %#v", got, want)
-				}
-			}
-		})
-	}
-}
-
-func TestOutgoingSubnetBroadcast(t *testing.T) {
-	const (
-		unspecifiedNICID = 0
-		nicID1           = 1
-	)
-
-	defaultAddr := tcpip.AddressWithPrefix{
-		Address:   header.IPv4Any,
-		PrefixLen: 0,
-	}
-	defaultSubnet := defaultAddr.Subnet()
-	ipv4Addr := tcpip.AddressWithPrefix{
-		Address:   "\xc0\xa8\x01\x3a",
-		PrefixLen: 24,
-	}
-	ipv4Subnet := ipv4Addr.Subnet()
-	ipv4SubnetBcast := ipv4Subnet.Broadcast()
-	ipv4Gateway := tcpip.Address("\xc0\xa8\x01\x01")
-	ipv4AddrPrefix31 := tcpip.AddressWithPrefix{
-		Address:   "\xc0\xa8\x01\x3a",
-		PrefixLen: 31,
-	}
-	ipv4Subnet31 := ipv4AddrPrefix31.Subnet()
-	ipv4Subnet31Bcast := ipv4Subnet31.Broadcast()
-	ipv4AddrPrefix32 := tcpip.AddressWithPrefix{
-		Address:   "\xc0\xa8\x01\x3a",
-		PrefixLen: 32,
-	}
-	ipv4Subnet32 := ipv4AddrPrefix32.Subnet()
-	ipv4Subnet32Bcast := ipv4Subnet32.Broadcast()
-	ipv6Addr := tcpip.AddressWithPrefix{
-		Address:   "\x20\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01",
-		PrefixLen: 64,
-	}
-	ipv6Subnet := ipv6Addr.Subnet()
-	ipv6SubnetBcast := ipv6Subnet.Broadcast()
-	remNetAddr := tcpip.AddressWithPrefix{
-		Address:   "\x64\x0a\x7b\x18",
-		PrefixLen: 24,
-	}
-	remNetSubnet := remNetAddr.Subnet()
-	remNetSubnetBcast := remNetSubnet.Broadcast()
-
-	tests := []struct {
-		name                      string
-		nicAddr                   tcpip.ProtocolAddress
-		routes                    []tcpip.Route
-		remoteAddr                tcpip.Address
-		expectedLocalAddress      tcpip.Address
-		expectedRemoteAddress     tcpip.Address
-		expectedRemoteLinkAddress tcpip.LinkAddress
-		expectedNextHop           tcpip.Address
-		expectedNetProto          tcpip.NetworkProtocolNumber
-		expectedLoop              stack.PacketLooping
-	}{
-		// Broadcast to a locally attached subnet populates the broadcast MAC.
-		{
-			name: "IPv4 Broadcast to local subnet",
-			nicAddr: tcpip.ProtocolAddress{
-				Protocol:          header.IPv4ProtocolNumber,
-				AddressWithPrefix: ipv4Addr,
-			},
-			routes: []tcpip.Route{
-				{
-					Destination: ipv4Subnet,
-					NIC:         nicID1,
-				},
-			},
-			remoteAddr:                ipv4SubnetBcast,
-			expectedLocalAddress:      ipv4Addr.Address,
-			expectedRemoteAddress:     ipv4SubnetBcast,
-			expectedRemoteLinkAddress: header.EthernetBroadcastAddress,
-			expectedNetProto:          header.IPv4ProtocolNumber,
-			expectedLoop:              stack.PacketOut | stack.PacketLoop,
-		},
-		// Broadcast to a locally attached /31 subnet does not populate the
-		// broadcast MAC.
-		{
-			name: "IPv4 Broadcast to local /31 subnet",
-			nicAddr: tcpip.ProtocolAddress{
-				Protocol:          header.IPv4ProtocolNumber,
-				AddressWithPrefix: ipv4AddrPrefix31,
-			},
-			routes: []tcpip.Route{
-				{
-					Destination: ipv4Subnet31,
-					NIC:         nicID1,
-				},
-			},
-			remoteAddr:            ipv4Subnet31Bcast,
-			expectedLocalAddress:  ipv4AddrPrefix31.Address,
-			expectedRemoteAddress: ipv4Subnet31Bcast,
-			expectedNetProto:      header.IPv4ProtocolNumber,
-			expectedLoop:          stack.PacketOut,
-		},
-		// Broadcast to a locally attached /32 subnet does not populate the
-		// broadcast MAC.
-		{
-			name: "IPv4 Broadcast to local /32 subnet",
-			nicAddr: tcpip.ProtocolAddress{
-				Protocol:          header.IPv4ProtocolNumber,
-				AddressWithPrefix: ipv4AddrPrefix32,
-			},
-			routes: []tcpip.Route{
-				{
-					Destination: ipv4Subnet32,
-					NIC:         nicID1,
-				},
-			},
-			remoteAddr:            ipv4Subnet32Bcast,
-			expectedLocalAddress:  ipv4AddrPrefix32.Address,
-			expectedRemoteAddress: ipv4Subnet32Bcast,
-			expectedNetProto:      header.IPv4ProtocolNumber,
-			expectedLoop:          stack.PacketOut,
-		},
-		// IPv6 has no notion of a broadcast.
-		{
-			name: "IPv6 'Broadcast' to local subnet",
-			nicAddr: tcpip.ProtocolAddress{
-				Protocol:          header.IPv6ProtocolNumber,
-				AddressWithPrefix: ipv6Addr,
-			},
-			routes: []tcpip.Route{
-				{
-					Destination: ipv6Subnet,
-					NIC:         nicID1,
-				},
-			},
-			remoteAddr:            ipv6SubnetBcast,
-			expectedLocalAddress:  ipv6Addr.Address,
-			expectedRemoteAddress: ipv6SubnetBcast,
-			expectedNetProto:      header.IPv6ProtocolNumber,
-			expectedLoop:          stack.PacketOut,
-		},
-		// Broadcast to a remote subnet in the route table is send to the next-hop
-		// gateway.
-		{
-			name: "IPv4 Broadcast to remote subnet",
-			nicAddr: tcpip.ProtocolAddress{
-				Protocol:          header.IPv4ProtocolNumber,
-				AddressWithPrefix: ipv4Addr,
-			},
-			routes: []tcpip.Route{
-				{
-					Destination: remNetSubnet,
-					Gateway:     ipv4Gateway,
-					NIC:         nicID1,
-				},
-			},
-			remoteAddr:            remNetSubnetBcast,
-			expectedLocalAddress:  ipv4Addr.Address,
-			expectedRemoteAddress: remNetSubnetBcast,
-			expectedNextHop:       ipv4Gateway,
-			expectedNetProto:      header.IPv4ProtocolNumber,
-			expectedLoop:          stack.PacketOut,
-		},
-		// Broadcast to an unknown subnet follows the default route. Note that this
-		// is essentially just routing an unknown destination IP, because w/o any
-		// subnet prefix information a subnet broadcast address is just a normal IP.
-		{
-			name: "IPv4 Broadcast to unknown subnet",
-			nicAddr: tcpip.ProtocolAddress{
-				Protocol:          header.IPv4ProtocolNumber,
-				AddressWithPrefix: ipv4Addr,
-			},
-			routes: []tcpip.Route{
-				{
-					Destination: defaultSubnet,
-					Gateway:     ipv4Gateway,
-					NIC:         nicID1,
-				},
-			},
-			remoteAddr:            remNetSubnetBcast,
-			expectedLocalAddress:  ipv4Addr.Address,
-			expectedRemoteAddress: remNetSubnetBcast,
-			expectedNextHop:       ipv4Gateway,
-			expectedNetProto:      header.IPv4ProtocolNumber,
-			expectedLoop:          stack.PacketOut,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			s := stack.New(stack.Options{
-				NetworkProtocols: []stack.NetworkProtocolFactory{arp.NewProtocol, ipv4.NewProtocol, ipv6.NewProtocol},
-			})
-			ep := channel.New(0, defaultMTU, "")
-			ep.LinkEPCapabilities |= stack.CapabilityResolutionRequired
-			if err := s.CreateNIC(nicID1, ep); err != nil {
-				t.Fatalf("CreateNIC(%d, _): %s", nicID1, err)
-			}
-			if err := s.AddProtocolAddress(nicID1, test.nicAddr); err != nil {
-				t.Fatalf("AddProtocolAddress(%d, %+v): %s", nicID1, test.nicAddr, err)
-			}
-
-			s.SetRouteTable(test.routes)
-
-			var netProto tcpip.NetworkProtocolNumber
-			switch l := len(test.remoteAddr); l {
-			case header.IPv4AddressSize:
-				netProto = header.IPv4ProtocolNumber
-			case header.IPv6AddressSize:
-				netProto = header.IPv6ProtocolNumber
-			default:
-				t.Fatalf("got unexpected address length = %d bytes", l)
-			}
-
-			r, err := s.FindRoute(unspecifiedNICID, "" /* localAddr */, test.remoteAddr, netProto, false /* multicastLoop */)
-			if err != nil {
-				t.Fatalf("FindRoute(%d, '', %s, %d): %s", unspecifiedNICID, test.remoteAddr, netProto, err)
-			}
-			if r.LocalAddress != test.expectedLocalAddress {
-				t.Errorf("got r.LocalAddress = %s, want = %s", r.LocalAddress, test.expectedLocalAddress)
-			}
-			if r.RemoteAddress != test.expectedRemoteAddress {
-				t.Errorf("got r.RemoteAddress = %s, want = %s", r.RemoteAddress, test.expectedRemoteAddress)
-			}
-			if got := r.RemoteLinkAddress(); got != test.expectedRemoteLinkAddress {
-				t.Errorf("got r.RemoteLinkAddress() = %s, want = %s", got, test.expectedRemoteLinkAddress)
-			}
-			if r.NextHop != test.expectedNextHop {
-				t.Errorf("got r.NextHop = %s, want = %s", r.NextHop, test.expectedNextHop)
-			}
-			if r.NetProto != test.expectedNetProto {
-				t.Errorf("got r.NetProto = %d, want = %d", r.NetProto, test.expectedNetProto)
-			}
-			if r.Loop != test.expectedLoop {
-				t.Errorf("got r.Loop = %x, want = %x", r.Loop, test.expectedLoop)
-			}
-		})
-	}
-}
-
-func TestResolveWith(t *testing.T) {
-	const (
-		unspecifiedNICID = 0
-		nicID            = 1
-	)
-
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol, arp.NewProtocol},
-	})
-	ep := channel.New(0, defaultMTU, "")
-	ep.LinkEPCapabilities |= stack.CapabilityResolutionRequired
-	if err := s.CreateNIC(nicID, ep); err != nil {
-		t.Fatalf("CreateNIC(%d, _): %s", nicID, err)
-	}
-	addr := tcpip.ProtocolAddress{
-		Protocol: header.IPv4ProtocolNumber,
-		AddressWithPrefix: tcpip.AddressWithPrefix{
-			Address:   tcpip.Address([]byte{192, 168, 1, 58}),
-			PrefixLen: 24,
-		},
-	}
-	if err := s.AddProtocolAddress(nicID, addr); err != nil {
-		t.Fatalf("AddProtocolAddress(%d, %#v): %s", nicID, addr, err)
-	}
-
-	s.SetRouteTable([]tcpip.Route{{Destination: header.IPv4EmptySubnet, NIC: nicID}})
-
-	remoteAddr := tcpip.Address([]byte{192, 168, 1, 59})
-	r, err := s.FindRoute(unspecifiedNICID, "" /* localAddr */, remoteAddr, header.IPv4ProtocolNumber, false /* multicastLoop */)
-	if err != nil {
-		t.Fatalf("FindRoute(%d, '', %s, %d): %s", unspecifiedNICID, remoteAddr, header.IPv4ProtocolNumber, err)
-	}
-	defer r.Release()
-
-	// Should initially require resolution.
-	if !r.IsResolutionRequired() {
-		t.Fatal("got r.IsResolutionRequired() = false, want = true")
-	}
-
-	// Manually resolving the route should no longer require resolution.
-	r.ResolveWith("\x01")
-	if r.IsResolutionRequired() {
-		t.Fatal("got r.IsResolutionRequired() = true, want = false")
-	}
-}
-
-// TestRouteReleaseAfterAddrRemoval tests that releasing a Route after its
-// associated address is removed should not cause a panic.
-func TestRouteReleaseAfterAddrRemoval(t *testing.T) {
-	const (
-		nicID      = 1
-		localAddr  = tcpip.Address("\x01")
-		remoteAddr = tcpip.Address("\x02")
-	)
-
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
-	})
-
-	ep := channel.New(0, defaultMTU, "")
-	if err := s.CreateNIC(nicID, ep); err != nil {
-		t.Fatalf("CreateNIC(%d, _): %s", nicID, err)
-	}
-	if err := s.AddAddress(nicID, fakeNetNumber, localAddr); err != nil {
-		t.Fatalf("s.AddAddress(%d, %d, %s): %s", nicID, fakeNetNumber, localAddr, err)
-	}
-	{
-		subnet, err := tcpip.NewSubnet("\x00", "\x00")
-		if err != nil {
-			t.Fatal(err)
-		}
-		s.SetRouteTable([]tcpip.Route{{Destination: subnet, Gateway: "\x00", NIC: 1}})
-	}
-
-	r, err := s.FindRoute(nicID, localAddr, remoteAddr, fakeNetNumber, false /* multicastLoop */)
-	if err != nil {
-		t.Fatalf("s.FindRoute(%d, %s, %s, %d, false): %s", nicID, localAddr, remoteAddr, fakeNetNumber, err)
-	}
-	// Should not panic.
-	defer r.Release()
-
-	// Check that removing the same address fails.
-	if err := s.RemoveAddress(nicID, localAddr); err != nil {
-		t.Fatalf("s.RemoveAddress(%d, %s): %s", nicID, localAddr, err)
-	}
-}
-
-func TestGetNetworkEndpoint(t *testing.T) {
-	const nicID = 1
-
-	tests := []struct {
-		name         string
-		protoFactory stack.NetworkProtocolFactory
-		protoNum     tcpip.NetworkProtocolNumber
-	}{
-		{
-			name:         "IPv4",
-			protoFactory: ipv4.NewProtocol,
-			protoNum:     ipv4.ProtocolNumber,
-		},
-		{
-			name:         "IPv6",
-			protoFactory: ipv6.NewProtocol,
-			protoNum:     ipv6.ProtocolNumber,
-		},
-	}
-
-	factories := make([]stack.NetworkProtocolFactory, 0, len(tests))
-	for _, test := range tests {
-		factories = append(factories, test.protoFactory)
-	}
-
-	s := stack.New(stack.Options{
-		NetworkProtocols: factories,
-	})
-
-	if err := s.CreateNIC(nicID, channel.New(0, defaultMTU, "")); err != nil {
-		t.Fatalf("CreateNIC(%d, _): %s", nicID, err)
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			ep, err := s.GetNetworkEndpoint(nicID, test.protoNum)
-			if err != nil {
-				t.Fatalf("s.GetNetworkEndpoint(%d, %d): %s", nicID, test.protoNum, err)
-			}
-
-			if got := ep.NetworkProtocolNumber(); got != test.protoNum {
-				t.Fatalf("got ep.NetworkProtocolNumber() = %d, want = %d", got, test.protoNum)
-			}
-		})
-	}
-}
-
-func TestGetMainNICAddressWhenNICDisabled(t *testing.T) {
-	const nicID = 1
-
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory},
-	})
-
-	if err := s.CreateNIC(nicID, channel.New(0, defaultMTU, "")); err != nil {
-		t.Fatalf("CreateNIC(%d, _): %s", nicID, err)
-	}
-
-	protocolAddress := tcpip.ProtocolAddress{
-		Protocol: fakeNetNumber,
-		AddressWithPrefix: tcpip.AddressWithPrefix{
-			Address:   "\x01",
-			PrefixLen: 8,
-		},
-	}
-	if err := s.AddProtocolAddress(nicID, protocolAddress); err != nil {
-		t.Fatalf("AddProtocolAddress(%d, %#v): %s", nicID, protocolAddress, err)
-	}
-
-	// Check that we get the right initial address and prefix length.
-	if err := checkGetMainNICAddress(s, nicID, fakeNetNumber, protocolAddress.AddressWithPrefix); err != nil {
-		t.Fatal(err)
-	}
-
-	// Should still get the address when the NIC is diabled.
-	if err := s.DisableNIC(nicID); err != nil {
-		t.Fatalf("DisableNIC(%d): %s", nicID, err)
-	}
-	if err := checkGetMainNICAddress(s, nicID, fakeNetNumber, protocolAddress.AddressWithPrefix); err != nil {
-		t.Fatal(err)
-	}
-}
-
-// TestAddRoute tests Stack.AddRoute
-func TestAddRoute(t *testing.T) {
-	const nicID = 1
-
-	s := stack.New(stack.Options{})
-
-	subnet1, err := tcpip.NewSubnet("\x00", "\x00")
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	subnet2, err := tcpip.NewSubnet("\x01", "\x01")
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	expected := []tcpip.Route{
-		{Destination: subnet1, Gateway: "\x00", NIC: 1},
-		{Destination: subnet2, Gateway: "\x00", NIC: 1},
-	}
-
-	// Initialize the route table with one route.
-	s.SetRouteTable([]tcpip.Route{expected[0]})
-
-	// Add another route.
-	s.AddRoute(expected[1])
-
-	rt := s.GetRouteTable()
-	if got, want := len(rt), len(expected); got != want {
-		t.Fatalf("Unexpected route table length got = %d, want = %d", got, want)
-	}
-	for i, route := range rt {
-		if got, want := route, expected[i]; got != want {
-			t.Fatalf("Unexpected route got = %#v, want = %#v", got, want)
-		}
-	}
-}
-
-// TestRemoveRoutes tests Stack.RemoveRoutes
-func TestRemoveRoutes(t *testing.T) {
-	const nicID = 1
-
-	s := stack.New(stack.Options{})
-
-	addressToRemove := tcpip.Address("\x01")
-	subnet1, err := tcpip.NewSubnet(addressToRemove, "\x01")
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	subnet2, err := tcpip.NewSubnet(addressToRemove, "\x01")
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	subnet3, err := tcpip.NewSubnet("\x02", "\x02")
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	// Initialize the route table with three routes.
-	s.SetRouteTable([]tcpip.Route{
-		{Destination: subnet1, Gateway: "\x00", NIC: 1},
-		{Destination: subnet2, Gateway: "\x00", NIC: 1},
-		{Destination: subnet3, Gateway: "\x00", NIC: 1},
-	})
-
-	// Remove routes with the specific address.
-	s.RemoveRoutes(func(r tcpip.Route) bool {
-		return r.Destination.ID() == addressToRemove
-	})
-
-	expected := []tcpip.Route{{Destination: subnet3, Gateway: "\x00", NIC: 1}}
-	rt := s.GetRouteTable()
-	if got, want := len(rt), len(expected); got != want {
-		t.Fatalf("Unexpected route table length got = %d, want = %d", got, want)
-	}
-	for i, route := range rt {
-		if got, want := route, expected[i]; got != want {
-			t.Fatalf("Unexpected route got = %#v, want = %#v", got, want)
-		}
-	}
-}
-
-func TestFindRouteWithForwarding(t *testing.T) {
-	const (
-		nicID1 = 1
-		nicID2 = 2
-
-		nic1Addr   = tcpip.Address("\x01")
-		nic2Addr   = tcpip.Address("\x02")
-		remoteAddr = tcpip.Address("\x03")
-	)
-
-	type netCfg struct {
-		proto      tcpip.NetworkProtocolNumber
-		factory    stack.NetworkProtocolFactory
-		nic1Addr   tcpip.Address
-		nic2Addr   tcpip.Address
-		remoteAddr tcpip.Address
-	}
-
-	fakeNetCfg := netCfg{
-		proto:      fakeNetNumber,
-		factory:    fakeNetFactory,
-		nic1Addr:   nic1Addr,
-		nic2Addr:   nic2Addr,
-		remoteAddr: remoteAddr,
-	}
-
-	globalIPv6Addr1 := tcpip.Address(net.ParseIP("a::1").To16())
-	globalIPv6Addr2 := tcpip.Address(net.ParseIP("a::2").To16())
-
-	ipv6LinkLocalNIC1WithGlobalRemote := netCfg{
-		proto:      ipv6.ProtocolNumber,
-		factory:    ipv6.NewProtocol,
-		nic1Addr:   llAddr1,
-		nic2Addr:   globalIPv6Addr2,
-		remoteAddr: globalIPv6Addr1,
-	}
-	ipv6GlobalNIC1WithLinkLocalRemote := netCfg{
-		proto:      ipv6.ProtocolNumber,
-		factory:    ipv6.NewProtocol,
-		nic1Addr:   globalIPv6Addr1,
-		nic2Addr:   llAddr1,
-		remoteAddr: llAddr2,
-	}
-	ipv6GlobalNIC1WithLinkLocalMulticastRemote := netCfg{
-		proto:      ipv6.ProtocolNumber,
-		factory:    ipv6.NewProtocol,
-		nic1Addr:   globalIPv6Addr1,
-		nic2Addr:   globalIPv6Addr2,
-		remoteAddr: "\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01",
-	}
-
-	tests := []struct {
-		name string
-
-		netCfg            netCfg
-		forwardingEnabled bool
-
-		addrNIC   tcpip.NICID
-		localAddr tcpip.Address
-
-		findRouteErr          tcpip.Error
-		dependentOnForwarding bool
-	}{
-		{
-			name:                  "forwarding disabled and localAddr not on specified NIC but route from different NIC",
-			netCfg:                fakeNetCfg,
-			forwardingEnabled:     false,
-			addrNIC:               nicID1,
-			localAddr:             fakeNetCfg.nic2Addr,
-			findRouteErr:          &tcpip.ErrNoRoute{},
-			dependentOnForwarding: false,
-		},
-		{
-			name:                  "forwarding enabled and localAddr not on specified NIC but route from different NIC",
-			netCfg:                fakeNetCfg,
-			forwardingEnabled:     true,
-			addrNIC:               nicID1,
-			localAddr:             fakeNetCfg.nic2Addr,
-			findRouteErr:          &tcpip.ErrNoRoute{},
-			dependentOnForwarding: false,
-		},
-		{
-			name:                  "forwarding disabled and localAddr on specified NIC but route from different NIC",
-			netCfg:                fakeNetCfg,
-			forwardingEnabled:     false,
-			addrNIC:               nicID1,
-			localAddr:             fakeNetCfg.nic1Addr,
-			findRouteErr:          &tcpip.ErrNoRoute{},
-			dependentOnForwarding: false,
-		},
-		{
-			name:                  "forwarding enabled and localAddr on specified NIC but route from different NIC",
-			netCfg:                fakeNetCfg,
-			forwardingEnabled:     true,
-			addrNIC:               nicID1,
-			localAddr:             fakeNetCfg.nic1Addr,
-			findRouteErr:          nil,
-			dependentOnForwarding: true,
-		},
-		{
-			name:                  "forwarding disabled and localAddr on specified NIC and route from same NIC",
-			netCfg:                fakeNetCfg,
-			forwardingEnabled:     false,
-			addrNIC:               nicID2,
-			localAddr:             fakeNetCfg.nic2Addr,
-			findRouteErr:          nil,
-			dependentOnForwarding: false,
-		},
-		{
-			name:                  "forwarding enabled and localAddr on specified NIC and route from same NIC",
-			netCfg:                fakeNetCfg,
-			forwardingEnabled:     true,
-			addrNIC:               nicID2,
-			localAddr:             fakeNetCfg.nic2Addr,
-			findRouteErr:          nil,
-			dependentOnForwarding: false,
-		},
-		{
-			name:                  "forwarding disabled and localAddr not on specified NIC but route from same NIC",
-			netCfg:                fakeNetCfg,
-			forwardingEnabled:     false,
-			addrNIC:               nicID2,
-			localAddr:             fakeNetCfg.nic1Addr,
-			findRouteErr:          &tcpip.ErrNoRoute{},
-			dependentOnForwarding: false,
-		},
-		{
-			name:                  "forwarding enabled and localAddr not on specified NIC but route from same NIC",
-			netCfg:                fakeNetCfg,
-			forwardingEnabled:     true,
-			addrNIC:               nicID2,
-			localAddr:             fakeNetCfg.nic1Addr,
-			findRouteErr:          &tcpip.ErrNoRoute{},
-			dependentOnForwarding: false,
-		},
-		{
-			name:                  "forwarding disabled and localAddr on same NIC as route",
-			netCfg:                fakeNetCfg,
-			forwardingEnabled:     false,
-			localAddr:             fakeNetCfg.nic2Addr,
-			findRouteErr:          nil,
-			dependentOnForwarding: false,
-		},
-		{
-			name:                  "forwarding enabled and localAddr on same NIC as route",
-			netCfg:                fakeNetCfg,
-			forwardingEnabled:     false,
-			localAddr:             fakeNetCfg.nic2Addr,
-			findRouteErr:          nil,
-			dependentOnForwarding: false,
-		},
-		{
-			name:                  "forwarding disabled and localAddr on different NIC as route",
-			netCfg:                fakeNetCfg,
-			forwardingEnabled:     false,
-			localAddr:             fakeNetCfg.nic1Addr,
-			findRouteErr:          &tcpip.ErrNoRoute{},
-			dependentOnForwarding: false,
-		},
-		{
-			name:                  "forwarding enabled and localAddr on different NIC as route",
-			netCfg:                fakeNetCfg,
-			forwardingEnabled:     true,
-			localAddr:             fakeNetCfg.nic1Addr,
-			findRouteErr:          nil,
-			dependentOnForwarding: true,
-		},
-		{
-			name:                  "forwarding disabled and specified NIC only has link-local addr with route on different NIC",
-			netCfg:                ipv6LinkLocalNIC1WithGlobalRemote,
-			forwardingEnabled:     false,
-			addrNIC:               nicID1,
-			findRouteErr:          &tcpip.ErrNoRoute{},
-			dependentOnForwarding: false,
-		},
-		{
-			name:                  "forwarding enabled and specified NIC only has link-local addr with route on different NIC",
-			netCfg:                ipv6LinkLocalNIC1WithGlobalRemote,
-			forwardingEnabled:     true,
-			addrNIC:               nicID1,
-			findRouteErr:          &tcpip.ErrNoRoute{},
-			dependentOnForwarding: false,
-		},
-		{
-			name:                  "forwarding disabled and link-local local addr with route on different NIC",
-			netCfg:                ipv6LinkLocalNIC1WithGlobalRemote,
-			forwardingEnabled:     false,
-			localAddr:             ipv6LinkLocalNIC1WithGlobalRemote.nic1Addr,
-			findRouteErr:          &tcpip.ErrNoRoute{},
-			dependentOnForwarding: false,
-		},
-		{
-			name:                  "forwarding enabled and link-local local addr with route on same NIC",
-			netCfg:                ipv6LinkLocalNIC1WithGlobalRemote,
-			forwardingEnabled:     true,
-			localAddr:             ipv6LinkLocalNIC1WithGlobalRemote.nic1Addr,
-			findRouteErr:          &tcpip.ErrNoRoute{},
-			dependentOnForwarding: false,
-		},
-		{
-			name:                  "forwarding disabled and global local addr with route on same NIC",
-			netCfg:                ipv6LinkLocalNIC1WithGlobalRemote,
-			forwardingEnabled:     true,
-			localAddr:             ipv6LinkLocalNIC1WithGlobalRemote.nic2Addr,
-			findRouteErr:          nil,
-			dependentOnForwarding: false,
-		},
-		{
-			name:                  "forwarding disabled and link-local local addr with route on same NIC",
-			netCfg:                ipv6GlobalNIC1WithLinkLocalRemote,
-			forwardingEnabled:     false,
-			localAddr:             ipv6GlobalNIC1WithLinkLocalRemote.nic2Addr,
-			findRouteErr:          nil,
-			dependentOnForwarding: false,
-		},
-		{
-			name:                  "forwarding enabled and link-local local addr with route on same NIC",
-			netCfg:                ipv6GlobalNIC1WithLinkLocalRemote,
-			forwardingEnabled:     true,
-			localAddr:             ipv6GlobalNIC1WithLinkLocalRemote.nic2Addr,
-			findRouteErr:          nil,
-			dependentOnForwarding: false,
-		},
-		{
-			name:                  "forwarding disabled and global local addr with link-local remote on different NIC",
-			netCfg:                ipv6GlobalNIC1WithLinkLocalRemote,
-			forwardingEnabled:     false,
-			localAddr:             ipv6GlobalNIC1WithLinkLocalRemote.nic1Addr,
-			findRouteErr:          &tcpip.ErrNetworkUnreachable{},
-			dependentOnForwarding: false,
-		},
-		{
-			name:                  "forwarding enabled and global local addr with link-local remote on different NIC",
-			netCfg:                ipv6GlobalNIC1WithLinkLocalRemote,
-			forwardingEnabled:     true,
-			localAddr:             ipv6GlobalNIC1WithLinkLocalRemote.nic1Addr,
-			findRouteErr:          &tcpip.ErrNetworkUnreachable{},
-			dependentOnForwarding: false,
-		},
-		{
-			name:                  "forwarding disabled and global local addr with link-local multicast remote on different NIC",
-			netCfg:                ipv6GlobalNIC1WithLinkLocalMulticastRemote,
-			forwardingEnabled:     false,
-			localAddr:             ipv6GlobalNIC1WithLinkLocalMulticastRemote.nic1Addr,
-			findRouteErr:          &tcpip.ErrNetworkUnreachable{},
-			dependentOnForwarding: false,
-		},
-		{
-			name:                  "forwarding enabled and global local addr with link-local multicast remote on different NIC",
-			netCfg:                ipv6GlobalNIC1WithLinkLocalMulticastRemote,
-			forwardingEnabled:     true,
-			localAddr:             ipv6GlobalNIC1WithLinkLocalMulticastRemote.nic1Addr,
-			findRouteErr:          &tcpip.ErrNetworkUnreachable{},
-			dependentOnForwarding: false,
-		},
-		{
-			name:                  "forwarding disabled and global local addr with link-local multicast remote on same NIC",
-			netCfg:                ipv6GlobalNIC1WithLinkLocalMulticastRemote,
-			forwardingEnabled:     false,
-			localAddr:             ipv6GlobalNIC1WithLinkLocalMulticastRemote.nic2Addr,
-			findRouteErr:          nil,
-			dependentOnForwarding: false,
-		},
-		{
-			name:                  "forwarding enabled and global local addr with link-local multicast remote on same NIC",
-			netCfg:                ipv6GlobalNIC1WithLinkLocalMulticastRemote,
-			forwardingEnabled:     true,
-			localAddr:             ipv6GlobalNIC1WithLinkLocalMulticastRemote.nic2Addr,
-			findRouteErr:          nil,
-			dependentOnForwarding: false,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			s := stack.New(stack.Options{
-				NetworkProtocols: []stack.NetworkProtocolFactory{test.netCfg.factory},
-			})
-
-			ep1 := channel.New(1, defaultMTU, "")
-			if err := s.CreateNIC(nicID1, ep1); err != nil {
-				t.Fatalf("CreateNIC(%d, _): %s:", nicID1, err)
-			}
-
-			ep2 := channel.New(1, defaultMTU, "")
-			if err := s.CreateNIC(nicID2, ep2); err != nil {
-				t.Fatalf("CreateNIC(%d, _): %s:", nicID2, err)
-			}
-
-			if err := s.AddAddress(nicID1, test.netCfg.proto, test.netCfg.nic1Addr); err != nil {
-				t.Fatalf("AddAddress(%d, %d, %s): %s", nicID1, test.netCfg.proto, test.netCfg.nic1Addr, err)
-			}
-
-			if err := s.AddAddress(nicID2, test.netCfg.proto, test.netCfg.nic2Addr); err != nil {
-				t.Fatalf("AddAddress(%d, %d, %s): %s", nicID2, test.netCfg.proto, test.netCfg.nic2Addr, err)
-			}
-
-			if err := s.SetForwarding(test.netCfg.proto, test.forwardingEnabled); err != nil {
-				t.Fatalf("SetForwarding(%d, %t): %s", test.netCfg.proto, test.forwardingEnabled, err)
-			}
-
-			s.SetRouteTable([]tcpip.Route{{Destination: test.netCfg.remoteAddr.WithPrefix().Subnet(), NIC: nicID2}})
-
-			r, err := s.FindRoute(test.addrNIC, test.localAddr, test.netCfg.remoteAddr, test.netCfg.proto, false /* multicastLoop */)
-			if r != nil {
-				defer r.Release()
-			}
-			if diff := cmp.Diff(test.findRouteErr, err); diff != "" {
-				t.Fatalf("unexpected error from FindRoute(%d, %s, %s, %d, false), (-want, +got):\n%s", test.addrNIC, test.localAddr, test.netCfg.remoteAddr, test.netCfg.proto, diff)
-			}
-
-			if test.findRouteErr != nil {
-				return
-			}
-
-			if r.LocalAddress != test.localAddr {
-				t.Errorf("got r.LocalAddress = %s, want = %s", r.LocalAddress, test.localAddr)
-			}
-			if r.RemoteAddress != test.netCfg.remoteAddr {
-				t.Errorf("got r.RemoteAddress = %s, want = %s", r.RemoteAddress, test.netCfg.remoteAddr)
-			}
-
-			if t.Failed() {
-				t.FailNow()
-			}
-
-			// Sending a packet should always go through NIC2 since we only install a
-			// route to test.netCfg.remoteAddr through NIC2.
-			data := buffer.View([]byte{1, 2, 3, 4})
-			if err := send(r, data); err != nil {
-				t.Fatalf("send(_, _): %s", err)
-			}
-			if n := ep1.Drain(); n != 0 {
-				t.Errorf("got %d unexpected packets from ep1", n)
-			}
-			pkt, ok := ep2.Read()
-			if !ok {
-				t.Fatal("packet not sent through ep2")
-			}
-			if pkt.Route.LocalAddress != test.localAddr {
-				t.Errorf("got pkt.Route.LocalAddress = %s, want = %s", pkt.Route.LocalAddress, test.localAddr)
-			}
-			if pkt.Route.RemoteAddress != test.netCfg.remoteAddr {
-				t.Errorf("got pkt.Route.RemoteAddress = %s, want = %s", pkt.Route.RemoteAddress, test.netCfg.remoteAddr)
-			}
-
-			if !test.forwardingEnabled || !test.dependentOnForwarding {
-				return
-			}
-
-			// Disabling forwarding when the route is dependent on forwarding being
-			// enabled should make the route invalid.
-			if err := s.SetForwarding(test.netCfg.proto, false); err != nil {
-				t.Fatalf("SetForwarding(%d, false): %s", test.netCfg.proto, err)
-			}
-			{
-				err := send(r, data)
-				if _, ok := err.(*tcpip.ErrInvalidEndpointState); !ok {
-					t.Fatalf("got send(_, _) = %s, want = %s", err, &tcpip.ErrInvalidEndpointState{})
-				}
-			}
-			if n := ep1.Drain(); n != 0 {
-				t.Errorf("got %d unexpected packets from ep1", n)
-			}
-			if n := ep2.Drain(); n != 0 {
-				t.Errorf("got %d unexpected packets from ep2", n)
-			}
-		})
-	}
-}
-
-func TestWritePacketToRemote(t *testing.T) {
-	const nicID = 1
-	const MTU = 1280
-	e := channel.New(1, MTU, linkAddr1)
-	s := stack.New(stack.Options{})
-	if err := s.CreateNIC(nicID, e); err != nil {
-		t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
-	}
-	if err := s.EnableNIC(nicID); err != nil {
-		t.Fatalf("CreateNIC(%d) = %s", nicID, err)
-	}
-	tests := []struct {
-		name     string
-		protocol tcpip.NetworkProtocolNumber
-		payload  []byte
-	}{
-		{
-			name:     "SuccessIPv4",
-			protocol: header.IPv4ProtocolNumber,
-			payload:  []byte{1, 2, 3, 4},
-		},
-		{
-			name:     "SuccessIPv6",
-			protocol: header.IPv6ProtocolNumber,
-			payload:  []byte{5, 6, 7, 8},
-		},
-	}
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			if err := s.WritePacketToRemote(nicID, linkAddr2, test.protocol, buffer.View(test.payload).ToVectorisedView()); err != nil {
-				t.Fatalf("s.WritePacketToRemote(_, _, _, _) = %s", err)
-			}
-
-			pkt, ok := e.Read()
-			if got, want := ok, true; got != want {
-				t.Fatalf("e.Read() = %t, want %t", got, want)
-			}
-			if got, want := pkt.Proto, test.protocol; got != want {
-				t.Fatalf("pkt.Proto = %d, want %d", got, want)
-			}
-			if pkt.Route.RemoteLinkAddress != linkAddr2 {
-				t.Fatalf("pkt.Route.RemoteAddress = %s, want %s", pkt.Route.RemoteLinkAddress, linkAddr2)
-			}
-			if diff := cmp.Diff(pkt.Pkt.Data().AsRange().ToOwnedView(), buffer.View(test.payload)); diff != "" {
-				t.Errorf("pkt.Pkt.Data mismatch (-want +got):\n%s", diff)
-			}
-		})
-	}
-
-	t.Run("InvalidNICID", func(t *testing.T) {
-		err := s.WritePacketToRemote(234, linkAddr2, header.IPv4ProtocolNumber, buffer.View([]byte{1}).ToVectorisedView())
-		if _, ok := err.(*tcpip.ErrUnknownDevice); !ok {
-			t.Fatalf("s.WritePacketToRemote(_, _, _, _) = %s, want = %s", err, &tcpip.ErrUnknownDevice{})
-		}
-		pkt, ok := e.Read()
-		if got, want := ok, false; got != want {
-			t.Fatalf("e.Read() = %t, %v; want %t", got, pkt, want)
-		}
-	})
-}
-
-func TestClearNeighborCacheOnNICDisable(t *testing.T) {
-	const (
-		nicID = 1
-
-		ipv4Addr = tcpip.Address("\x01\x02\x03\x04")
-		ipv6Addr = tcpip.Address("\x01\x02\x03\x04\x01\x02\x03\x04\x01\x02\x03\x04\x01\x02\x03\x04")
-		linkAddr = tcpip.LinkAddress("\x02\x02\x03\x04\x05\x06")
-	)
-
-	clock := faketime.NewManualClock()
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocolFactory{arp.NewProtocol, ipv4.NewProtocol, ipv6.NewProtocol},
-		Clock:            clock,
-	})
-	e := channel.New(0, 0, "")
-	e.LinkEPCapabilities |= stack.CapabilityResolutionRequired
-	if err := s.CreateNIC(nicID, e); err != nil {
-		t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
-	}
-
-	addrs := []struct {
-		proto tcpip.NetworkProtocolNumber
-		addr  tcpip.Address
-	}{
-		{
-			proto: ipv4.ProtocolNumber,
-			addr:  ipv4Addr,
-		},
-		{
-			proto: ipv6.ProtocolNumber,
-			addr:  ipv6Addr,
-		},
-	}
-	for _, addr := range addrs {
-		if err := s.AddStaticNeighbor(nicID, addr.proto, addr.addr, linkAddr); err != nil {
-			t.Fatalf("s.AddStaticNeighbor(%d, %d, %s, %s): %s", nicID, addr.proto, addr.addr, linkAddr, err)
-		}
-
-		if neighbors, err := s.Neighbors(nicID, addr.proto); err != nil {
-			t.Fatalf("s.Neighbors(%d, %d): %s", nicID, addr.proto, err)
-		} else if diff := cmp.Diff(
-			[]stack.NeighborEntry{{Addr: addr.addr, LinkAddr: linkAddr, State: stack.Static, UpdatedAtNanos: clock.NowNanoseconds()}},
-			neighbors,
-		); diff != "" {
-			t.Fatalf("proto=%d neighbors mismatch (-want +got):\n%s", addr.proto, diff)
-		}
-	}
-
-	// Disabling the NIC should clear the neighbor table.
-	if err := s.DisableNIC(nicID); err != nil {
-		t.Fatalf("s.DisableNIC(%d): %s", nicID, err)
-	}
-	for _, addr := range addrs {
-		if neighbors, err := s.Neighbors(nicID, addr.proto); err != nil {
-			t.Fatalf("s.Neighbors(%d, %d): %s", nicID, addr.proto, err)
-		} else if len(neighbors) != 0 {
-			t.Fatalf("got proto=%d len(neighbors) = %d, want = 0; neighbors = %#v", addr.proto, len(neighbors), neighbors)
-		}
-	}
-
-	// Enabling the NIC should have an empty neighbor table.
-	if err := s.EnableNIC(nicID); err != nil {
-		t.Fatalf("s.EnableNIC(%d): %s", nicID, err)
-	}
-	for _, addr := range addrs {
-		if neighbors, err := s.Neighbors(nicID, addr.proto); err != nil {
-			t.Fatalf("s.Neighbors(%d, %d): %s", nicID, addr.proto, err)
-		} else if len(neighbors) != 0 {
-			t.Fatalf("got proto=%d len(neighbors) = %d, want = 0; neighbors = %#v", addr.proto, len(neighbors), neighbors)
-		}
-	}
-}
-
-func TestGetLinkAddressErrors(t *testing.T) {
-	const (
-		nicID        = 1
-		unknownNICID = nicID + 1
-	)
-
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol},
-	})
-	if err := s.CreateNIC(nicID, channel.New(0, 0, "")); err != nil {
-		t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
-	}
-
-	{
-		err := s.GetLinkAddress(unknownNICID, "", "", ipv4.ProtocolNumber, nil)
-		if _, ok := err.(*tcpip.ErrUnknownNICID); !ok {
-			t.Errorf("got s.GetLinkAddress(%d, '', '', %d, nil) = %s, want = %s", unknownNICID, ipv4.ProtocolNumber, err, &tcpip.ErrUnknownNICID{})
-		}
-	}
-	{
-		err := s.GetLinkAddress(nicID, "", "", ipv4.ProtocolNumber, nil)
-		if _, ok := err.(*tcpip.ErrNotSupported); !ok {
-			t.Errorf("got s.GetLinkAddress(%d, '', '', %d, nil) = %s, want = %s", unknownNICID, ipv4.ProtocolNumber, err, &tcpip.ErrNotSupported{})
-		}
-	}
-}
-
-func TestStaticGetLinkAddress(t *testing.T) {
-	const (
-		nicID = 1
-	)
-
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocolFactory{arp.NewProtocol, ipv4.NewProtocol, ipv6.NewProtocol},
-	})
-	e := channel.New(0, 0, "")
-	e.LinkEPCapabilities |= stack.CapabilityResolutionRequired
-	if err := s.CreateNIC(nicID, e); err != nil {
-		t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
-	}
-
-	tests := []struct {
-		name             string
-		proto            tcpip.NetworkProtocolNumber
-		addr             tcpip.Address
-		expectedLinkAddr tcpip.LinkAddress
-	}{
-		{
-			name:             "IPv4",
-			proto:            ipv4.ProtocolNumber,
-			addr:             header.IPv4Broadcast,
-			expectedLinkAddr: header.EthernetBroadcastAddress,
-		},
-		{
-			name:             "IPv6",
-			proto:            ipv6.ProtocolNumber,
-			addr:             header.IPv6AllNodesMulticastAddress,
-			expectedLinkAddr: header.EthernetAddressFromMulticastIPv6Address(header.IPv6AllNodesMulticastAddress),
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			ch := make(chan stack.LinkResolutionResult, 1)
-			if err := s.GetLinkAddress(nicID, test.addr, "", test.proto, func(r stack.LinkResolutionResult) {
-				ch <- r
-			}); err != nil {
-				t.Fatalf("s.GetLinkAddress(%d, %s, '', %d, _): %s", nicID, test.addr, test.proto, err)
-			}
-
-			if diff := cmp.Diff(stack.LinkResolutionResult{LinkAddress: test.expectedLinkAddr, Err: nil}, <-ch); diff != "" {
-				t.Fatalf("link resolution result mismatch (-want +got):\n%s", diff)
-			}
-		})
-	}
-}
diff --git a/pkg/tcpip/stack/stack_unsafe_state_autogen.go b/pkg/tcpip/stack/stack_unsafe_state_autogen.go
new file mode 100644
index 0000000..758ab34
--- /dev/null
+++ b/pkg/tcpip/stack/stack_unsafe_state_autogen.go
@@ -0,0 +1,3 @@
+// automatically generated by stateify.
+
+package stack
diff --git a/pkg/tcpip/stack/transport_demuxer_test.go b/pkg/tcpip/stack/transport_demuxer_test.go
deleted file mode 100644
index c1c6cbc..0000000
--- a/pkg/tcpip/stack/transport_demuxer_test.go
+++ /dev/null
@@ -1,385 +0,0 @@
-// 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 stack_test
-
-import (
-	"io/ioutil"
-	"math"
-	"math/rand"
-	"testing"
-
-	"gvisor.dev/gvisor/pkg/tcpip"
-	"gvisor.dev/gvisor/pkg/tcpip/buffer"
-	"gvisor.dev/gvisor/pkg/tcpip/header"
-	"gvisor.dev/gvisor/pkg/tcpip/link/channel"
-	"gvisor.dev/gvisor/pkg/tcpip/network/ipv4"
-	"gvisor.dev/gvisor/pkg/tcpip/network/ipv6"
-	"gvisor.dev/gvisor/pkg/tcpip/ports"
-	"gvisor.dev/gvisor/pkg/tcpip/stack"
-	"gvisor.dev/gvisor/pkg/tcpip/transport/udp"
-	"gvisor.dev/gvisor/pkg/waiter"
-)
-
-const (
-	testSrcAddrV6 = "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"
-	testDstAddrV6 = "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02"
-
-	testSrcAddrV4 = "\x0a\x00\x00\x01"
-	testDstAddrV4 = "\x0a\x00\x00\x02"
-
-	testDstPort = 1234
-	testSrcPort = 4096
-)
-
-type testContext struct {
-	linkEps map[tcpip.NICID]*channel.Endpoint
-	s       *stack.Stack
-	wq      waiter.Queue
-}
-
-// newDualTestContextMultiNIC creates the testing context and also linkEpIDs NICs.
-func newDualTestContextMultiNIC(t *testing.T, mtu uint32, linkEpIDs []tcpip.NICID) *testContext {
-	s := stack.New(stack.Options{
-		NetworkProtocols:   []stack.NetworkProtocolFactory{ipv4.NewProtocol, ipv6.NewProtocol},
-		TransportProtocols: []stack.TransportProtocolFactory{udp.NewProtocol},
-	})
-	linkEps := make(map[tcpip.NICID]*channel.Endpoint)
-	for _, linkEpID := range linkEpIDs {
-		channelEp := channel.New(256, mtu, "")
-		if err := s.CreateNIC(linkEpID, channelEp); err != nil {
-			t.Fatalf("CreateNIC failed: %s", err)
-		}
-		linkEps[linkEpID] = channelEp
-
-		if err := s.AddAddress(linkEpID, ipv4.ProtocolNumber, testDstAddrV4); err != nil {
-			t.Fatalf("AddAddress IPv4 failed: %s", err)
-		}
-
-		if err := s.AddAddress(linkEpID, ipv6.ProtocolNumber, testDstAddrV6); err != nil {
-			t.Fatalf("AddAddress IPv6 failed: %s", err)
-		}
-	}
-
-	s.SetRouteTable([]tcpip.Route{
-		{Destination: header.IPv4EmptySubnet, NIC: 1},
-		{Destination: header.IPv6EmptySubnet, NIC: 1},
-	})
-
-	return &testContext{
-		s:       s,
-		linkEps: linkEps,
-	}
-}
-
-type headers struct {
-	srcPort, dstPort uint16
-}
-
-func newPayload() []byte {
-	b := make([]byte, 30+rand.Intn(100))
-	for i := range b {
-		b[i] = byte(rand.Intn(256))
-	}
-	return b
-}
-
-func (c *testContext) sendV4Packet(payload []byte, h *headers, linkEpID tcpip.NICID) {
-	buf := buffer.NewView(header.UDPMinimumSize + header.IPv4MinimumSize + len(payload))
-	payloadStart := len(buf) - len(payload)
-	copy(buf[payloadStart:], payload)
-
-	// Initialize the IP header.
-	ip := header.IPv4(buf)
-	ip.Encode(&header.IPv4Fields{
-		TOS:         0x80,
-		TotalLength: uint16(len(buf)),
-		TTL:         65,
-		Protocol:    uint8(udp.ProtocolNumber),
-		SrcAddr:     testSrcAddrV4,
-		DstAddr:     testDstAddrV4,
-	})
-	ip.SetChecksum(^ip.CalculateChecksum())
-
-	// Initialize the UDP header.
-	u := header.UDP(buf[header.IPv4MinimumSize:])
-	u.Encode(&header.UDPFields{
-		SrcPort: h.srcPort,
-		DstPort: h.dstPort,
-		Length:  uint16(header.UDPMinimumSize + len(payload)),
-	})
-
-	// Calculate the UDP pseudo-header checksum.
-	xsum := header.PseudoHeaderChecksum(udp.ProtocolNumber, testSrcAddrV4, testDstAddrV4, uint16(len(u)))
-
-	// Calculate the UDP checksum and set it.
-	xsum = header.Checksum(payload, xsum)
-	u.SetChecksum(^u.CalculateChecksum(xsum))
-
-	// Inject packet.
-	pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{
-		Data: buf.ToVectorisedView(),
-	})
-	c.linkEps[linkEpID].InjectInbound(ipv4.ProtocolNumber, pkt)
-}
-
-func (c *testContext) sendV6Packet(payload []byte, h *headers, linkEpID tcpip.NICID) {
-	// Allocate a buffer for data and headers.
-	buf := buffer.NewView(header.UDPMinimumSize + header.IPv6MinimumSize + len(payload))
-	copy(buf[len(buf)-len(payload):], payload)
-
-	// Initialize the IP header.
-	ip := header.IPv6(buf)
-	ip.Encode(&header.IPv6Fields{
-		PayloadLength:     uint16(header.UDPMinimumSize + len(payload)),
-		TransportProtocol: udp.ProtocolNumber,
-		HopLimit:          65,
-		SrcAddr:           testSrcAddrV6,
-		DstAddr:           testDstAddrV6,
-	})
-
-	// Initialize the UDP header.
-	u := header.UDP(buf[header.IPv6MinimumSize:])
-	u.Encode(&header.UDPFields{
-		SrcPort: h.srcPort,
-		DstPort: h.dstPort,
-		Length:  uint16(header.UDPMinimumSize + len(payload)),
-	})
-
-	// Calculate the UDP pseudo-header checksum.
-	xsum := header.PseudoHeaderChecksum(udp.ProtocolNumber, testSrcAddrV6, testDstAddrV6, uint16(len(u)))
-
-	// Calculate the UDP checksum and set it.
-	xsum = header.Checksum(payload, xsum)
-	u.SetChecksum(^u.CalculateChecksum(xsum))
-
-	// Inject packet.
-	pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{
-		Data: buf.ToVectorisedView(),
-	})
-	c.linkEps[linkEpID].InjectInbound(ipv6.ProtocolNumber, pkt)
-}
-
-func TestTransportDemuxerRegister(t *testing.T) {
-	for _, test := range []struct {
-		name  string
-		proto tcpip.NetworkProtocolNumber
-		want  tcpip.Error
-	}{
-		{"failure", ipv6.ProtocolNumber, &tcpip.ErrUnknownProtocol{}},
-		{"success", ipv4.ProtocolNumber, nil},
-	} {
-		t.Run(test.name, func(t *testing.T) {
-			s := stack.New(stack.Options{
-				NetworkProtocols:   []stack.NetworkProtocolFactory{ipv4.NewProtocol},
-				TransportProtocols: []stack.TransportProtocolFactory{udp.NewProtocol},
-			})
-			var wq waiter.Queue
-			ep, err := s.NewEndpoint(udp.ProtocolNumber, ipv4.ProtocolNumber, &wq)
-			if err != nil {
-				t.Fatal(err)
-			}
-			tEP, ok := ep.(stack.TransportEndpoint)
-			if !ok {
-				t.Fatalf("%T does not implement stack.TransportEndpoint", ep)
-			}
-			if got, want := s.RegisterTransportEndpoint([]tcpip.NetworkProtocolNumber{test.proto}, udp.ProtocolNumber, stack.TransportEndpointID{}, tEP, ports.Flags{}, 0), test.want; got != want {
-				t.Fatalf("s.RegisterTransportEndpoint(...) = %s, want %s", got, want)
-			}
-		})
-	}
-}
-
-// TestBindToDeviceDistribution injects varied packets on input devices and checks that
-// the distribution of packets received matches expectations.
-func TestBindToDeviceDistribution(t *testing.T) {
-	type endpointSockopts struct {
-		reuse        bool
-		bindToDevice tcpip.NICID
-	}
-	for _, test := range []struct {
-		name string
-		// endpoints will received the inject packets.
-		endpoints []endpointSockopts
-		// wantDistributions is the want ratio of packets received on each
-		// endpoint for each NIC on which packets are injected.
-		wantDistributions map[tcpip.NICID][]float64
-	}{
-		{
-			"BindPortReuse",
-			// 5 endpoints that all have reuse set.
-			[]endpointSockopts{
-				{reuse: true, bindToDevice: 0},
-				{reuse: true, bindToDevice: 0},
-				{reuse: true, bindToDevice: 0},
-				{reuse: true, bindToDevice: 0},
-				{reuse: true, bindToDevice: 0},
-			},
-			map[tcpip.NICID][]float64{
-				// Injected packets on dev0 get distributed evenly.
-				1: {0.2, 0.2, 0.2, 0.2, 0.2},
-			},
-		},
-		{
-			"BindToDevice",
-			// 3 endpoints with various bindings.
-			[]endpointSockopts{
-				{reuse: false, bindToDevice: 1},
-				{reuse: false, bindToDevice: 2},
-				{reuse: false, bindToDevice: 3},
-			},
-			map[tcpip.NICID][]float64{
-				// Injected packets on dev0 go only to the endpoint bound to dev0.
-				1: {1, 0, 0},
-				// Injected packets on dev1 go only to the endpoint bound to dev1.
-				2: {0, 1, 0},
-				// Injected packets on dev2 go only to the endpoint bound to dev2.
-				3: {0, 0, 1},
-			},
-		},
-		{
-			"ReuseAndBindToDevice",
-			// 6 endpoints with various bindings.
-			[]endpointSockopts{
-				{reuse: true, bindToDevice: 1},
-				{reuse: true, bindToDevice: 1},
-				{reuse: true, bindToDevice: 2},
-				{reuse: true, bindToDevice: 2},
-				{reuse: true, bindToDevice: 2},
-				{reuse: true, bindToDevice: 0},
-			},
-			map[tcpip.NICID][]float64{
-				// Injected packets on dev0 get distributed among endpoints bound to
-				// dev0.
-				1: {0.5, 0.5, 0, 0, 0, 0},
-				// Injected packets on dev1 get distributed among endpoints bound to
-				// dev1 or unbound.
-				2: {0, 0, 1. / 3, 1. / 3, 1. / 3, 0},
-				// Injected packets on dev999 go only to the unbound.
-				1000: {0, 0, 0, 0, 0, 1},
-			},
-		},
-	} {
-		for protoName, netProtoNum := range map[string]tcpip.NetworkProtocolNumber{
-			"IPv4": ipv4.ProtocolNumber,
-			"IPv6": ipv6.ProtocolNumber,
-		} {
-			for device, wantDistribution := range test.wantDistributions {
-				t.Run(test.name+protoName+string(device), func(t *testing.T) {
-					var devices []tcpip.NICID
-					for d := range test.wantDistributions {
-						devices = append(devices, d)
-					}
-					c := newDualTestContextMultiNIC(t, defaultMTU, devices)
-
-					eps := make(map[tcpip.Endpoint]int)
-
-					pollChannel := make(chan tcpip.Endpoint)
-					for i, endpoint := range test.endpoints {
-						// Try to receive the data.
-						wq := waiter.Queue{}
-						we, ch := waiter.NewChannelEntry(nil)
-						wq.EventRegister(&we, waiter.EventIn)
-						defer wq.EventUnregister(&we)
-						defer close(ch)
-
-						var err tcpip.Error
-						ep, err := c.s.NewEndpoint(udp.ProtocolNumber, netProtoNum, &wq)
-						if err != nil {
-							t.Fatalf("NewEndpoint failed: %s", err)
-						}
-						eps[ep] = i
-
-						go func(ep tcpip.Endpoint) {
-							for range ch {
-								pollChannel <- ep
-							}
-						}(ep)
-
-						defer ep.Close()
-						ep.SocketOptions().SetReusePort(endpoint.reuse)
-						if err := ep.SocketOptions().SetBindToDevice(int32(endpoint.bindToDevice)); err != nil {
-							t.Fatalf("SetSockOpt(&%T(%d)) on endpoint %d failed: %s", endpoint.bindToDevice, endpoint.bindToDevice, i, err)
-						}
-
-						var dstAddr tcpip.Address
-						switch netProtoNum {
-						case ipv4.ProtocolNumber:
-							dstAddr = testDstAddrV4
-						case ipv6.ProtocolNumber:
-							dstAddr = testDstAddrV6
-						default:
-							t.Fatalf("unexpected protocol number: %d", netProtoNum)
-						}
-						if err := ep.Bind(tcpip.FullAddress{Addr: dstAddr, Port: testDstPort}); err != nil {
-							t.Fatalf("ep.Bind(...) on endpoint %d failed: %s", i, err)
-						}
-					}
-
-					npackets := 100000
-					nports := 10000
-					if got, want := len(test.endpoints), len(wantDistribution); got != want {
-						t.Fatalf("got len(test.endpoints) = %d, want %d", got, want)
-					}
-					ports := make(map[uint16]tcpip.Endpoint)
-					stats := make(map[tcpip.Endpoint]int)
-					for i := 0; i < npackets; i++ {
-						// Send a packet.
-						port := uint16(i % nports)
-						payload := newPayload()
-						hdrs := &headers{
-							srcPort: testSrcPort + port,
-							dstPort: testDstPort,
-						}
-						switch netProtoNum {
-						case ipv4.ProtocolNumber:
-							c.sendV4Packet(payload, hdrs, device)
-						case ipv6.ProtocolNumber:
-							c.sendV6Packet(payload, hdrs, device)
-						default:
-							t.Fatalf("unexpected protocol number: %d", netProtoNum)
-						}
-
-						ep := <-pollChannel
-						if _, err := ep.Read(ioutil.Discard, tcpip.ReadOptions{}); err != nil {
-							t.Fatalf("Read on endpoint %d failed: %s", eps[ep], err)
-						}
-						stats[ep]++
-						if i < nports {
-							ports[uint16(i)] = ep
-						} else {
-							// Check that all packets from one client are handled by the same
-							// socket.
-							if want, got := ports[port], ep; want != got {
-								t.Fatalf("Packet sent on port %d expected on endpoint %d but received on endpoint %d", port, eps[want], eps[got])
-							}
-						}
-					}
-
-					// Check that a packet distribution is as expected.
-					for ep, i := range eps {
-						wantRatio := wantDistribution[i]
-						wantRecv := wantRatio * float64(npackets)
-						actualRecv := stats[ep]
-						actualRatio := float64(stats[ep]) / float64(npackets)
-						// The deviation is less than 10%.
-						if math.Abs(actualRatio-wantRatio) > 0.05 {
-							t.Errorf("want about %.0f%% (%.0f of %d) packets to arrive on endpoint %d, got %.0f%% (%d of %d)", wantRatio*100, wantRecv, npackets, i, actualRatio*100, actualRecv, npackets)
-						}
-					}
-				})
-			}
-		}
-	}
-}
diff --git a/pkg/tcpip/stack/transport_test.go b/pkg/tcpip/stack/transport_test.go
deleted file mode 100644
index bebf4e6..0000000
--- a/pkg/tcpip/stack/transport_test.go
+++ /dev/null
@@ -1,555 +0,0 @@
-// 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 stack_test
-
-import (
-	"bytes"
-	"io"
-	"testing"
-
-	"gvisor.dev/gvisor/pkg/tcpip"
-	"gvisor.dev/gvisor/pkg/tcpip/buffer"
-	"gvisor.dev/gvisor/pkg/tcpip/link/channel"
-	"gvisor.dev/gvisor/pkg/tcpip/ports"
-	"gvisor.dev/gvisor/pkg/tcpip/stack"
-	"gvisor.dev/gvisor/pkg/waiter"
-)
-
-const (
-	fakeTransNumber    tcpip.TransportProtocolNumber = 1
-	fakeTransHeaderLen int                           = 3
-)
-
-// fakeTransportEndpoint is a transport-layer protocol endpoint. It counts
-// received packets; the counts of all endpoints are aggregated in the protocol
-// descriptor.
-//
-// Headers of this protocol are fakeTransHeaderLen bytes, but we currently don't
-// use it.
-type fakeTransportEndpoint struct {
-	stack.TransportEndpointInfo
-	tcpip.DefaultSocketOptionsHandler
-
-	proto    *fakeTransportProtocol
-	peerAddr tcpip.Address
-	route    *stack.Route
-	uniqueID uint64
-
-	// acceptQueue is non-nil iff bound.
-	acceptQueue []*fakeTransportEndpoint
-
-	// ops is used to set and get socket options.
-	ops tcpip.SocketOptions
-}
-
-func (f *fakeTransportEndpoint) Info() tcpip.EndpointInfo {
-	return &f.TransportEndpointInfo
-}
-
-func (*fakeTransportEndpoint) Stats() tcpip.EndpointStats {
-	return nil
-}
-
-func (*fakeTransportEndpoint) SetOwner(owner tcpip.PacketOwner) {}
-
-func (f *fakeTransportEndpoint) SocketOptions() *tcpip.SocketOptions {
-	return &f.ops
-}
-
-func newFakeTransportEndpoint(proto *fakeTransportProtocol, netProto tcpip.NetworkProtocolNumber, s *stack.Stack) tcpip.Endpoint {
-	ep := &fakeTransportEndpoint{TransportEndpointInfo: stack.TransportEndpointInfo{NetProto: netProto}, proto: proto, uniqueID: s.UniqueID()}
-	ep.ops.InitHandler(ep, s, tcpip.GetStackSendBufferLimits)
-	return ep
-}
-
-func (f *fakeTransportEndpoint) Abort() {
-	f.Close()
-}
-
-func (f *fakeTransportEndpoint) Close() {
-	// TODO(gvisor.dev/issue/5153): Consider retaining the route.
-	f.route.Release()
-}
-
-func (*fakeTransportEndpoint) Readiness(mask waiter.EventMask) waiter.EventMask {
-	return mask
-}
-
-func (*fakeTransportEndpoint) Read(io.Writer, tcpip.ReadOptions) (tcpip.ReadResult, tcpip.Error) {
-	return tcpip.ReadResult{}, nil
-}
-
-func (f *fakeTransportEndpoint) Write(p tcpip.Payloader, opts tcpip.WriteOptions) (int64, tcpip.Error) {
-	if len(f.route.RemoteAddress) == 0 {
-		return 0, &tcpip.ErrNoRoute{}
-	}
-
-	v := make([]byte, p.Len())
-	if _, err := io.ReadFull(p, v); err != nil {
-		return 0, &tcpip.ErrBadBuffer{}
-	}
-
-	pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{
-		ReserveHeaderBytes: int(f.route.MaxHeaderLength()) + fakeTransHeaderLen,
-		Data:               buffer.View(v).ToVectorisedView(),
-	})
-	_ = pkt.TransportHeader().Push(fakeTransHeaderLen)
-	if err := f.route.WritePacket(nil /* gso */, stack.NetworkHeaderParams{Protocol: fakeTransNumber, TTL: 123, TOS: stack.DefaultTOS}, pkt); err != nil {
-		return 0, err
-	}
-
-	return int64(len(v)), nil
-}
-
-// SetSockOpt sets a socket option. Currently not supported.
-func (*fakeTransportEndpoint) SetSockOpt(tcpip.SettableSocketOption) tcpip.Error {
-	return &tcpip.ErrInvalidEndpointState{}
-}
-
-// SetSockOptInt sets a socket option. Currently not supported.
-func (*fakeTransportEndpoint) SetSockOptInt(tcpip.SockOptInt, int) tcpip.Error {
-	return &tcpip.ErrInvalidEndpointState{}
-}
-
-// GetSockOptInt implements tcpip.Endpoint.GetSockOptInt.
-func (*fakeTransportEndpoint) GetSockOptInt(opt tcpip.SockOptInt) (int, tcpip.Error) {
-	return -1, &tcpip.ErrUnknownProtocolOption{}
-}
-
-// GetSockOpt implements tcpip.Endpoint.GetSockOpt.
-func (*fakeTransportEndpoint) GetSockOpt(tcpip.GettableSocketOption) tcpip.Error {
-	return &tcpip.ErrInvalidEndpointState{}
-}
-
-// Disconnect implements tcpip.Endpoint.Disconnect.
-func (*fakeTransportEndpoint) Disconnect() tcpip.Error {
-	return &tcpip.ErrNotSupported{}
-}
-
-func (f *fakeTransportEndpoint) Connect(addr tcpip.FullAddress) tcpip.Error {
-	f.peerAddr = addr.Addr
-
-	// Find the route.
-	r, err := f.proto.stack.FindRoute(addr.NIC, "", addr.Addr, fakeNetNumber, false /* multicastLoop */)
-	if err != nil {
-		return &tcpip.ErrNoRoute{}
-	}
-
-	// Try to register so that we can start receiving packets.
-	f.ID.RemoteAddress = addr.Addr
-	err = f.proto.stack.RegisterTransportEndpoint([]tcpip.NetworkProtocolNumber{fakeNetNumber}, fakeTransNumber, f.ID, f, ports.Flags{}, 0 /* bindToDevice */)
-	if err != nil {
-		r.Release()
-		return err
-	}
-
-	f.route = r
-
-	return nil
-}
-
-func (f *fakeTransportEndpoint) UniqueID() uint64 {
-	return f.uniqueID
-}
-
-func (*fakeTransportEndpoint) ConnectEndpoint(e tcpip.Endpoint) tcpip.Error {
-	return nil
-}
-
-func (*fakeTransportEndpoint) Shutdown(tcpip.ShutdownFlags) tcpip.Error {
-	return nil
-}
-
-func (*fakeTransportEndpoint) Reset() {
-}
-
-func (*fakeTransportEndpoint) Listen(int) tcpip.Error {
-	return nil
-}
-
-func (f *fakeTransportEndpoint) Accept(*tcpip.FullAddress) (tcpip.Endpoint, *waiter.Queue, tcpip.Error) {
-	if len(f.acceptQueue) == 0 {
-		return nil, nil, nil
-	}
-	a := f.acceptQueue[0]
-	f.acceptQueue = f.acceptQueue[1:]
-	return a, nil, nil
-}
-
-func (f *fakeTransportEndpoint) Bind(a tcpip.FullAddress) tcpip.Error {
-	if err := f.proto.stack.RegisterTransportEndpoint(
-		[]tcpip.NetworkProtocolNumber{fakeNetNumber},
-		fakeTransNumber,
-		stack.TransportEndpointID{LocalAddress: a.Addr},
-		f,
-		ports.Flags{},
-		0, /* bindtoDevice */
-	); err != nil {
-		return err
-	}
-	f.acceptQueue = []*fakeTransportEndpoint{}
-	return nil
-}
-
-func (*fakeTransportEndpoint) GetLocalAddress() (tcpip.FullAddress, tcpip.Error) {
-	return tcpip.FullAddress{}, nil
-}
-
-func (*fakeTransportEndpoint) GetRemoteAddress() (tcpip.FullAddress, tcpip.Error) {
-	return tcpip.FullAddress{}, nil
-}
-
-func (f *fakeTransportEndpoint) HandlePacket(id stack.TransportEndpointID, pkt *stack.PacketBuffer) {
-	// Increment the number of received packets.
-	f.proto.packetCount++
-	if f.acceptQueue == nil {
-		return
-	}
-
-	netHdr := pkt.NetworkHeader().View()
-	route, err := f.proto.stack.FindRoute(pkt.NICID, tcpip.Address(netHdr[dstAddrOffset]), tcpip.Address(netHdr[srcAddrOffset]), pkt.NetworkProtocolNumber, false /* multicastLoop */)
-	if err != nil {
-		return
-	}
-
-	ep := &fakeTransportEndpoint{
-		TransportEndpointInfo: stack.TransportEndpointInfo{
-			ID:       f.ID,
-			NetProto: f.NetProto,
-		},
-		proto:    f.proto,
-		peerAddr: route.RemoteAddress,
-		route:    route,
-	}
-	ep.ops.InitHandler(ep, f.proto.stack, tcpip.GetStackSendBufferLimits)
-	f.acceptQueue = append(f.acceptQueue, ep)
-}
-
-func (f *fakeTransportEndpoint) HandleError(stack.TransportError, *stack.PacketBuffer) {
-	// Increment the number of received control packets.
-	f.proto.controlCount++
-}
-
-func (*fakeTransportEndpoint) State() uint32 {
-	return 0
-}
-
-func (*fakeTransportEndpoint) ModerateRecvBuf(copied int) {}
-
-func (*fakeTransportEndpoint) Resume(*stack.Stack) {}
-
-func (*fakeTransportEndpoint) Wait() {}
-
-func (*fakeTransportEndpoint) LastError() tcpip.Error {
-	return nil
-}
-
-type fakeTransportGoodOption bool
-
-type fakeTransportBadOption bool
-
-type fakeTransportInvalidValueOption int
-
-type fakeTransportProtocolOptions struct {
-	good bool
-}
-
-// fakeTransportProtocol is a transport-layer protocol descriptor. It
-// aggregates the number of packets received via endpoints of this protocol.
-type fakeTransportProtocol struct {
-	stack *stack.Stack
-
-	packetCount  int
-	controlCount int
-	opts         fakeTransportProtocolOptions
-}
-
-func (*fakeTransportProtocol) Number() tcpip.TransportProtocolNumber {
-	return fakeTransNumber
-}
-
-func (f *fakeTransportProtocol) NewEndpoint(netProto tcpip.NetworkProtocolNumber, _ *waiter.Queue) (tcpip.Endpoint, tcpip.Error) {
-	return newFakeTransportEndpoint(f, netProto, f.stack), nil
-}
-
-func (*fakeTransportProtocol) NewRawEndpoint(tcpip.NetworkProtocolNumber, *waiter.Queue) (tcpip.Endpoint, tcpip.Error) {
-	return nil, &tcpip.ErrUnknownProtocol{}
-}
-
-func (*fakeTransportProtocol) MinimumPacketSize() int {
-	return fakeTransHeaderLen
-}
-
-func (*fakeTransportProtocol) ParsePorts(buffer.View) (src, dst uint16, err tcpip.Error) {
-	return 0, 0, nil
-}
-
-func (*fakeTransportProtocol) HandleUnknownDestinationPacket(stack.TransportEndpointID, *stack.PacketBuffer) stack.UnknownDestinationPacketDisposition {
-	return stack.UnknownDestinationPacketHandled
-}
-
-func (f *fakeTransportProtocol) SetOption(option tcpip.SettableTransportProtocolOption) tcpip.Error {
-	switch v := option.(type) {
-	case *tcpip.TCPModerateReceiveBufferOption:
-		f.opts.good = bool(*v)
-		return nil
-	default:
-		return &tcpip.ErrUnknownProtocolOption{}
-	}
-}
-
-func (f *fakeTransportProtocol) Option(option tcpip.GettableTransportProtocolOption) tcpip.Error {
-	switch v := option.(type) {
-	case *tcpip.TCPModerateReceiveBufferOption:
-		*v = tcpip.TCPModerateReceiveBufferOption(f.opts.good)
-		return nil
-	default:
-		return &tcpip.ErrUnknownProtocolOption{}
-	}
-}
-
-// Abort implements TransportProtocol.Abort.
-func (*fakeTransportProtocol) Abort() {}
-
-// Close implements tcpip.Endpoint.Close.
-func (*fakeTransportProtocol) Close() {}
-
-// Wait implements TransportProtocol.Wait.
-func (*fakeTransportProtocol) Wait() {}
-
-// Parse implements TransportProtocol.Parse.
-func (*fakeTransportProtocol) Parse(pkt *stack.PacketBuffer) bool {
-	_, ok := pkt.TransportHeader().Consume(fakeTransHeaderLen)
-	return ok
-}
-
-func fakeTransFactory(s *stack.Stack) stack.TransportProtocol {
-	return &fakeTransportProtocol{stack: s}
-}
-
-func TestTransportReceive(t *testing.T) {
-	linkEP := channel.New(10, defaultMTU, "")
-	s := stack.New(stack.Options{
-		NetworkProtocols:   []stack.NetworkProtocolFactory{fakeNetFactory},
-		TransportProtocols: []stack.TransportProtocolFactory{fakeTransFactory},
-	})
-	if err := s.CreateNIC(1, linkEP); err != nil {
-		t.Fatalf("CreateNIC failed: %v", err)
-	}
-
-	{
-		subnet, err := tcpip.NewSubnet("\x00", "\x00")
-		if err != nil {
-			t.Fatal(err)
-		}
-		s.SetRouteTable([]tcpip.Route{{Destination: subnet, Gateway: "\x00", NIC: 1}})
-	}
-
-	if err := s.AddAddress(1, fakeNetNumber, "\x01"); err != nil {
-		t.Fatalf("AddAddress failed: %v", err)
-	}
-
-	// Create endpoint and connect to remote address.
-	wq := waiter.Queue{}
-	ep, err := s.NewEndpoint(fakeTransNumber, fakeNetNumber, &wq)
-	if err != nil {
-		t.Fatalf("NewEndpoint failed: %v", err)
-	}
-
-	if err := ep.Connect(tcpip.FullAddress{0, "\x02", 0}); err != nil {
-		t.Fatalf("Connect failed: %v", err)
-	}
-
-	fakeTrans := s.TransportProtocolInstance(fakeTransNumber).(*fakeTransportProtocol)
-
-	// Create buffer that will hold the packet.
-	buf := buffer.NewView(30)
-
-	// Make sure packet with wrong protocol is not delivered.
-	buf[0] = 1
-	buf[2] = 0
-	linkEP.InjectInbound(fakeNetNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
-		Data: buf.ToVectorisedView(),
-	}))
-	if fakeTrans.packetCount != 0 {
-		t.Errorf("packetCount = %d, want %d", fakeTrans.packetCount, 0)
-	}
-
-	// Make sure packet from the wrong source is not delivered.
-	buf[0] = 1
-	buf[1] = 3
-	buf[2] = byte(fakeTransNumber)
-	linkEP.InjectInbound(fakeNetNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
-		Data: buf.ToVectorisedView(),
-	}))
-	if fakeTrans.packetCount != 0 {
-		t.Errorf("packetCount = %d, want %d", fakeTrans.packetCount, 0)
-	}
-
-	// Make sure packet is delivered.
-	buf[0] = 1
-	buf[1] = 2
-	buf[2] = byte(fakeTransNumber)
-	linkEP.InjectInbound(fakeNetNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
-		Data: buf.ToVectorisedView(),
-	}))
-	if fakeTrans.packetCount != 1 {
-		t.Errorf("packetCount = %d, want %d", fakeTrans.packetCount, 1)
-	}
-}
-
-func TestTransportControlReceive(t *testing.T) {
-	linkEP := channel.New(10, defaultMTU, "")
-	s := stack.New(stack.Options{
-		NetworkProtocols:   []stack.NetworkProtocolFactory{fakeNetFactory},
-		TransportProtocols: []stack.TransportProtocolFactory{fakeTransFactory},
-	})
-	if err := s.CreateNIC(1, linkEP); err != nil {
-		t.Fatalf("CreateNIC failed: %v", err)
-	}
-
-	{
-		subnet, err := tcpip.NewSubnet("\x00", "\x00")
-		if err != nil {
-			t.Fatal(err)
-		}
-		s.SetRouteTable([]tcpip.Route{{Destination: subnet, Gateway: "\x00", NIC: 1}})
-	}
-
-	if err := s.AddAddress(1, fakeNetNumber, "\x01"); err != nil {
-		t.Fatalf("AddAddress failed: %v", err)
-	}
-
-	// Create endpoint and connect to remote address.
-	wq := waiter.Queue{}
-	ep, err := s.NewEndpoint(fakeTransNumber, fakeNetNumber, &wq)
-	if err != nil {
-		t.Fatalf("NewEndpoint failed: %v", err)
-	}
-
-	if err := ep.Connect(tcpip.FullAddress{0, "\x02", 0}); err != nil {
-		t.Fatalf("Connect failed: %v", err)
-	}
-
-	fakeTrans := s.TransportProtocolInstance(fakeTransNumber).(*fakeTransportProtocol)
-
-	// Create buffer that will hold the control packet.
-	buf := buffer.NewView(2*fakeNetHeaderLen + 30)
-
-	// Outer packet contains the control protocol number.
-	buf[0] = 1
-	buf[1] = 0xfe
-	buf[2] = uint8(fakeControlProtocol)
-
-	// Make sure packet with wrong protocol is not delivered.
-	buf[fakeNetHeaderLen+0] = 0
-	buf[fakeNetHeaderLen+1] = 1
-	buf[fakeNetHeaderLen+2] = 0
-	linkEP.InjectInbound(fakeNetNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
-		Data: buf.ToVectorisedView(),
-	}))
-	if fakeTrans.controlCount != 0 {
-		t.Errorf("controlCount = %d, want %d", fakeTrans.controlCount, 0)
-	}
-
-	// Make sure packet from the wrong source is not delivered.
-	buf[fakeNetHeaderLen+0] = 3
-	buf[fakeNetHeaderLen+1] = 1
-	buf[fakeNetHeaderLen+2] = byte(fakeTransNumber)
-	linkEP.InjectInbound(fakeNetNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
-		Data: buf.ToVectorisedView(),
-	}))
-	if fakeTrans.controlCount != 0 {
-		t.Errorf("controlCount = %d, want %d", fakeTrans.controlCount, 0)
-	}
-
-	// Make sure packet is delivered.
-	buf[fakeNetHeaderLen+0] = 2
-	buf[fakeNetHeaderLen+1] = 1
-	buf[fakeNetHeaderLen+2] = byte(fakeTransNumber)
-	linkEP.InjectInbound(fakeNetNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
-		Data: buf.ToVectorisedView(),
-	}))
-	if fakeTrans.controlCount != 1 {
-		t.Errorf("controlCount = %d, want %d", fakeTrans.controlCount, 1)
-	}
-}
-
-func TestTransportSend(t *testing.T) {
-	linkEP := channel.New(10, defaultMTU, "")
-	s := stack.New(stack.Options{
-		NetworkProtocols:   []stack.NetworkProtocolFactory{fakeNetFactory},
-		TransportProtocols: []stack.TransportProtocolFactory{fakeTransFactory},
-	})
-	if err := s.CreateNIC(1, linkEP); err != nil {
-		t.Fatalf("CreateNIC failed: %v", err)
-	}
-
-	if err := s.AddAddress(1, fakeNetNumber, "\x01"); err != nil {
-		t.Fatalf("AddAddress failed: %v", err)
-	}
-
-	{
-		subnet, err := tcpip.NewSubnet("\x00", "\x00")
-		if err != nil {
-			t.Fatal(err)
-		}
-		s.SetRouteTable([]tcpip.Route{{Destination: subnet, Gateway: "\x00", NIC: 1}})
-	}
-
-	// Create endpoint and bind it.
-	wq := waiter.Queue{}
-	ep, err := s.NewEndpoint(fakeTransNumber, fakeNetNumber, &wq)
-	if err != nil {
-		t.Fatalf("NewEndpoint failed: %v", err)
-	}
-
-	if err := ep.Connect(tcpip.FullAddress{0, "\x02", 0}); err != nil {
-		t.Fatalf("Connect failed: %v", err)
-	}
-
-	// Create buffer that will hold the payload.
-	b := make([]byte, 30)
-	var r bytes.Reader
-	r.Reset(b)
-	if _, err := ep.Write(&r, tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("write failed: %v", err)
-	}
-
-	fakeNet := s.NetworkProtocolInstance(fakeNetNumber).(*fakeNetworkProtocol)
-
-	if fakeNet.sendPacketCount[2] != 1 {
-		t.Errorf("sendPacketCount = %d, want %d", fakeNet.sendPacketCount[2], 1)
-	}
-}
-
-func TestTransportOptions(t *testing.T) {
-	s := stack.New(stack.Options{
-		NetworkProtocols:   []stack.NetworkProtocolFactory{fakeNetFactory},
-		TransportProtocols: []stack.TransportProtocolFactory{fakeTransFactory},
-	})
-
-	v := tcpip.TCPModerateReceiveBufferOption(true)
-	if err := s.SetTransportProtocolOption(fakeTransNumber, &v); err != nil {
-		t.Errorf("s.SetTransportProtocolOption(fakeTrans, &%T(%t)): %s", v, v, err)
-	}
-	v = false
-	if err := s.TransportProtocolOption(fakeTransNumber, &v); err != nil {
-		t.Fatalf("s.TransportProtocolOption(fakeTransNumber, &%T): %s", v, err)
-	}
-	if !v {
-		t.Fatalf("got tcpip.TCPModerateReceiveBufferOption = false, want = true")
-	}
-}
diff --git a/pkg/tcpip/stack/tuple_list.go b/pkg/tcpip/stack/tuple_list.go
new file mode 100644
index 0000000..31d0fee
--- /dev/null
+++ b/pkg/tcpip/stack/tuple_list.go
@@ -0,0 +1,221 @@
+package stack
+
+// ElementMapper provides an identity mapping by default.
+//
+// This can be replaced to provide a struct that maps elements to linker
+// objects, if they are not the same. An ElementMapper is not typically
+// required if: Linker is left as is, Element is left as is, or Linker and
+// Element are the same type.
+type tupleElementMapper struct{}
+
+// linkerFor maps an Element to a Linker.
+//
+// This default implementation should be inlined.
+//
+//go:nosplit
+func (tupleElementMapper) linkerFor(elem *tuple) *tuple { return elem }
+
+// List is an intrusive list. Entries can be added to or removed from the list
+// in O(1) time and with no additional memory allocations.
+//
+// The zero value for List is an empty list ready to use.
+//
+// To iterate over a list (where l is a List):
+//      for e := l.Front(); e != nil; e = e.Next() {
+// 		// do something with e.
+//      }
+//
+// +stateify savable
+type tupleList struct {
+	head *tuple
+	tail *tuple
+}
+
+// Reset resets list l to the empty state.
+func (l *tupleList) Reset() {
+	l.head = nil
+	l.tail = nil
+}
+
+// Empty returns true iff the list is empty.
+//
+//go:nosplit
+func (l *tupleList) Empty() bool {
+	return l.head == nil
+}
+
+// Front returns the first element of list l or nil.
+//
+//go:nosplit
+func (l *tupleList) Front() *tuple {
+	return l.head
+}
+
+// Back returns the last element of list l or nil.
+//
+//go:nosplit
+func (l *tupleList) Back() *tuple {
+	return l.tail
+}
+
+// Len returns the number of elements in the list.
+//
+// NOTE: This is an O(n) operation.
+//
+//go:nosplit
+func (l *tupleList) Len() (count int) {
+	for e := l.Front(); e != nil; e = (tupleElementMapper{}.linkerFor(e)).Next() {
+		count++
+	}
+	return count
+}
+
+// PushFront inserts the element e at the front of list l.
+//
+//go:nosplit
+func (l *tupleList) PushFront(e *tuple) {
+	linker := tupleElementMapper{}.linkerFor(e)
+	linker.SetNext(l.head)
+	linker.SetPrev(nil)
+	if l.head != nil {
+		tupleElementMapper{}.linkerFor(l.head).SetPrev(e)
+	} else {
+		l.tail = e
+	}
+
+	l.head = e
+}
+
+// PushBack inserts the element e at the back of list l.
+//
+//go:nosplit
+func (l *tupleList) PushBack(e *tuple) {
+	linker := tupleElementMapper{}.linkerFor(e)
+	linker.SetNext(nil)
+	linker.SetPrev(l.tail)
+	if l.tail != nil {
+		tupleElementMapper{}.linkerFor(l.tail).SetNext(e)
+	} else {
+		l.head = e
+	}
+
+	l.tail = e
+}
+
+// PushBackList inserts list m at the end of list l, emptying m.
+//
+//go:nosplit
+func (l *tupleList) PushBackList(m *tupleList) {
+	if l.head == nil {
+		l.head = m.head
+		l.tail = m.tail
+	} else if m.head != nil {
+		tupleElementMapper{}.linkerFor(l.tail).SetNext(m.head)
+		tupleElementMapper{}.linkerFor(m.head).SetPrev(l.tail)
+
+		l.tail = m.tail
+	}
+	m.head = nil
+	m.tail = nil
+}
+
+// InsertAfter inserts e after b.
+//
+//go:nosplit
+func (l *tupleList) InsertAfter(b, e *tuple) {
+	bLinker := tupleElementMapper{}.linkerFor(b)
+	eLinker := tupleElementMapper{}.linkerFor(e)
+
+	a := bLinker.Next()
+
+	eLinker.SetNext(a)
+	eLinker.SetPrev(b)
+	bLinker.SetNext(e)
+
+	if a != nil {
+		tupleElementMapper{}.linkerFor(a).SetPrev(e)
+	} else {
+		l.tail = e
+	}
+}
+
+// InsertBefore inserts e before a.
+//
+//go:nosplit
+func (l *tupleList) InsertBefore(a, e *tuple) {
+	aLinker := tupleElementMapper{}.linkerFor(a)
+	eLinker := tupleElementMapper{}.linkerFor(e)
+
+	b := aLinker.Prev()
+	eLinker.SetNext(a)
+	eLinker.SetPrev(b)
+	aLinker.SetPrev(e)
+
+	if b != nil {
+		tupleElementMapper{}.linkerFor(b).SetNext(e)
+	} else {
+		l.head = e
+	}
+}
+
+// Remove removes e from l.
+//
+//go:nosplit
+func (l *tupleList) Remove(e *tuple) {
+	linker := tupleElementMapper{}.linkerFor(e)
+	prev := linker.Prev()
+	next := linker.Next()
+
+	if prev != nil {
+		tupleElementMapper{}.linkerFor(prev).SetNext(next)
+	} else if l.head == e {
+		l.head = next
+	}
+
+	if next != nil {
+		tupleElementMapper{}.linkerFor(next).SetPrev(prev)
+	} else if l.tail == e {
+		l.tail = prev
+	}
+
+	linker.SetNext(nil)
+	linker.SetPrev(nil)
+}
+
+// Entry is a default implementation of Linker. Users can add anonymous fields
+// of this type to their structs to make them automatically implement the
+// methods needed by List.
+//
+// +stateify savable
+type tupleEntry struct {
+	next *tuple
+	prev *tuple
+}
+
+// Next returns the entry that follows e in the list.
+//
+//go:nosplit
+func (e *tupleEntry) Next() *tuple {
+	return e.next
+}
+
+// Prev returns the entry that precedes e in the list.
+//
+//go:nosplit
+func (e *tupleEntry) Prev() *tuple {
+	return e.prev
+}
+
+// SetNext assigns 'entry' as the entry that follows e in the list.
+//
+//go:nosplit
+func (e *tupleEntry) SetNext(elem *tuple) {
+	e.next = elem
+}
+
+// SetPrev assigns 'entry' as the entry that precedes e in the list.
+//
+//go:nosplit
+func (e *tupleEntry) SetPrev(elem *tuple) {
+	e.prev = elem
+}
diff --git a/pkg/tcpip/tcpip_state_autogen.go b/pkg/tcpip/tcpip_state_autogen.go
new file mode 100644
index 0000000..2557f2b
--- /dev/null
+++ b/pkg/tcpip/tcpip_state_autogen.go
@@ -0,0 +1,1269 @@
+// automatically generated by stateify.
+
+package tcpip
+
+import (
+	"gvisor.dev/gvisor/pkg/state"
+)
+
+func (e *ErrAborted) StateTypeName() string {
+	return "pkg/tcpip.ErrAborted"
+}
+
+func (e *ErrAborted) StateFields() []string {
+	return []string{}
+}
+
+func (e *ErrAborted) beforeSave() {}
+
+// +checklocksignore
+func (e *ErrAborted) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+}
+
+func (e *ErrAborted) afterLoad() {}
+
+// +checklocksignore
+func (e *ErrAborted) StateLoad(stateSourceObject state.Source) {
+}
+
+func (e *ErrAddressFamilyNotSupported) StateTypeName() string {
+	return "pkg/tcpip.ErrAddressFamilyNotSupported"
+}
+
+func (e *ErrAddressFamilyNotSupported) StateFields() []string {
+	return []string{}
+}
+
+func (e *ErrAddressFamilyNotSupported) beforeSave() {}
+
+// +checklocksignore
+func (e *ErrAddressFamilyNotSupported) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+}
+
+func (e *ErrAddressFamilyNotSupported) afterLoad() {}
+
+// +checklocksignore
+func (e *ErrAddressFamilyNotSupported) StateLoad(stateSourceObject state.Source) {
+}
+
+func (e *ErrAlreadyBound) StateTypeName() string {
+	return "pkg/tcpip.ErrAlreadyBound"
+}
+
+func (e *ErrAlreadyBound) StateFields() []string {
+	return []string{}
+}
+
+func (e *ErrAlreadyBound) beforeSave() {}
+
+// +checklocksignore
+func (e *ErrAlreadyBound) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+}
+
+func (e *ErrAlreadyBound) afterLoad() {}
+
+// +checklocksignore
+func (e *ErrAlreadyBound) StateLoad(stateSourceObject state.Source) {
+}
+
+func (e *ErrAlreadyConnected) StateTypeName() string {
+	return "pkg/tcpip.ErrAlreadyConnected"
+}
+
+func (e *ErrAlreadyConnected) StateFields() []string {
+	return []string{}
+}
+
+func (e *ErrAlreadyConnected) beforeSave() {}
+
+// +checklocksignore
+func (e *ErrAlreadyConnected) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+}
+
+func (e *ErrAlreadyConnected) afterLoad() {}
+
+// +checklocksignore
+func (e *ErrAlreadyConnected) StateLoad(stateSourceObject state.Source) {
+}
+
+func (e *ErrAlreadyConnecting) StateTypeName() string {
+	return "pkg/tcpip.ErrAlreadyConnecting"
+}
+
+func (e *ErrAlreadyConnecting) StateFields() []string {
+	return []string{}
+}
+
+func (e *ErrAlreadyConnecting) beforeSave() {}
+
+// +checklocksignore
+func (e *ErrAlreadyConnecting) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+}
+
+func (e *ErrAlreadyConnecting) afterLoad() {}
+
+// +checklocksignore
+func (e *ErrAlreadyConnecting) StateLoad(stateSourceObject state.Source) {
+}
+
+func (e *ErrBadAddress) StateTypeName() string {
+	return "pkg/tcpip.ErrBadAddress"
+}
+
+func (e *ErrBadAddress) StateFields() []string {
+	return []string{}
+}
+
+func (e *ErrBadAddress) beforeSave() {}
+
+// +checklocksignore
+func (e *ErrBadAddress) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+}
+
+func (e *ErrBadAddress) afterLoad() {}
+
+// +checklocksignore
+func (e *ErrBadAddress) StateLoad(stateSourceObject state.Source) {
+}
+
+func (e *ErrBadBuffer) StateTypeName() string {
+	return "pkg/tcpip.ErrBadBuffer"
+}
+
+func (e *ErrBadBuffer) StateFields() []string {
+	return []string{}
+}
+
+func (e *ErrBadBuffer) beforeSave() {}
+
+// +checklocksignore
+func (e *ErrBadBuffer) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+}
+
+func (e *ErrBadBuffer) afterLoad() {}
+
+// +checklocksignore
+func (e *ErrBadBuffer) StateLoad(stateSourceObject state.Source) {
+}
+
+func (e *ErrBadLocalAddress) StateTypeName() string {
+	return "pkg/tcpip.ErrBadLocalAddress"
+}
+
+func (e *ErrBadLocalAddress) StateFields() []string {
+	return []string{}
+}
+
+func (e *ErrBadLocalAddress) beforeSave() {}
+
+// +checklocksignore
+func (e *ErrBadLocalAddress) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+}
+
+func (e *ErrBadLocalAddress) afterLoad() {}
+
+// +checklocksignore
+func (e *ErrBadLocalAddress) StateLoad(stateSourceObject state.Source) {
+}
+
+func (e *ErrBroadcastDisabled) StateTypeName() string {
+	return "pkg/tcpip.ErrBroadcastDisabled"
+}
+
+func (e *ErrBroadcastDisabled) StateFields() []string {
+	return []string{}
+}
+
+func (e *ErrBroadcastDisabled) beforeSave() {}
+
+// +checklocksignore
+func (e *ErrBroadcastDisabled) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+}
+
+func (e *ErrBroadcastDisabled) afterLoad() {}
+
+// +checklocksignore
+func (e *ErrBroadcastDisabled) StateLoad(stateSourceObject state.Source) {
+}
+
+func (e *ErrClosedForReceive) StateTypeName() string {
+	return "pkg/tcpip.ErrClosedForReceive"
+}
+
+func (e *ErrClosedForReceive) StateFields() []string {
+	return []string{}
+}
+
+func (e *ErrClosedForReceive) beforeSave() {}
+
+// +checklocksignore
+func (e *ErrClosedForReceive) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+}
+
+func (e *ErrClosedForReceive) afterLoad() {}
+
+// +checklocksignore
+func (e *ErrClosedForReceive) StateLoad(stateSourceObject state.Source) {
+}
+
+func (e *ErrClosedForSend) StateTypeName() string {
+	return "pkg/tcpip.ErrClosedForSend"
+}
+
+func (e *ErrClosedForSend) StateFields() []string {
+	return []string{}
+}
+
+func (e *ErrClosedForSend) beforeSave() {}
+
+// +checklocksignore
+func (e *ErrClosedForSend) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+}
+
+func (e *ErrClosedForSend) afterLoad() {}
+
+// +checklocksignore
+func (e *ErrClosedForSend) StateLoad(stateSourceObject state.Source) {
+}
+
+func (e *ErrConnectStarted) StateTypeName() string {
+	return "pkg/tcpip.ErrConnectStarted"
+}
+
+func (e *ErrConnectStarted) StateFields() []string {
+	return []string{}
+}
+
+func (e *ErrConnectStarted) beforeSave() {}
+
+// +checklocksignore
+func (e *ErrConnectStarted) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+}
+
+func (e *ErrConnectStarted) afterLoad() {}
+
+// +checklocksignore
+func (e *ErrConnectStarted) StateLoad(stateSourceObject state.Source) {
+}
+
+func (e *ErrConnectionAborted) StateTypeName() string {
+	return "pkg/tcpip.ErrConnectionAborted"
+}
+
+func (e *ErrConnectionAborted) StateFields() []string {
+	return []string{}
+}
+
+func (e *ErrConnectionAborted) beforeSave() {}
+
+// +checklocksignore
+func (e *ErrConnectionAborted) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+}
+
+func (e *ErrConnectionAborted) afterLoad() {}
+
+// +checklocksignore
+func (e *ErrConnectionAborted) StateLoad(stateSourceObject state.Source) {
+}
+
+func (e *ErrConnectionRefused) StateTypeName() string {
+	return "pkg/tcpip.ErrConnectionRefused"
+}
+
+func (e *ErrConnectionRefused) StateFields() []string {
+	return []string{}
+}
+
+func (e *ErrConnectionRefused) beforeSave() {}
+
+// +checklocksignore
+func (e *ErrConnectionRefused) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+}
+
+func (e *ErrConnectionRefused) afterLoad() {}
+
+// +checklocksignore
+func (e *ErrConnectionRefused) StateLoad(stateSourceObject state.Source) {
+}
+
+func (e *ErrConnectionReset) StateTypeName() string {
+	return "pkg/tcpip.ErrConnectionReset"
+}
+
+func (e *ErrConnectionReset) StateFields() []string {
+	return []string{}
+}
+
+func (e *ErrConnectionReset) beforeSave() {}
+
+// +checklocksignore
+func (e *ErrConnectionReset) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+}
+
+func (e *ErrConnectionReset) afterLoad() {}
+
+// +checklocksignore
+func (e *ErrConnectionReset) StateLoad(stateSourceObject state.Source) {
+}
+
+func (e *ErrDestinationRequired) StateTypeName() string {
+	return "pkg/tcpip.ErrDestinationRequired"
+}
+
+func (e *ErrDestinationRequired) StateFields() []string {
+	return []string{}
+}
+
+func (e *ErrDestinationRequired) beforeSave() {}
+
+// +checklocksignore
+func (e *ErrDestinationRequired) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+}
+
+func (e *ErrDestinationRequired) afterLoad() {}
+
+// +checklocksignore
+func (e *ErrDestinationRequired) StateLoad(stateSourceObject state.Source) {
+}
+
+func (e *ErrDuplicateAddress) StateTypeName() string {
+	return "pkg/tcpip.ErrDuplicateAddress"
+}
+
+func (e *ErrDuplicateAddress) StateFields() []string {
+	return []string{}
+}
+
+func (e *ErrDuplicateAddress) beforeSave() {}
+
+// +checklocksignore
+func (e *ErrDuplicateAddress) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+}
+
+func (e *ErrDuplicateAddress) afterLoad() {}
+
+// +checklocksignore
+func (e *ErrDuplicateAddress) StateLoad(stateSourceObject state.Source) {
+}
+
+func (e *ErrDuplicateNICID) StateTypeName() string {
+	return "pkg/tcpip.ErrDuplicateNICID"
+}
+
+func (e *ErrDuplicateNICID) StateFields() []string {
+	return []string{}
+}
+
+func (e *ErrDuplicateNICID) beforeSave() {}
+
+// +checklocksignore
+func (e *ErrDuplicateNICID) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+}
+
+func (e *ErrDuplicateNICID) afterLoad() {}
+
+// +checklocksignore
+func (e *ErrDuplicateNICID) StateLoad(stateSourceObject state.Source) {
+}
+
+func (e *ErrInvalidEndpointState) StateTypeName() string {
+	return "pkg/tcpip.ErrInvalidEndpointState"
+}
+
+func (e *ErrInvalidEndpointState) StateFields() []string {
+	return []string{}
+}
+
+func (e *ErrInvalidEndpointState) beforeSave() {}
+
+// +checklocksignore
+func (e *ErrInvalidEndpointState) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+}
+
+func (e *ErrInvalidEndpointState) afterLoad() {}
+
+// +checklocksignore
+func (e *ErrInvalidEndpointState) StateLoad(stateSourceObject state.Source) {
+}
+
+func (e *ErrInvalidOptionValue) StateTypeName() string {
+	return "pkg/tcpip.ErrInvalidOptionValue"
+}
+
+func (e *ErrInvalidOptionValue) StateFields() []string {
+	return []string{}
+}
+
+func (e *ErrInvalidOptionValue) beforeSave() {}
+
+// +checklocksignore
+func (e *ErrInvalidOptionValue) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+}
+
+func (e *ErrInvalidOptionValue) afterLoad() {}
+
+// +checklocksignore
+func (e *ErrInvalidOptionValue) StateLoad(stateSourceObject state.Source) {
+}
+
+func (e *ErrInvalidPortRange) StateTypeName() string {
+	return "pkg/tcpip.ErrInvalidPortRange"
+}
+
+func (e *ErrInvalidPortRange) StateFields() []string {
+	return []string{}
+}
+
+func (e *ErrInvalidPortRange) beforeSave() {}
+
+// +checklocksignore
+func (e *ErrInvalidPortRange) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+}
+
+func (e *ErrInvalidPortRange) afterLoad() {}
+
+// +checklocksignore
+func (e *ErrInvalidPortRange) StateLoad(stateSourceObject state.Source) {
+}
+
+func (e *ErrMalformedHeader) StateTypeName() string {
+	return "pkg/tcpip.ErrMalformedHeader"
+}
+
+func (e *ErrMalformedHeader) StateFields() []string {
+	return []string{}
+}
+
+func (e *ErrMalformedHeader) beforeSave() {}
+
+// +checklocksignore
+func (e *ErrMalformedHeader) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+}
+
+func (e *ErrMalformedHeader) afterLoad() {}
+
+// +checklocksignore
+func (e *ErrMalformedHeader) StateLoad(stateSourceObject state.Source) {
+}
+
+func (e *ErrMessageTooLong) StateTypeName() string {
+	return "pkg/tcpip.ErrMessageTooLong"
+}
+
+func (e *ErrMessageTooLong) StateFields() []string {
+	return []string{}
+}
+
+func (e *ErrMessageTooLong) beforeSave() {}
+
+// +checklocksignore
+func (e *ErrMessageTooLong) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+}
+
+func (e *ErrMessageTooLong) afterLoad() {}
+
+// +checklocksignore
+func (e *ErrMessageTooLong) StateLoad(stateSourceObject state.Source) {
+}
+
+func (e *ErrNetworkUnreachable) StateTypeName() string {
+	return "pkg/tcpip.ErrNetworkUnreachable"
+}
+
+func (e *ErrNetworkUnreachable) StateFields() []string {
+	return []string{}
+}
+
+func (e *ErrNetworkUnreachable) beforeSave() {}
+
+// +checklocksignore
+func (e *ErrNetworkUnreachable) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+}
+
+func (e *ErrNetworkUnreachable) afterLoad() {}
+
+// +checklocksignore
+func (e *ErrNetworkUnreachable) StateLoad(stateSourceObject state.Source) {
+}
+
+func (e *ErrNoBufferSpace) StateTypeName() string {
+	return "pkg/tcpip.ErrNoBufferSpace"
+}
+
+func (e *ErrNoBufferSpace) StateFields() []string {
+	return []string{}
+}
+
+func (e *ErrNoBufferSpace) beforeSave() {}
+
+// +checklocksignore
+func (e *ErrNoBufferSpace) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+}
+
+func (e *ErrNoBufferSpace) afterLoad() {}
+
+// +checklocksignore
+func (e *ErrNoBufferSpace) StateLoad(stateSourceObject state.Source) {
+}
+
+func (e *ErrNoPortAvailable) StateTypeName() string {
+	return "pkg/tcpip.ErrNoPortAvailable"
+}
+
+func (e *ErrNoPortAvailable) StateFields() []string {
+	return []string{}
+}
+
+func (e *ErrNoPortAvailable) beforeSave() {}
+
+// +checklocksignore
+func (e *ErrNoPortAvailable) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+}
+
+func (e *ErrNoPortAvailable) afterLoad() {}
+
+// +checklocksignore
+func (e *ErrNoPortAvailable) StateLoad(stateSourceObject state.Source) {
+}
+
+func (e *ErrNoRoute) StateTypeName() string {
+	return "pkg/tcpip.ErrNoRoute"
+}
+
+func (e *ErrNoRoute) StateFields() []string {
+	return []string{}
+}
+
+func (e *ErrNoRoute) beforeSave() {}
+
+// +checklocksignore
+func (e *ErrNoRoute) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+}
+
+func (e *ErrNoRoute) afterLoad() {}
+
+// +checklocksignore
+func (e *ErrNoRoute) StateLoad(stateSourceObject state.Source) {
+}
+
+func (e *ErrNoSuchFile) StateTypeName() string {
+	return "pkg/tcpip.ErrNoSuchFile"
+}
+
+func (e *ErrNoSuchFile) StateFields() []string {
+	return []string{}
+}
+
+func (e *ErrNoSuchFile) beforeSave() {}
+
+// +checklocksignore
+func (e *ErrNoSuchFile) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+}
+
+func (e *ErrNoSuchFile) afterLoad() {}
+
+// +checklocksignore
+func (e *ErrNoSuchFile) StateLoad(stateSourceObject state.Source) {
+}
+
+func (e *ErrNotConnected) StateTypeName() string {
+	return "pkg/tcpip.ErrNotConnected"
+}
+
+func (e *ErrNotConnected) StateFields() []string {
+	return []string{}
+}
+
+func (e *ErrNotConnected) beforeSave() {}
+
+// +checklocksignore
+func (e *ErrNotConnected) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+}
+
+func (e *ErrNotConnected) afterLoad() {}
+
+// +checklocksignore
+func (e *ErrNotConnected) StateLoad(stateSourceObject state.Source) {
+}
+
+func (e *ErrNotPermitted) StateTypeName() string {
+	return "pkg/tcpip.ErrNotPermitted"
+}
+
+func (e *ErrNotPermitted) StateFields() []string {
+	return []string{}
+}
+
+func (e *ErrNotPermitted) beforeSave() {}
+
+// +checklocksignore
+func (e *ErrNotPermitted) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+}
+
+func (e *ErrNotPermitted) afterLoad() {}
+
+// +checklocksignore
+func (e *ErrNotPermitted) StateLoad(stateSourceObject state.Source) {
+}
+
+func (e *ErrNotSupported) StateTypeName() string {
+	return "pkg/tcpip.ErrNotSupported"
+}
+
+func (e *ErrNotSupported) StateFields() []string {
+	return []string{}
+}
+
+func (e *ErrNotSupported) beforeSave() {}
+
+// +checklocksignore
+func (e *ErrNotSupported) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+}
+
+func (e *ErrNotSupported) afterLoad() {}
+
+// +checklocksignore
+func (e *ErrNotSupported) StateLoad(stateSourceObject state.Source) {
+}
+
+func (e *ErrPortInUse) StateTypeName() string {
+	return "pkg/tcpip.ErrPortInUse"
+}
+
+func (e *ErrPortInUse) StateFields() []string {
+	return []string{}
+}
+
+func (e *ErrPortInUse) beforeSave() {}
+
+// +checklocksignore
+func (e *ErrPortInUse) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+}
+
+func (e *ErrPortInUse) afterLoad() {}
+
+// +checklocksignore
+func (e *ErrPortInUse) StateLoad(stateSourceObject state.Source) {
+}
+
+func (e *ErrQueueSizeNotSupported) StateTypeName() string {
+	return "pkg/tcpip.ErrQueueSizeNotSupported"
+}
+
+func (e *ErrQueueSizeNotSupported) StateFields() []string {
+	return []string{}
+}
+
+func (e *ErrQueueSizeNotSupported) beforeSave() {}
+
+// +checklocksignore
+func (e *ErrQueueSizeNotSupported) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+}
+
+func (e *ErrQueueSizeNotSupported) afterLoad() {}
+
+// +checklocksignore
+func (e *ErrQueueSizeNotSupported) StateLoad(stateSourceObject state.Source) {
+}
+
+func (e *ErrTimeout) StateTypeName() string {
+	return "pkg/tcpip.ErrTimeout"
+}
+
+func (e *ErrTimeout) StateFields() []string {
+	return []string{}
+}
+
+func (e *ErrTimeout) beforeSave() {}
+
+// +checklocksignore
+func (e *ErrTimeout) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+}
+
+func (e *ErrTimeout) afterLoad() {}
+
+// +checklocksignore
+func (e *ErrTimeout) StateLoad(stateSourceObject state.Source) {
+}
+
+func (e *ErrUnknownDevice) StateTypeName() string {
+	return "pkg/tcpip.ErrUnknownDevice"
+}
+
+func (e *ErrUnknownDevice) StateFields() []string {
+	return []string{}
+}
+
+func (e *ErrUnknownDevice) beforeSave() {}
+
+// +checklocksignore
+func (e *ErrUnknownDevice) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+}
+
+func (e *ErrUnknownDevice) afterLoad() {}
+
+// +checklocksignore
+func (e *ErrUnknownDevice) StateLoad(stateSourceObject state.Source) {
+}
+
+func (e *ErrUnknownNICID) StateTypeName() string {
+	return "pkg/tcpip.ErrUnknownNICID"
+}
+
+func (e *ErrUnknownNICID) StateFields() []string {
+	return []string{}
+}
+
+func (e *ErrUnknownNICID) beforeSave() {}
+
+// +checklocksignore
+func (e *ErrUnknownNICID) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+}
+
+func (e *ErrUnknownNICID) afterLoad() {}
+
+// +checklocksignore
+func (e *ErrUnknownNICID) StateLoad(stateSourceObject state.Source) {
+}
+
+func (e *ErrUnknownProtocol) StateTypeName() string {
+	return "pkg/tcpip.ErrUnknownProtocol"
+}
+
+func (e *ErrUnknownProtocol) StateFields() []string {
+	return []string{}
+}
+
+func (e *ErrUnknownProtocol) beforeSave() {}
+
+// +checklocksignore
+func (e *ErrUnknownProtocol) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+}
+
+func (e *ErrUnknownProtocol) afterLoad() {}
+
+// +checklocksignore
+func (e *ErrUnknownProtocol) StateLoad(stateSourceObject state.Source) {
+}
+
+func (e *ErrUnknownProtocolOption) StateTypeName() string {
+	return "pkg/tcpip.ErrUnknownProtocolOption"
+}
+
+func (e *ErrUnknownProtocolOption) StateFields() []string {
+	return []string{}
+}
+
+func (e *ErrUnknownProtocolOption) beforeSave() {}
+
+// +checklocksignore
+func (e *ErrUnknownProtocolOption) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+}
+
+func (e *ErrUnknownProtocolOption) afterLoad() {}
+
+// +checklocksignore
+func (e *ErrUnknownProtocolOption) StateLoad(stateSourceObject state.Source) {
+}
+
+func (e *ErrWouldBlock) StateTypeName() string {
+	return "pkg/tcpip.ErrWouldBlock"
+}
+
+func (e *ErrWouldBlock) StateFields() []string {
+	return []string{}
+}
+
+func (e *ErrWouldBlock) beforeSave() {}
+
+// +checklocksignore
+func (e *ErrWouldBlock) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+}
+
+func (e *ErrWouldBlock) afterLoad() {}
+
+// +checklocksignore
+func (e *ErrWouldBlock) StateLoad(stateSourceObject state.Source) {
+}
+
+func (l *sockErrorList) StateTypeName() string {
+	return "pkg/tcpip.sockErrorList"
+}
+
+func (l *sockErrorList) StateFields() []string {
+	return []string{
+		"head",
+		"tail",
+	}
+}
+
+func (l *sockErrorList) beforeSave() {}
+
+// +checklocksignore
+func (l *sockErrorList) StateSave(stateSinkObject state.Sink) {
+	l.beforeSave()
+	stateSinkObject.Save(0, &l.head)
+	stateSinkObject.Save(1, &l.tail)
+}
+
+func (l *sockErrorList) afterLoad() {}
+
+// +checklocksignore
+func (l *sockErrorList) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &l.head)
+	stateSourceObject.Load(1, &l.tail)
+}
+
+func (e *sockErrorEntry) StateTypeName() string {
+	return "pkg/tcpip.sockErrorEntry"
+}
+
+func (e *sockErrorEntry) StateFields() []string {
+	return []string{
+		"next",
+		"prev",
+	}
+}
+
+func (e *sockErrorEntry) beforeSave() {}
+
+// +checklocksignore
+func (e *sockErrorEntry) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+	stateSinkObject.Save(0, &e.next)
+	stateSinkObject.Save(1, &e.prev)
+}
+
+func (e *sockErrorEntry) afterLoad() {}
+
+// +checklocksignore
+func (e *sockErrorEntry) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &e.next)
+	stateSourceObject.Load(1, &e.prev)
+}
+
+func (so *SocketOptions) StateTypeName() string {
+	return "pkg/tcpip.SocketOptions"
+}
+
+func (so *SocketOptions) StateFields() []string {
+	return []string{
+		"handler",
+		"broadcastEnabled",
+		"passCredEnabled",
+		"noChecksumEnabled",
+		"reuseAddressEnabled",
+		"reusePortEnabled",
+		"keepAliveEnabled",
+		"multicastLoopEnabled",
+		"receiveTOSEnabled",
+		"receiveTClassEnabled",
+		"receivePacketInfoEnabled",
+		"hdrIncludedEnabled",
+		"v6OnlyEnabled",
+		"quickAckEnabled",
+		"delayOptionEnabled",
+		"corkOptionEnabled",
+		"receiveOriginalDstAddress",
+		"recvErrEnabled",
+		"errQueue",
+		"bindToDevice",
+		"sendBufferSize",
+		"linger",
+	}
+}
+
+func (so *SocketOptions) beforeSave() {}
+
+// +checklocksignore
+func (so *SocketOptions) StateSave(stateSinkObject state.Sink) {
+	so.beforeSave()
+	stateSinkObject.Save(0, &so.handler)
+	stateSinkObject.Save(1, &so.broadcastEnabled)
+	stateSinkObject.Save(2, &so.passCredEnabled)
+	stateSinkObject.Save(3, &so.noChecksumEnabled)
+	stateSinkObject.Save(4, &so.reuseAddressEnabled)
+	stateSinkObject.Save(5, &so.reusePortEnabled)
+	stateSinkObject.Save(6, &so.keepAliveEnabled)
+	stateSinkObject.Save(7, &so.multicastLoopEnabled)
+	stateSinkObject.Save(8, &so.receiveTOSEnabled)
+	stateSinkObject.Save(9, &so.receiveTClassEnabled)
+	stateSinkObject.Save(10, &so.receivePacketInfoEnabled)
+	stateSinkObject.Save(11, &so.hdrIncludedEnabled)
+	stateSinkObject.Save(12, &so.v6OnlyEnabled)
+	stateSinkObject.Save(13, &so.quickAckEnabled)
+	stateSinkObject.Save(14, &so.delayOptionEnabled)
+	stateSinkObject.Save(15, &so.corkOptionEnabled)
+	stateSinkObject.Save(16, &so.receiveOriginalDstAddress)
+	stateSinkObject.Save(17, &so.recvErrEnabled)
+	stateSinkObject.Save(18, &so.errQueue)
+	stateSinkObject.Save(19, &so.bindToDevice)
+	stateSinkObject.Save(20, &so.sendBufferSize)
+	stateSinkObject.Save(21, &so.linger)
+}
+
+func (so *SocketOptions) afterLoad() {}
+
+// +checklocksignore
+func (so *SocketOptions) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &so.handler)
+	stateSourceObject.Load(1, &so.broadcastEnabled)
+	stateSourceObject.Load(2, &so.passCredEnabled)
+	stateSourceObject.Load(3, &so.noChecksumEnabled)
+	stateSourceObject.Load(4, &so.reuseAddressEnabled)
+	stateSourceObject.Load(5, &so.reusePortEnabled)
+	stateSourceObject.Load(6, &so.keepAliveEnabled)
+	stateSourceObject.Load(7, &so.multicastLoopEnabled)
+	stateSourceObject.Load(8, &so.receiveTOSEnabled)
+	stateSourceObject.Load(9, &so.receiveTClassEnabled)
+	stateSourceObject.Load(10, &so.receivePacketInfoEnabled)
+	stateSourceObject.Load(11, &so.hdrIncludedEnabled)
+	stateSourceObject.Load(12, &so.v6OnlyEnabled)
+	stateSourceObject.Load(13, &so.quickAckEnabled)
+	stateSourceObject.Load(14, &so.delayOptionEnabled)
+	stateSourceObject.Load(15, &so.corkOptionEnabled)
+	stateSourceObject.Load(16, &so.receiveOriginalDstAddress)
+	stateSourceObject.Load(17, &so.recvErrEnabled)
+	stateSourceObject.Load(18, &so.errQueue)
+	stateSourceObject.Load(19, &so.bindToDevice)
+	stateSourceObject.Load(20, &so.sendBufferSize)
+	stateSourceObject.Load(21, &so.linger)
+}
+
+func (l *LocalSockError) StateTypeName() string {
+	return "pkg/tcpip.LocalSockError"
+}
+
+func (l *LocalSockError) StateFields() []string {
+	return []string{
+		"info",
+	}
+}
+
+func (l *LocalSockError) beforeSave() {}
+
+// +checklocksignore
+func (l *LocalSockError) StateSave(stateSinkObject state.Sink) {
+	l.beforeSave()
+	stateSinkObject.Save(0, &l.info)
+}
+
+func (l *LocalSockError) afterLoad() {}
+
+// +checklocksignore
+func (l *LocalSockError) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &l.info)
+}
+
+func (s *SockError) StateTypeName() string {
+	return "pkg/tcpip.SockError"
+}
+
+func (s *SockError) StateFields() []string {
+	return []string{
+		"sockErrorEntry",
+		"Err",
+		"Cause",
+		"Payload",
+		"Dst",
+		"Offender",
+		"NetProto",
+	}
+}
+
+func (s *SockError) beforeSave() {}
+
+// +checklocksignore
+func (s *SockError) StateSave(stateSinkObject state.Sink) {
+	s.beforeSave()
+	stateSinkObject.Save(0, &s.sockErrorEntry)
+	stateSinkObject.Save(1, &s.Err)
+	stateSinkObject.Save(2, &s.Cause)
+	stateSinkObject.Save(3, &s.Payload)
+	stateSinkObject.Save(4, &s.Dst)
+	stateSinkObject.Save(5, &s.Offender)
+	stateSinkObject.Save(6, &s.NetProto)
+}
+
+func (s *SockError) afterLoad() {}
+
+// +checklocksignore
+func (s *SockError) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &s.sockErrorEntry)
+	stateSourceObject.Load(1, &s.Err)
+	stateSourceObject.Load(2, &s.Cause)
+	stateSourceObject.Load(3, &s.Payload)
+	stateSourceObject.Load(4, &s.Dst)
+	stateSourceObject.Load(5, &s.Offender)
+	stateSourceObject.Load(6, &s.NetProto)
+}
+
+func (f *FullAddress) StateTypeName() string {
+	return "pkg/tcpip.FullAddress"
+}
+
+func (f *FullAddress) StateFields() []string {
+	return []string{
+		"NIC",
+		"Addr",
+		"Port",
+	}
+}
+
+func (f *FullAddress) beforeSave() {}
+
+// +checklocksignore
+func (f *FullAddress) StateSave(stateSinkObject state.Sink) {
+	f.beforeSave()
+	stateSinkObject.Save(0, &f.NIC)
+	stateSinkObject.Save(1, &f.Addr)
+	stateSinkObject.Save(2, &f.Port)
+}
+
+func (f *FullAddress) afterLoad() {}
+
+// +checklocksignore
+func (f *FullAddress) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &f.NIC)
+	stateSourceObject.Load(1, &f.Addr)
+	stateSourceObject.Load(2, &f.Port)
+}
+
+func (c *ControlMessages) StateTypeName() string {
+	return "pkg/tcpip.ControlMessages"
+}
+
+func (c *ControlMessages) StateFields() []string {
+	return []string{
+		"HasTimestamp",
+		"Timestamp",
+		"HasInq",
+		"Inq",
+		"HasTOS",
+		"TOS",
+		"HasTClass",
+		"TClass",
+		"HasIPPacketInfo",
+		"PacketInfo",
+		"HasOriginalDstAddress",
+		"OriginalDstAddress",
+		"SockErr",
+	}
+}
+
+func (c *ControlMessages) beforeSave() {}
+
+// +checklocksignore
+func (c *ControlMessages) StateSave(stateSinkObject state.Sink) {
+	c.beforeSave()
+	stateSinkObject.Save(0, &c.HasTimestamp)
+	stateSinkObject.Save(1, &c.Timestamp)
+	stateSinkObject.Save(2, &c.HasInq)
+	stateSinkObject.Save(3, &c.Inq)
+	stateSinkObject.Save(4, &c.HasTOS)
+	stateSinkObject.Save(5, &c.TOS)
+	stateSinkObject.Save(6, &c.HasTClass)
+	stateSinkObject.Save(7, &c.TClass)
+	stateSinkObject.Save(8, &c.HasIPPacketInfo)
+	stateSinkObject.Save(9, &c.PacketInfo)
+	stateSinkObject.Save(10, &c.HasOriginalDstAddress)
+	stateSinkObject.Save(11, &c.OriginalDstAddress)
+	stateSinkObject.Save(12, &c.SockErr)
+}
+
+func (c *ControlMessages) afterLoad() {}
+
+// +checklocksignore
+func (c *ControlMessages) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &c.HasTimestamp)
+	stateSourceObject.Load(1, &c.Timestamp)
+	stateSourceObject.Load(2, &c.HasInq)
+	stateSourceObject.Load(3, &c.Inq)
+	stateSourceObject.Load(4, &c.HasTOS)
+	stateSourceObject.Load(5, &c.TOS)
+	stateSourceObject.Load(6, &c.HasTClass)
+	stateSourceObject.Load(7, &c.TClass)
+	stateSourceObject.Load(8, &c.HasIPPacketInfo)
+	stateSourceObject.Load(9, &c.PacketInfo)
+	stateSourceObject.Load(10, &c.HasOriginalDstAddress)
+	stateSourceObject.Load(11, &c.OriginalDstAddress)
+	stateSourceObject.Load(12, &c.SockErr)
+}
+
+func (l *LinkPacketInfo) StateTypeName() string {
+	return "pkg/tcpip.LinkPacketInfo"
+}
+
+func (l *LinkPacketInfo) StateFields() []string {
+	return []string{
+		"Protocol",
+		"PktType",
+	}
+}
+
+func (l *LinkPacketInfo) beforeSave() {}
+
+// +checklocksignore
+func (l *LinkPacketInfo) StateSave(stateSinkObject state.Sink) {
+	l.beforeSave()
+	stateSinkObject.Save(0, &l.Protocol)
+	stateSinkObject.Save(1, &l.PktType)
+}
+
+func (l *LinkPacketInfo) afterLoad() {}
+
+// +checklocksignore
+func (l *LinkPacketInfo) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &l.Protocol)
+	stateSourceObject.Load(1, &l.PktType)
+}
+
+func (l *LingerOption) StateTypeName() string {
+	return "pkg/tcpip.LingerOption"
+}
+
+func (l *LingerOption) StateFields() []string {
+	return []string{
+		"Enabled",
+		"Timeout",
+	}
+}
+
+func (l *LingerOption) beforeSave() {}
+
+// +checklocksignore
+func (l *LingerOption) StateSave(stateSinkObject state.Sink) {
+	l.beforeSave()
+	stateSinkObject.Save(0, &l.Enabled)
+	stateSinkObject.Save(1, &l.Timeout)
+}
+
+func (l *LingerOption) afterLoad() {}
+
+// +checklocksignore
+func (l *LingerOption) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &l.Enabled)
+	stateSourceObject.Load(1, &l.Timeout)
+}
+
+func (i *IPPacketInfo) StateTypeName() string {
+	return "pkg/tcpip.IPPacketInfo"
+}
+
+func (i *IPPacketInfo) StateFields() []string {
+	return []string{
+		"NIC",
+		"LocalAddr",
+		"DestinationAddr",
+	}
+}
+
+func (i *IPPacketInfo) beforeSave() {}
+
+// +checklocksignore
+func (i *IPPacketInfo) StateSave(stateSinkObject state.Sink) {
+	i.beforeSave()
+	stateSinkObject.Save(0, &i.NIC)
+	stateSinkObject.Save(1, &i.LocalAddr)
+	stateSinkObject.Save(2, &i.DestinationAddr)
+}
+
+func (i *IPPacketInfo) afterLoad() {}
+
+// +checklocksignore
+func (i *IPPacketInfo) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &i.NIC)
+	stateSourceObject.Load(1, &i.LocalAddr)
+	stateSourceObject.Load(2, &i.DestinationAddr)
+}
+
+func init() {
+	state.Register((*ErrAborted)(nil))
+	state.Register((*ErrAddressFamilyNotSupported)(nil))
+	state.Register((*ErrAlreadyBound)(nil))
+	state.Register((*ErrAlreadyConnected)(nil))
+	state.Register((*ErrAlreadyConnecting)(nil))
+	state.Register((*ErrBadAddress)(nil))
+	state.Register((*ErrBadBuffer)(nil))
+	state.Register((*ErrBadLocalAddress)(nil))
+	state.Register((*ErrBroadcastDisabled)(nil))
+	state.Register((*ErrClosedForReceive)(nil))
+	state.Register((*ErrClosedForSend)(nil))
+	state.Register((*ErrConnectStarted)(nil))
+	state.Register((*ErrConnectionAborted)(nil))
+	state.Register((*ErrConnectionRefused)(nil))
+	state.Register((*ErrConnectionReset)(nil))
+	state.Register((*ErrDestinationRequired)(nil))
+	state.Register((*ErrDuplicateAddress)(nil))
+	state.Register((*ErrDuplicateNICID)(nil))
+	state.Register((*ErrInvalidEndpointState)(nil))
+	state.Register((*ErrInvalidOptionValue)(nil))
+	state.Register((*ErrInvalidPortRange)(nil))
+	state.Register((*ErrMalformedHeader)(nil))
+	state.Register((*ErrMessageTooLong)(nil))
+	state.Register((*ErrNetworkUnreachable)(nil))
+	state.Register((*ErrNoBufferSpace)(nil))
+	state.Register((*ErrNoPortAvailable)(nil))
+	state.Register((*ErrNoRoute)(nil))
+	state.Register((*ErrNoSuchFile)(nil))
+	state.Register((*ErrNotConnected)(nil))
+	state.Register((*ErrNotPermitted)(nil))
+	state.Register((*ErrNotSupported)(nil))
+	state.Register((*ErrPortInUse)(nil))
+	state.Register((*ErrQueueSizeNotSupported)(nil))
+	state.Register((*ErrTimeout)(nil))
+	state.Register((*ErrUnknownDevice)(nil))
+	state.Register((*ErrUnknownNICID)(nil))
+	state.Register((*ErrUnknownProtocol)(nil))
+	state.Register((*ErrUnknownProtocolOption)(nil))
+	state.Register((*ErrWouldBlock)(nil))
+	state.Register((*sockErrorList)(nil))
+	state.Register((*sockErrorEntry)(nil))
+	state.Register((*SocketOptions)(nil))
+	state.Register((*LocalSockError)(nil))
+	state.Register((*SockError)(nil))
+	state.Register((*FullAddress)(nil))
+	state.Register((*ControlMessages)(nil))
+	state.Register((*LinkPacketInfo)(nil))
+	state.Register((*LingerOption)(nil))
+	state.Register((*IPPacketInfo)(nil))
+}
diff --git a/pkg/tcpip/tcpip_test.go b/pkg/tcpip/tcpip_test.go
deleted file mode 100644
index 269081f..0000000
--- a/pkg/tcpip/tcpip_test.go
+++ /dev/null
@@ -1,346 +0,0 @@
-// 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 tcpip
-
-import (
-	"bytes"
-	"fmt"
-	"io"
-	"net"
-	"strings"
-	"testing"
-
-	"github.com/google/go-cmp/cmp"
-)
-
-func TestLimitedWriter_Write(t *testing.T) {
-	var b bytes.Buffer
-	l := LimitedWriter{
-		W: &b,
-		N: 5,
-	}
-	if n, err := l.Write([]byte{0, 1, 2}); err != nil {
-		t.Errorf("got l.Write(3/5) = (_, %s), want nil", err)
-	} else if n != 3 {
-		t.Errorf("got l.Write(3/5) = (%d, _), want 3", n)
-	}
-	if n, err := l.Write([]byte{3, 4, 5}); err != io.ErrShortWrite {
-		t.Errorf("got l.Write(3/2) = (_, %s), want io.ErrShortWrite", err)
-	} else if n != 2 {
-		t.Errorf("got l.Write(3/2) = (%d, _), want 2", n)
-	}
-	if l.N != 0 {
-		t.Errorf("got l.N = %d, want 0", l.N)
-	}
-	l.N = 1
-	if n, err := l.Write([]byte{5}); err != nil {
-		t.Errorf("got l.Write(1/1) = (_, %s), want nil", err)
-	} else if n != 1 {
-		t.Errorf("got l.Write(1/1) = (%d, _), want 1", n)
-	}
-	if diff := cmp.Diff(b.Bytes(), []byte{0, 1, 2, 3, 4, 5}); diff != "" {
-		t.Errorf("%T wrote incorrect data: (-want +got):\n%s", l, diff)
-	}
-}
-
-func TestSubnetContains(t *testing.T) {
-	tests := []struct {
-		s    Address
-		m    AddressMask
-		a    Address
-		want bool
-	}{
-		{"\xa0", "\xf0", "\x90", false},
-		{"\xa0", "\xf0", "\xa0", true},
-		{"\xa0", "\xf0", "\xa5", true},
-		{"\xa0", "\xf0", "\xaf", true},
-		{"\xa0", "\xf0", "\xb0", false},
-		{"\xa0", "\xf0", "", false},
-		{"\xa0", "\xf0", "\xa0\x00", false},
-		{"\xc2\x80", "\xff\xf0", "\xc2\x80", true},
-		{"\xc2\x80", "\xff\xf0", "\xc2\x00", false},
-		{"\xc2\x00", "\xff\xf0", "\xc2\x00", true},
-		{"\xc2\x00", "\xff\xf0", "\xc2\x80", false},
-	}
-	for _, tt := range tests {
-		s, err := NewSubnet(tt.s, tt.m)
-		if err != nil {
-			t.Errorf("NewSubnet(%v, %v) = %v", tt.s, tt.m, err)
-			continue
-		}
-		if got := s.Contains(tt.a); got != tt.want {
-			t.Errorf("Subnet(%v).Contains(%v) = %v, want %v", s, tt.a, got, tt.want)
-		}
-	}
-}
-
-func TestSubnetBits(t *testing.T) {
-	tests := []struct {
-		a     AddressMask
-		want1 int
-		want0 int
-	}{
-		{"\x00", 0, 8},
-		{"\x00\x00", 0, 16},
-		{"\x36", 0, 8},
-		{"\x5c", 0, 8},
-		{"\x5c\x5c", 0, 16},
-		{"\x5c\x36", 0, 16},
-		{"\x36\x5c", 0, 16},
-		{"\x36\x36", 0, 16},
-		{"\xff", 8, 0},
-		{"\xff\xff", 16, 0},
-	}
-	for _, tt := range tests {
-		s := &Subnet{mask: tt.a}
-		got1, got0 := s.Bits()
-		if got1 != tt.want1 || got0 != tt.want0 {
-			t.Errorf("Subnet{mask: %x}.Bits() = %d, %d, want %d, %d", tt.a, got1, got0, tt.want1, tt.want0)
-		}
-	}
-}
-
-func TestSubnetPrefix(t *testing.T) {
-	tests := []struct {
-		a    AddressMask
-		want int
-	}{
-		{"\x00", 0},
-		{"\x00\x00", 0},
-		{"\x36", 0},
-		{"\x86", 1},
-		{"\xc5", 2},
-		{"\xff\x00", 8},
-		{"\xff\x36", 8},
-		{"\xff\x8c", 9},
-		{"\xff\xc8", 10},
-		{"\xff", 8},
-		{"\xff\xff", 16},
-	}
-	for _, tt := range tests {
-		s := &Subnet{mask: tt.a}
-		got := s.Prefix()
-		if got != tt.want {
-			t.Errorf("Subnet{mask: %x}.Bits() = %d want %d", tt.a, got, tt.want)
-		}
-	}
-}
-
-func TestSubnetCreation(t *testing.T) {
-	tests := []struct {
-		a    Address
-		m    AddressMask
-		want error
-	}{
-		{"\xa0", "\xf0", nil},
-		{"\xa0\xa0", "\xf0", errSubnetLengthMismatch},
-		{"\xaa", "\xf0", errSubnetAddressMasked},
-		{"", "", nil},
-	}
-	for _, tt := range tests {
-		if _, err := NewSubnet(tt.a, tt.m); err != tt.want {
-			t.Errorf("NewSubnet(%v, %v) = %v, want %v", tt.a, tt.m, err, tt.want)
-		}
-	}
-}
-
-func TestAddressString(t *testing.T) {
-	for _, want := range []string{
-		// Taken from stdlib.
-		"2001:db8::123:12:1",
-		"2001:db8::1",
-		"2001:db8:0:1:0:1:0:1",
-		"2001:db8:1:0:1:0:1:0",
-		"2001::1:0:0:1",
-		"2001:db8:0:0:1::",
-		"2001:db8::1:0:0:1",
-		"2001:db8::a:b:c:d",
-
-		// Leading zeros.
-		"::1",
-		// Trailing zeros.
-		"8::",
-		// No zeros.
-		"1:1:1:1:1:1:1:1",
-		// Longer sequence is after other zeros, but not at the end.
-		"1:0:0:1::1",
-		// Longer sequence is at the beginning, shorter sequence is at
-		// the end.
-		"::1:1:1:0:0",
-		// Longer sequence is not at the beginning, shorter sequence is
-		// at the end.
-		"1::1:1:0:0",
-		// Longer sequence is at the beginning, shorter sequence is not
-		// at the end.
-		"::1:1:0:0:1",
-		// Neither sequence is at an end, longer is after shorter.
-		"1:0:0:1::1",
-		// Shorter sequence is at the beginning, longer sequence is not
-		// at the end.
-		"0:0:1:1::1",
-		// Shorter sequence is at the beginning, longer sequence is at
-		// the end.
-		"0:0:1:1:1::",
-		// Short sequences at both ends, longer one in the middle.
-		"0:1:1::1:1:0",
-		// Short sequences at both ends, longer one in the middle.
-		"0:1::1:0:0",
-		// Short sequences at both ends, longer one in the middle.
-		"0:0:1::1:0",
-		// Longer sequence surrounded by shorter sequences, but none at
-		// the end.
-		"1:0:1::1:0:1",
-	} {
-		addr := Address(net.ParseIP(want))
-		if got := addr.String(); got != want {
-			t.Errorf("Address(%x).String() = '%s', want = '%s'", addr, got, want)
-		}
-	}
-}
-
-func TestStatsString(t *testing.T) {
-	got := fmt.Sprintf("%+v", Stats{}.FillIn())
-
-	matchers := []string{
-		// Print root-level stats correctly.
-		"UnknownProtocolRcvdPackets:0",
-		// Print protocol-specific stats correctly.
-		"TCP:{ActiveConnectionOpenings:0",
-	}
-
-	for _, m := range matchers {
-		if !strings.Contains(got, m) {
-			t.Errorf("string.Contains(got, %q) = false", m)
-		}
-	}
-	if t.Failed() {
-		t.Logf(`got = fmt.Sprintf("%%+v", Stats{}.FillIn()) = %q`, got)
-	}
-}
-
-func TestAddressWithPrefixSubnet(t *testing.T) {
-	tests := []struct {
-		addr       Address
-		prefixLen  int
-		subnetAddr Address
-		subnetMask AddressMask
-	}{
-		{"\xaa\x55\x33\x42", -1, "\x00\x00\x00\x00", "\x00\x00\x00\x00"},
-		{"\xaa\x55\x33\x42", 0, "\x00\x00\x00\x00", "\x00\x00\x00\x00"},
-		{"\xaa\x55\x33\x42", 1, "\x80\x00\x00\x00", "\x80\x00\x00\x00"},
-		{"\xaa\x55\x33\x42", 7, "\xaa\x00\x00\x00", "\xfe\x00\x00\x00"},
-		{"\xaa\x55\x33\x42", 8, "\xaa\x00\x00\x00", "\xff\x00\x00\x00"},
-		{"\xaa\x55\x33\x42", 24, "\xaa\x55\x33\x00", "\xff\xff\xff\x00"},
-		{"\xaa\x55\x33\x42", 31, "\xaa\x55\x33\x42", "\xff\xff\xff\xfe"},
-		{"\xaa\x55\x33\x42", 32, "\xaa\x55\x33\x42", "\xff\xff\xff\xff"},
-		{"\xaa\x55\x33\x42", 33, "\xaa\x55\x33\x42", "\xff\xff\xff\xff"},
-	}
-	for _, tt := range tests {
-		ap := AddressWithPrefix{Address: tt.addr, PrefixLen: tt.prefixLen}
-		gotSubnet := ap.Subnet()
-		wantSubnet, err := NewSubnet(tt.subnetAddr, tt.subnetMask)
-		if err != nil {
-			t.Errorf("NewSubnet(%q, %q) failed: %s", tt.subnetAddr, tt.subnetMask, err)
-			continue
-		}
-		if gotSubnet != wantSubnet {
-			t.Errorf("got subnet = %q, want = %q", gotSubnet, wantSubnet)
-		}
-	}
-}
-
-func TestAddressUnspecified(t *testing.T) {
-	tests := []struct {
-		addr        Address
-		unspecified bool
-	}{
-		{
-			addr:        "",
-			unspecified: true,
-		},
-		{
-			addr:        "\x00",
-			unspecified: true,
-		},
-		{
-			addr:        "\x01",
-			unspecified: false,
-		},
-		{
-			addr:        "\x00\x00",
-			unspecified: true,
-		},
-		{
-			addr:        "\x01\x00",
-			unspecified: false,
-		},
-		{
-			addr:        "\x00\x01",
-			unspecified: false,
-		},
-		{
-			addr:        "\x01\x01",
-			unspecified: false,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(fmt.Sprintf("addr=%s", test.addr), func(t *testing.T) {
-			if got := test.addr.Unspecified(); got != test.unspecified {
-				t.Fatalf("got addr.Unspecified() = %t, want = %t", got, test.unspecified)
-			}
-		})
-	}
-}
-
-func TestAddressMatchingPrefix(t *testing.T) {
-	tests := []struct {
-		addrA  Address
-		addrB  Address
-		prefix uint8
-	}{
-		{
-			addrA:  "\x01\x01",
-			addrB:  "\x01\x01",
-			prefix: 16,
-		},
-		{
-			addrA:  "\x01\x01",
-			addrB:  "\x01\x00",
-			prefix: 15,
-		},
-		{
-			addrA:  "\x01\x01",
-			addrB:  "\x81\x00",
-			prefix: 0,
-		},
-		{
-			addrA:  "\x01\x01",
-			addrB:  "\x01\x80",
-			prefix: 8,
-		},
-		{
-			addrA:  "\x01\x01",
-			addrB:  "\x02\x80",
-			prefix: 6,
-		},
-	}
-
-	for _, test := range tests {
-		if got := test.addrA.MatchingPrefix(test.addrB); got != test.prefix {
-			t.Errorf("got (%s).MatchingPrefix(%s) = %d, want = %d", test.addrA, test.addrB, got, test.prefix)
-		}
-	}
-}
diff --git a/pkg/tcpip/tcpip_unsafe_state_autogen.go b/pkg/tcpip/tcpip_unsafe_state_autogen.go
new file mode 100644
index 0000000..387b5aa
--- /dev/null
+++ b/pkg/tcpip/tcpip_unsafe_state_autogen.go
@@ -0,0 +1,35 @@
+// automatically generated by stateify.
+
+// +build go1.9
+// +build !go1.18
+
+package tcpip
+
+import (
+	"gvisor.dev/gvisor/pkg/state"
+)
+
+func (s *StdClock) StateTypeName() string {
+	return "pkg/tcpip.StdClock"
+}
+
+func (s *StdClock) StateFields() []string {
+	return []string{}
+}
+
+func (s *StdClock) beforeSave() {}
+
+// +checklocksignore
+func (s *StdClock) StateSave(stateSinkObject state.Sink) {
+	s.beforeSave()
+}
+
+func (s *StdClock) afterLoad() {}
+
+// +checklocksignore
+func (s *StdClock) StateLoad(stateSourceObject state.Source) {
+}
+
+func init() {
+	state.Register((*StdClock)(nil))
+}
diff --git a/pkg/tcpip/time.s b/pkg/tcpip/time.s
deleted file mode 100644
index fb37360..0000000
--- a/pkg/tcpip/time.s
+++ /dev/null
@@ -1,15 +0,0 @@
-// 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.
-
-// Empty assembly file so empty func definitions work.
diff --git a/pkg/tcpip/timer_test.go b/pkg/tcpip/timer_test.go
deleted file mode 100644
index a82384c..0000000
--- a/pkg/tcpip/timer_test.go
+++ /dev/null
@@ -1,268 +0,0 @@
-// Copyright 2020 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 tcpip_test
-
-import (
-	"sync"
-	"testing"
-	"time"
-
-	"gvisor.dev/gvisor/pkg/tcpip"
-)
-
-const (
-	shortDuration  = 1 * time.Nanosecond
-	middleDuration = 100 * time.Millisecond
-	longDuration   = 1 * time.Second
-)
-
-func TestJobReschedule(t *testing.T) {
-	var clock tcpip.StdClock
-	var wg sync.WaitGroup
-	var lock sync.Mutex
-
-	for i := 0; i < 2; i++ {
-		wg.Add(1)
-
-		go func() {
-			lock.Lock()
-			// Assigning a new timer value updates the timer's locker and function.
-			// This test makes sure there is no data race when reassigning a timer
-			// that has an active timer (even if it has been stopped as a stopped
-			// timer may be blocked on a lock before it can check if it has been
-			// stopped while another goroutine holds the same lock).
-			job := tcpip.NewJob(&clock, &lock, func() {
-				wg.Done()
-			})
-			job.Schedule(shortDuration)
-			lock.Unlock()
-		}()
-	}
-	wg.Wait()
-}
-
-func TestJobExecution(t *testing.T) {
-	t.Parallel()
-
-	var clock tcpip.StdClock
-	var lock sync.Mutex
-	ch := make(chan struct{})
-
-	job := tcpip.NewJob(&clock, &lock, func() {
-		ch <- struct{}{}
-	})
-	job.Schedule(shortDuration)
-
-	// Wait for timer to fire.
-	select {
-	case <-ch:
-	case <-time.After(middleDuration):
-		t.Fatal("timed out waiting for timer to fire")
-	}
-
-	// The timer should have fired only once.
-	select {
-	case <-ch:
-		t.Fatal("no other timers should have fired")
-	case <-time.After(middleDuration):
-	}
-}
-
-func TestCancellableTimerResetFromLongDuration(t *testing.T) {
-	t.Parallel()
-
-	var clock tcpip.StdClock
-	var lock sync.Mutex
-	ch := make(chan struct{})
-
-	job := tcpip.NewJob(&clock, &lock, func() { ch <- struct{}{} })
-	job.Schedule(middleDuration)
-
-	lock.Lock()
-	job.Cancel()
-	lock.Unlock()
-
-	job.Schedule(shortDuration)
-
-	// Wait for timer to fire.
-	select {
-	case <-ch:
-	case <-time.After(middleDuration):
-		t.Fatal("timed out waiting for timer to fire")
-	}
-
-	// The timer should have fired only once.
-	select {
-	case <-ch:
-		t.Fatal("no other timers should have fired")
-	case <-time.After(middleDuration):
-	}
-}
-
-func TestJobRescheduleFromShortDuration(t *testing.T) {
-	t.Parallel()
-
-	var clock tcpip.StdClock
-	var lock sync.Mutex
-	ch := make(chan struct{})
-
-	lock.Lock()
-	job := tcpip.NewJob(&clock, &lock, func() { ch <- struct{}{} })
-	job.Schedule(shortDuration)
-	job.Cancel()
-	lock.Unlock()
-
-	// Wait for timer to fire if it wasn't correctly stopped.
-	select {
-	case <-ch:
-		t.Fatal("timer fired after being stopped")
-	case <-time.After(middleDuration):
-	}
-
-	job.Schedule(shortDuration)
-
-	// Wait for timer to fire.
-	select {
-	case <-ch:
-	case <-time.After(middleDuration):
-		t.Fatal("timed out waiting for timer to fire")
-	}
-
-	// The timer should have fired only once.
-	select {
-	case <-ch:
-		t.Fatal("no other timers should have fired")
-	case <-time.After(middleDuration):
-	}
-}
-
-func TestJobImmediatelyCancel(t *testing.T) {
-	t.Parallel()
-
-	var clock tcpip.StdClock
-	var lock sync.Mutex
-	ch := make(chan struct{})
-
-	for i := 0; i < 1000; i++ {
-		lock.Lock()
-		job := tcpip.NewJob(&clock, &lock, func() { ch <- struct{}{} })
-		job.Schedule(shortDuration)
-		job.Cancel()
-		lock.Unlock()
-	}
-
-	// Wait for timer to fire if it wasn't correctly stopped.
-	select {
-	case <-ch:
-		t.Fatal("timer fired after being stopped")
-	case <-time.After(middleDuration):
-	}
-}
-
-func TestJobCancelledRescheduleWithoutLock(t *testing.T) {
-	t.Parallel()
-
-	var clock tcpip.StdClock
-	var lock sync.Mutex
-	ch := make(chan struct{})
-
-	lock.Lock()
-	job := tcpip.NewJob(&clock, &lock, func() { ch <- struct{}{} })
-	job.Schedule(shortDuration)
-	job.Cancel()
-	lock.Unlock()
-
-	for i := 0; i < 10; i++ {
-		job.Schedule(middleDuration)
-
-		lock.Lock()
-		// Sleep until the timer fires and gets blocked trying to take the lock.
-		time.Sleep(middleDuration * 2)
-		job.Cancel()
-		lock.Unlock()
-	}
-
-	// Wait for double the duration so timers that weren't correctly stopped can
-	// fire.
-	select {
-	case <-ch:
-		t.Fatal("timer fired after being stopped")
-	case <-time.After(middleDuration * 2):
-	}
-}
-
-func TestManyCancellableTimerResetAfterBlockedOnLock(t *testing.T) {
-	t.Parallel()
-
-	var clock tcpip.StdClock
-	var lock sync.Mutex
-	ch := make(chan struct{})
-
-	lock.Lock()
-	job := tcpip.NewJob(&clock, &lock, func() { ch <- struct{}{} })
-	job.Schedule(shortDuration)
-	for i := 0; i < 10; i++ {
-		// Sleep until the timer fires and gets blocked trying to take the lock.
-		time.Sleep(middleDuration)
-		job.Cancel()
-		job.Schedule(shortDuration)
-	}
-	lock.Unlock()
-
-	// Wait for double the duration for the last timer to fire.
-	select {
-	case <-ch:
-	case <-time.After(middleDuration):
-		t.Fatal("timed out waiting for timer to fire")
-	}
-
-	// The timer should have fired only once.
-	select {
-	case <-ch:
-		t.Fatal("no other timers should have fired")
-	case <-time.After(middleDuration):
-	}
-}
-
-func TestManyJobReschedulesUnderLock(t *testing.T) {
-	t.Parallel()
-
-	var clock tcpip.StdClock
-	var lock sync.Mutex
-	ch := make(chan struct{})
-
-	lock.Lock()
-	job := tcpip.NewJob(&clock, &lock, func() { ch <- struct{}{} })
-	job.Schedule(shortDuration)
-	for i := 0; i < 10; i++ {
-		job.Cancel()
-		job.Schedule(shortDuration)
-	}
-	lock.Unlock()
-
-	// Wait for double the duration for the last timer to fire.
-	select {
-	case <-ch:
-	case <-time.After(middleDuration):
-		t.Fatal("timed out waiting for timer to fire")
-	}
-
-	// The timer should have fired only once.
-	select {
-	case <-ch:
-		t.Fatal("no other timers should have fired")
-	case <-time.After(middleDuration):
-	}
-}
diff --git a/pkg/tcpip/transport/icmp/icmp_packet_list.go b/pkg/tcpip/transport/icmp/icmp_packet_list.go
new file mode 100644
index 0000000..0aacdad
--- /dev/null
+++ b/pkg/tcpip/transport/icmp/icmp_packet_list.go
@@ -0,0 +1,221 @@
+package icmp
+
+// ElementMapper provides an identity mapping by default.
+//
+// This can be replaced to provide a struct that maps elements to linker
+// objects, if they are not the same. An ElementMapper is not typically
+// required if: Linker is left as is, Element is left as is, or Linker and
+// Element are the same type.
+type icmpPacketElementMapper struct{}
+
+// linkerFor maps an Element to a Linker.
+//
+// This default implementation should be inlined.
+//
+//go:nosplit
+func (icmpPacketElementMapper) linkerFor(elem *icmpPacket) *icmpPacket { return elem }
+
+// List is an intrusive list. Entries can be added to or removed from the list
+// in O(1) time and with no additional memory allocations.
+//
+// The zero value for List is an empty list ready to use.
+//
+// To iterate over a list (where l is a List):
+//      for e := l.Front(); e != nil; e = e.Next() {
+// 		// do something with e.
+//      }
+//
+// +stateify savable
+type icmpPacketList struct {
+	head *icmpPacket
+	tail *icmpPacket
+}
+
+// Reset resets list l to the empty state.
+func (l *icmpPacketList) Reset() {
+	l.head = nil
+	l.tail = nil
+}
+
+// Empty returns true iff the list is empty.
+//
+//go:nosplit
+func (l *icmpPacketList) Empty() bool {
+	return l.head == nil
+}
+
+// Front returns the first element of list l or nil.
+//
+//go:nosplit
+func (l *icmpPacketList) Front() *icmpPacket {
+	return l.head
+}
+
+// Back returns the last element of list l or nil.
+//
+//go:nosplit
+func (l *icmpPacketList) Back() *icmpPacket {
+	return l.tail
+}
+
+// Len returns the number of elements in the list.
+//
+// NOTE: This is an O(n) operation.
+//
+//go:nosplit
+func (l *icmpPacketList) Len() (count int) {
+	for e := l.Front(); e != nil; e = (icmpPacketElementMapper{}.linkerFor(e)).Next() {
+		count++
+	}
+	return count
+}
+
+// PushFront inserts the element e at the front of list l.
+//
+//go:nosplit
+func (l *icmpPacketList) PushFront(e *icmpPacket) {
+	linker := icmpPacketElementMapper{}.linkerFor(e)
+	linker.SetNext(l.head)
+	linker.SetPrev(nil)
+	if l.head != nil {
+		icmpPacketElementMapper{}.linkerFor(l.head).SetPrev(e)
+	} else {
+		l.tail = e
+	}
+
+	l.head = e
+}
+
+// PushBack inserts the element e at the back of list l.
+//
+//go:nosplit
+func (l *icmpPacketList) PushBack(e *icmpPacket) {
+	linker := icmpPacketElementMapper{}.linkerFor(e)
+	linker.SetNext(nil)
+	linker.SetPrev(l.tail)
+	if l.tail != nil {
+		icmpPacketElementMapper{}.linkerFor(l.tail).SetNext(e)
+	} else {
+		l.head = e
+	}
+
+	l.tail = e
+}
+
+// PushBackList inserts list m at the end of list l, emptying m.
+//
+//go:nosplit
+func (l *icmpPacketList) PushBackList(m *icmpPacketList) {
+	if l.head == nil {
+		l.head = m.head
+		l.tail = m.tail
+	} else if m.head != nil {
+		icmpPacketElementMapper{}.linkerFor(l.tail).SetNext(m.head)
+		icmpPacketElementMapper{}.linkerFor(m.head).SetPrev(l.tail)
+
+		l.tail = m.tail
+	}
+	m.head = nil
+	m.tail = nil
+}
+
+// InsertAfter inserts e after b.
+//
+//go:nosplit
+func (l *icmpPacketList) InsertAfter(b, e *icmpPacket) {
+	bLinker := icmpPacketElementMapper{}.linkerFor(b)
+	eLinker := icmpPacketElementMapper{}.linkerFor(e)
+
+	a := bLinker.Next()
+
+	eLinker.SetNext(a)
+	eLinker.SetPrev(b)
+	bLinker.SetNext(e)
+
+	if a != nil {
+		icmpPacketElementMapper{}.linkerFor(a).SetPrev(e)
+	} else {
+		l.tail = e
+	}
+}
+
+// InsertBefore inserts e before a.
+//
+//go:nosplit
+func (l *icmpPacketList) InsertBefore(a, e *icmpPacket) {
+	aLinker := icmpPacketElementMapper{}.linkerFor(a)
+	eLinker := icmpPacketElementMapper{}.linkerFor(e)
+
+	b := aLinker.Prev()
+	eLinker.SetNext(a)
+	eLinker.SetPrev(b)
+	aLinker.SetPrev(e)
+
+	if b != nil {
+		icmpPacketElementMapper{}.linkerFor(b).SetNext(e)
+	} else {
+		l.head = e
+	}
+}
+
+// Remove removes e from l.
+//
+//go:nosplit
+func (l *icmpPacketList) Remove(e *icmpPacket) {
+	linker := icmpPacketElementMapper{}.linkerFor(e)
+	prev := linker.Prev()
+	next := linker.Next()
+
+	if prev != nil {
+		icmpPacketElementMapper{}.linkerFor(prev).SetNext(next)
+	} else if l.head == e {
+		l.head = next
+	}
+
+	if next != nil {
+		icmpPacketElementMapper{}.linkerFor(next).SetPrev(prev)
+	} else if l.tail == e {
+		l.tail = prev
+	}
+
+	linker.SetNext(nil)
+	linker.SetPrev(nil)
+}
+
+// Entry is a default implementation of Linker. Users can add anonymous fields
+// of this type to their structs to make them automatically implement the
+// methods needed by List.
+//
+// +stateify savable
+type icmpPacketEntry struct {
+	next *icmpPacket
+	prev *icmpPacket
+}
+
+// Next returns the entry that follows e in the list.
+//
+//go:nosplit
+func (e *icmpPacketEntry) Next() *icmpPacket {
+	return e.next
+}
+
+// Prev returns the entry that precedes e in the list.
+//
+//go:nosplit
+func (e *icmpPacketEntry) Prev() *icmpPacket {
+	return e.prev
+}
+
+// SetNext assigns 'entry' as the entry that follows e in the list.
+//
+//go:nosplit
+func (e *icmpPacketEntry) SetNext(elem *icmpPacket) {
+	e.next = elem
+}
+
+// SetPrev assigns 'entry' as the entry that precedes e in the list.
+//
+//go:nosplit
+func (e *icmpPacketEntry) SetPrev(elem *icmpPacket) {
+	e.prev = elem
+}
diff --git a/pkg/tcpip/transport/icmp/icmp_state_autogen.go b/pkg/tcpip/transport/icmp/icmp_state_autogen.go
new file mode 100644
index 0000000..4175f0f
--- /dev/null
+++ b/pkg/tcpip/transport/icmp/icmp_state_autogen.go
@@ -0,0 +1,168 @@
+// automatically generated by stateify.
+
+package icmp
+
+import (
+	"gvisor.dev/gvisor/pkg/state"
+	"gvisor.dev/gvisor/pkg/tcpip/buffer"
+)
+
+func (p *icmpPacket) StateTypeName() string {
+	return "pkg/tcpip/transport/icmp.icmpPacket"
+}
+
+func (p *icmpPacket) StateFields() []string {
+	return []string{
+		"icmpPacketEntry",
+		"senderAddress",
+		"data",
+		"timestamp",
+	}
+}
+
+func (p *icmpPacket) beforeSave() {}
+
+// +checklocksignore
+func (p *icmpPacket) StateSave(stateSinkObject state.Sink) {
+	p.beforeSave()
+	var dataValue buffer.VectorisedView = p.saveData()
+	stateSinkObject.SaveValue(2, dataValue)
+	stateSinkObject.Save(0, &p.icmpPacketEntry)
+	stateSinkObject.Save(1, &p.senderAddress)
+	stateSinkObject.Save(3, &p.timestamp)
+}
+
+func (p *icmpPacket) afterLoad() {}
+
+// +checklocksignore
+func (p *icmpPacket) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &p.icmpPacketEntry)
+	stateSourceObject.Load(1, &p.senderAddress)
+	stateSourceObject.Load(3, &p.timestamp)
+	stateSourceObject.LoadValue(2, new(buffer.VectorisedView), func(y interface{}) { p.loadData(y.(buffer.VectorisedView)) })
+}
+
+func (e *endpoint) StateTypeName() string {
+	return "pkg/tcpip/transport/icmp.endpoint"
+}
+
+func (e *endpoint) StateFields() []string {
+	return []string{
+		"TransportEndpointInfo",
+		"DefaultSocketOptionsHandler",
+		"waiterQueue",
+		"uniqueID",
+		"rcvReady",
+		"rcvList",
+		"rcvBufSizeMax",
+		"rcvBufSize",
+		"rcvClosed",
+		"shutdownFlags",
+		"state",
+		"ttl",
+		"owner",
+		"ops",
+	}
+}
+
+// +checklocksignore
+func (e *endpoint) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+	var rcvBufSizeMaxValue int = e.saveRcvBufSizeMax()
+	stateSinkObject.SaveValue(6, rcvBufSizeMaxValue)
+	stateSinkObject.Save(0, &e.TransportEndpointInfo)
+	stateSinkObject.Save(1, &e.DefaultSocketOptionsHandler)
+	stateSinkObject.Save(2, &e.waiterQueue)
+	stateSinkObject.Save(3, &e.uniqueID)
+	stateSinkObject.Save(4, &e.rcvReady)
+	stateSinkObject.Save(5, &e.rcvList)
+	stateSinkObject.Save(7, &e.rcvBufSize)
+	stateSinkObject.Save(8, &e.rcvClosed)
+	stateSinkObject.Save(9, &e.shutdownFlags)
+	stateSinkObject.Save(10, &e.state)
+	stateSinkObject.Save(11, &e.ttl)
+	stateSinkObject.Save(12, &e.owner)
+	stateSinkObject.Save(13, &e.ops)
+}
+
+// +checklocksignore
+func (e *endpoint) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &e.TransportEndpointInfo)
+	stateSourceObject.Load(1, &e.DefaultSocketOptionsHandler)
+	stateSourceObject.Load(2, &e.waiterQueue)
+	stateSourceObject.Load(3, &e.uniqueID)
+	stateSourceObject.Load(4, &e.rcvReady)
+	stateSourceObject.Load(5, &e.rcvList)
+	stateSourceObject.Load(7, &e.rcvBufSize)
+	stateSourceObject.Load(8, &e.rcvClosed)
+	stateSourceObject.Load(9, &e.shutdownFlags)
+	stateSourceObject.Load(10, &e.state)
+	stateSourceObject.Load(11, &e.ttl)
+	stateSourceObject.Load(12, &e.owner)
+	stateSourceObject.Load(13, &e.ops)
+	stateSourceObject.LoadValue(6, new(int), func(y interface{}) { e.loadRcvBufSizeMax(y.(int)) })
+	stateSourceObject.AfterLoad(e.afterLoad)
+}
+
+func (l *icmpPacketList) StateTypeName() string {
+	return "pkg/tcpip/transport/icmp.icmpPacketList"
+}
+
+func (l *icmpPacketList) StateFields() []string {
+	return []string{
+		"head",
+		"tail",
+	}
+}
+
+func (l *icmpPacketList) beforeSave() {}
+
+// +checklocksignore
+func (l *icmpPacketList) StateSave(stateSinkObject state.Sink) {
+	l.beforeSave()
+	stateSinkObject.Save(0, &l.head)
+	stateSinkObject.Save(1, &l.tail)
+}
+
+func (l *icmpPacketList) afterLoad() {}
+
+// +checklocksignore
+func (l *icmpPacketList) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &l.head)
+	stateSourceObject.Load(1, &l.tail)
+}
+
+func (e *icmpPacketEntry) StateTypeName() string {
+	return "pkg/tcpip/transport/icmp.icmpPacketEntry"
+}
+
+func (e *icmpPacketEntry) StateFields() []string {
+	return []string{
+		"next",
+		"prev",
+	}
+}
+
+func (e *icmpPacketEntry) beforeSave() {}
+
+// +checklocksignore
+func (e *icmpPacketEntry) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+	stateSinkObject.Save(0, &e.next)
+	stateSinkObject.Save(1, &e.prev)
+}
+
+func (e *icmpPacketEntry) afterLoad() {}
+
+// +checklocksignore
+func (e *icmpPacketEntry) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &e.next)
+	stateSourceObject.Load(1, &e.prev)
+}
+
+func init() {
+	state.Register((*icmpPacket)(nil))
+	state.Register((*endpoint)(nil))
+	state.Register((*icmpPacketList)(nil))
+	state.Register((*icmpPacketEntry)(nil))
+}
diff --git a/pkg/tcpip/transport/packet/packet_list.go b/pkg/tcpip/transport/packet/packet_list.go
new file mode 100644
index 0000000..2c983aa
--- /dev/null
+++ b/pkg/tcpip/transport/packet/packet_list.go
@@ -0,0 +1,221 @@
+package packet
+
+// ElementMapper provides an identity mapping by default.
+//
+// This can be replaced to provide a struct that maps elements to linker
+// objects, if they are not the same. An ElementMapper is not typically
+// required if: Linker is left as is, Element is left as is, or Linker and
+// Element are the same type.
+type packetElementMapper struct{}
+
+// linkerFor maps an Element to a Linker.
+//
+// This default implementation should be inlined.
+//
+//go:nosplit
+func (packetElementMapper) linkerFor(elem *packet) *packet { return elem }
+
+// List is an intrusive list. Entries can be added to or removed from the list
+// in O(1) time and with no additional memory allocations.
+//
+// The zero value for List is an empty list ready to use.
+//
+// To iterate over a list (where l is a List):
+//      for e := l.Front(); e != nil; e = e.Next() {
+// 		// do something with e.
+//      }
+//
+// +stateify savable
+type packetList struct {
+	head *packet
+	tail *packet
+}
+
+// Reset resets list l to the empty state.
+func (l *packetList) Reset() {
+	l.head = nil
+	l.tail = nil
+}
+
+// Empty returns true iff the list is empty.
+//
+//go:nosplit
+func (l *packetList) Empty() bool {
+	return l.head == nil
+}
+
+// Front returns the first element of list l or nil.
+//
+//go:nosplit
+func (l *packetList) Front() *packet {
+	return l.head
+}
+
+// Back returns the last element of list l or nil.
+//
+//go:nosplit
+func (l *packetList) Back() *packet {
+	return l.tail
+}
+
+// Len returns the number of elements in the list.
+//
+// NOTE: This is an O(n) operation.
+//
+//go:nosplit
+func (l *packetList) Len() (count int) {
+	for e := l.Front(); e != nil; e = (packetElementMapper{}.linkerFor(e)).Next() {
+		count++
+	}
+	return count
+}
+
+// PushFront inserts the element e at the front of list l.
+//
+//go:nosplit
+func (l *packetList) PushFront(e *packet) {
+	linker := packetElementMapper{}.linkerFor(e)
+	linker.SetNext(l.head)
+	linker.SetPrev(nil)
+	if l.head != nil {
+		packetElementMapper{}.linkerFor(l.head).SetPrev(e)
+	} else {
+		l.tail = e
+	}
+
+	l.head = e
+}
+
+// PushBack inserts the element e at the back of list l.
+//
+//go:nosplit
+func (l *packetList) PushBack(e *packet) {
+	linker := packetElementMapper{}.linkerFor(e)
+	linker.SetNext(nil)
+	linker.SetPrev(l.tail)
+	if l.tail != nil {
+		packetElementMapper{}.linkerFor(l.tail).SetNext(e)
+	} else {
+		l.head = e
+	}
+
+	l.tail = e
+}
+
+// PushBackList inserts list m at the end of list l, emptying m.
+//
+//go:nosplit
+func (l *packetList) PushBackList(m *packetList) {
+	if l.head == nil {
+		l.head = m.head
+		l.tail = m.tail
+	} else if m.head != nil {
+		packetElementMapper{}.linkerFor(l.tail).SetNext(m.head)
+		packetElementMapper{}.linkerFor(m.head).SetPrev(l.tail)
+
+		l.tail = m.tail
+	}
+	m.head = nil
+	m.tail = nil
+}
+
+// InsertAfter inserts e after b.
+//
+//go:nosplit
+func (l *packetList) InsertAfter(b, e *packet) {
+	bLinker := packetElementMapper{}.linkerFor(b)
+	eLinker := packetElementMapper{}.linkerFor(e)
+
+	a := bLinker.Next()
+
+	eLinker.SetNext(a)
+	eLinker.SetPrev(b)
+	bLinker.SetNext(e)
+
+	if a != nil {
+		packetElementMapper{}.linkerFor(a).SetPrev(e)
+	} else {
+		l.tail = e
+	}
+}
+
+// InsertBefore inserts e before a.
+//
+//go:nosplit
+func (l *packetList) InsertBefore(a, e *packet) {
+	aLinker := packetElementMapper{}.linkerFor(a)
+	eLinker := packetElementMapper{}.linkerFor(e)
+
+	b := aLinker.Prev()
+	eLinker.SetNext(a)
+	eLinker.SetPrev(b)
+	aLinker.SetPrev(e)
+
+	if b != nil {
+		packetElementMapper{}.linkerFor(b).SetNext(e)
+	} else {
+		l.head = e
+	}
+}
+
+// Remove removes e from l.
+//
+//go:nosplit
+func (l *packetList) Remove(e *packet) {
+	linker := packetElementMapper{}.linkerFor(e)
+	prev := linker.Prev()
+	next := linker.Next()
+
+	if prev != nil {
+		packetElementMapper{}.linkerFor(prev).SetNext(next)
+	} else if l.head == e {
+		l.head = next
+	}
+
+	if next != nil {
+		packetElementMapper{}.linkerFor(next).SetPrev(prev)
+	} else if l.tail == e {
+		l.tail = prev
+	}
+
+	linker.SetNext(nil)
+	linker.SetPrev(nil)
+}
+
+// Entry is a default implementation of Linker. Users can add anonymous fields
+// of this type to their structs to make them automatically implement the
+// methods needed by List.
+//
+// +stateify savable
+type packetEntry struct {
+	next *packet
+	prev *packet
+}
+
+// Next returns the entry that follows e in the list.
+//
+//go:nosplit
+func (e *packetEntry) Next() *packet {
+	return e.next
+}
+
+// Prev returns the entry that precedes e in the list.
+//
+//go:nosplit
+func (e *packetEntry) Prev() *packet {
+	return e.prev
+}
+
+// SetNext assigns 'entry' as the entry that follows e in the list.
+//
+//go:nosplit
+func (e *packetEntry) SetNext(elem *packet) {
+	e.next = elem
+}
+
+// SetPrev assigns 'entry' as the entry that precedes e in the list.
+//
+//go:nosplit
+func (e *packetEntry) SetPrev(elem *packet) {
+	e.prev = elem
+}
diff --git a/pkg/tcpip/transport/packet/packet_state_autogen.go b/pkg/tcpip/transport/packet/packet_state_autogen.go
new file mode 100644
index 0000000..f8b82e5
--- /dev/null
+++ b/pkg/tcpip/transport/packet/packet_state_autogen.go
@@ -0,0 +1,171 @@
+// automatically generated by stateify.
+
+package packet
+
+import (
+	"gvisor.dev/gvisor/pkg/state"
+	"gvisor.dev/gvisor/pkg/tcpip/buffer"
+)
+
+func (p *packet) StateTypeName() string {
+	return "pkg/tcpip/transport/packet.packet"
+}
+
+func (p *packet) StateFields() []string {
+	return []string{
+		"packetEntry",
+		"data",
+		"timestampNS",
+		"senderAddr",
+		"packetInfo",
+	}
+}
+
+func (p *packet) beforeSave() {}
+
+// +checklocksignore
+func (p *packet) StateSave(stateSinkObject state.Sink) {
+	p.beforeSave()
+	var dataValue buffer.VectorisedView = p.saveData()
+	stateSinkObject.SaveValue(1, dataValue)
+	stateSinkObject.Save(0, &p.packetEntry)
+	stateSinkObject.Save(2, &p.timestampNS)
+	stateSinkObject.Save(3, &p.senderAddr)
+	stateSinkObject.Save(4, &p.packetInfo)
+}
+
+func (p *packet) afterLoad() {}
+
+// +checklocksignore
+func (p *packet) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &p.packetEntry)
+	stateSourceObject.Load(2, &p.timestampNS)
+	stateSourceObject.Load(3, &p.senderAddr)
+	stateSourceObject.Load(4, &p.packetInfo)
+	stateSourceObject.LoadValue(1, new(buffer.VectorisedView), func(y interface{}) { p.loadData(y.(buffer.VectorisedView)) })
+}
+
+func (ep *endpoint) StateTypeName() string {
+	return "pkg/tcpip/transport/packet.endpoint"
+}
+
+func (ep *endpoint) StateFields() []string {
+	return []string{
+		"TransportEndpointInfo",
+		"DefaultSocketOptionsHandler",
+		"netProto",
+		"waiterQueue",
+		"cooked",
+		"rcvList",
+		"rcvBufSizeMax",
+		"rcvBufSize",
+		"rcvClosed",
+		"closed",
+		"bound",
+		"boundNIC",
+		"lastError",
+		"ops",
+	}
+}
+
+// +checklocksignore
+func (ep *endpoint) StateSave(stateSinkObject state.Sink) {
+	ep.beforeSave()
+	var rcvBufSizeMaxValue int = ep.saveRcvBufSizeMax()
+	stateSinkObject.SaveValue(6, rcvBufSizeMaxValue)
+	stateSinkObject.Save(0, &ep.TransportEndpointInfo)
+	stateSinkObject.Save(1, &ep.DefaultSocketOptionsHandler)
+	stateSinkObject.Save(2, &ep.netProto)
+	stateSinkObject.Save(3, &ep.waiterQueue)
+	stateSinkObject.Save(4, &ep.cooked)
+	stateSinkObject.Save(5, &ep.rcvList)
+	stateSinkObject.Save(7, &ep.rcvBufSize)
+	stateSinkObject.Save(8, &ep.rcvClosed)
+	stateSinkObject.Save(9, &ep.closed)
+	stateSinkObject.Save(10, &ep.bound)
+	stateSinkObject.Save(11, &ep.boundNIC)
+	stateSinkObject.Save(12, &ep.lastError)
+	stateSinkObject.Save(13, &ep.ops)
+}
+
+// +checklocksignore
+func (ep *endpoint) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &ep.TransportEndpointInfo)
+	stateSourceObject.Load(1, &ep.DefaultSocketOptionsHandler)
+	stateSourceObject.Load(2, &ep.netProto)
+	stateSourceObject.Load(3, &ep.waiterQueue)
+	stateSourceObject.Load(4, &ep.cooked)
+	stateSourceObject.Load(5, &ep.rcvList)
+	stateSourceObject.Load(7, &ep.rcvBufSize)
+	stateSourceObject.Load(8, &ep.rcvClosed)
+	stateSourceObject.Load(9, &ep.closed)
+	stateSourceObject.Load(10, &ep.bound)
+	stateSourceObject.Load(11, &ep.boundNIC)
+	stateSourceObject.Load(12, &ep.lastError)
+	stateSourceObject.Load(13, &ep.ops)
+	stateSourceObject.LoadValue(6, new(int), func(y interface{}) { ep.loadRcvBufSizeMax(y.(int)) })
+	stateSourceObject.AfterLoad(ep.afterLoad)
+}
+
+func (l *packetList) StateTypeName() string {
+	return "pkg/tcpip/transport/packet.packetList"
+}
+
+func (l *packetList) StateFields() []string {
+	return []string{
+		"head",
+		"tail",
+	}
+}
+
+func (l *packetList) beforeSave() {}
+
+// +checklocksignore
+func (l *packetList) StateSave(stateSinkObject state.Sink) {
+	l.beforeSave()
+	stateSinkObject.Save(0, &l.head)
+	stateSinkObject.Save(1, &l.tail)
+}
+
+func (l *packetList) afterLoad() {}
+
+// +checklocksignore
+func (l *packetList) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &l.head)
+	stateSourceObject.Load(1, &l.tail)
+}
+
+func (e *packetEntry) StateTypeName() string {
+	return "pkg/tcpip/transport/packet.packetEntry"
+}
+
+func (e *packetEntry) StateFields() []string {
+	return []string{
+		"next",
+		"prev",
+	}
+}
+
+func (e *packetEntry) beforeSave() {}
+
+// +checklocksignore
+func (e *packetEntry) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+	stateSinkObject.Save(0, &e.next)
+	stateSinkObject.Save(1, &e.prev)
+}
+
+func (e *packetEntry) afterLoad() {}
+
+// +checklocksignore
+func (e *packetEntry) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &e.next)
+	stateSourceObject.Load(1, &e.prev)
+}
+
+func init() {
+	state.Register((*packet)(nil))
+	state.Register((*endpoint)(nil))
+	state.Register((*packetList)(nil))
+	state.Register((*packetEntry)(nil))
+}
diff --git a/pkg/tcpip/transport/raw/raw_packet_list.go b/pkg/tcpip/transport/raw/raw_packet_list.go
new file mode 100644
index 0000000..48804ff
--- /dev/null
+++ b/pkg/tcpip/transport/raw/raw_packet_list.go
@@ -0,0 +1,221 @@
+package raw
+
+// ElementMapper provides an identity mapping by default.
+//
+// This can be replaced to provide a struct that maps elements to linker
+// objects, if they are not the same. An ElementMapper is not typically
+// required if: Linker is left as is, Element is left as is, or Linker and
+// Element are the same type.
+type rawPacketElementMapper struct{}
+
+// linkerFor maps an Element to a Linker.
+//
+// This default implementation should be inlined.
+//
+//go:nosplit
+func (rawPacketElementMapper) linkerFor(elem *rawPacket) *rawPacket { return elem }
+
+// List is an intrusive list. Entries can be added to or removed from the list
+// in O(1) time and with no additional memory allocations.
+//
+// The zero value for List is an empty list ready to use.
+//
+// To iterate over a list (where l is a List):
+//      for e := l.Front(); e != nil; e = e.Next() {
+// 		// do something with e.
+//      }
+//
+// +stateify savable
+type rawPacketList struct {
+	head *rawPacket
+	tail *rawPacket
+}
+
+// Reset resets list l to the empty state.
+func (l *rawPacketList) Reset() {
+	l.head = nil
+	l.tail = nil
+}
+
+// Empty returns true iff the list is empty.
+//
+//go:nosplit
+func (l *rawPacketList) Empty() bool {
+	return l.head == nil
+}
+
+// Front returns the first element of list l or nil.
+//
+//go:nosplit
+func (l *rawPacketList) Front() *rawPacket {
+	return l.head
+}
+
+// Back returns the last element of list l or nil.
+//
+//go:nosplit
+func (l *rawPacketList) Back() *rawPacket {
+	return l.tail
+}
+
+// Len returns the number of elements in the list.
+//
+// NOTE: This is an O(n) operation.
+//
+//go:nosplit
+func (l *rawPacketList) Len() (count int) {
+	for e := l.Front(); e != nil; e = (rawPacketElementMapper{}.linkerFor(e)).Next() {
+		count++
+	}
+	return count
+}
+
+// PushFront inserts the element e at the front of list l.
+//
+//go:nosplit
+func (l *rawPacketList) PushFront(e *rawPacket) {
+	linker := rawPacketElementMapper{}.linkerFor(e)
+	linker.SetNext(l.head)
+	linker.SetPrev(nil)
+	if l.head != nil {
+		rawPacketElementMapper{}.linkerFor(l.head).SetPrev(e)
+	} else {
+		l.tail = e
+	}
+
+	l.head = e
+}
+
+// PushBack inserts the element e at the back of list l.
+//
+//go:nosplit
+func (l *rawPacketList) PushBack(e *rawPacket) {
+	linker := rawPacketElementMapper{}.linkerFor(e)
+	linker.SetNext(nil)
+	linker.SetPrev(l.tail)
+	if l.tail != nil {
+		rawPacketElementMapper{}.linkerFor(l.tail).SetNext(e)
+	} else {
+		l.head = e
+	}
+
+	l.tail = e
+}
+
+// PushBackList inserts list m at the end of list l, emptying m.
+//
+//go:nosplit
+func (l *rawPacketList) PushBackList(m *rawPacketList) {
+	if l.head == nil {
+		l.head = m.head
+		l.tail = m.tail
+	} else if m.head != nil {
+		rawPacketElementMapper{}.linkerFor(l.tail).SetNext(m.head)
+		rawPacketElementMapper{}.linkerFor(m.head).SetPrev(l.tail)
+
+		l.tail = m.tail
+	}
+	m.head = nil
+	m.tail = nil
+}
+
+// InsertAfter inserts e after b.
+//
+//go:nosplit
+func (l *rawPacketList) InsertAfter(b, e *rawPacket) {
+	bLinker := rawPacketElementMapper{}.linkerFor(b)
+	eLinker := rawPacketElementMapper{}.linkerFor(e)
+
+	a := bLinker.Next()
+
+	eLinker.SetNext(a)
+	eLinker.SetPrev(b)
+	bLinker.SetNext(e)
+
+	if a != nil {
+		rawPacketElementMapper{}.linkerFor(a).SetPrev(e)
+	} else {
+		l.tail = e
+	}
+}
+
+// InsertBefore inserts e before a.
+//
+//go:nosplit
+func (l *rawPacketList) InsertBefore(a, e *rawPacket) {
+	aLinker := rawPacketElementMapper{}.linkerFor(a)
+	eLinker := rawPacketElementMapper{}.linkerFor(e)
+
+	b := aLinker.Prev()
+	eLinker.SetNext(a)
+	eLinker.SetPrev(b)
+	aLinker.SetPrev(e)
+
+	if b != nil {
+		rawPacketElementMapper{}.linkerFor(b).SetNext(e)
+	} else {
+		l.head = e
+	}
+}
+
+// Remove removes e from l.
+//
+//go:nosplit
+func (l *rawPacketList) Remove(e *rawPacket) {
+	linker := rawPacketElementMapper{}.linkerFor(e)
+	prev := linker.Prev()
+	next := linker.Next()
+
+	if prev != nil {
+		rawPacketElementMapper{}.linkerFor(prev).SetNext(next)
+	} else if l.head == e {
+		l.head = next
+	}
+
+	if next != nil {
+		rawPacketElementMapper{}.linkerFor(next).SetPrev(prev)
+	} else if l.tail == e {
+		l.tail = prev
+	}
+
+	linker.SetNext(nil)
+	linker.SetPrev(nil)
+}
+
+// Entry is a default implementation of Linker. Users can add anonymous fields
+// of this type to their structs to make them automatically implement the
+// methods needed by List.
+//
+// +stateify savable
+type rawPacketEntry struct {
+	next *rawPacket
+	prev *rawPacket
+}
+
+// Next returns the entry that follows e in the list.
+//
+//go:nosplit
+func (e *rawPacketEntry) Next() *rawPacket {
+	return e.next
+}
+
+// Prev returns the entry that precedes e in the list.
+//
+//go:nosplit
+func (e *rawPacketEntry) Prev() *rawPacket {
+	return e.prev
+}
+
+// SetNext assigns 'entry' as the entry that follows e in the list.
+//
+//go:nosplit
+func (e *rawPacketEntry) SetNext(elem *rawPacket) {
+	e.next = elem
+}
+
+// SetPrev assigns 'entry' as the entry that precedes e in the list.
+//
+//go:nosplit
+func (e *rawPacketEntry) SetPrev(elem *rawPacket) {
+	e.prev = elem
+}
diff --git a/pkg/tcpip/transport/raw/raw_state_autogen.go b/pkg/tcpip/transport/raw/raw_state_autogen.go
new file mode 100644
index 0000000..3bcfc7c
--- /dev/null
+++ b/pkg/tcpip/transport/raw/raw_state_autogen.go
@@ -0,0 +1,165 @@
+// automatically generated by stateify.
+
+package raw
+
+import (
+	"gvisor.dev/gvisor/pkg/state"
+	"gvisor.dev/gvisor/pkg/tcpip/buffer"
+)
+
+func (p *rawPacket) StateTypeName() string {
+	return "pkg/tcpip/transport/raw.rawPacket"
+}
+
+func (p *rawPacket) StateFields() []string {
+	return []string{
+		"rawPacketEntry",
+		"data",
+		"timestampNS",
+		"senderAddr",
+	}
+}
+
+func (p *rawPacket) beforeSave() {}
+
+// +checklocksignore
+func (p *rawPacket) StateSave(stateSinkObject state.Sink) {
+	p.beforeSave()
+	var dataValue buffer.VectorisedView = p.saveData()
+	stateSinkObject.SaveValue(1, dataValue)
+	stateSinkObject.Save(0, &p.rawPacketEntry)
+	stateSinkObject.Save(2, &p.timestampNS)
+	stateSinkObject.Save(3, &p.senderAddr)
+}
+
+func (p *rawPacket) afterLoad() {}
+
+// +checklocksignore
+func (p *rawPacket) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &p.rawPacketEntry)
+	stateSourceObject.Load(2, &p.timestampNS)
+	stateSourceObject.Load(3, &p.senderAddr)
+	stateSourceObject.LoadValue(1, new(buffer.VectorisedView), func(y interface{}) { p.loadData(y.(buffer.VectorisedView)) })
+}
+
+func (e *endpoint) StateTypeName() string {
+	return "pkg/tcpip/transport/raw.endpoint"
+}
+
+func (e *endpoint) StateFields() []string {
+	return []string{
+		"TransportEndpointInfo",
+		"DefaultSocketOptionsHandler",
+		"waiterQueue",
+		"associated",
+		"rcvList",
+		"rcvBufSize",
+		"rcvBufSizeMax",
+		"rcvClosed",
+		"closed",
+		"connected",
+		"bound",
+		"owner",
+		"ops",
+	}
+}
+
+// +checklocksignore
+func (e *endpoint) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+	var rcvBufSizeMaxValue int = e.saveRcvBufSizeMax()
+	stateSinkObject.SaveValue(6, rcvBufSizeMaxValue)
+	stateSinkObject.Save(0, &e.TransportEndpointInfo)
+	stateSinkObject.Save(1, &e.DefaultSocketOptionsHandler)
+	stateSinkObject.Save(2, &e.waiterQueue)
+	stateSinkObject.Save(3, &e.associated)
+	stateSinkObject.Save(4, &e.rcvList)
+	stateSinkObject.Save(5, &e.rcvBufSize)
+	stateSinkObject.Save(7, &e.rcvClosed)
+	stateSinkObject.Save(8, &e.closed)
+	stateSinkObject.Save(9, &e.connected)
+	stateSinkObject.Save(10, &e.bound)
+	stateSinkObject.Save(11, &e.owner)
+	stateSinkObject.Save(12, &e.ops)
+}
+
+// +checklocksignore
+func (e *endpoint) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &e.TransportEndpointInfo)
+	stateSourceObject.Load(1, &e.DefaultSocketOptionsHandler)
+	stateSourceObject.Load(2, &e.waiterQueue)
+	stateSourceObject.Load(3, &e.associated)
+	stateSourceObject.Load(4, &e.rcvList)
+	stateSourceObject.Load(5, &e.rcvBufSize)
+	stateSourceObject.Load(7, &e.rcvClosed)
+	stateSourceObject.Load(8, &e.closed)
+	stateSourceObject.Load(9, &e.connected)
+	stateSourceObject.Load(10, &e.bound)
+	stateSourceObject.Load(11, &e.owner)
+	stateSourceObject.Load(12, &e.ops)
+	stateSourceObject.LoadValue(6, new(int), func(y interface{}) { e.loadRcvBufSizeMax(y.(int)) })
+	stateSourceObject.AfterLoad(e.afterLoad)
+}
+
+func (l *rawPacketList) StateTypeName() string {
+	return "pkg/tcpip/transport/raw.rawPacketList"
+}
+
+func (l *rawPacketList) StateFields() []string {
+	return []string{
+		"head",
+		"tail",
+	}
+}
+
+func (l *rawPacketList) beforeSave() {}
+
+// +checklocksignore
+func (l *rawPacketList) StateSave(stateSinkObject state.Sink) {
+	l.beforeSave()
+	stateSinkObject.Save(0, &l.head)
+	stateSinkObject.Save(1, &l.tail)
+}
+
+func (l *rawPacketList) afterLoad() {}
+
+// +checklocksignore
+func (l *rawPacketList) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &l.head)
+	stateSourceObject.Load(1, &l.tail)
+}
+
+func (e *rawPacketEntry) StateTypeName() string {
+	return "pkg/tcpip/transport/raw.rawPacketEntry"
+}
+
+func (e *rawPacketEntry) StateFields() []string {
+	return []string{
+		"next",
+		"prev",
+	}
+}
+
+func (e *rawPacketEntry) beforeSave() {}
+
+// +checklocksignore
+func (e *rawPacketEntry) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+	stateSinkObject.Save(0, &e.next)
+	stateSinkObject.Save(1, &e.prev)
+}
+
+func (e *rawPacketEntry) afterLoad() {}
+
+// +checklocksignore
+func (e *rawPacketEntry) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &e.next)
+	stateSourceObject.Load(1, &e.prev)
+}
+
+func init() {
+	state.Register((*rawPacket)(nil))
+	state.Register((*endpoint)(nil))
+	state.Register((*rawPacketList)(nil))
+	state.Register((*rawPacketEntry)(nil))
+}
diff --git a/pkg/tcpip/transport/tcp/dual_stack_test.go b/pkg/tcpip/transport/tcp/dual_stack_test.go
deleted file mode 100644
index 2d90246..0000000
--- a/pkg/tcpip/transport/tcp/dual_stack_test.go
+++ /dev/null
@@ -1,651 +0,0 @@
-// 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 tcp_test
-
-import (
-	"strings"
-	"testing"
-	"time"
-
-	"gvisor.dev/gvisor/pkg/tcpip"
-	"gvisor.dev/gvisor/pkg/tcpip/checker"
-	"gvisor.dev/gvisor/pkg/tcpip/header"
-	"gvisor.dev/gvisor/pkg/tcpip/network/ipv4"
-	"gvisor.dev/gvisor/pkg/tcpip/seqnum"
-	"gvisor.dev/gvisor/pkg/tcpip/transport/tcp"
-	"gvisor.dev/gvisor/pkg/tcpip/transport/tcp/testing/context"
-	"gvisor.dev/gvisor/pkg/waiter"
-)
-
-func TestV4MappedConnectOnV6Only(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateV6Endpoint(true)
-
-	// Start connection attempt, it must fail.
-	err := c.EP.Connect(tcpip.FullAddress{Addr: context.TestV4MappedAddr, Port: context.TestPort})
-	if _, ok := err.(*tcpip.ErrNoRoute); !ok {
-		t.Fatalf("Unexpected return value from Connect: %v", err)
-	}
-}
-
-func testV4Connect(t *testing.T, c *context.Context, checkers ...checker.NetworkChecker) {
-	// Start connection attempt.
-	we, ch := waiter.NewChannelEntry(nil)
-	c.WQ.EventRegister(&we, waiter.EventOut)
-	defer c.WQ.EventUnregister(&we)
-
-	err := c.EP.Connect(tcpip.FullAddress{Addr: context.TestV4MappedAddr, Port: context.TestPort})
-	if _, ok := err.(*tcpip.ErrConnectStarted); !ok {
-		t.Fatalf("Unexpected return value from Connect: %v", err)
-	}
-
-	// Receive SYN packet.
-	b := c.GetPacket()
-	synCheckers := append(checkers, checker.TCP(
-		checker.DstPort(context.TestPort),
-		checker.TCPFlags(header.TCPFlagSyn),
-	))
-	checker.IPv4(t, b, synCheckers...)
-
-	tcp := header.TCP(header.IPv4(b).Payload())
-	c.IRS = seqnum.Value(tcp.SequenceNumber())
-
-	iss := seqnum.Value(789)
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: tcp.DestinationPort(),
-		DstPort: tcp.SourcePort(),
-		Flags:   header.TCPFlagSyn | header.TCPFlagAck,
-		SeqNum:  iss,
-		AckNum:  c.IRS.Add(1),
-		RcvWnd:  30000,
-	})
-
-	// Receive ACK packet.
-	ackCheckers := append(checkers, checker.TCP(
-		checker.DstPort(context.TestPort),
-		checker.TCPFlags(header.TCPFlagAck),
-		checker.TCPSeqNum(uint32(c.IRS)+1),
-		checker.TCPAckNum(uint32(iss)+1),
-	))
-	checker.IPv4(t, c.GetPacket(), ackCheckers...)
-
-	// Wait for connection to be established.
-	select {
-	case <-ch:
-		if err := c.EP.LastError(); err != nil {
-			t.Fatalf("Unexpected error when connecting: %v", err)
-		}
-	case <-time.After(1 * time.Second):
-		t.Fatalf("Timed out waiting for connection")
-	}
-}
-
-func TestV4MappedConnect(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateV6Endpoint(false)
-
-	// Test the connection request.
-	testV4Connect(t, c)
-}
-
-func TestV4ConnectWhenBoundToWildcard(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateV6Endpoint(false)
-
-	// Bind to wildcard.
-	if err := c.EP.Bind(tcpip.FullAddress{}); err != nil {
-		t.Fatalf("Bind failed: %v", err)
-	}
-
-	// Test the connection request.
-	testV4Connect(t, c)
-}
-
-func TestV4ConnectWhenBoundToV4MappedWildcard(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateV6Endpoint(false)
-
-	// Bind to v4 mapped wildcard.
-	if err := c.EP.Bind(tcpip.FullAddress{Addr: context.V4MappedWildcardAddr}); err != nil {
-		t.Fatalf("Bind failed: %v", err)
-	}
-
-	// Test the connection request.
-	testV4Connect(t, c)
-}
-
-func TestV4ConnectWhenBoundToV4Mapped(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateV6Endpoint(false)
-
-	// Bind to v4 mapped address.
-	if err := c.EP.Bind(tcpip.FullAddress{Addr: context.StackV4MappedAddr}); err != nil {
-		t.Fatalf("Bind failed: %v", err)
-	}
-
-	// Test the connection request.
-	testV4Connect(t, c)
-}
-
-func testV6Connect(t *testing.T, c *context.Context, checkers ...checker.NetworkChecker) {
-	// Start connection attempt to IPv6 address.
-	we, ch := waiter.NewChannelEntry(nil)
-	c.WQ.EventRegister(&we, waiter.EventOut)
-	defer c.WQ.EventUnregister(&we)
-
-	err := c.EP.Connect(tcpip.FullAddress{Addr: context.TestV6Addr, Port: context.TestPort})
-	if _, ok := err.(*tcpip.ErrConnectStarted); !ok {
-		t.Fatalf("Unexpected return value from Connect: %v", err)
-	}
-
-	// Receive SYN packet.
-	b := c.GetV6Packet()
-	synCheckers := append(checkers, checker.TCP(
-		checker.DstPort(context.TestPort),
-		checker.TCPFlags(header.TCPFlagSyn),
-	))
-	checker.IPv6(t, b, synCheckers...)
-
-	tcp := header.TCP(header.IPv6(b).Payload())
-	c.IRS = seqnum.Value(tcp.SequenceNumber())
-
-	iss := seqnum.Value(789)
-	c.SendV6Packet(nil, &context.Headers{
-		SrcPort: tcp.DestinationPort(),
-		DstPort: tcp.SourcePort(),
-		Flags:   header.TCPFlagSyn | header.TCPFlagAck,
-		SeqNum:  iss,
-		AckNum:  c.IRS.Add(1),
-		RcvWnd:  30000,
-	})
-
-	// Receive ACK packet.
-	ackCheckers := append(checkers, checker.TCP(
-		checker.DstPort(context.TestPort),
-		checker.TCPFlags(header.TCPFlagAck),
-		checker.TCPSeqNum(uint32(c.IRS)+1),
-		checker.TCPAckNum(uint32(iss)+1),
-	))
-	checker.IPv6(t, c.GetV6Packet(), ackCheckers...)
-
-	// Wait for connection to be established.
-	select {
-	case <-ch:
-		if err := c.EP.LastError(); err != nil {
-			t.Fatalf("Unexpected error when connecting: %v", err)
-		}
-	case <-time.After(1 * time.Second):
-		t.Fatalf("Timed out waiting for connection")
-	}
-}
-
-func TestV6Connect(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateV6Endpoint(false)
-
-	// Test the connection request.
-	testV6Connect(t, c)
-}
-
-func TestV6ConnectV6Only(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateV6Endpoint(true)
-
-	// Test the connection request.
-	testV6Connect(t, c)
-}
-
-func TestV6ConnectWhenBoundToWildcard(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateV6Endpoint(false)
-
-	// Bind to wildcard.
-	if err := c.EP.Bind(tcpip.FullAddress{}); err != nil {
-		t.Fatalf("Bind failed: %v", err)
-	}
-
-	// Test the connection request.
-	testV6Connect(t, c)
-}
-
-func TestStackV6OnlyConnectWhenBoundToWildcard(t *testing.T) {
-	c := context.NewWithOpts(t, context.Options{
-		EnableV6: true,
-		MTU:      defaultMTU,
-	})
-	defer c.Cleanup()
-
-	// Create a v6 endpoint but don't set the v6-only TCP option.
-	c.CreateV6Endpoint(false)
-
-	// Bind to wildcard.
-	if err := c.EP.Bind(tcpip.FullAddress{}); err != nil {
-		t.Fatalf("Bind failed: %v", err)
-	}
-
-	// Test the connection request.
-	testV6Connect(t, c)
-}
-
-func TestV6ConnectWhenBoundToLocalAddress(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateV6Endpoint(false)
-
-	// Bind to local address.
-	if err := c.EP.Bind(tcpip.FullAddress{Addr: context.StackV6Addr}); err != nil {
-		t.Fatalf("Bind failed: %v", err)
-	}
-
-	// Test the connection request.
-	testV6Connect(t, c)
-}
-
-func TestV4RefuseOnV6Only(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateV6Endpoint(true)
-
-	// Bind to wildcard.
-	if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %v", err)
-	}
-
-	// Start listening.
-	if err := c.EP.Listen(10); err != nil {
-		t.Fatalf("Listen failed: %v", err)
-	}
-
-	// Send a SYN request.
-	irs := seqnum.Value(789)
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagSyn,
-		SeqNum:  irs,
-		RcvWnd:  30000,
-	})
-
-	// Receive the RST reply.
-	checker.IPv4(t, c.GetPacket(),
-		checker.TCP(
-			checker.SrcPort(context.StackPort),
-			checker.DstPort(context.TestPort),
-			checker.TCPFlags(header.TCPFlagRst|header.TCPFlagAck),
-			checker.TCPAckNum(uint32(irs)+1),
-		),
-	)
-}
-
-func TestV6RefuseOnBoundToV4Mapped(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateV6Endpoint(false)
-
-	// Bind and listen.
-	if err := c.EP.Bind(tcpip.FullAddress{Addr: context.V4MappedWildcardAddr, Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %v", err)
-	}
-
-	if err := c.EP.Listen(10); err != nil {
-		t.Fatalf("Listen failed: %v", err)
-	}
-
-	// Send a SYN request.
-	irs := seqnum.Value(789)
-	c.SendV6Packet(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagSyn,
-		SeqNum:  irs,
-		RcvWnd:  30000,
-	})
-
-	// Receive the RST reply.
-	checker.IPv6(t, c.GetV6Packet(),
-		checker.TCP(
-			checker.SrcPort(context.StackPort),
-			checker.DstPort(context.TestPort),
-			checker.TCPFlags(header.TCPFlagRst|header.TCPFlagAck),
-			checker.TCPAckNum(uint32(irs)+1),
-		),
-	)
-}
-
-func testV4Accept(t *testing.T, c *context.Context) {
-	c.SetGSOEnabled(true)
-	defer c.SetGSOEnabled(false)
-
-	// Start listening.
-	if err := c.EP.Listen(10); err != nil {
-		t.Fatalf("Listen failed: %v", err)
-	}
-
-	// Send a SYN request.
-	irs := seqnum.Value(789)
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagSyn,
-		SeqNum:  irs,
-		RcvWnd:  30000,
-	})
-
-	// Receive the SYN-ACK reply.
-	b := c.GetPacket()
-	tcp := header.TCP(header.IPv4(b).Payload())
-	iss := seqnum.Value(tcp.SequenceNumber())
-	checker.IPv4(t, b,
-		checker.TCP(
-			checker.SrcPort(context.StackPort),
-			checker.DstPort(context.TestPort),
-			checker.TCPFlags(header.TCPFlagAck|header.TCPFlagSyn),
-			checker.TCPAckNum(uint32(irs)+1),
-		),
-	)
-
-	// Send ACK.
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  irs + 1,
-		AckNum:  iss + 1,
-		RcvWnd:  30000,
-	})
-
-	// Try to accept the connection.
-	we, ch := waiter.NewChannelEntry(nil)
-	c.WQ.EventRegister(&we, waiter.EventIn)
-	defer c.WQ.EventUnregister(&we)
-
-	nep, _, err := c.EP.Accept(nil)
-	if _, ok := err.(*tcpip.ErrWouldBlock); ok {
-		// Wait for connection to be established.
-		select {
-		case <-ch:
-			nep, _, err = c.EP.Accept(nil)
-			if err != nil {
-				t.Fatalf("Accept failed: %v", err)
-			}
-
-		case <-time.After(1 * time.Second):
-			t.Fatalf("Timed out waiting for accept")
-		}
-	}
-
-	// Check the peer address.
-	addr, err := nep.GetRemoteAddress()
-	if err != nil {
-		t.Fatalf("GetRemoteAddress failed failed: %v", err)
-	}
-
-	if addr.Addr != context.TestAddr {
-		t.Fatalf("Unexpected remote address: got %v, want %v", addr.Addr, context.TestAddr)
-	}
-
-	var r strings.Reader
-	data := "Don't panic"
-	r.Reset(data)
-	nep.Write(&r, tcpip.WriteOptions{})
-	b = c.GetPacket()
-	tcp = header.TCP(header.IPv4(b).Payload())
-	if string(tcp.Payload()) != data {
-		t.Fatalf("Unexpected data: got %v, want %v", string(tcp.Payload()), data)
-	}
-}
-
-func TestV4AcceptOnV6(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateV6Endpoint(false)
-
-	// Bind to wildcard.
-	if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %v", err)
-	}
-
-	// Test acceptance.
-	testV4Accept(t, c)
-}
-
-func TestV4AcceptOnBoundToV4MappedWildcard(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateV6Endpoint(false)
-
-	// Bind to v4 mapped wildcard.
-	if err := c.EP.Bind(tcpip.FullAddress{Addr: context.V4MappedWildcardAddr, Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %v", err)
-	}
-
-	// Test acceptance.
-	testV4Accept(t, c)
-}
-
-func TestV4AcceptOnBoundToV4Mapped(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateV6Endpoint(false)
-
-	// Bind and listen.
-	if err := c.EP.Bind(tcpip.FullAddress{Addr: context.StackV4MappedAddr, Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %v", err)
-	}
-
-	// Test acceptance.
-	testV4Accept(t, c)
-}
-
-func TestV6AcceptOnV6(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateV6Endpoint(false)
-
-	// Bind and listen.
-	if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %v", err)
-	}
-
-	if err := c.EP.Listen(10); err != nil {
-		t.Fatalf("Listen failed: %v", err)
-	}
-
-	// Send a SYN request.
-	irs := seqnum.Value(789)
-	c.SendV6Packet(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagSyn,
-		SeqNum:  irs,
-		RcvWnd:  30000,
-	})
-
-	// Receive the SYN-ACK reply.
-	b := c.GetV6Packet()
-	tcp := header.TCP(header.IPv6(b).Payload())
-	iss := seqnum.Value(tcp.SequenceNumber())
-	checker.IPv6(t, b,
-		checker.TCP(
-			checker.SrcPort(context.StackPort),
-			checker.DstPort(context.TestPort),
-			checker.TCPFlags(header.TCPFlagAck|header.TCPFlagSyn),
-			checker.TCPAckNum(uint32(irs)+1),
-		),
-	)
-
-	// Send ACK.
-	c.SendV6Packet(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  irs + 1,
-		AckNum:  iss + 1,
-		RcvWnd:  30000,
-	})
-
-	// Try to accept the connection.
-	we, ch := waiter.NewChannelEntry(nil)
-	c.WQ.EventRegister(&we, waiter.EventIn)
-	defer c.WQ.EventUnregister(&we)
-	var addr tcpip.FullAddress
-	_, _, err := c.EP.Accept(&addr)
-	if _, ok := err.(*tcpip.ErrWouldBlock); ok {
-		// Wait for connection to be established.
-		select {
-		case <-ch:
-			_, _, err = c.EP.Accept(&addr)
-			if err != nil {
-				t.Fatalf("Accept failed: %v", err)
-			}
-
-		case <-time.After(1 * time.Second):
-			t.Fatalf("Timed out waiting for accept")
-		}
-	}
-
-	if addr.Addr != context.TestV6Addr {
-		t.Errorf("Unexpected remote address: got %s, want %s", addr.Addr, context.TestV6Addr)
-	}
-}
-
-func TestV4AcceptOnV4(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	// Create TCP endpoint.
-	var err tcpip.Error
-	c.EP, err = c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &c.WQ)
-	if err != nil {
-		t.Fatalf("NewEndpoint failed: %v", err)
-	}
-
-	// Bind to wildcard.
-	if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %v", err)
-	}
-
-	// Test acceptance.
-	testV4Accept(t, c)
-}
-
-func testV4ListenClose(t *testing.T, c *context.Context) {
-	// Set the SynRcvd threshold to zero to force a syn cookie based accept
-	// to happen.
-	var opt tcpip.TCPSynRcvdCountThresholdOption
-	if err := c.Stack().SetTransportProtocolOption(tcp.ProtocolNumber, &opt); err != nil {
-		t.Fatalf("setting TCPSynRcvdCountThresholdOption(%d, &%T(%d)): %s", tcp.ProtocolNumber, opt, opt, err)
-	}
-
-	const n = uint16(32)
-
-	// Start listening.
-	if err := c.EP.Listen(int(tcp.SynRcvdCountThreshold + 1)); err != nil {
-		t.Fatalf("Listen failed: %v", err)
-	}
-
-	irs := seqnum.Value(789)
-	for i := uint16(0); i < n; i++ {
-		// Send a SYN request.
-		c.SendPacket(nil, &context.Headers{
-			SrcPort: context.TestPort + i,
-			DstPort: context.StackPort,
-			Flags:   header.TCPFlagSyn,
-			SeqNum:  irs,
-			RcvWnd:  30000,
-		})
-	}
-
-	// Each of these ACK's will cause a syn-cookie based connection to be
-	// accepted and delivered to the listening endpoint.
-	for i := uint16(0); i < n; i++ {
-		b := c.GetPacket()
-		tcp := header.TCP(header.IPv4(b).Payload())
-		iss := seqnum.Value(tcp.SequenceNumber())
-		// Send ACK.
-		c.SendPacket(nil, &context.Headers{
-			SrcPort: tcp.DestinationPort(),
-			DstPort: context.StackPort,
-			Flags:   header.TCPFlagAck,
-			SeqNum:  irs + 1,
-			AckNum:  iss + 1,
-			RcvWnd:  30000,
-		})
-	}
-
-	// Try to accept the connection.
-	we, ch := waiter.NewChannelEntry(nil)
-	c.WQ.EventRegister(&we, waiter.EventIn)
-	defer c.WQ.EventUnregister(&we)
-	nep, _, err := c.EP.Accept(nil)
-	if _, ok := err.(*tcpip.ErrWouldBlock); ok {
-		// Wait for connection to be established.
-		select {
-		case <-ch:
-			nep, _, err = c.EP.Accept(nil)
-			if err != nil {
-				t.Fatalf("Accept failed: %v", err)
-			}
-
-		case <-time.After(10 * time.Second):
-			t.Fatalf("Timed out waiting for accept")
-		}
-	}
-	nep.Close()
-	c.EP.Close()
-}
-
-func TestV4ListenCloseOnV4(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	// Create TCP endpoint.
-	var err tcpip.Error
-	c.EP, err = c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &c.WQ)
-	if err != nil {
-		t.Fatalf("NewEndpoint failed: %v", err)
-	}
-
-	// Bind to wildcard.
-	if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %v", err)
-	}
-
-	// Test acceptance.
-	testV4ListenClose(t, c)
-}
diff --git a/pkg/tcpip/transport/tcp/rcv_test.go b/pkg/tcpip/transport/tcp/rcv_test.go
deleted file mode 100644
index 8a026ec..0000000
--- a/pkg/tcpip/transport/tcp/rcv_test.go
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2020 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 rcv_test
-
-import (
-	"testing"
-
-	"gvisor.dev/gvisor/pkg/tcpip/header"
-	"gvisor.dev/gvisor/pkg/tcpip/seqnum"
-)
-
-func TestAcceptable(t *testing.T) {
-	for _, tt := range []struct {
-		segSeq         seqnum.Value
-		segLen         seqnum.Size
-		rcvNxt, rcvAcc seqnum.Value
-		want           bool
-	}{
-		// The segment is smaller than the window.
-		{105, 2, 100, 104, false},
-		{105, 2, 101, 105, true},
-		{105, 2, 102, 106, true},
-		{105, 2, 103, 107, true},
-		{105, 2, 104, 108, true},
-		{105, 2, 105, 109, true},
-		{105, 2, 106, 110, true},
-		{105, 2, 107, 111, false},
-
-		// The segment is larger than the window.
-		{105, 4, 103, 105, true},
-		{105, 4, 104, 106, true},
-		{105, 4, 105, 107, true},
-		{105, 4, 106, 108, true},
-		{105, 4, 107, 109, true},
-		{105, 4, 108, 110, true},
-		{105, 4, 109, 111, false},
-		{105, 4, 110, 112, false},
-
-		// The segment has no width.
-		{105, 0, 100, 102, false},
-		{105, 0, 101, 103, false},
-		{105, 0, 102, 104, false},
-		{105, 0, 103, 105, true},
-		{105, 0, 104, 106, true},
-		{105, 0, 105, 107, true},
-		{105, 0, 106, 108, false},
-		{105, 0, 107, 109, false},
-
-		// The receive window has no width.
-		{105, 2, 103, 103, false},
-		{105, 2, 104, 104, false},
-		{105, 2, 105, 105, false},
-		{105, 2, 106, 106, false},
-		{105, 2, 107, 107, false},
-		{105, 2, 108, 108, false},
-		{105, 2, 109, 109, false},
-	} {
-		if got := header.Acceptable(tt.segSeq, tt.segLen, tt.rcvNxt, tt.rcvAcc); got != tt.want {
-			t.Errorf("header.Acceptable(%d, %d, %d, %d) = %t, want %t", tt.segSeq, tt.segLen, tt.rcvNxt, tt.rcvAcc, got, tt.want)
-		}
-	}
-}
diff --git a/pkg/tcpip/transport/tcp/sack_scoreboard_test.go b/pkg/tcpip/transport/tcp/sack_scoreboard_test.go
deleted file mode 100644
index b4e5ba0..0000000
--- a/pkg/tcpip/transport/tcp/sack_scoreboard_test.go
+++ /dev/null
@@ -1,249 +0,0 @@
-// 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 tcp_test
-
-import (
-	"testing"
-
-	"gvisor.dev/gvisor/pkg/tcpip/header"
-	"gvisor.dev/gvisor/pkg/tcpip/seqnum"
-	"gvisor.dev/gvisor/pkg/tcpip/transport/tcp"
-)
-
-const smss = 1500
-
-func initScoreboard(blocks []header.SACKBlock, iss seqnum.Value) *tcp.SACKScoreboard {
-	s := tcp.NewSACKScoreboard(smss, iss)
-	for _, blk := range blocks {
-		s.Insert(blk)
-	}
-	return s
-}
-
-func TestSACKScoreboardIsSACKED(t *testing.T) {
-	type blockTest struct {
-		block  header.SACKBlock
-		sacked bool
-	}
-	testCases := []struct {
-		comment          string
-		scoreboardBlocks []header.SACKBlock
-		blockTests       []blockTest
-		iss              seqnum.Value
-	}{
-		{
-			"Test holes and unsacked SACK blocks in SACKed ranges and insertion of overlapping SACK blocks",
-			[]header.SACKBlock{{10, 20}, {10, 30}, {30, 40}, {41, 50}, {5, 10}, {1, 50}, {111, 120}, {101, 110}, {52, 120}},
-			[]blockTest{
-				{header.SACKBlock{15, 21}, true},
-				{header.SACKBlock{200, 201}, false},
-				{header.SACKBlock{50, 51}, false},
-				{header.SACKBlock{53, 120}, true},
-			},
-			0,
-		},
-		{
-			"Test disjoint SACKBlocks",
-			[]header.SACKBlock{{2288624809, 2288810057}, {2288811477, 2288838565}},
-			[]blockTest{
-				{header.SACKBlock{2288624809, 2288810057}, true},
-				{header.SACKBlock{2288811477, 2288838565}, true},
-				{header.SACKBlock{2288810057, 2288811477}, false},
-			},
-			2288624809,
-		},
-		{
-			"Test sequence number wrap around",
-			[]header.SACKBlock{{4294254144, 225652}, {5340409, 5350509}},
-			[]blockTest{
-				{header.SACKBlock{4294254144, 4294254145}, true},
-				{header.SACKBlock{4294254143, 4294254144}, false},
-				{header.SACKBlock{4294254144, 1}, true},
-				{header.SACKBlock{225652, 5350509}, false},
-				{header.SACKBlock{5340409, 5350509}, true},
-				{header.SACKBlock{5350509, 5350609}, false},
-			},
-			4294254144,
-		},
-		{
-			"Test disjoint SACKBlocks out of order",
-			[]header.SACKBlock{{827450276, 827454536}, {827426028, 827428868}},
-			[]blockTest{
-				{header.SACKBlock{827426028, 827428867}, true},
-				{header.SACKBlock{827450168, 827450275}, false},
-			},
-			827426000,
-		},
-	}
-	for _, tc := range testCases {
-		sb := initScoreboard(tc.scoreboardBlocks, tc.iss)
-		for _, blkTest := range tc.blockTests {
-			if want, got := blkTest.sacked, sb.IsSACKED(blkTest.block); got != want {
-				t.Errorf("%s: s.IsSACKED(%v) = %v, want %v", tc.comment, blkTest.block, got, want)
-			}
-		}
-	}
-}
-
-func TestSACKScoreboardIsRangeLost(t *testing.T) {
-	s := tcp.NewSACKScoreboard(10, 0)
-	s.Insert(header.SACKBlock{1, 25})
-	s.Insert(header.SACKBlock{25, 50})
-	s.Insert(header.SACKBlock{51, 100})
-	s.Insert(header.SACKBlock{111, 120})
-	s.Insert(header.SACKBlock{101, 110})
-	s.Insert(header.SACKBlock{121, 141})
-	s.Insert(header.SACKBlock{145, 146})
-	s.Insert(header.SACKBlock{147, 148})
-	s.Insert(header.SACKBlock{149, 150})
-	s.Insert(header.SACKBlock{153, 154})
-	s.Insert(header.SACKBlock{155, 156})
-	testCases := []struct {
-		block header.SACKBlock
-		lost  bool
-	}{
-		// Block not covered by SACK block and has more than
-		// nDupAckThreshold discontiguous SACK blocks after it as well
-		// as (nDupAckThreshold -1) * 10 (smss) bytes that have been
-		// SACKED above the sequence number covered by this block.
-		{block: header.SACKBlock{0, 1}, lost: true},
-
-		// These blocks have all been SACKed and should not be
-		// considered lost.
-		{block: header.SACKBlock{1, 2}, lost: false},
-		{block: header.SACKBlock{25, 26}, lost: false},
-		{block: header.SACKBlock{1, 45}, lost: false},
-
-		// Same as the first case above.
-		{block: header.SACKBlock{50, 51}, lost: true},
-
-		// This block has been SACKed and should not be considered lost.
-		{block: header.SACKBlock{119, 120}, lost: false},
-
-		// This one should return true because there are >
-		// (nDupAckThreshold - 1) * 10 (smss) bytes that have been
-		// sacked above this sequence number.
-		{block: header.SACKBlock{120, 121}, lost: true},
-
-		// This block has been SACKed and should not be considered lost.
-		{block: header.SACKBlock{125, 126}, lost: false},
-
-		// This block has not been SACKed and there are nDupAckThreshold
-		// number of SACKed blocks after it.
-		{block: header.SACKBlock{141, 145}, lost: true},
-
-		// This block has not been SACKed and there are less than
-		// nDupAckThreshold SACKed sequences after it.
-		{block: header.SACKBlock{151, 152}, lost: false},
-	}
-	for _, tc := range testCases {
-		if want, got := tc.lost, s.IsRangeLost(tc.block); got != want {
-			t.Errorf("s.IsRangeLost(%v) = %v, want %v", tc.block, got, want)
-		}
-	}
-}
-
-func TestSACKScoreboardIsLost(t *testing.T) {
-	s := tcp.NewSACKScoreboard(10, 0)
-	s.Insert(header.SACKBlock{1, 25})
-	s.Insert(header.SACKBlock{25, 50})
-	s.Insert(header.SACKBlock{51, 100})
-	s.Insert(header.SACKBlock{111, 120})
-	s.Insert(header.SACKBlock{101, 110})
-	s.Insert(header.SACKBlock{121, 141})
-	s.Insert(header.SACKBlock{121, 141})
-	s.Insert(header.SACKBlock{145, 146})
-	s.Insert(header.SACKBlock{147, 148})
-	s.Insert(header.SACKBlock{149, 150})
-	s.Insert(header.SACKBlock{153, 154})
-	s.Insert(header.SACKBlock{155, 156})
-	testCases := []struct {
-		seq  seqnum.Value
-		lost bool
-	}{
-		// Sequence number not covered by SACK block and has more than
-		// nDupAckThreshold discontiguous SACK blocks after it as well
-		// as (nDupAckThreshold -1) * 10 (smss) bytes that have been
-		// SACKED above the sequence number.
-		{seq: 0, lost: true},
-
-		// These sequence numbers have all been SACKed and should not be
-		// considered lost.
-		{seq: 1, lost: false},
-		{seq: 25, lost: false},
-		{seq: 45, lost: false},
-
-		// Same as first case above.
-		{seq: 50, lost: true},
-
-		// This block has been SACKed and should not be considered lost.
-		{seq: 119, lost: false},
-
-		// This one should return true because there are >
-		// (nDupAckThreshold - 1) * 10 (smss) bytes that have been
-		// sacked above this sequence number.
-		{seq: 120, lost: true},
-
-		// This sequence number has been SACKed and should not be
-		// considered lost.
-		{seq: 125, lost: false},
-
-		// This sequence number has not been SACKed and there are
-		// nDupAckThreshold number of SACKed blocks after it.
-		{seq: 141, lost: true},
-
-		// This sequence number has not been SACKed and there are less
-		// than nDupAckThreshold SACKed sequences after it.
-		{seq: 151, lost: false},
-	}
-	for _, tc := range testCases {
-		if want, got := tc.lost, s.IsLost(tc.seq); got != want {
-			t.Errorf("s.IsLost(%v) = %v, want %v", tc.seq, got, want)
-		}
-	}
-}
-
-func TestSACKScoreboardDelete(t *testing.T) {
-	blocks := []header.SACKBlock{{4294254144, 225652}, {5340409, 5350509}}
-	s := initScoreboard(blocks, 4294254143)
-	s.Delete(5340408)
-	if s.Empty() {
-		t.Fatalf("s.Empty() = true, want false")
-	}
-	if got, want := s.Sacked(), blocks[1].Start.Size(blocks[1].End); got != want {
-		t.Fatalf("incorrect sacked bytes in scoreboard got: %v, want: %v", got, want)
-	}
-	s.Delete(5340410)
-	if s.Empty() {
-		t.Fatal("s.Empty() = true, want false")
-	}
-	newSB := header.SACKBlock{5340410, 5350509}
-	if !s.IsSACKED(newSB) {
-		t.Fatalf("s.IsSACKED(%v) = false, want true, scoreboard: %v", newSB, s)
-	}
-	s.Delete(5350509)
-	lastOctet := header.SACKBlock{5350508, 5350509}
-	if s.IsSACKED(lastOctet) {
-		t.Fatalf("s.IsSACKED(%v) = false, want true", lastOctet)
-	}
-
-	s.Delete(5350510)
-	if !s.Empty() {
-		t.Fatal("s.Empty() = false, want true")
-	}
-	if got, want := s.Sacked(), seqnum.Size(0); got != want {
-		t.Fatalf("incorrect sacked bytes in scoreboard got: %v, want: %v", got, want)
-	}
-}
diff --git a/pkg/tcpip/transport/tcp/tcp_endpoint_list.go b/pkg/tcpip/transport/tcp/tcp_endpoint_list.go
new file mode 100644
index 0000000..a7dc5df
--- /dev/null
+++ b/pkg/tcpip/transport/tcp/tcp_endpoint_list.go
@@ -0,0 +1,221 @@
+package tcp
+
+// ElementMapper provides an identity mapping by default.
+//
+// This can be replaced to provide a struct that maps elements to linker
+// objects, if they are not the same. An ElementMapper is not typically
+// required if: Linker is left as is, Element is left as is, or Linker and
+// Element are the same type.
+type endpointElementMapper struct{}
+
+// linkerFor maps an Element to a Linker.
+//
+// This default implementation should be inlined.
+//
+//go:nosplit
+func (endpointElementMapper) linkerFor(elem *endpoint) *endpoint { return elem }
+
+// List is an intrusive list. Entries can be added to or removed from the list
+// in O(1) time and with no additional memory allocations.
+//
+// The zero value for List is an empty list ready to use.
+//
+// To iterate over a list (where l is a List):
+//      for e := l.Front(); e != nil; e = e.Next() {
+// 		// do something with e.
+//      }
+//
+// +stateify savable
+type endpointList struct {
+	head *endpoint
+	tail *endpoint
+}
+
+// Reset resets list l to the empty state.
+func (l *endpointList) Reset() {
+	l.head = nil
+	l.tail = nil
+}
+
+// Empty returns true iff the list is empty.
+//
+//go:nosplit
+func (l *endpointList) Empty() bool {
+	return l.head == nil
+}
+
+// Front returns the first element of list l or nil.
+//
+//go:nosplit
+func (l *endpointList) Front() *endpoint {
+	return l.head
+}
+
+// Back returns the last element of list l or nil.
+//
+//go:nosplit
+func (l *endpointList) Back() *endpoint {
+	return l.tail
+}
+
+// Len returns the number of elements in the list.
+//
+// NOTE: This is an O(n) operation.
+//
+//go:nosplit
+func (l *endpointList) Len() (count int) {
+	for e := l.Front(); e != nil; e = (endpointElementMapper{}.linkerFor(e)).Next() {
+		count++
+	}
+	return count
+}
+
+// PushFront inserts the element e at the front of list l.
+//
+//go:nosplit
+func (l *endpointList) PushFront(e *endpoint) {
+	linker := endpointElementMapper{}.linkerFor(e)
+	linker.SetNext(l.head)
+	linker.SetPrev(nil)
+	if l.head != nil {
+		endpointElementMapper{}.linkerFor(l.head).SetPrev(e)
+	} else {
+		l.tail = e
+	}
+
+	l.head = e
+}
+
+// PushBack inserts the element e at the back of list l.
+//
+//go:nosplit
+func (l *endpointList) PushBack(e *endpoint) {
+	linker := endpointElementMapper{}.linkerFor(e)
+	linker.SetNext(nil)
+	linker.SetPrev(l.tail)
+	if l.tail != nil {
+		endpointElementMapper{}.linkerFor(l.tail).SetNext(e)
+	} else {
+		l.head = e
+	}
+
+	l.tail = e
+}
+
+// PushBackList inserts list m at the end of list l, emptying m.
+//
+//go:nosplit
+func (l *endpointList) PushBackList(m *endpointList) {
+	if l.head == nil {
+		l.head = m.head
+		l.tail = m.tail
+	} else if m.head != nil {
+		endpointElementMapper{}.linkerFor(l.tail).SetNext(m.head)
+		endpointElementMapper{}.linkerFor(m.head).SetPrev(l.tail)
+
+		l.tail = m.tail
+	}
+	m.head = nil
+	m.tail = nil
+}
+
+// InsertAfter inserts e after b.
+//
+//go:nosplit
+func (l *endpointList) InsertAfter(b, e *endpoint) {
+	bLinker := endpointElementMapper{}.linkerFor(b)
+	eLinker := endpointElementMapper{}.linkerFor(e)
+
+	a := bLinker.Next()
+
+	eLinker.SetNext(a)
+	eLinker.SetPrev(b)
+	bLinker.SetNext(e)
+
+	if a != nil {
+		endpointElementMapper{}.linkerFor(a).SetPrev(e)
+	} else {
+		l.tail = e
+	}
+}
+
+// InsertBefore inserts e before a.
+//
+//go:nosplit
+func (l *endpointList) InsertBefore(a, e *endpoint) {
+	aLinker := endpointElementMapper{}.linkerFor(a)
+	eLinker := endpointElementMapper{}.linkerFor(e)
+
+	b := aLinker.Prev()
+	eLinker.SetNext(a)
+	eLinker.SetPrev(b)
+	aLinker.SetPrev(e)
+
+	if b != nil {
+		endpointElementMapper{}.linkerFor(b).SetNext(e)
+	} else {
+		l.head = e
+	}
+}
+
+// Remove removes e from l.
+//
+//go:nosplit
+func (l *endpointList) Remove(e *endpoint) {
+	linker := endpointElementMapper{}.linkerFor(e)
+	prev := linker.Prev()
+	next := linker.Next()
+
+	if prev != nil {
+		endpointElementMapper{}.linkerFor(prev).SetNext(next)
+	} else if l.head == e {
+		l.head = next
+	}
+
+	if next != nil {
+		endpointElementMapper{}.linkerFor(next).SetPrev(prev)
+	} else if l.tail == e {
+		l.tail = prev
+	}
+
+	linker.SetNext(nil)
+	linker.SetPrev(nil)
+}
+
+// Entry is a default implementation of Linker. Users can add anonymous fields
+// of this type to their structs to make them automatically implement the
+// methods needed by List.
+//
+// +stateify savable
+type endpointEntry struct {
+	next *endpoint
+	prev *endpoint
+}
+
+// Next returns the entry that follows e in the list.
+//
+//go:nosplit
+func (e *endpointEntry) Next() *endpoint {
+	return e.next
+}
+
+// Prev returns the entry that precedes e in the list.
+//
+//go:nosplit
+func (e *endpointEntry) Prev() *endpoint {
+	return e.prev
+}
+
+// SetNext assigns 'entry' as the entry that follows e in the list.
+//
+//go:nosplit
+func (e *endpointEntry) SetNext(elem *endpoint) {
+	e.next = elem
+}
+
+// SetPrev assigns 'entry' as the entry that precedes e in the list.
+//
+//go:nosplit
+func (e *endpointEntry) SetPrev(elem *endpoint) {
+	e.prev = elem
+}
diff --git a/pkg/tcpip/transport/tcp/tcp_noracedetector_test.go b/pkg/tcpip/transport/tcp/tcp_noracedetector_test.go
deleted file mode 100644
index ced3a9c..0000000
--- a/pkg/tcpip/transport/tcp/tcp_noracedetector_test.go
+++ /dev/null
@@ -1,558 +0,0 @@
-// 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.
-//
-// These tests are flaky when run under the go race detector due to some
-// iterations taking long enough that the retransmit timer can kick in causing
-// the congestion window measurements to fail due to extra packets etc.
-//
-// +build !race
-
-package tcp_test
-
-import (
-	"bytes"
-	"fmt"
-	"math"
-	"testing"
-	"time"
-
-	"gvisor.dev/gvisor/pkg/tcpip"
-	"gvisor.dev/gvisor/pkg/tcpip/header"
-	"gvisor.dev/gvisor/pkg/tcpip/transport/tcp"
-	"gvisor.dev/gvisor/pkg/tcpip/transport/tcp/testing/context"
-	"gvisor.dev/gvisor/pkg/test/testutil"
-)
-
-func TestFastRecovery(t *testing.T) {
-	maxPayload := 32
-	c := context.New(t, uint32(header.TCPMinimumSize+header.IPv4MinimumSize+maxPayload))
-	defer c.Cleanup()
-
-	c.CreateConnected(789, 30000, -1 /* epRcvBuf */)
-
-	const iterations = 3
-	data := make([]byte, 2*maxPayload*(tcp.InitialCwnd<<(iterations+1)))
-	for i := range data {
-		data[i] = byte(i)
-	}
-
-	// Write all the data in one shot. Packets will only be written at the
-	// MTU size though.
-	var r bytes.Reader
-	r.Reset(data)
-	if _, err := c.EP.Write(&r, tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %s", err)
-	}
-
-	// Do slow start for a few iterations.
-	expected := tcp.InitialCwnd
-	bytesRead := 0
-	for i := 0; i < iterations; i++ {
-		expected = tcp.InitialCwnd << uint(i)
-		if i > 0 {
-			// Acknowledge all the data received so far if not on
-			// first iteration.
-			c.SendAck(790, bytesRead)
-		}
-
-		// Read all packets expected on this iteration. Don't
-		// acknowledge any of them just yet, so that we can measure the
-		// congestion window.
-		for j := 0; j < expected; j++ {
-			c.ReceiveAndCheckPacket(data, bytesRead, maxPayload)
-			bytesRead += maxPayload
-		}
-
-		// Check we don't receive any more packets on this iteration.
-		// The timeout can't be too high or we'll trigger a timeout.
-		c.CheckNoPacketTimeout("More packets received than expected for this cwnd.", 50*time.Millisecond)
-	}
-
-	// Send 3 duplicate acks. This should force an immediate retransmit of
-	// the pending packet and put the sender into fast recovery.
-	rtxOffset := bytesRead - maxPayload*expected
-	for i := 0; i < 3; i++ {
-		c.SendAck(790, rtxOffset)
-	}
-
-	// Receive the retransmitted packet.
-	c.ReceiveAndCheckPacket(data, rtxOffset, maxPayload)
-
-	// Wait before checking metrics.
-	metricPollFn := func() error {
-		if got, want := c.Stack().Stats().TCP.FastRetransmit.Value(), uint64(1); got != want {
-			return fmt.Errorf("got stats.TCP.FastRetransmit.Value = %d, want = %d", got, want)
-		}
-		if got, want := c.Stack().Stats().TCP.Retransmits.Value(), uint64(1); got != want {
-			return fmt.Errorf("got stats.TCP.Retransmit.Value = %d, want = %d", got, want)
-		}
-
-		if got, want := c.Stack().Stats().TCP.FastRecovery.Value(), uint64(1); got != want {
-			return fmt.Errorf("got stats.TCP.FastRecovery.Value = %d, want = %d", got, want)
-		}
-		return nil
-	}
-
-	if err := testutil.Poll(metricPollFn, 1*time.Second); err != nil {
-		t.Error(err)
-	}
-
-	// Now send 7 mode duplicate acks. Each of these should cause a window
-	// inflation by 1 and cause the sender to send an extra packet.
-	for i := 0; i < 7; i++ {
-		c.SendAck(790, rtxOffset)
-	}
-
-	recover := bytesRead
-
-	// Ensure no new packets arrive.
-	c.CheckNoPacketTimeout("More packets received than expected during recovery after dupacks for this cwnd.",
-		50*time.Millisecond)
-
-	// Acknowledge half of the pending data.
-	rtxOffset = bytesRead - expected*maxPayload/2
-	c.SendAck(790, rtxOffset)
-
-	// Receive the retransmit due to partial ack.
-	c.ReceiveAndCheckPacket(data, rtxOffset, maxPayload)
-
-	// Wait before checking metrics.
-	metricPollFn = func() error {
-		if got, want := c.Stack().Stats().TCP.FastRetransmit.Value(), uint64(2); got != want {
-			return fmt.Errorf("got stats.TCP.FastRetransmit.Value = %d, want = %d", got, want)
-		}
-		if got, want := c.Stack().Stats().TCP.Retransmits.Value(), uint64(2); got != want {
-			return fmt.Errorf("got stats.TCP.Retransmit.Value = %d, want = %d", got, want)
-		}
-		return nil
-	}
-	if err := testutil.Poll(metricPollFn, 1*time.Second); err != nil {
-		t.Error(err)
-	}
-
-	// Receive the 10 extra packets that should have been released due to
-	// the congestion window inflation in recovery.
-	for i := 0; i < 10; i++ {
-		c.ReceiveAndCheckPacket(data, bytesRead, maxPayload)
-		bytesRead += maxPayload
-	}
-
-	// A partial ACK during recovery should reduce congestion window by the
-	// number acked. Since we had "expected" packets outstanding before sending
-	// partial ack and we acked expected/2 , the cwnd and outstanding should
-	// be expected/2 + 10 (7 dupAcks + 3 for the original 3 dupacks that triggered
-	// fast recovery). Which means the sender should not send any more packets
-	// till we ack this one.
-	c.CheckNoPacketTimeout("More packets received than expected during recovery after partial ack for this cwnd.",
-		50*time.Millisecond)
-
-	// Acknowledge all pending data to recover point.
-	c.SendAck(790, recover)
-
-	// At this point, the cwnd should reset to expected/2 and there are 10
-	// packets outstanding.
-	//
-	// NOTE: Technically netstack is incorrect in that we adjust the cwnd on
-	// the same segment that takes us out of recovery. But because of that
-	// the actual cwnd at exit of recovery will be expected/2 + 1 as we
-	// acked a cwnd worth of packets which will increase the cwnd further by
-	// 1 in congestion avoidance.
-	//
-	// Now in the first iteration since there are 10 packets outstanding.
-	// We would expect to get expected/2 +1 - 10 packets. But subsequent
-	// iterations will send us expected/2 + 1 + 1 (per iteration).
-	expected = expected/2 + 1 - 10
-	for i := 0; i < iterations; i++ {
-		// Read all packets expected on this iteration. Don't
-		// acknowledge any of them just yet, so that we can measure the
-		// congestion window.
-		for j := 0; j < expected; j++ {
-			c.ReceiveAndCheckPacket(data, bytesRead, maxPayload)
-			bytesRead += maxPayload
-		}
-
-		// Check we don't receive any more packets on this iteration.
-		// The timeout can't be too high or we'll trigger a timeout.
-		c.CheckNoPacketTimeout(fmt.Sprintf("More packets received(after deflation) than expected %d for this cwnd.", expected), 50*time.Millisecond)
-
-		// Acknowledge all the data received so far.
-		c.SendAck(790, bytesRead)
-
-		// In cogestion avoidance, the packets trains increase by 1 in
-		// each iteration.
-		if i == 0 {
-			// After the first iteration we expect to get the full
-			// congestion window worth of packets in every
-			// iteration.
-			expected += 10
-		}
-		expected++
-	}
-}
-
-func TestExponentialIncreaseDuringSlowStart(t *testing.T) {
-	maxPayload := 32
-	c := context.New(t, uint32(header.TCPMinimumSize+header.IPv4MinimumSize+maxPayload))
-	defer c.Cleanup()
-
-	c.CreateConnected(789, 30000, -1 /* epRcvBuf */)
-
-	const iterations = 3
-	data := make([]byte, maxPayload*(tcp.InitialCwnd<<(iterations+1)))
-	for i := range data {
-		data[i] = byte(i)
-	}
-
-	// Write all the data in one shot. Packets will only be written at the
-	// MTU size though.
-	var r bytes.Reader
-	r.Reset(data)
-	if _, err := c.EP.Write(&r, tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %s", err)
-	}
-
-	expected := tcp.InitialCwnd
-	bytesRead := 0
-	for i := 0; i < iterations; i++ {
-		// Read all packets expected on this iteration. Don't
-		// acknowledge any of them just yet, so that we can measure the
-		// congestion window.
-		for j := 0; j < expected; j++ {
-			c.ReceiveAndCheckPacket(data, bytesRead, maxPayload)
-			bytesRead += maxPayload
-		}
-
-		// Check we don't receive any more packets on this iteration.
-		// The timeout can't be too high or we'll trigger a timeout.
-		c.CheckNoPacketTimeout("More packets received than expected for this cwnd.", 50*time.Millisecond)
-
-		// Acknowledge all the data received so far.
-		c.SendAck(790, bytesRead)
-
-		// Double the number of expected packets for the next iteration.
-		expected *= 2
-	}
-}
-
-func TestCongestionAvoidance(t *testing.T) {
-	maxPayload := 32
-	c := context.New(t, uint32(header.TCPMinimumSize+header.IPv4MinimumSize+maxPayload))
-	defer c.Cleanup()
-
-	c.CreateConnected(789, 30000, -1 /* epRcvBuf */)
-
-	const iterations = 3
-	data := make([]byte, 2*maxPayload*(tcp.InitialCwnd<<(iterations+1)))
-	for i := range data {
-		data[i] = byte(i)
-	}
-
-	// Write all the data in one shot. Packets will only be written at the
-	// MTU size though.
-	var r bytes.Reader
-	r.Reset(data)
-	if _, err := c.EP.Write(&r, tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %s", err)
-	}
-
-	// Do slow start for a few iterations.
-	expected := tcp.InitialCwnd
-	bytesRead := 0
-	for i := 0; i < iterations; i++ {
-		expected = tcp.InitialCwnd << uint(i)
-		if i > 0 {
-			// Acknowledge all the data received so far if not on
-			// first iteration.
-			c.SendAck(790, bytesRead)
-		}
-
-		// Read all packets expected on this iteration. Don't
-		// acknowledge any of them just yet, so that we can measure the
-		// congestion window.
-		for j := 0; j < expected; j++ {
-			c.ReceiveAndCheckPacket(data, bytesRead, maxPayload)
-			bytesRead += maxPayload
-		}
-
-		// Check we don't receive any more packets on this iteration.
-		// The timeout can't be too high or we'll trigger a timeout.
-		c.CheckNoPacketTimeout("More packets received than expected for this cwnd (slow start phase).", 50*time.Millisecond)
-	}
-
-	// Don't acknowledge the first packet of the last packet train. Let's
-	// wait for them to time out, which will trigger a restart of slow
-	// start, and initialization of ssthresh to cwnd/2.
-	rtxOffset := bytesRead - maxPayload*expected
-	c.ReceiveAndCheckPacket(data, rtxOffset, maxPayload)
-
-	// Acknowledge all the data received so far.
-	c.SendAck(790, bytesRead)
-
-	// This part is tricky: when the timeout happened, we had "expected"
-	// packets pending, cwnd reset to 1, and ssthresh set to expected/2.
-	// By acknowledging "expected" packets, the slow-start part will
-	// increase cwnd to expected/2 (which "consumes" expected/2-1 of the
-	// acknowledgements), then the congestion avoidance part will consume
-	// an extra expected/2 acks to take cwnd to expected/2 + 1. One ack
-	// remains in the "ack count" (which will cause cwnd to be incremented
-	// once it reaches cwnd acks).
-	//
-	// So we're straight into congestion avoidance with cwnd set to
-	// expected/2 + 1.
-	//
-	// Check that packets trains of cwnd packets are sent, and that cwnd is
-	// incremented by 1 after we acknowledge each packet.
-	expected = expected/2 + 1
-	for i := 0; i < iterations; i++ {
-		// Read all packets expected on this iteration. Don't
-		// acknowledge any of them just yet, so that we can measure the
-		// congestion window.
-		for j := 0; j < expected; j++ {
-			c.ReceiveAndCheckPacket(data, bytesRead, maxPayload)
-			bytesRead += maxPayload
-		}
-
-		// Check we don't receive any more packets on this iteration.
-		// The timeout can't be too high or we'll trigger a timeout.
-		c.CheckNoPacketTimeout("More packets received than expected for this cwnd (congestion avoidance phase).", 50*time.Millisecond)
-
-		// Acknowledge all the data received so far.
-		c.SendAck(790, bytesRead)
-
-		// In cogestion avoidance, the packets trains increase by 1 in
-		// each iteration.
-		expected++
-	}
-}
-
-// cubicCwnd returns an estimate of a cubic window given the
-// originalCwnd, wMax, last congestion event time and sRTT.
-func cubicCwnd(origCwnd int, wMax int, congEventTime time.Time, sRTT time.Duration) int {
-	cwnd := float64(origCwnd)
-	// We wait 50ms between each iteration so sRTT as computed by cubic
-	// should be close to 50ms.
-	elapsed := (time.Since(congEventTime) + sRTT).Seconds()
-	k := math.Cbrt(float64(wMax) * 0.3 / 0.7)
-	wtRTT := 0.4*math.Pow(elapsed-k, 3) + float64(wMax)
-	cwnd += (wtRTT - cwnd) / cwnd
-	return int(cwnd)
-}
-
-func TestCubicCongestionAvoidance(t *testing.T) {
-	maxPayload := 32
-	c := context.New(t, uint32(header.TCPMinimumSize+header.IPv4MinimumSize+maxPayload))
-	defer c.Cleanup()
-
-	enableCUBIC(t, c)
-
-	c.CreateConnected(789, 30000, -1 /* epRcvBuf */)
-
-	const iterations = 3
-	data := make([]byte, 2*maxPayload*(tcp.InitialCwnd<<(iterations+1)))
-	for i := range data {
-		data[i] = byte(i)
-	}
-
-	// Write all the data in one shot. Packets will only be written at the
-	// MTU size though.
-	var r bytes.Reader
-	r.Reset(data)
-	if _, err := c.EP.Write(&r, tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %s", err)
-	}
-
-	// Do slow start for a few iterations.
-	expected := tcp.InitialCwnd
-	bytesRead := 0
-	for i := 0; i < iterations; i++ {
-		expected = tcp.InitialCwnd << uint(i)
-		if i > 0 {
-			// Acknowledge all the data received so far if not on
-			// first iteration.
-			c.SendAck(790, bytesRead)
-		}
-
-		// Read all packets expected on this iteration. Don't
-		// acknowledge any of them just yet, so that we can measure the
-		// congestion window.
-		for j := 0; j < expected; j++ {
-			c.ReceiveAndCheckPacket(data, bytesRead, maxPayload)
-			bytesRead += maxPayload
-		}
-
-		// Check we don't receive any more packets on this iteration.
-		// The timeout can't be too high or we'll trigger a timeout.
-		c.CheckNoPacketTimeout("More packets received than expected for this cwnd (during slow-start phase).", 50*time.Millisecond)
-	}
-
-	// Don't acknowledge the first packet of the last packet train. Let's
-	// wait for them to time out, which will trigger a restart of slow
-	// start, and initialization of ssthresh to cwnd * 0.7.
-	rtxOffset := bytesRead - maxPayload*expected
-	c.ReceiveAndCheckPacket(data, rtxOffset, maxPayload)
-
-	// Acknowledge all pending data.
-	c.SendAck(790, bytesRead)
-
-	// Store away the time we sent the ACK and assuming a 200ms RTO
-	// we estimate that the sender will have an RTO 200ms from now
-	// and go back into slow start.
-	packetDropTime := time.Now().Add(200 * time.Millisecond)
-
-	// This part is tricky: when the timeout happened, we had "expected"
-	// packets pending, cwnd reset to 1, and ssthresh set to expected * 0.7.
-	// By acknowledging "expected" packets, the slow-start part will
-	// increase cwnd to expected/2 essentially putting the connection
-	// straight into congestion avoidance.
-	wMax := expected
-	// Lower expected as per cubic spec after a congestion event.
-	expected = int(float64(expected) * 0.7)
-	cwnd := expected
-	for i := 0; i < iterations; i++ {
-		// Cubic grows window independent of ACKs. Cubic Window growth
-		// is a function of time elapsed since last congestion event.
-		// As a result the congestion window does not grow
-		// deterministically in response to ACKs.
-		//
-		// We need to roughly estimate what the cwnd of the sender is
-		// based on when we sent the dupacks.
-		cwnd := cubicCwnd(cwnd, wMax, packetDropTime, 50*time.Millisecond)
-
-		packetsExpected := cwnd
-		for j := 0; j < packetsExpected; j++ {
-			c.ReceiveAndCheckPacket(data, bytesRead, maxPayload)
-			bytesRead += maxPayload
-		}
-		t.Logf("expected packets received, next trying to receive any extra packets that may come")
-
-		// If our estimate was correct there should be no more pending packets.
-		// We attempt to read a packet a few times with a short sleep in between
-		// to ensure that we don't see the sender send any unexpected packets.
-		unexpectedPackets := 0
-		for {
-			gotPacket := c.ReceiveNonBlockingAndCheckPacket(data, bytesRead, maxPayload)
-			if !gotPacket {
-				break
-			}
-			bytesRead += maxPayload
-			unexpectedPackets++
-			time.Sleep(1 * time.Millisecond)
-		}
-		if unexpectedPackets != 0 {
-			t.Fatalf("received %d unexpected packets for iteration %d", unexpectedPackets, i)
-		}
-		// Check we don't receive any more packets on this iteration.
-		// The timeout can't be too high or we'll trigger a timeout.
-		c.CheckNoPacketTimeout("More packets received than expected for this cwnd(congestion avoidance)", 5*time.Millisecond)
-
-		// Acknowledge all the data received so far.
-		c.SendAck(790, bytesRead)
-	}
-}
-
-func TestRetransmit(t *testing.T) {
-	maxPayload := 32
-	c := context.New(t, uint32(header.TCPMinimumSize+header.IPv4MinimumSize+maxPayload))
-	defer c.Cleanup()
-
-	c.CreateConnected(789, 30000, -1 /* epRcvBuf */)
-
-	const iterations = 3
-	data := make([]byte, maxPayload*(tcp.InitialCwnd<<(iterations+1)))
-	for i := range data {
-		data[i] = byte(i)
-	}
-
-	// Write all the data in two shots. Packets will only be written at the
-	// MTU size though.
-	var r bytes.Reader
-	r.Reset(data[:len(data)/2])
-	if _, err := c.EP.Write(&r, tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %s", err)
-	}
-	r.Reset(data[len(data)/2:])
-	if _, err := c.EP.Write(&r, tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %s", err)
-	}
-
-	// Do slow start for a few iterations.
-	expected := tcp.InitialCwnd
-	bytesRead := 0
-	for i := 0; i < iterations; i++ {
-		expected = tcp.InitialCwnd << uint(i)
-		if i > 0 {
-			// Acknowledge all the data received so far if not on
-			// first iteration.
-			c.SendAck(790, bytesRead)
-		}
-
-		// Read all packets expected on this iteration. Don't
-		// acknowledge any of them just yet, so that we can measure the
-		// congestion window.
-		for j := 0; j < expected; j++ {
-			c.ReceiveAndCheckPacket(data, bytesRead, maxPayload)
-			bytesRead += maxPayload
-		}
-
-		// Check we don't receive any more packets on this iteration.
-		// The timeout can't be too high or we'll trigger a timeout.
-		c.CheckNoPacketTimeout("More packets received than expected for this cwnd.", 50*time.Millisecond)
-	}
-
-	// Wait for a timeout and retransmit.
-	rtxOffset := bytesRead - maxPayload*expected
-	c.ReceiveAndCheckPacket(data, rtxOffset, maxPayload)
-
-	metricPollFn := func() error {
-		if got, want := c.Stack().Stats().TCP.Timeouts.Value(), uint64(1); got != want {
-			return fmt.Errorf("got stats.TCP.Timeouts.Value = %d, want = %d", got, want)
-		}
-
-		if got, want := c.Stack().Stats().TCP.Retransmits.Value(), uint64(1); got != want {
-			return fmt.Errorf("got stats.TCP.Retransmits.Value = %d, want = %d", got, want)
-		}
-
-		if got, want := c.EP.Stats().(*tcp.Stats).SendErrors.Timeouts.Value(), uint64(1); got != want {
-			return fmt.Errorf("got EP SendErrors.Timeouts.Value = %d, want = %d", got, want)
-		}
-
-		if got, want := c.EP.Stats().(*tcp.Stats).SendErrors.Retransmits.Value(), uint64(1); got != want {
-			return fmt.Errorf("got EP stats SendErrors.Retransmits.Value = %d, want = %d", got, want)
-		}
-
-		if got, want := c.Stack().Stats().TCP.SlowStartRetransmits.Value(), uint64(1); got != want {
-			return fmt.Errorf("got stats.TCP.SlowStartRetransmits.Value = %d, want = %d", got, want)
-		}
-
-		return nil
-	}
-
-	// Poll when checking metrics.
-	if err := testutil.Poll(metricPollFn, 1*time.Second); err != nil {
-		t.Error(err)
-	}
-
-	// Acknowledge half of the pending data.
-	rtxOffset = bytesRead - expected*maxPayload/2
-	c.SendAck(790, rtxOffset)
-
-	// Receive the remaining data, making sure that acknowledged data is not
-	// retransmitted.
-	for offset := rtxOffset; offset < len(data); offset += maxPayload {
-		c.ReceiveAndCheckPacket(data, offset, maxPayload)
-		c.SendAck(790, offset+maxPayload)
-	}
-
-	c.CheckNoPacketTimeout("More packets received than expected for this cwnd.", 50*time.Millisecond)
-}
diff --git a/pkg/tcpip/transport/tcp/tcp_rack_test.go b/pkg/tcpip/transport/tcp/tcp_rack_test.go
deleted file mode 100644
index 5cdd5b5..0000000
--- a/pkg/tcpip/transport/tcp/tcp_rack_test.go
+++ /dev/null
@@ -1,1057 +0,0 @@
-// Copyright 2020 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 tcp_test
-
-import (
-	"bytes"
-	"fmt"
-	"testing"
-	"time"
-
-	"gvisor.dev/gvisor/pkg/tcpip"
-	"gvisor.dev/gvisor/pkg/tcpip/header"
-	"gvisor.dev/gvisor/pkg/tcpip/seqnum"
-	"gvisor.dev/gvisor/pkg/tcpip/stack"
-	"gvisor.dev/gvisor/pkg/tcpip/transport/tcp/testing/context"
-	"gvisor.dev/gvisor/pkg/test/testutil"
-)
-
-const (
-	maxPayload       = 10
-	tsOptionSize     = 12
-	maxTCPOptionSize = 40
-	mtu              = header.TCPMinimumSize + header.IPv4MinimumSize + maxTCPOptionSize + maxPayload
-)
-
-func setStackRACKPermitted(t *testing.T, c *context.Context) {
-	t.Helper()
-	opt := tcpip.TCPRecovery(tcpip.TCPRACKLossDetection)
-	if err := c.Stack().SetTransportProtocolOption(header.TCPProtocolNumber, &opt); err != nil {
-		t.Fatalf("c.s.SetTransportProtocolOption(%d, &%v(%v)): %s", header.TCPProtocolNumber, opt, opt, err)
-	}
-}
-
-// TestRACKUpdate tests the RACK related fields are updated when an ACK is
-// received on a SACK enabled connection.
-func TestRACKUpdate(t *testing.T) {
-	c := context.New(t, uint32(mtu))
-	defer c.Cleanup()
-
-	var xmitTime time.Time
-	probeDone := make(chan struct{})
-	c.Stack().AddTCPProbe(func(state stack.TCPEndpointState) {
-		// Validate that the endpoint Sender.RACKState is what we expect.
-		if state.Sender.RACKState.XmitTime.Before(xmitTime) {
-			t.Fatalf("RACK transmit time failed to update when an ACK is received")
-		}
-
-		gotSeq := state.Sender.RACKState.EndSequence
-		wantSeq := state.Sender.SndNxt
-		if !gotSeq.LessThanEq(wantSeq) || gotSeq.LessThan(wantSeq) {
-			t.Fatalf("RACK sequence number failed to update, got: %v, but want: %v", gotSeq, wantSeq)
-		}
-
-		if state.Sender.RACKState.RTT == 0 {
-			t.Fatalf("RACK RTT failed to update when an ACK is received, got RACKState.RTT == 0 want != 0")
-		}
-		close(probeDone)
-	})
-	setStackSACKPermitted(t, c, true)
-	setStackRACKPermitted(t, c)
-	createConnectedWithSACKAndTS(c)
-
-	data := make([]byte, maxPayload)
-	for i := range data {
-		data[i] = byte(i)
-	}
-
-	// Write the data.
-	xmitTime = time.Now()
-	var r bytes.Reader
-	r.Reset(data)
-	if _, err := c.EP.Write(&r, tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %s", err)
-	}
-
-	bytesRead := 0
-	c.ReceiveAndCheckPacketWithOptions(data, bytesRead, maxPayload, tsOptionSize)
-	bytesRead += maxPayload
-	c.SendAck(seqnum.Value(context.TestInitialSequenceNumber).Add(1), bytesRead)
-
-	// Wait for the probe function to finish processing the ACK before the
-	// test completes.
-	<-probeDone
-}
-
-// TestRACKDetectReorder tests that RACK detects packet reordering.
-func TestRACKDetectReorder(t *testing.T) {
-	c := context.New(t, uint32(mtu))
-	defer c.Cleanup()
-
-	t.Skipf("Skipping this test as reorder detection does not consider DSACK.")
-
-	var n int
-	const ackNumToVerify = 2
-	probeDone := make(chan struct{})
-	c.Stack().AddTCPProbe(func(state stack.TCPEndpointState) {
-		gotSeq := state.Sender.RACKState.FACK
-		wantSeq := state.Sender.SndNxt
-		// FACK should be updated to the highest ending sequence number of the
-		// segment acknowledged most recently.
-		if !gotSeq.LessThanEq(wantSeq) || gotSeq.LessThan(wantSeq) {
-			t.Fatalf("RACK FACK failed to update, got: %v, but want: %v", gotSeq, wantSeq)
-		}
-
-		n++
-		if n < ackNumToVerify {
-			if state.Sender.RACKState.Reord {
-				t.Fatalf("RACK reorder detected when there is no reordering")
-			}
-			return
-		}
-
-		if state.Sender.RACKState.Reord == false {
-			t.Fatalf("RACK reorder detection failed")
-		}
-		close(probeDone)
-	})
-	setStackSACKPermitted(t, c, true)
-	setStackRACKPermitted(t, c)
-	createConnectedWithSACKAndTS(c)
-	data := make([]byte, ackNumToVerify*maxPayload)
-	for i := range data {
-		data[i] = byte(i)
-	}
-
-	// Write the data.
-	var r bytes.Reader
-	r.Reset(data)
-	if _, err := c.EP.Write(&r, tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %s", err)
-	}
-
-	bytesRead := 0
-	for i := 0; i < ackNumToVerify; i++ {
-		c.ReceiveAndCheckPacketWithOptions(data, bytesRead, maxPayload, tsOptionSize)
-		bytesRead += maxPayload
-	}
-
-	start := c.IRS.Add(maxPayload + 1)
-	end := start.Add(maxPayload)
-	seq := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	c.SendAckWithSACK(seq, 0, []header.SACKBlock{{start, end}})
-	c.SendAck(seq, bytesRead)
-
-	// Wait for the probe function to finish processing the ACK before the
-	// test completes.
-	<-probeDone
-}
-
-func sendAndReceiveWithSACK(t *testing.T, c *context.Context, numPackets int, enableRACK bool) []byte {
-	setStackSACKPermitted(t, c, true)
-	if enableRACK {
-		setStackRACKPermitted(t, c)
-	}
-	createConnectedWithSACKAndTS(c)
-
-	data := make([]byte, numPackets*maxPayload)
-	for i := range data {
-		data[i] = byte(i)
-	}
-
-	// Write the data.
-	var r bytes.Reader
-	r.Reset(data)
-	if _, err := c.EP.Write(&r, tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %s", err)
-	}
-
-	bytesRead := 0
-	for i := 0; i < numPackets; i++ {
-		c.ReceiveAndCheckPacketWithOptions(data, bytesRead, maxPayload, tsOptionSize)
-		bytesRead += maxPayload
-	}
-
-	return data
-}
-
-const (
-	validDSACKDetected   = 1
-	failedToDetectDSACK  = 2
-	invalidDSACKDetected = 3
-)
-
-func addDSACKSeenCheckerProbe(t *testing.T, c *context.Context, numACK int, probeDone chan int) {
-	var n int
-	c.Stack().AddTCPProbe(func(state stack.TCPEndpointState) {
-		// Validate that RACK detects DSACK.
-		n++
-		if n < numACK {
-			if state.Sender.RACKState.DSACKSeen {
-				probeDone <- invalidDSACKDetected
-			}
-			return
-		}
-
-		if !state.Sender.RACKState.DSACKSeen {
-			probeDone <- failedToDetectDSACK
-			return
-		}
-		probeDone <- validDSACKDetected
-	})
-}
-
-// TestRACKTLPRecovery tests that RACK sends a tail loss probe (TLP) in the
-// case of a tail loss. This simulates a situation where the TLP is able to
-// insinuate the SACK holes and sender is able to retransmit the rest.
-func TestRACKTLPRecovery(t *testing.T) {
-	c := context.New(t, uint32(mtu))
-	defer c.Cleanup()
-
-	// Send 8 packets.
-	numPackets := 8
-	data := sendAndReceiveWithSACK(t, c, numPackets, true /* enableRACK */)
-
-	// Packets [6-8] are lost. Send cumulative ACK for [1-5].
-	seq := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	bytesRead := 5 * maxPayload
-	c.SendAck(seq, bytesRead)
-
-	// PTO should fire and send #8 packet as a TLP.
-	c.ReceiveAndCheckPacketWithOptions(data, 7*maxPayload, maxPayload, tsOptionSize)
-	var info tcpip.TCPInfoOption
-	if err := c.EP.GetSockOpt(&info); err != nil {
-		t.Fatalf("GetSockOpt failed: %v", err)
-	}
-
-	// Send the SACK after RTT because RACK RFC states that if the ACK for a
-	// retransmission arrives before the smoothed RTT then the sender should not
-	// update RACK state as it could be a spurious inference.
-	time.Sleep(info.RTT)
-
-	// Okay, let the sender know we got #8 using a SACK block.
-	eighthPStart := c.IRS.Add(1 + seqnum.Size(7*maxPayload))
-	eighthPEnd := eighthPStart.Add(maxPayload)
-	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{eighthPStart, eighthPEnd}})
-
-	// The sender should be entering RACK based loss-recovery and sending #6 and
-	// #7 one after another.
-	c.ReceiveAndCheckPacketWithOptions(data, bytesRead, maxPayload, tsOptionSize)
-	bytesRead += maxPayload
-	c.ReceiveAndCheckPacketWithOptions(data, bytesRead, maxPayload, tsOptionSize)
-	bytesRead += 2 * maxPayload
-	c.SendAck(seq, bytesRead)
-
-	metricPollFn := func() error {
-		tcpStats := c.Stack().Stats().TCP
-		stats := []struct {
-			stat *tcpip.StatCounter
-			name string
-			want uint64
-		}{
-			// One fast retransmit after the SACK.
-			{tcpStats.FastRetransmit, "stats.TCP.FastRetransmit", 1},
-			// Recovery should be SACK recovery.
-			{tcpStats.SACKRecovery, "stats.TCP.SACKRecovery", 1},
-			// Packets 6, 7 and 8 were retransmitted.
-			{tcpStats.Retransmits, "stats.TCP.Retransmits", 3},
-			// TLP recovery should have been detected.
-			{tcpStats.TLPRecovery, "stats.TCP.TLPRecovery", 1},
-			// No RTOs should have occurred.
-			{tcpStats.Timeouts, "stats.TCP.Timeouts", 0},
-		}
-		for _, s := range stats {
-			if got, want := s.stat.Value(), s.want; got != want {
-				return fmt.Errorf("got %s.Value() = %d, want = %d", s.name, got, want)
-			}
-		}
-		return nil
-	}
-	if err := testutil.Poll(metricPollFn, 1*time.Second); err != nil {
-		t.Error(err)
-	}
-}
-
-// TestRACKTLPFallbackRTO tests that RACK sends a tail loss probe (TLP) in the
-// case of a tail loss. This simulates a situation where either the TLP or its
-// ACK is lost. The sender should retransmit when RTO fires.
-func TestRACKTLPFallbackRTO(t *testing.T) {
-	c := context.New(t, uint32(mtu))
-	defer c.Cleanup()
-
-	// Send 8 packets.
-	numPackets := 8
-	data := sendAndReceiveWithSACK(t, c, numPackets, true /* enableRACK */)
-
-	// Packets [6-8] are lost. Send cumulative ACK for [1-5].
-	seq := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	bytesRead := 5 * maxPayload
-	c.SendAck(seq, bytesRead)
-
-	// PTO should fire and send #8 packet as a TLP.
-	c.ReceiveAndCheckPacketWithOptions(data, 7*maxPayload, maxPayload, tsOptionSize)
-
-	// Either the TLP or the ACK the receiver sent with SACK blocks was lost.
-
-	// Confirm that RTO fires and retransmits packet #6.
-	c.ReceiveAndCheckPacketWithOptions(data, bytesRead, maxPayload, tsOptionSize)
-
-	metricPollFn := func() error {
-		tcpStats := c.Stack().Stats().TCP
-		stats := []struct {
-			stat *tcpip.StatCounter
-			name string
-			want uint64
-		}{
-			// No fast retransmits happened.
-			{tcpStats.FastRetransmit, "stats.TCP.FastRetransmit", 0},
-			// No SACK recovery happened.
-			{tcpStats.SACKRecovery, "stats.TCP.SACKRecovery", 0},
-			// TLP was unsuccessful.
-			{tcpStats.TLPRecovery, "stats.TCP.TLPRecovery", 0},
-			// RTO should have fired.
-			{tcpStats.Timeouts, "stats.TCP.Timeouts", 1},
-		}
-		for _, s := range stats {
-			if got, want := s.stat.Value(), s.want; got != want {
-				return fmt.Errorf("got %s.Value() = %d, want = %d", s.name, got, want)
-			}
-		}
-		return nil
-	}
-	if err := testutil.Poll(metricPollFn, 1*time.Second); err != nil {
-		t.Error(err)
-	}
-}
-
-// TestNoTLPRecoveryOnDSACK tests the scenario where the sender speculates a
-// tail loss and sends a TLP. Everything is received and acked. The probe
-// segment is DSACKed. No fast recovery should be triggered in this case.
-func TestNoTLPRecoveryOnDSACK(t *testing.T) {
-	c := context.New(t, uint32(mtu))
-	defer c.Cleanup()
-
-	// Send 8 packets.
-	numPackets := 8
-	data := sendAndReceiveWithSACK(t, c, numPackets, true /* enableRACK */)
-
-	// Packets [1-5] are received first. [6-8] took a detour and will take a
-	// while to arrive. Ack [1-5].
-	seq := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	bytesRead := 5 * maxPayload
-	c.SendAck(seq, bytesRead)
-
-	// The tail loss probe (#8 packet) is received.
-	c.ReceiveAndCheckPacketWithOptions(data, 7*maxPayload, maxPayload, tsOptionSize)
-
-	// Now that all 8 packets are received + duplicate 8th packet, send ack.
-	bytesRead += 3 * maxPayload
-	eighthPStart := c.IRS.Add(1 + seqnum.Size(7*maxPayload))
-	eighthPEnd := eighthPStart.Add(maxPayload)
-	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{eighthPStart, eighthPEnd}})
-
-	// Wait for RTO and make sure that nothing else is received.
-	var info tcpip.TCPInfoOption
-	if err := c.EP.GetSockOpt(&info); err != nil {
-		t.Fatalf("GetSockOpt failed: %v", err)
-	}
-	if p := c.GetPacketWithTimeout(info.RTO); p != nil {
-		t.Errorf("received an unexpected packet: %v", p)
-	}
-
-	metricPollFn := func() error {
-		tcpStats := c.Stack().Stats().TCP
-		stats := []struct {
-			stat *tcpip.StatCounter
-			name string
-			want uint64
-		}{
-			// Make sure no recovery was entered.
-			{tcpStats.FastRetransmit, "stats.TCP.FastRetransmit", 0},
-			{tcpStats.SACKRecovery, "stats.TCP.SACKRecovery", 0},
-			{tcpStats.TLPRecovery, "stats.TCP.TLPRecovery", 0},
-			// RTO should not have fired.
-			{tcpStats.Timeouts, "stats.TCP.Timeouts", 0},
-			// Only #8 was retransmitted.
-			{tcpStats.Retransmits, "stats.TCP.Retransmits", 1},
-		}
-		for _, s := range stats {
-			if got, want := s.stat.Value(), s.want; got != want {
-				return fmt.Errorf("got %s.Value() = %d, want = %d", s.name, got, want)
-			}
-		}
-		return nil
-	}
-	if err := testutil.Poll(metricPollFn, 1*time.Second); err != nil {
-		t.Error(err)
-	}
-}
-
-// TestNoTLPOnSACK tests the scenario where there is not exactly a tail loss
-// due to the presence of multiple SACK holes. In such a scenario, TLP should
-// not be sent.
-func TestNoTLPOnSACK(t *testing.T) {
-	c := context.New(t, uint32(mtu))
-	defer c.Cleanup()
-
-	// Send 8 packets.
-	numPackets := 8
-	data := sendAndReceiveWithSACK(t, c, numPackets, true /* enableRACK */)
-
-	// Packets [1-5] and #7 were received. #6 and #8 were dropped.
-	seq := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	bytesRead := 5 * maxPayload
-	seventhStart := c.IRS.Add(1 + seqnum.Size(6*maxPayload))
-	seventhEnd := seventhStart.Add(maxPayload)
-	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{seventhStart, seventhEnd}})
-
-	// The sender should retransmit #6. If the sender sends a TLP, then #8 will
-	// received and fail this test.
-	c.ReceiveAndCheckPacketWithOptions(data, 5*maxPayload, maxPayload, tsOptionSize)
-
-	metricPollFn := func() error {
-		tcpStats := c.Stack().Stats().TCP
-		stats := []struct {
-			stat *tcpip.StatCounter
-			name string
-			want uint64
-		}{
-			// #6 was retransmitted due to SACK recovery.
-			{tcpStats.FastRetransmit, "stats.TCP.FastRetransmit", 1},
-			{tcpStats.SACKRecovery, "stats.TCP.SACKRecovery", 1},
-			{tcpStats.TLPRecovery, "stats.TCP.TLPRecovery", 0},
-			// RTO should not have fired.
-			{tcpStats.Timeouts, "stats.TCP.Timeouts", 0},
-			// Only #6 was retransmitted.
-			{tcpStats.Retransmits, "stats.TCP.Retransmits", 1},
-		}
-		for _, s := range stats {
-			if got, want := s.stat.Value(), s.want; got != want {
-				return fmt.Errorf("got %s.Value() = %d, want = %d", s.name, got, want)
-			}
-		}
-		return nil
-	}
-	if err := testutil.Poll(metricPollFn, 1*time.Second); err != nil {
-		t.Error(err)
-	}
-}
-
-// TestRACKOnePacketTailLoss tests the trivial case of a tail loss of only one
-// packet. The probe should itself repairs the loss instead of having to go
-// into any recovery.
-func TestRACKOnePacketTailLoss(t *testing.T) {
-	c := context.New(t, uint32(mtu))
-	defer c.Cleanup()
-
-	// Send 3 packets.
-	numPackets := 3
-	data := sendAndReceiveWithSACK(t, c, numPackets, true /* enableRACK */)
-
-	// Packets [1-2] are received. #3 is lost.
-	seq := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	bytesRead := 2 * maxPayload
-	c.SendAck(seq, bytesRead)
-
-	// PTO should fire and send #3 packet as a TLP.
-	c.ReceiveAndCheckPacketWithOptions(data, 2*maxPayload, maxPayload, tsOptionSize)
-	bytesRead += maxPayload
-	c.SendAck(seq, bytesRead)
-
-	metricPollFn := func() error {
-		tcpStats := c.Stack().Stats().TCP
-		stats := []struct {
-			stat *tcpip.StatCounter
-			name string
-			want uint64
-		}{
-			// #3 was retransmitted as TLP.
-			{tcpStats.FastRetransmit, "stats.TCP.FastRetransmit", 0},
-			{tcpStats.SACKRecovery, "stats.TCP.SACKRecovery", 0},
-			{tcpStats.TLPRecovery, "stats.TCP.TLPRecovery", 0},
-			// RTO should not have fired.
-			{tcpStats.Timeouts, "stats.TCP.Timeouts", 0},
-			// Only #3 was retransmitted.
-			{tcpStats.Retransmits, "stats.TCP.Retransmits", 1},
-		}
-		for _, s := range stats {
-			if got, want := s.stat.Value(), s.want; got != want {
-				return fmt.Errorf("got %s.Value() = %d, want = %d", s.name, got, want)
-			}
-		}
-		return nil
-	}
-	if err := testutil.Poll(metricPollFn, 1*time.Second); err != nil {
-		t.Error(err)
-	}
-}
-
-// TestRACKDetectDSACK tests that RACK detects DSACK with duplicate segments.
-// See: https://tools.ietf.org/html/rfc2883#section-4.1.1.
-func TestRACKDetectDSACK(t *testing.T) {
-	c := context.New(t, uint32(mtu))
-	defer c.Cleanup()
-
-	probeDone := make(chan int)
-	const ackNumToVerify = 2
-	addDSACKSeenCheckerProbe(t, c, ackNumToVerify, probeDone)
-
-	numPackets := 8
-	data := sendAndReceiveWithSACK(t, c, numPackets, true /* enableRACK */)
-
-	// Cumulative ACK for [1-5] packets and SACK #8 packet (to prevent TLP).
-	seq := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	bytesRead := 5 * maxPayload
-	eighthPStart := c.IRS.Add(1 + seqnum.Size(7*maxPayload))
-	eighthPEnd := eighthPStart.Add(maxPayload)
-	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{eighthPStart, eighthPEnd}})
-
-	// Expect retransmission of #6 packet after RTO expires.
-	c.ReceiveAndCheckPacketWithOptions(data, bytesRead, maxPayload, tsOptionSize)
-
-	// Send DSACK block for #6 packet indicating both
-	// initial and retransmitted packet are received and
-	// packets [1-8] are received.
-	start := c.IRS.Add(1 + seqnum.Size(bytesRead))
-	end := start.Add(maxPayload)
-	bytesRead += 3 * maxPayload
-	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{start, end}})
-
-	// Wait for the probe function to finish processing the
-	// ACK before the test completes.
-	err := <-probeDone
-	switch err {
-	case failedToDetectDSACK:
-		t.Fatalf("RACK DSACK detection failed")
-	case invalidDSACKDetected:
-		t.Fatalf("RACK DSACK detected when there is no duplicate SACK")
-	}
-}
-
-// TestRACKDetectDSACKWithOutOfOrder tests that RACK detects DSACK with out of
-// order segments.
-// See: https://tools.ietf.org/html/rfc2883#section-4.1.2.
-func TestRACKDetectDSACKWithOutOfOrder(t *testing.T) {
-	c := context.New(t, uint32(mtu))
-	defer c.Cleanup()
-
-	probeDone := make(chan int)
-	const ackNumToVerify = 2
-	addDSACKSeenCheckerProbe(t, c, ackNumToVerify, probeDone)
-
-	numPackets := 10
-	data := sendAndReceiveWithSACK(t, c, numPackets, true /* enableRACK */)
-
-	// Cumulative ACK for [1-5] packets and SACK for #7 packet (to prevent TLP).
-	seq := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	bytesRead := 5 * maxPayload
-	seventhPStart := c.IRS.Add(1 + seqnum.Size(6*maxPayload))
-	seventhPEnd := seventhPStart.Add(maxPayload)
-	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{seventhPStart, seventhPEnd}})
-
-	// Expect retransmission of #6 packet.
-	c.ReceiveAndCheckPacketWithOptions(data, bytesRead, maxPayload, tsOptionSize)
-
-	// Send DSACK block for #6 packet indicating both
-	// initial and retransmitted packet are received and
-	// packets [1-7] are received.
-	start := c.IRS.Add(1 + seqnum.Size(bytesRead))
-	end := start.Add(maxPayload)
-	bytesRead += 2 * maxPayload
-	// Send DSACK block for #6 along with SACK for out of
-	// order #9 packet.
-	start1 := c.IRS.Add(1 + seqnum.Size(bytesRead) + maxPayload)
-	end1 := start1.Add(maxPayload)
-	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{start, end}, {start1, end1}})
-
-	// Wait for the probe function to finish processing the
-	// ACK before the test completes.
-	err := <-probeDone
-	switch err {
-	case failedToDetectDSACK:
-		t.Fatalf("RACK DSACK detection failed")
-	case invalidDSACKDetected:
-		t.Fatalf("RACK DSACK detected when there is no duplicate SACK")
-	}
-}
-
-// TestRACKDetectDSACKWithOutOfOrderDup tests that DSACK is detected on a
-// duplicate of out of order packet.
-// See: https://tools.ietf.org/html/rfc2883#section-4.1.3
-func TestRACKDetectDSACKWithOutOfOrderDup(t *testing.T) {
-	c := context.New(t, uint32(mtu))
-	defer c.Cleanup()
-
-	probeDone := make(chan int)
-	const ackNumToVerify = 4
-	addDSACKSeenCheckerProbe(t, c, ackNumToVerify, probeDone)
-
-	numPackets := 10
-	sendAndReceiveWithSACK(t, c, numPackets, true /* enableRACK */)
-
-	// ACK [1-5] packets.
-	seq := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	bytesRead := 5 * maxPayload
-	c.SendAck(seq, bytesRead)
-
-	// Send SACK indicating #6 packet is missing and received #7 packet.
-	offset := seqnum.Size(bytesRead + maxPayload)
-	start := c.IRS.Add(1 + offset)
-	end := start.Add(maxPayload)
-	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{start, end}})
-
-	// Send SACK with #6 packet is missing and received [7-8] packets.
-	end = start.Add(2 * maxPayload)
-	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{start, end}})
-
-	// Consider #8 packet is duplicated on the network and send DSACK.
-	dsackStart := c.IRS.Add(1 + offset + maxPayload)
-	dsackEnd := dsackStart.Add(maxPayload)
-	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{dsackStart, dsackEnd}, {start, end}})
-
-	// Wait for the probe function to finish processing the ACK before the
-	// test completes.
-	err := <-probeDone
-	switch err {
-	case failedToDetectDSACK:
-		t.Fatalf("RACK DSACK detection failed")
-	case invalidDSACKDetected:
-		t.Fatalf("RACK DSACK detected when there is no duplicate SACK")
-	}
-}
-
-// TestRACKDetectDSACKSingleDup tests DSACK for a single duplicate subsegment.
-// See: https://tools.ietf.org/html/rfc2883#section-4.2.1.
-func TestRACKDetectDSACKSingleDup(t *testing.T) {
-	c := context.New(t, uint32(mtu))
-	defer c.Cleanup()
-
-	probeDone := make(chan int)
-	const ackNumToVerify = 4
-	addDSACKSeenCheckerProbe(t, c, ackNumToVerify, probeDone)
-
-	numPackets := 4
-	data := sendAndReceiveWithSACK(t, c, numPackets, true /* enableRACK */)
-
-	// Send ACK for #1 packet.
-	bytesRead := maxPayload
-	seq := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	c.SendAck(seq, bytesRead)
-
-	// Missing [2-3] packets and received #4 packet.
-	seq = seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	start := c.IRS.Add(1 + seqnum.Size(3*maxPayload))
-	end := start.Add(seqnum.Size(maxPayload))
-	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{start, end}})
-
-	// Expect retransmission of #2 packet.
-	c.ReceiveAndCheckPacketWithOptions(data, bytesRead, maxPayload, tsOptionSize)
-
-	// ACK for retransmitted #2 packet.
-	bytesRead += maxPayload
-	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{start, end}})
-
-	// Simulate receving delayed subsegment of #2 packet and delayed #3 packet by
-	// sending DSACK block for the subsegment.
-	dsackStart := c.IRS.Add(1 + seqnum.Size(bytesRead))
-	dsackEnd := dsackStart.Add(seqnum.Size(maxPayload / 2))
-	c.SendAckWithSACK(seq, numPackets*maxPayload, []header.SACKBlock{{dsackStart, dsackEnd}})
-
-	// Wait for the probe function to finish processing the ACK before the
-	// test completes.
-	err := <-probeDone
-	switch err {
-	case failedToDetectDSACK:
-		t.Fatalf("RACK DSACK detection failed")
-	case invalidDSACKDetected:
-		t.Fatalf("RACK DSACK detected when there is no duplicate SACK")
-	}
-}
-
-// TestRACKDetectDSACKDupWithCumulativeACK tests DSACK for two non-contiguous
-// duplicate subsegments covered by the cumulative acknowledgement.
-// See: https://tools.ietf.org/html/rfc2883#section-4.2.2.
-func TestRACKDetectDSACKDupWithCumulativeACK(t *testing.T) {
-	c := context.New(t, uint32(mtu))
-	defer c.Cleanup()
-
-	probeDone := make(chan int)
-	const ackNumToVerify = 5
-	addDSACKSeenCheckerProbe(t, c, ackNumToVerify, probeDone)
-
-	numPackets := 6
-	data := sendAndReceiveWithSACK(t, c, numPackets, true /* enableRACK */)
-
-	// Send ACK for #1 packet.
-	bytesRead := maxPayload
-	seq := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	c.SendAck(seq, bytesRead)
-
-	// Missing [2-5] packets and received #6 packet.
-	seq = seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	start := c.IRS.Add(1 + seqnum.Size(5*maxPayload))
-	end := start.Add(seqnum.Size(maxPayload))
-	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{start, end}})
-
-	// Expect retransmission of #2 packet.
-	c.ReceiveAndCheckPacketWithOptions(data, bytesRead, maxPayload, tsOptionSize)
-
-	// Received delayed #2 packet.
-	bytesRead += maxPayload
-	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{start, end}})
-
-	// Received delayed #4 packet.
-	start1 := c.IRS.Add(1 + seqnum.Size(3*maxPayload))
-	end1 := start1.Add(seqnum.Size(maxPayload))
-	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{start1, end1}, {start, end}})
-
-	// Simulate receiving retransmitted subsegment for #2 packet and delayed #3
-	// packet by sending DSACK block for #2 packet.
-	dsackStart := c.IRS.Add(1 + seqnum.Size(maxPayload))
-	dsackEnd := dsackStart.Add(seqnum.Size(maxPayload / 2))
-	c.SendAckWithSACK(seq, 4*maxPayload, []header.SACKBlock{{dsackStart, dsackEnd}, {start, end}})
-
-	// Wait for the probe function to finish processing the ACK before the
-	// test completes.
-	err := <-probeDone
-	switch err {
-	case failedToDetectDSACK:
-		t.Fatalf("RACK DSACK detection failed")
-	case invalidDSACKDetected:
-		t.Fatalf("RACK DSACK detected when there is no duplicate SACK")
-	}
-}
-
-// TestRACKDetectDSACKDup tests two non-contiguous duplicate subsegments not
-// covered by the cumulative acknowledgement.
-// See: https://tools.ietf.org/html/rfc2883#section-4.2.3.
-func TestRACKDetectDSACKDup(t *testing.T) {
-	c := context.New(t, uint32(mtu))
-	defer c.Cleanup()
-
-	probeDone := make(chan int)
-	const ackNumToVerify = 5
-	addDSACKSeenCheckerProbe(t, c, ackNumToVerify, probeDone)
-
-	numPackets := 7
-	data := sendAndReceiveWithSACK(t, c, numPackets, true /* enableRACK */)
-
-	// Send ACK for #1 packet.
-	bytesRead := maxPayload
-	seq := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	c.SendAck(seq, bytesRead)
-
-	// Missing [2-6] packets and SACK #7 packet.
-	seq = seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	start := c.IRS.Add(1 + seqnum.Size(6*maxPayload))
-	end := start.Add(seqnum.Size(maxPayload))
-	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{start, end}})
-
-	// Received delayed #3 packet.
-	start1 := c.IRS.Add(1 + seqnum.Size(2*maxPayload))
-	end1 := start1.Add(seqnum.Size(maxPayload))
-	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{start1, end1}, {start, end}})
-
-	// Expect retransmission of #2 packet.
-	c.ReceiveAndCheckPacketWithOptions(data, bytesRead, maxPayload, tsOptionSize)
-
-	// Consider #2 packet has been dropped and SACK #4 packet.
-	start2 := c.IRS.Add(1 + seqnum.Size(3*maxPayload))
-	end2 := start2.Add(seqnum.Size(maxPayload))
-	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{start2, end2}, {start1, end1}, {start, end}})
-
-	// Simulate receiving retransmitted subsegment for #3 packet and delayed #5
-	// packet by sending DSACK block for the subsegment.
-	dsackStart := c.IRS.Add(1 + seqnum.Size(2*maxPayload))
-	dsackEnd := dsackStart.Add(seqnum.Size(maxPayload / 2))
-	end1 = end1.Add(seqnum.Size(2 * maxPayload))
-	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{dsackStart, dsackEnd}, {start1, end1}})
-
-	// Wait for the probe function to finish processing the ACK before the
-	// test completes.
-	err := <-probeDone
-	switch err {
-	case failedToDetectDSACK:
-		t.Fatalf("RACK DSACK detection failed")
-	case invalidDSACKDetected:
-		t.Fatalf("RACK DSACK detected when there is no duplicate SACK")
-	}
-}
-
-// TestRACKWithInvalidDSACKBlock tests that DSACK is not detected when DSACK
-// is not the first SACK block.
-func TestRACKWithInvalidDSACKBlock(t *testing.T) {
-	c := context.New(t, uint32(mtu))
-	defer c.Cleanup()
-
-	probeDone := make(chan struct{})
-	const ackNumToVerify = 2
-	var n int
-	c.Stack().AddTCPProbe(func(state stack.TCPEndpointState) {
-		// Validate that RACK does not detect DSACK when DSACK block is
-		// not the first SACK block.
-		n++
-		t.Helper()
-		if state.Sender.RACKState.DSACKSeen {
-			t.Fatalf("RACK DSACK detected when there is no duplicate SACK")
-		}
-
-		if n == ackNumToVerify {
-			close(probeDone)
-		}
-	})
-
-	numPackets := 10
-	data := sendAndReceiveWithSACK(t, c, numPackets, true /* enableRACK */)
-
-	// Cumulative ACK for [1-5] packets and SACK for #7 packet (to prevent TLP).
-	seq := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	bytesRead := 5 * maxPayload
-	seventhPStart := c.IRS.Add(1 + seqnum.Size(6*maxPayload))
-	seventhPEnd := seventhPStart.Add(maxPayload)
-	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{seventhPStart, seventhPEnd}})
-
-	// Expect retransmission of #6 packet.
-	c.ReceiveAndCheckPacketWithOptions(data, bytesRead, maxPayload, tsOptionSize)
-
-	// Send DSACK block for #6 packet indicating both
-	// initial and retransmitted packet are received and
-	// packets [1-7] are received.
-	start := c.IRS.Add(1 + seqnum.Size(bytesRead))
-	end := start.Add(maxPayload)
-	bytesRead += 2 * maxPayload
-
-	// Send DSACK block as second block. The first block is a SACK for #9 packet.
-	start1 := c.IRS.Add(1 + seqnum.Size(bytesRead) + maxPayload)
-	end1 := start1.Add(maxPayload)
-	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{start1, end1}, {start, end}})
-
-	// Wait for the probe function to finish processing the
-	// ACK before the test completes.
-	<-probeDone
-}
-
-func addReorderWindowCheckerProbe(c *context.Context, numACK int, probeDone chan error) {
-	var n int
-	c.Stack().AddTCPProbe(func(state stack.TCPEndpointState) {
-		// Validate that RACK detects DSACK.
-		n++
-		if n < numACK {
-			return
-		}
-
-		if state.Sender.RACKState.ReoWnd == 0 || state.Sender.RACKState.ReoWnd > state.Sender.SRTT {
-			probeDone <- fmt.Errorf("got RACKState.ReoWnd: %v, expected it to be greater than 0 and less than %v", state.Sender.RACKState.ReoWnd, state.Sender.SRTT)
-			return
-		}
-
-		if state.Sender.RACKState.ReoWndIncr != 1 {
-			probeDone <- fmt.Errorf("got RACKState.ReoWndIncr: %v, want: 1", state.Sender.RACKState.ReoWndIncr)
-			return
-		}
-
-		if state.Sender.RACKState.ReoWndPersist > 0 {
-			probeDone <- fmt.Errorf("got RACKState.ReoWndPersist: %v, want: greater than 0", state.Sender.RACKState.ReoWndPersist)
-			return
-		}
-		probeDone <- nil
-	})
-}
-
-func TestRACKCheckReorderWindow(t *testing.T) {
-	c := context.New(t, uint32(mtu))
-	defer c.Cleanup()
-
-	probeDone := make(chan error)
-	const ackNumToVerify = 3
-	addReorderWindowCheckerProbe(c, ackNumToVerify, probeDone)
-
-	const numPackets = 7
-	sendAndReceiveWithSACK(t, c, numPackets, true /* enableRACK */)
-
-	// Send ACK for #1 packet.
-	bytesRead := maxPayload
-	seq := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	c.SendAck(seq, bytesRead)
-
-	// Missing [2-6] packets and SACK #7 packet.
-	start := c.IRS.Add(1 + seqnum.Size(6*maxPayload))
-	end := start.Add(seqnum.Size(maxPayload))
-	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{start, end}})
-
-	// Received delayed packets [2-6] which indicates there is reordering
-	// in the connection.
-	bytesRead += 6 * maxPayload
-	c.SendAck(seq, bytesRead)
-
-	// Wait for the probe function to finish processing the ACK before the
-	// test completes.
-	if err := <-probeDone; err != nil {
-		t.Fatalf("unexpected values for RACK variables: %v", err)
-	}
-}
-
-func TestRACKWithDuplicateACK(t *testing.T) {
-	c := context.New(t, uint32(mtu))
-	defer c.Cleanup()
-
-	const numPackets = 4
-	data := sendAndReceiveWithSACK(t, c, numPackets, true /* enableRACK */)
-
-	// Send three duplicate ACKs to trigger fast recovery. The first
-	// segment is considered as lost and will be retransmitted after
-	// receiving the duplicate ACKs.
-	seq := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	start := c.IRS.Add(1 + seqnum.Size(maxPayload))
-	end := start.Add(seqnum.Size(maxPayload))
-	for i := 0; i < 3; i++ {
-		c.SendAckWithSACK(seq, 0, []header.SACKBlock{{start, end}})
-		end = end.Add(seqnum.Size(maxPayload))
-	}
-
-	// Receive the retransmitted packet.
-	c.ReceiveAndCheckPacketWithOptions(data, 0, maxPayload, tsOptionSize)
-
-	metricPollFn := func() error {
-		tcpStats := c.Stack().Stats().TCP
-		stats := []struct {
-			stat *tcpip.StatCounter
-			name string
-			want uint64
-		}{
-			{tcpStats.FastRetransmit, "stats.TCP.FastRetransmit", 1},
-			{tcpStats.SACKRecovery, "stats.TCP.SACKRecovery", 1},
-			{tcpStats.FastRecovery, "stats.TCP.FastRecovery", 0},
-		}
-		for _, s := range stats {
-			if got, want := s.stat.Value(), s.want; got != want {
-				return fmt.Errorf("got %s.Value() = %d, want = %d", s.name, got, want)
-			}
-		}
-		return nil
-	}
-
-	if err := testutil.Poll(metricPollFn, 1*time.Second); err != nil {
-		t.Error(err)
-	}
-}
-
-// TestRACKUpdateSackedOut tests the sacked out field is updated when a SACK
-// is received.
-func TestRACKUpdateSackedOut(t *testing.T) {
-	c := context.New(t, uint32(mtu))
-	defer c.Cleanup()
-
-	probeDone := make(chan struct{})
-	ackNum := 0
-	c.Stack().AddTCPProbe(func(state stack.TCPEndpointState) {
-		// Validate that the endpoint Sender.SackedOut is what we expect.
-		if state.Sender.SackedOut != 2 && ackNum == 0 {
-			t.Fatalf("SackedOut got updated to wrong value got: %v want: 2", state.Sender.SackedOut)
-		}
-
-		if state.Sender.SackedOut != 0 && ackNum == 1 {
-			t.Fatalf("SackedOut got updated to wrong value got: %v want: 0", state.Sender.SackedOut)
-		}
-		if ackNum > 0 {
-			close(probeDone)
-		}
-		ackNum++
-	})
-
-	sendAndReceiveWithSACK(t, c, 8, true /* enableRACK */)
-
-	// ACK for [3-5] packets.
-	seq := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	start := c.IRS.Add(seqnum.Size(1 + 3*maxPayload))
-	bytesRead := 2 * maxPayload
-	end := start.Add(seqnum.Size(bytesRead))
-	c.SendAckWithSACK(seq, bytesRead, []header.SACKBlock{{start, end}})
-
-	bytesRead += 3 * maxPayload
-	c.SendAck(seq, bytesRead)
-
-	// Wait for the probe function to finish processing the ACK before the
-	// test completes.
-	<-probeDone
-}
-
-// TestRACKWithWindowFull tests that RACK honors the receive window size.
-func TestRACKWithWindowFull(t *testing.T) {
-	c := context.New(t, uint32(mtu))
-	defer c.Cleanup()
-
-	setStackSACKPermitted(t, c, true)
-	setStackRACKPermitted(t, c)
-	createConnectedWithSACKAndTS(c)
-
-	seq := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	const numPkts = 10
-	data := make([]byte, numPkts*maxPayload)
-	for i := range data {
-		data[i] = byte(i)
-	}
-
-	// Write the data.
-	var r bytes.Reader
-	r.Reset(data)
-	if _, err := c.EP.Write(&r, tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %s", err)
-	}
-
-	bytesRead := 0
-	for i := 0; i < numPkts; i++ {
-		c.ReceiveAndCheckPacketWithOptions(data, bytesRead, maxPayload, tsOptionSize)
-		bytesRead += maxPayload
-		if i == 0 {
-			// Send ACK for the first packet to establish RTT.
-			c.SendAck(seq, maxPayload)
-		}
-	}
-
-	// SACK for #10 packet.
-	start := c.IRS.Add(seqnum.Size(1 + (numPkts-1)*maxPayload))
-	end := start.Add(seqnum.Size(maxPayload))
-	c.SendAckWithSACK(seq, 2*maxPayload, []header.SACKBlock{{start, end}})
-
-	var info tcpip.TCPInfoOption
-	if err := c.EP.GetSockOpt(&info); err != nil {
-		t.Fatalf("GetSockOpt failed: %v", err)
-	}
-	// Wait for RTT to trigger recovery.
-	time.Sleep(info.RTT)
-
-	// Expect retransmission of #2 packet.
-	c.ReceiveAndCheckPacketWithOptions(data, 2*maxPayload, maxPayload, tsOptionSize)
-
-	// Send ACK for #2 packet.
-	c.SendAck(seq, 3*maxPayload)
-
-	// Expect retransmission of #3 packet.
-	c.ReceiveAndCheckPacketWithOptions(data, 3*maxPayload, maxPayload, tsOptionSize)
-
-	// Send ACK with zero window size.
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  seq,
-		AckNum:  c.IRS.Add(1 + 4*maxPayload),
-		RcvWnd:  0,
-	})
-
-	// No packet should be received as the receive window size is zero.
-	c.CheckNoPacket("unexpected packet received after userTimeout has expired")
-}
diff --git a/pkg/tcpip/transport/tcp/tcp_sack_test.go b/pkg/tcpip/transport/tcp/tcp_sack_test.go
deleted file mode 100644
index 81f800c..0000000
--- a/pkg/tcpip/transport/tcp/tcp_sack_test.go
+++ /dev/null
@@ -1,705 +0,0 @@
-// 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 tcp_test
-
-import (
-	"bytes"
-	"fmt"
-	"log"
-	"reflect"
-	"testing"
-	"time"
-
-	"gvisor.dev/gvisor/pkg/tcpip"
-	"gvisor.dev/gvisor/pkg/tcpip/header"
-	"gvisor.dev/gvisor/pkg/tcpip/seqnum"
-	"gvisor.dev/gvisor/pkg/tcpip/stack"
-	"gvisor.dev/gvisor/pkg/tcpip/transport/tcp"
-	"gvisor.dev/gvisor/pkg/tcpip/transport/tcp/testing/context"
-	"gvisor.dev/gvisor/pkg/test/testutil"
-)
-
-// createConnectedWithSACKPermittedOption creates and connects c.ep with the
-// SACKPermitted option enabled if the stack in the context has the SACK support
-// enabled.
-func createConnectedWithSACKPermittedOption(c *context.Context) *context.RawEndpoint {
-	return c.CreateConnectedWithOptions(header.TCPSynOptions{SACKPermitted: c.SACKEnabled()})
-}
-
-// createConnectedWithSACKAndTS creates and connects c.ep with the SACK & TS
-// option enabled if the stack in the context has SACK and TS enabled.
-func createConnectedWithSACKAndTS(c *context.Context) *context.RawEndpoint {
-	return c.CreateConnectedWithOptions(header.TCPSynOptions{SACKPermitted: c.SACKEnabled(), TS: true})
-}
-
-func setStackSACKPermitted(t *testing.T, c *context.Context, enable bool) {
-	t.Helper()
-	opt := tcpip.TCPSACKEnabled(enable)
-	if err := c.Stack().SetTransportProtocolOption(tcp.ProtocolNumber, &opt); err != nil {
-		t.Fatalf("c.s.SetTransportProtocolOption(%d, &%T(%t)): %s", tcp.ProtocolNumber, opt, opt, err)
-	}
-}
-
-// TestSackPermittedConnect establishes a connection with the SACK option
-// enabled.
-func TestSackPermittedConnect(t *testing.T) {
-	for _, sackEnabled := range []bool{false, true} {
-		t.Run(fmt.Sprintf("stack.sackEnabled: %v", sackEnabled), func(t *testing.T) {
-			c := context.New(t, defaultMTU)
-			defer c.Cleanup()
-
-			setStackSACKPermitted(t, c, sackEnabled)
-			rep := createConnectedWithSACKPermittedOption(c)
-			data := []byte{1, 2, 3}
-
-			rep.SendPacket(data, nil)
-			savedSeqNum := rep.NextSeqNum
-			rep.VerifyACKNoSACK()
-
-			// Make an out of order packet and send it.
-			rep.NextSeqNum += 3
-			sackBlocks := []header.SACKBlock{
-				{rep.NextSeqNum, rep.NextSeqNum.Add(seqnum.Size(len(data)))},
-			}
-			rep.SendPacket(data, nil)
-
-			// Restore the saved sequence number so that the
-			// VerifyXXX calls use the right sequence number for
-			// checking ACK numbers.
-			rep.NextSeqNum = savedSeqNum
-			if sackEnabled {
-				rep.VerifyACKHasSACK(sackBlocks)
-			} else {
-				rep.VerifyACKNoSACK()
-			}
-
-			// Send the missing segment.
-			rep.SendPacket(data, nil)
-			// The ACK should contain the cumulative ACK for all 9
-			// bytes sent and no SACK blocks.
-			rep.NextSeqNum += 3
-			// Check that no SACK block is returned in the ACK.
-			rep.VerifyACKNoSACK()
-		})
-	}
-}
-
-// TestSackDisabledConnect establishes a connection with the SACK option
-// disabled and verifies that no SACKs are sent for out of order segments.
-func TestSackDisabledConnect(t *testing.T) {
-	for _, sackEnabled := range []bool{false, true} {
-		t.Run(fmt.Sprintf("sackEnabled: %v", sackEnabled), func(t *testing.T) {
-			c := context.New(t, defaultMTU)
-			defer c.Cleanup()
-
-			setStackSACKPermitted(t, c, sackEnabled)
-
-			rep := c.CreateConnectedWithOptions(header.TCPSynOptions{})
-
-			data := []byte{1, 2, 3}
-
-			rep.SendPacket(data, nil)
-			savedSeqNum := rep.NextSeqNum
-			rep.VerifyACKNoSACK()
-
-			// Make an out of order packet and send it.
-			rep.NextSeqNum += 3
-			rep.SendPacket(data, nil)
-
-			// The ACK should contain the older sequence number and
-			// no SACK blocks.
-			rep.NextSeqNum = savedSeqNum
-			rep.VerifyACKNoSACK()
-
-			// Send the missing segment.
-			rep.SendPacket(data, nil)
-			// The ACK should contain the cumulative ACK for all 9
-			// bytes sent and no SACK blocks.
-			rep.NextSeqNum += 3
-			// Check that no SACK block is returned in the ACK.
-			rep.VerifyACKNoSACK()
-		})
-	}
-}
-
-// TestSackPermittedAccept accepts and establishes a connection with the
-// SACKPermitted option enabled if the connection request specifies the
-// SACKPermitted option. In case of SYN cookies SACK should be disabled as we
-// don't encode the SACK information in the cookie.
-func TestSackPermittedAccept(t *testing.T) {
-	type testCase struct {
-		cookieEnabled bool
-		sackPermitted bool
-		wndScale      int
-		wndSize       uint16
-	}
-
-	testCases := []testCase{
-		// When cookie is used window scaling is disabled.
-		{true, false, -1, 0xffff}, // When cookie is used window scaling is disabled.
-		{false, true, 5, 0x8000},  // 0x8000 * 2^5 = 1<<20 = 1MB window (the default).
-	}
-
-	for _, tc := range testCases {
-		t.Run(fmt.Sprintf("test: %#v", tc), func(t *testing.T) {
-			for _, sackEnabled := range []bool{false, true} {
-				t.Run(fmt.Sprintf("test stack.sackEnabled: %v", sackEnabled), func(t *testing.T) {
-					c := context.New(t, defaultMTU)
-					defer c.Cleanup()
-
-					if tc.cookieEnabled {
-						// Set the SynRcvd threshold to
-						// zero to force a syn cookie
-						// based accept to happen.
-						var opt tcpip.TCPSynRcvdCountThresholdOption
-						if err := c.Stack().SetTransportProtocolOption(tcp.ProtocolNumber, &opt); err != nil {
-							t.Fatalf("SetTransportProtocolOption(%d, &%T(%d)): %s", tcp.ProtocolNumber, opt, opt, err)
-						}
-					}
-					setStackSACKPermitted(t, c, sackEnabled)
-
-					rep := c.AcceptWithOptions(tc.wndScale, header.TCPSynOptions{MSS: defaultIPv4MSS, SACKPermitted: tc.sackPermitted})
-					//  Now verify no SACK blocks are
-					//  received when sack is disabled.
-					data := []byte{1, 2, 3}
-					rep.SendPacket(data, nil)
-					rep.VerifyACKNoSACK()
-
-					savedSeqNum := rep.NextSeqNum
-
-					// Make an out of order packet and send
-					// it.
-					rep.NextSeqNum += 3
-					sackBlocks := []header.SACKBlock{
-						{rep.NextSeqNum, rep.NextSeqNum.Add(seqnum.Size(len(data)))},
-					}
-					rep.SendPacket(data, nil)
-
-					// The ACK should contain the older
-					// sequence number.
-					rep.NextSeqNum = savedSeqNum
-					if sackEnabled && tc.sackPermitted {
-						rep.VerifyACKHasSACK(sackBlocks)
-					} else {
-						rep.VerifyACKNoSACK()
-					}
-
-					// Send the missing segment.
-					rep.SendPacket(data, nil)
-					// The ACK should contain the cumulative
-					// ACK for all 9 bytes sent and no SACK
-					// blocks.
-					rep.NextSeqNum += 3
-					// Check that no SACK block is returned
-					// in the ACK.
-					rep.VerifyACKNoSACK()
-				})
-			}
-		})
-	}
-}
-
-// TestSackDisabledAccept accepts and establishes a connection with
-// the SACKPermitted option disabled and verifies that no SACKs are
-// sent for out of order packets.
-func TestSackDisabledAccept(t *testing.T) {
-	type testCase struct {
-		cookieEnabled bool
-		wndScale      int
-		wndSize       uint16
-	}
-
-	testCases := []testCase{
-		// When cookie is used window scaling is disabled.
-		{true, -1, 0xffff}, // When cookie is used window scaling is disabled.
-		{false, 5, 0x8000}, // 0x8000 * 2^5 = 1<<20 = 1MB window (the default).
-	}
-
-	for _, tc := range testCases {
-		t.Run(fmt.Sprintf("test: %#v", tc), func(t *testing.T) {
-			for _, sackEnabled := range []bool{false, true} {
-				t.Run(fmt.Sprintf("test: sackEnabled: %v", sackEnabled), func(t *testing.T) {
-					c := context.New(t, defaultMTU)
-					defer c.Cleanup()
-
-					if tc.cookieEnabled {
-						// Set the SynRcvd threshold to
-						// zero to force a syn cookie
-						// based accept to happen.
-						var opt tcpip.TCPSynRcvdCountThresholdOption
-						if err := c.Stack().SetTransportProtocolOption(tcp.ProtocolNumber, &opt); err != nil {
-							t.Fatalf("SetTransportProtocolOption(%d, &%T(%d)): %s", tcp.ProtocolNumber, opt, opt, err)
-						}
-					}
-
-					setStackSACKPermitted(t, c, sackEnabled)
-
-					rep := c.AcceptWithOptions(tc.wndScale, header.TCPSynOptions{MSS: defaultIPv4MSS})
-
-					//  Now verify no SACK blocks are
-					//  received when sack is disabled.
-					data := []byte{1, 2, 3}
-					rep.SendPacket(data, nil)
-					rep.VerifyACKNoSACK()
-					savedSeqNum := rep.NextSeqNum
-
-					// Make an out of order packet and send
-					// it.
-					rep.NextSeqNum += 3
-					rep.SendPacket(data, nil)
-
-					// The ACK should contain the older
-					// sequence number and no SACK blocks.
-					rep.NextSeqNum = savedSeqNum
-					rep.VerifyACKNoSACK()
-
-					// Send the missing segment.
-					rep.SendPacket(data, nil)
-					// The ACK should contain the cumulative
-					// ACK for all 9 bytes sent and no SACK
-					// blocks.
-					rep.NextSeqNum += 3
-					// Check that no SACK block is returned
-					// in the ACK.
-					rep.VerifyACKNoSACK()
-				})
-			}
-		})
-	}
-}
-
-func TestUpdateSACKBlocks(t *testing.T) {
-	testCases := []struct {
-		segStart   seqnum.Value
-		segEnd     seqnum.Value
-		rcvNxt     seqnum.Value
-		sackBlocks []header.SACKBlock
-		updated    []header.SACKBlock
-	}{
-		// Trivial cases where current SACK block list is empty and we
-		// have an out of order delivery.
-		{10, 11, 2, []header.SACKBlock{}, []header.SACKBlock{{10, 11}}},
-		{10, 12, 2, []header.SACKBlock{}, []header.SACKBlock{{10, 12}}},
-		{10, 20, 2, []header.SACKBlock{}, []header.SACKBlock{{10, 20}}},
-
-		// Cases where current SACK block list is not empty and we have
-		// an out of order delivery. Tests that the updated SACK block
-		// list has the first block as the one that contains the new
-		// SACK block representing the segment that was just delivered.
-		{10, 11, 9, []header.SACKBlock{{12, 20}}, []header.SACKBlock{{10, 11}, {12, 20}}},
-		{24, 30, 9, []header.SACKBlock{{12, 20}}, []header.SACKBlock{{24, 30}, {12, 20}}},
-		{24, 30, 9, []header.SACKBlock{{12, 20}, {32, 40}}, []header.SACKBlock{{24, 30}, {12, 20}, {32, 40}}},
-
-		// Ensure that we only retain header.MaxSACKBlocks and drop the
-		// oldest one if adding a new block exceeds
-		// header.MaxSACKBlocks.
-		{24, 30, 9,
-			[]header.SACKBlock{{12, 20}, {32, 40}, {42, 50}, {52, 60}, {62, 70}, {72, 80}},
-			[]header.SACKBlock{{24, 30}, {12, 20}, {32, 40}, {42, 50}, {52, 60}, {62, 70}}},
-
-		// Cases where segment extends an existing SACK block.
-		{10, 12, 9, []header.SACKBlock{{12, 20}}, []header.SACKBlock{{10, 20}}},
-		{10, 22, 9, []header.SACKBlock{{12, 20}}, []header.SACKBlock{{10, 22}}},
-		{10, 22, 9, []header.SACKBlock{{12, 20}}, []header.SACKBlock{{10, 22}}},
-		{15, 22, 9, []header.SACKBlock{{12, 20}}, []header.SACKBlock{{12, 22}}},
-		{15, 25, 9, []header.SACKBlock{{12, 20}}, []header.SACKBlock{{12, 25}}},
-		{11, 25, 9, []header.SACKBlock{{12, 20}}, []header.SACKBlock{{11, 25}}},
-		{10, 12, 9, []header.SACKBlock{{12, 20}, {32, 40}}, []header.SACKBlock{{10, 20}, {32, 40}}},
-		{10, 22, 9, []header.SACKBlock{{12, 20}, {32, 40}}, []header.SACKBlock{{10, 22}, {32, 40}}},
-		{10, 22, 9, []header.SACKBlock{{12, 20}, {32, 40}}, []header.SACKBlock{{10, 22}, {32, 40}}},
-		{15, 22, 9, []header.SACKBlock{{12, 20}, {32, 40}}, []header.SACKBlock{{12, 22}, {32, 40}}},
-		{15, 25, 9, []header.SACKBlock{{12, 20}, {32, 40}}, []header.SACKBlock{{12, 25}, {32, 40}}},
-		{11, 25, 9, []header.SACKBlock{{12, 20}, {32, 40}}, []header.SACKBlock{{11, 25}, {32, 40}}},
-
-		// Cases where segment contains rcvNxt.
-		{10, 20, 15, []header.SACKBlock{{20, 30}, {40, 50}}, []header.SACKBlock{{40, 50}}},
-	}
-
-	for _, tc := range testCases {
-		var sack tcp.SACKInfo
-		copy(sack.Blocks[:], tc.sackBlocks)
-		sack.NumBlocks = len(tc.sackBlocks)
-		tcp.UpdateSACKBlocks(&sack, tc.segStart, tc.segEnd, tc.rcvNxt)
-		if got, want := sack.Blocks[:sack.NumBlocks], tc.updated; !reflect.DeepEqual(got, want) {
-			t.Errorf("UpdateSACKBlocks(%v, %v, %v, %v), got: %v, want: %v", tc.sackBlocks, tc.segStart, tc.segEnd, tc.rcvNxt, got, want)
-		}
-
-	}
-}
-
-func TestTrimSackBlockList(t *testing.T) {
-	testCases := []struct {
-		rcvNxt     seqnum.Value
-		sackBlocks []header.SACKBlock
-		trimmed    []header.SACKBlock
-	}{
-		// Simple cases where we trim whole entries.
-		{2, []header.SACKBlock{{10, 20}, {22, 30}, {32, 40}}, []header.SACKBlock{{10, 20}, {22, 30}, {32, 40}}},
-		{21, []header.SACKBlock{{10, 20}, {22, 30}, {32, 40}}, []header.SACKBlock{{22, 30}, {32, 40}}},
-		{31, []header.SACKBlock{{10, 20}, {22, 30}, {32, 40}}, []header.SACKBlock{{32, 40}}},
-		{40, []header.SACKBlock{{10, 20}, {22, 30}, {32, 40}}, []header.SACKBlock{}},
-		// Cases where we need to update a block.
-		{12, []header.SACKBlock{{10, 20}, {22, 30}, {32, 40}}, []header.SACKBlock{{12, 20}, {22, 30}, {32, 40}}},
-		{23, []header.SACKBlock{{10, 20}, {22, 30}, {32, 40}}, []header.SACKBlock{{23, 30}, {32, 40}}},
-		{33, []header.SACKBlock{{10, 20}, {22, 30}, {32, 40}}, []header.SACKBlock{{33, 40}}},
-		{41, []header.SACKBlock{{10, 20}, {22, 30}, {32, 40}}, []header.SACKBlock{}},
-	}
-	for _, tc := range testCases {
-		var sack tcp.SACKInfo
-		copy(sack.Blocks[:], tc.sackBlocks)
-		sack.NumBlocks = len(tc.sackBlocks)
-		tcp.TrimSACKBlockList(&sack, tc.rcvNxt)
-		if got, want := sack.Blocks[:sack.NumBlocks], tc.trimmed; !reflect.DeepEqual(got, want) {
-			t.Errorf("TrimSackBlockList(%v, %v), got: %v, want: %v", tc.sackBlocks, tc.rcvNxt, got, want)
-		}
-	}
-}
-
-func TestSACKRecovery(t *testing.T) {
-	const maxPayload = 10
-	// See: tcp.makeOptions for why tsOptionSize is set to 12 here.
-	const tsOptionSize = 12
-	// Enabling SACK means the payload size is reduced to account
-	// for the extra space required for the TCP options.
-	//
-	// We increase the MTU by 40 bytes to account for SACK and Timestamp
-	// options.
-	const maxTCPOptionSize = 40
-
-	c := context.New(t, uint32(header.TCPMinimumSize+header.IPv4MinimumSize+maxTCPOptionSize+maxPayload))
-	defer c.Cleanup()
-
-	c.Stack().AddTCPProbe(func(s stack.TCPEndpointState) {
-		// We use log.Printf instead of t.Logf here because this probe
-		// can fire even when the test function has finished. This is
-		// because closing the endpoint in cleanup() does not mean the
-		// actual worker loop terminates immediately as it still has to
-		// do a full TCP shutdown. But this test can finish running
-		// before the shutdown is done. Using t.Logf in such a case
-		// causes the test to panic due to logging after test finished.
-		log.Printf("state: %+v\n", s)
-	})
-	setStackSACKPermitted(t, c, true)
-	createConnectedWithSACKAndTS(c)
-
-	const iterations = 3
-	data := make([]byte, 2*maxPayload*(tcp.InitialCwnd<<(iterations+1)))
-	for i := range data {
-		data[i] = byte(i)
-	}
-
-	// Write all the data in one shot. Packets will only be written at the
-	// MTU size though.
-	var r bytes.Reader
-	r.Reset(data)
-	if _, err := c.EP.Write(&r, tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %s", err)
-	}
-
-	// Do slow start for a few iterations.
-	seq := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	expected := tcp.InitialCwnd
-	bytesRead := 0
-	for i := 0; i < iterations; i++ {
-		expected = tcp.InitialCwnd << uint(i)
-		if i > 0 {
-			// Acknowledge all the data received so far if not on
-			// first iteration.
-			c.SendAck(seq, bytesRead)
-		}
-
-		// Read all packets expected on this iteration. Don't
-		// acknowledge any of them just yet, so that we can measure the
-		// congestion window.
-		for j := 0; j < expected; j++ {
-			c.ReceiveAndCheckPacketWithOptions(data, bytesRead, maxPayload, tsOptionSize)
-			bytesRead += maxPayload
-		}
-
-		// Check we don't receive any more packets on this iteration.
-		// The timeout can't be too high or we'll trigger a timeout.
-		c.CheckNoPacketTimeout("More packets received than expected for this cwnd.", 50*time.Millisecond)
-	}
-
-	// Send 3 duplicate acks. This should force an immediate retransmit of
-	// the pending packet and put the sender into fast recovery.
-	rtxOffset := bytesRead - maxPayload*expected
-	start := c.IRS.Add(seqnum.Size(rtxOffset) + 30 + 1)
-	end := start.Add(10)
-	for i := 0; i < 3; i++ {
-		c.SendAckWithSACK(seq, rtxOffset, []header.SACKBlock{{start, end}})
-		end = end.Add(10)
-	}
-
-	// Receive the retransmitted packet.
-	c.ReceiveAndCheckPacketWithOptions(data, rtxOffset, maxPayload, tsOptionSize)
-
-	metricPollFn := func() error {
-		tcpStats := c.Stack().Stats().TCP
-		stats := []struct {
-			stat *tcpip.StatCounter
-			name string
-			want uint64
-		}{
-			{tcpStats.FastRetransmit, "stats.TCP.FastRetransmit", 1},
-			{tcpStats.Retransmits, "stats.TCP.Retransmits", 1},
-			{tcpStats.SACKRecovery, "stats.TCP.SACKRecovery", 1},
-			{tcpStats.FastRecovery, "stats.TCP.FastRecovery", 0},
-		}
-		for _, s := range stats {
-			if got, want := s.stat.Value(), s.want; got != want {
-				return fmt.Errorf("got %s.Value() = %d, want = %d", s.name, got, want)
-			}
-		}
-		return nil
-	}
-
-	if err := testutil.Poll(metricPollFn, 1*time.Second); err != nil {
-		t.Error(err)
-	}
-
-	// Now send 7 mode duplicate ACKs. In SACK TCP dupAcks do not cause
-	// window inflation and sending of packets is completely handled by the
-	// SACK Recovery algorithm. We should see no packets being released, as
-	// the cwnd at this point after entering recovery should be half of the
-	// outstanding number of packets in flight.
-	for i := 0; i < 7; i++ {
-		c.SendAckWithSACK(seq, rtxOffset, []header.SACKBlock{{start, end}})
-		end = end.Add(10)
-	}
-
-	recover := bytesRead
-
-	// Ensure no new packets arrive.
-	c.CheckNoPacketTimeout("More packets received than expected during recovery after dupacks for this cwnd.",
-		50*time.Millisecond)
-
-	// Acknowledge half of the pending data. This along with the 10 sacked
-	// segments above should reduce the outstanding below the current
-	// congestion window allowing the sender to transmit data.
-	rtxOffset = bytesRead - expected*maxPayload/2
-
-	// Now send a partial ACK w/ a SACK block that indicates that the next 3
-	// segments are lost and we have received 6 segments after the lost
-	// segments. This should cause the sender to immediately transmit all 3
-	// segments in response to this ACK unlike in FastRecovery where only 1
-	// segment is retransmitted per ACK.
-	start = c.IRS.Add(seqnum.Size(rtxOffset) + 30 + 1)
-	end = start.Add(60)
-	c.SendAckWithSACK(seq, rtxOffset, []header.SACKBlock{{start, end}})
-
-	// At this point, we acked expected/2 packets and we SACKED 6 packets and
-	// 3 segments were considered lost due to the SACK block we sent.
-	//
-	// So total packets outstanding can be calculated as follows after 7
-	// iterations of slow start -> 10/20/40/80/160/320/640. So expected
-	// should be 640 at start, then we went to recover at which point the
-	// cwnd should be set to 320 + 3 (for the 3 dupAcks which have left the
-	// network).
-	// Outstanding at this point after acking half the window
-	// (320 packets) will be:
-	//    outstanding = 640-320-6(due to SACK block)-3 = 311
-	//
-	// The last 3 is due to the fact that the first 3 packets after
-	// rtxOffset will be considered lost due to the SACK blocks sent.
-	// Receive the retransmit due to partial ack.
-
-	c.ReceiveAndCheckPacketWithOptions(data, rtxOffset, maxPayload, tsOptionSize)
-	// Receive the 2 extra packets that should have been retransmitted as
-	// those should be considered lost and immediately retransmitted based
-	// on the SACK information in the previous ACK sent above.
-	for i := 0; i < 2; i++ {
-		c.ReceiveAndCheckPacketWithOptions(data, rtxOffset+maxPayload*(i+1), maxPayload, tsOptionSize)
-	}
-
-	// Now we should get 9 more new unsent packets as the cwnd is 323 and
-	// outstanding is 311.
-	for i := 0; i < 9; i++ {
-		c.ReceiveAndCheckPacketWithOptions(data, bytesRead, maxPayload, tsOptionSize)
-		bytesRead += maxPayload
-	}
-
-	metricPollFn = func() error {
-		// In SACK recovery only the first segment is fast retransmitted when
-		// entering recovery.
-		if got, want := c.Stack().Stats().TCP.FastRetransmit.Value(), uint64(1); got != want {
-			return fmt.Errorf("got stats.TCP.FastRetransmit.Value = %d, want = %d", got, want)
-		}
-
-		if got, want := c.EP.Stats().(*tcp.Stats).SendErrors.FastRetransmit.Value(), uint64(1); got != want {
-			return fmt.Errorf("got EP stats SendErrors.FastRetransmit = %d, want = %d", got, want)
-		}
-
-		if got, want := c.Stack().Stats().TCP.Retransmits.Value(), uint64(4); got != want {
-			return fmt.Errorf("got stats.TCP.Retransmits.Value = %d, want = %d", got, want)
-		}
-
-		if got, want := c.EP.Stats().(*tcp.Stats).SendErrors.Retransmits.Value(), uint64(4); got != want {
-			return fmt.Errorf("got EP stats Stats.SendErrors.Retransmits = %d, want = %d", got, want)
-		}
-		return nil
-	}
-	if err := testutil.Poll(metricPollFn, 1*time.Second); err != nil {
-		t.Error(err)
-	}
-
-	c.CheckNoPacketTimeout("More packets received than expected during recovery after partial ack for this cwnd.", 50*time.Millisecond)
-
-	// Acknowledge all pending data to recover point.
-	c.SendAck(seq, recover)
-
-	// At this point, the cwnd should reset to expected/2 and there are 9
-	// packets outstanding.
-	//
-	// Now in the first iteration since there are 9 packets outstanding.
-	// We would expect to get expected/2  - 9 packets. But subsequent
-	// iterations will send us expected/2  + 1 (per iteration).
-	expected = expected/2 - 9
-	for i := 0; i < iterations; i++ {
-		// Read all packets expected on this iteration. Don't
-		// acknowledge any of them just yet, so that we can measure the
-		// congestion window.
-		for j := 0; j < expected; j++ {
-			c.ReceiveAndCheckPacketWithOptions(data, bytesRead, maxPayload, tsOptionSize)
-			bytesRead += maxPayload
-		}
-		// Check we don't receive any more packets on this iteration.
-		// The timeout can't be too high or we'll trigger a timeout.
-		c.CheckNoPacketTimeout(fmt.Sprintf("More packets received(after deflation) than expected %d for this cwnd and iteration: %d.", expected, i), 50*time.Millisecond)
-
-		// Acknowledge all the data received so far.
-		c.SendAck(seq, bytesRead)
-
-		// In cogestion avoidance, the packets trains increase by 1 in
-		// each iteration.
-		if i == 0 {
-			// After the first iteration we expect to get the full
-			// congestion window worth of packets in every
-			// iteration.
-			expected += 9
-		}
-		expected++
-	}
-}
-
-// TestRecoveryEntry tests the following two properties of entering recovery:
-// - Fast SACK recovery is entered when SND.UNA is considered lost by the SACK
-//   scoreboard but dupack count is still below threshold.
-// - Only enter recovery when at least one more byte of data beyond the highest
-//   byte that was outstanding when fast retransmit was last entered is acked.
-func TestRecoveryEntry(t *testing.T) {
-	c := context.New(t, uint32(mtu))
-	defer c.Cleanup()
-
-	numPackets := 5
-	data := sendAndReceiveWithSACK(t, c, numPackets, false /* enableRACK */)
-
-	// Ack #1 packet.
-	seq := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	c.SendAck(seq, maxPayload)
-
-	// Now SACK #3, #4 and #5 packets. This will simulate a situation where
-	// SND.UNA should be considered lost and the sender should enter fast recovery
-	// (even though dupack count is still below threshold).
-	p3Start := c.IRS.Add(1 + seqnum.Size(2*maxPayload))
-	p3End := p3Start.Add(maxPayload)
-	p4Start := p3End
-	p4End := p4Start.Add(maxPayload)
-	p5Start := p4End
-	p5End := p5Start.Add(maxPayload)
-	c.SendAckWithSACK(seq, maxPayload, []header.SACKBlock{{p3Start, p3End}, {p4Start, p4End}, {p5Start, p5End}})
-
-	// Expect #2 to be retransmitted.
-	c.ReceiveAndCheckPacketWithOptions(data, maxPayload, maxPayload, tsOptionSize)
-
-	metricPollFn := func() error {
-		tcpStats := c.Stack().Stats().TCP
-		stats := []struct {
-			stat *tcpip.StatCounter
-			name string
-			want uint64
-		}{
-			// SACK recovery must have happened.
-			{tcpStats.FastRetransmit, "stats.TCP.FastRetransmit", 1},
-			{tcpStats.SACKRecovery, "stats.TCP.SACKRecovery", 1},
-			// #2 was retransmitted.
-			{tcpStats.Retransmits, "stats.TCP.Retransmits", 1},
-			// No RTOs should have fired yet.
-			{tcpStats.Timeouts, "stats.TCP.Timeouts", 0},
-		}
-		for _, s := range stats {
-			if got, want := s.stat.Value(), s.want; got != want {
-				return fmt.Errorf("got %s.Value() = %d, want = %d", s.name, got, want)
-			}
-		}
-		return nil
-	}
-	if err := testutil.Poll(metricPollFn, 1*time.Second); err != nil {
-		t.Error(err)
-	}
-
-	// Send 4 more packets.
-	var r bytes.Reader
-	data = append(data, data...)
-	r.Reset(data[5*maxPayload : 9*maxPayload])
-	if _, err := c.EP.Write(&r, tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %s", err)
-	}
-
-	var sackBlocks []header.SACKBlock
-	bytesRead := numPackets * maxPayload
-	for i := 0; i < 4; i++ {
-		c.ReceiveAndCheckPacketWithOptions(data, bytesRead, maxPayload, tsOptionSize)
-		if i > 0 {
-			pStart := c.IRS.Add(1 + seqnum.Size(bytesRead))
-			sackBlocks = append(sackBlocks, header.SACKBlock{pStart, pStart.Add(maxPayload)})
-			c.SendAckWithSACK(seq, 5*maxPayload, sackBlocks)
-		}
-		bytesRead += maxPayload
-	}
-
-	// #6 should be retransmitted after RTO. The sender should NOT enter fast
-	// recovery because the highest byte that was outstanding when fast recovery
-	// was last entered is #5 packet's end. And the sender requires at least one
-	// more byte beyond that (#6 packet start) to be acked to enter recovery.
-	c.ReceiveAndCheckPacketWithOptions(data, 5*maxPayload, maxPayload, tsOptionSize)
-	c.SendAck(seq, 9*maxPayload)
-
-	metricPollFn = func() error {
-		tcpStats := c.Stack().Stats().TCP
-		stats := []struct {
-			stat *tcpip.StatCounter
-			name string
-			want uint64
-		}{
-			// Only 1 SACK recovery must have happened.
-			{tcpStats.FastRetransmit, "stats.TCP.FastRetransmit", 1},
-			{tcpStats.SACKRecovery, "stats.TCP.SACKRecovery", 1},
-			// #2 and #6 were retransmitted.
-			{tcpStats.Retransmits, "stats.TCP.Retransmits", 2},
-			// RTO should have fired once.
-			{tcpStats.Timeouts, "stats.TCP.Timeouts", 1},
-		}
-		for _, s := range stats {
-			if got, want := s.stat.Value(), s.want; got != want {
-				return fmt.Errorf("got %s.Value() = %d, want = %d", s.name, got, want)
-			}
-		}
-		return nil
-	}
-	if err := testutil.Poll(metricPollFn, 1*time.Second); err != nil {
-		t.Error(err)
-	}
-}
diff --git a/pkg/tcpip/transport/tcp/tcp_segment_list.go b/pkg/tcpip/transport/tcp/tcp_segment_list.go
new file mode 100644
index 0000000..a14cff2
--- /dev/null
+++ b/pkg/tcpip/transport/tcp/tcp_segment_list.go
@@ -0,0 +1,221 @@
+package tcp
+
+// ElementMapper provides an identity mapping by default.
+//
+// This can be replaced to provide a struct that maps elements to linker
+// objects, if they are not the same. An ElementMapper is not typically
+// required if: Linker is left as is, Element is left as is, or Linker and
+// Element are the same type.
+type segmentElementMapper struct{}
+
+// linkerFor maps an Element to a Linker.
+//
+// This default implementation should be inlined.
+//
+//go:nosplit
+func (segmentElementMapper) linkerFor(elem *segment) *segment { return elem }
+
+// List is an intrusive list. Entries can be added to or removed from the list
+// in O(1) time and with no additional memory allocations.
+//
+// The zero value for List is an empty list ready to use.
+//
+// To iterate over a list (where l is a List):
+//      for e := l.Front(); e != nil; e = e.Next() {
+// 		// do something with e.
+//      }
+//
+// +stateify savable
+type segmentList struct {
+	head *segment
+	tail *segment
+}
+
+// Reset resets list l to the empty state.
+func (l *segmentList) Reset() {
+	l.head = nil
+	l.tail = nil
+}
+
+// Empty returns true iff the list is empty.
+//
+//go:nosplit
+func (l *segmentList) Empty() bool {
+	return l.head == nil
+}
+
+// Front returns the first element of list l or nil.
+//
+//go:nosplit
+func (l *segmentList) Front() *segment {
+	return l.head
+}
+
+// Back returns the last element of list l or nil.
+//
+//go:nosplit
+func (l *segmentList) Back() *segment {
+	return l.tail
+}
+
+// Len returns the number of elements in the list.
+//
+// NOTE: This is an O(n) operation.
+//
+//go:nosplit
+func (l *segmentList) Len() (count int) {
+	for e := l.Front(); e != nil; e = (segmentElementMapper{}.linkerFor(e)).Next() {
+		count++
+	}
+	return count
+}
+
+// PushFront inserts the element e at the front of list l.
+//
+//go:nosplit
+func (l *segmentList) PushFront(e *segment) {
+	linker := segmentElementMapper{}.linkerFor(e)
+	linker.SetNext(l.head)
+	linker.SetPrev(nil)
+	if l.head != nil {
+		segmentElementMapper{}.linkerFor(l.head).SetPrev(e)
+	} else {
+		l.tail = e
+	}
+
+	l.head = e
+}
+
+// PushBack inserts the element e at the back of list l.
+//
+//go:nosplit
+func (l *segmentList) PushBack(e *segment) {
+	linker := segmentElementMapper{}.linkerFor(e)
+	linker.SetNext(nil)
+	linker.SetPrev(l.tail)
+	if l.tail != nil {
+		segmentElementMapper{}.linkerFor(l.tail).SetNext(e)
+	} else {
+		l.head = e
+	}
+
+	l.tail = e
+}
+
+// PushBackList inserts list m at the end of list l, emptying m.
+//
+//go:nosplit
+func (l *segmentList) PushBackList(m *segmentList) {
+	if l.head == nil {
+		l.head = m.head
+		l.tail = m.tail
+	} else if m.head != nil {
+		segmentElementMapper{}.linkerFor(l.tail).SetNext(m.head)
+		segmentElementMapper{}.linkerFor(m.head).SetPrev(l.tail)
+
+		l.tail = m.tail
+	}
+	m.head = nil
+	m.tail = nil
+}
+
+// InsertAfter inserts e after b.
+//
+//go:nosplit
+func (l *segmentList) InsertAfter(b, e *segment) {
+	bLinker := segmentElementMapper{}.linkerFor(b)
+	eLinker := segmentElementMapper{}.linkerFor(e)
+
+	a := bLinker.Next()
+
+	eLinker.SetNext(a)
+	eLinker.SetPrev(b)
+	bLinker.SetNext(e)
+
+	if a != nil {
+		segmentElementMapper{}.linkerFor(a).SetPrev(e)
+	} else {
+		l.tail = e
+	}
+}
+
+// InsertBefore inserts e before a.
+//
+//go:nosplit
+func (l *segmentList) InsertBefore(a, e *segment) {
+	aLinker := segmentElementMapper{}.linkerFor(a)
+	eLinker := segmentElementMapper{}.linkerFor(e)
+
+	b := aLinker.Prev()
+	eLinker.SetNext(a)
+	eLinker.SetPrev(b)
+	aLinker.SetPrev(e)
+
+	if b != nil {
+		segmentElementMapper{}.linkerFor(b).SetNext(e)
+	} else {
+		l.head = e
+	}
+}
+
+// Remove removes e from l.
+//
+//go:nosplit
+func (l *segmentList) Remove(e *segment) {
+	linker := segmentElementMapper{}.linkerFor(e)
+	prev := linker.Prev()
+	next := linker.Next()
+
+	if prev != nil {
+		segmentElementMapper{}.linkerFor(prev).SetNext(next)
+	} else if l.head == e {
+		l.head = next
+	}
+
+	if next != nil {
+		segmentElementMapper{}.linkerFor(next).SetPrev(prev)
+	} else if l.tail == e {
+		l.tail = prev
+	}
+
+	linker.SetNext(nil)
+	linker.SetPrev(nil)
+}
+
+// Entry is a default implementation of Linker. Users can add anonymous fields
+// of this type to their structs to make them automatically implement the
+// methods needed by List.
+//
+// +stateify savable
+type segmentEntry struct {
+	next *segment
+	prev *segment
+}
+
+// Next returns the entry that follows e in the list.
+//
+//go:nosplit
+func (e *segmentEntry) Next() *segment {
+	return e.next
+}
+
+// Prev returns the entry that precedes e in the list.
+//
+//go:nosplit
+func (e *segmentEntry) Prev() *segment {
+	return e.prev
+}
+
+// SetNext assigns 'entry' as the entry that follows e in the list.
+//
+//go:nosplit
+func (e *segmentEntry) SetNext(elem *segment) {
+	e.next = elem
+}
+
+// SetPrev assigns 'entry' as the entry that precedes e in the list.
+//
+//go:nosplit
+func (e *segmentEntry) SetPrev(elem *segment) {
+	e.prev = elem
+}
diff --git a/pkg/tcpip/transport/tcp/tcp_state_autogen.go b/pkg/tcpip/transport/tcp/tcp_state_autogen.go
new file mode 100644
index 0000000..a92bec6
--- /dev/null
+++ b/pkg/tcpip/transport/tcp/tcp_state_autogen.go
@@ -0,0 +1,1114 @@
+// automatically generated by stateify.
+
+package tcp
+
+import (
+	"gvisor.dev/gvisor/pkg/state"
+	"gvisor.dev/gvisor/pkg/tcpip/buffer"
+)
+
+func (c *cubicState) StateTypeName() string {
+	return "pkg/tcpip/transport/tcp.cubicState"
+}
+
+func (c *cubicState) StateFields() []string {
+	return []string{
+		"wLastMax",
+		"wMax",
+		"t",
+		"numCongestionEvents",
+		"c",
+		"k",
+		"beta",
+		"wC",
+		"wEst",
+		"s",
+	}
+}
+
+func (c *cubicState) beforeSave() {}
+
+// +checklocksignore
+func (c *cubicState) StateSave(stateSinkObject state.Sink) {
+	c.beforeSave()
+	var tValue unixTime = c.saveT()
+	stateSinkObject.SaveValue(2, tValue)
+	stateSinkObject.Save(0, &c.wLastMax)
+	stateSinkObject.Save(1, &c.wMax)
+	stateSinkObject.Save(3, &c.numCongestionEvents)
+	stateSinkObject.Save(4, &c.c)
+	stateSinkObject.Save(5, &c.k)
+	stateSinkObject.Save(6, &c.beta)
+	stateSinkObject.Save(7, &c.wC)
+	stateSinkObject.Save(8, &c.wEst)
+	stateSinkObject.Save(9, &c.s)
+}
+
+func (c *cubicState) afterLoad() {}
+
+// +checklocksignore
+func (c *cubicState) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &c.wLastMax)
+	stateSourceObject.Load(1, &c.wMax)
+	stateSourceObject.Load(3, &c.numCongestionEvents)
+	stateSourceObject.Load(4, &c.c)
+	stateSourceObject.Load(5, &c.k)
+	stateSourceObject.Load(6, &c.beta)
+	stateSourceObject.Load(7, &c.wC)
+	stateSourceObject.Load(8, &c.wEst)
+	stateSourceObject.Load(9, &c.s)
+	stateSourceObject.LoadValue(2, new(unixTime), func(y interface{}) { c.loadT(y.(unixTime)) })
+}
+
+func (s *SACKInfo) StateTypeName() string {
+	return "pkg/tcpip/transport/tcp.SACKInfo"
+}
+
+func (s *SACKInfo) StateFields() []string {
+	return []string{
+		"Blocks",
+		"NumBlocks",
+	}
+}
+
+func (s *SACKInfo) beforeSave() {}
+
+// +checklocksignore
+func (s *SACKInfo) StateSave(stateSinkObject state.Sink) {
+	s.beforeSave()
+	stateSinkObject.Save(0, &s.Blocks)
+	stateSinkObject.Save(1, &s.NumBlocks)
+}
+
+func (s *SACKInfo) afterLoad() {}
+
+// +checklocksignore
+func (s *SACKInfo) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &s.Blocks)
+	stateSourceObject.Load(1, &s.NumBlocks)
+}
+
+func (r *rcvBufAutoTuneParams) StateTypeName() string {
+	return "pkg/tcpip/transport/tcp.rcvBufAutoTuneParams"
+}
+
+func (r *rcvBufAutoTuneParams) StateFields() []string {
+	return []string{
+		"measureTime",
+		"copied",
+		"prevCopied",
+		"rtt",
+		"rttMeasureSeqNumber",
+		"rttMeasureTime",
+		"disabled",
+	}
+}
+
+func (r *rcvBufAutoTuneParams) beforeSave() {}
+
+// +checklocksignore
+func (r *rcvBufAutoTuneParams) StateSave(stateSinkObject state.Sink) {
+	r.beforeSave()
+	var measureTimeValue unixTime = r.saveMeasureTime()
+	stateSinkObject.SaveValue(0, measureTimeValue)
+	var rttMeasureTimeValue unixTime = r.saveRttMeasureTime()
+	stateSinkObject.SaveValue(5, rttMeasureTimeValue)
+	stateSinkObject.Save(1, &r.copied)
+	stateSinkObject.Save(2, &r.prevCopied)
+	stateSinkObject.Save(3, &r.rtt)
+	stateSinkObject.Save(4, &r.rttMeasureSeqNumber)
+	stateSinkObject.Save(6, &r.disabled)
+}
+
+func (r *rcvBufAutoTuneParams) afterLoad() {}
+
+// +checklocksignore
+func (r *rcvBufAutoTuneParams) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(1, &r.copied)
+	stateSourceObject.Load(2, &r.prevCopied)
+	stateSourceObject.Load(3, &r.rtt)
+	stateSourceObject.Load(4, &r.rttMeasureSeqNumber)
+	stateSourceObject.Load(6, &r.disabled)
+	stateSourceObject.LoadValue(0, new(unixTime), func(y interface{}) { r.loadMeasureTime(y.(unixTime)) })
+	stateSourceObject.LoadValue(5, new(unixTime), func(y interface{}) { r.loadRttMeasureTime(y.(unixTime)) })
+}
+
+func (e *EndpointInfo) StateTypeName() string {
+	return "pkg/tcpip/transport/tcp.EndpointInfo"
+}
+
+func (e *EndpointInfo) StateFields() []string {
+	return []string{
+		"TransportEndpointInfo",
+	}
+}
+
+func (e *EndpointInfo) beforeSave() {}
+
+// +checklocksignore
+func (e *EndpointInfo) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+	stateSinkObject.Save(0, &e.TransportEndpointInfo)
+}
+
+func (e *EndpointInfo) afterLoad() {}
+
+// +checklocksignore
+func (e *EndpointInfo) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &e.TransportEndpointInfo)
+}
+
+func (e *endpoint) StateTypeName() string {
+	return "pkg/tcpip/transport/tcp.endpoint"
+}
+
+func (e *endpoint) StateFields() []string {
+	return []string{
+		"EndpointInfo",
+		"DefaultSocketOptionsHandler",
+		"waiterQueue",
+		"uniqueID",
+		"hardError",
+		"lastError",
+		"rcvList",
+		"rcvClosed",
+		"rcvBufSize",
+		"rcvBufUsed",
+		"rcvAutoParams",
+		"rcvMemUsed",
+		"ownedByUser",
+		"state",
+		"boundNICID",
+		"ttl",
+		"isConnectNotified",
+		"portFlags",
+		"boundBindToDevice",
+		"boundPortFlags",
+		"boundDest",
+		"effectiveNetProtos",
+		"workerRunning",
+		"workerCleanup",
+		"sendTSOk",
+		"recentTS",
+		"recentTSTime",
+		"tsOffset",
+		"shutdownFlags",
+		"tcpRecovery",
+		"sackPermitted",
+		"sack",
+		"delay",
+		"scoreboard",
+		"segmentQueue",
+		"synRcvdCount",
+		"userMSS",
+		"maxSynRetries",
+		"windowClamp",
+		"sndBufUsed",
+		"sndClosed",
+		"sndBufInQueue",
+		"sndQueue",
+		"cc",
+		"packetTooBigCount",
+		"sndMTU",
+		"keepalive",
+		"userTimeout",
+		"deferAccept",
+		"acceptedChan",
+		"rcv",
+		"snd",
+		"connectingAddress",
+		"amss",
+		"sendTOS",
+		"gso",
+		"tcpLingerTimeout",
+		"closed",
+		"txHash",
+		"owner",
+		"ops",
+		"lastOutOfWindowAckTime",
+	}
+}
+
+// +checklocksignore
+func (e *endpoint) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+	var stateValue EndpointState = e.saveState()
+	stateSinkObject.SaveValue(13, stateValue)
+	var recentTSTimeValue unixTime = e.saveRecentTSTime()
+	stateSinkObject.SaveValue(26, recentTSTimeValue)
+	var acceptedChanValue []*endpoint = e.saveAcceptedChan()
+	stateSinkObject.SaveValue(49, acceptedChanValue)
+	var lastOutOfWindowAckTimeValue unixTime = e.saveLastOutOfWindowAckTime()
+	stateSinkObject.SaveValue(61, lastOutOfWindowAckTimeValue)
+	stateSinkObject.Save(0, &e.EndpointInfo)
+	stateSinkObject.Save(1, &e.DefaultSocketOptionsHandler)
+	stateSinkObject.Save(2, &e.waiterQueue)
+	stateSinkObject.Save(3, &e.uniqueID)
+	stateSinkObject.Save(4, &e.hardError)
+	stateSinkObject.Save(5, &e.lastError)
+	stateSinkObject.Save(6, &e.rcvList)
+	stateSinkObject.Save(7, &e.rcvClosed)
+	stateSinkObject.Save(8, &e.rcvBufSize)
+	stateSinkObject.Save(9, &e.rcvBufUsed)
+	stateSinkObject.Save(10, &e.rcvAutoParams)
+	stateSinkObject.Save(11, &e.rcvMemUsed)
+	stateSinkObject.Save(12, &e.ownedByUser)
+	stateSinkObject.Save(14, &e.boundNICID)
+	stateSinkObject.Save(15, &e.ttl)
+	stateSinkObject.Save(16, &e.isConnectNotified)
+	stateSinkObject.Save(17, &e.portFlags)
+	stateSinkObject.Save(18, &e.boundBindToDevice)
+	stateSinkObject.Save(19, &e.boundPortFlags)
+	stateSinkObject.Save(20, &e.boundDest)
+	stateSinkObject.Save(21, &e.effectiveNetProtos)
+	stateSinkObject.Save(22, &e.workerRunning)
+	stateSinkObject.Save(23, &e.workerCleanup)
+	stateSinkObject.Save(24, &e.sendTSOk)
+	stateSinkObject.Save(25, &e.recentTS)
+	stateSinkObject.Save(27, &e.tsOffset)
+	stateSinkObject.Save(28, &e.shutdownFlags)
+	stateSinkObject.Save(29, &e.tcpRecovery)
+	stateSinkObject.Save(30, &e.sackPermitted)
+	stateSinkObject.Save(31, &e.sack)
+	stateSinkObject.Save(32, &e.delay)
+	stateSinkObject.Save(33, &e.scoreboard)
+	stateSinkObject.Save(34, &e.segmentQueue)
+	stateSinkObject.Save(35, &e.synRcvdCount)
+	stateSinkObject.Save(36, &e.userMSS)
+	stateSinkObject.Save(37, &e.maxSynRetries)
+	stateSinkObject.Save(38, &e.windowClamp)
+	stateSinkObject.Save(39, &e.sndBufUsed)
+	stateSinkObject.Save(40, &e.sndClosed)
+	stateSinkObject.Save(41, &e.sndBufInQueue)
+	stateSinkObject.Save(42, &e.sndQueue)
+	stateSinkObject.Save(43, &e.cc)
+	stateSinkObject.Save(44, &e.packetTooBigCount)
+	stateSinkObject.Save(45, &e.sndMTU)
+	stateSinkObject.Save(46, &e.keepalive)
+	stateSinkObject.Save(47, &e.userTimeout)
+	stateSinkObject.Save(48, &e.deferAccept)
+	stateSinkObject.Save(50, &e.rcv)
+	stateSinkObject.Save(51, &e.snd)
+	stateSinkObject.Save(52, &e.connectingAddress)
+	stateSinkObject.Save(53, &e.amss)
+	stateSinkObject.Save(54, &e.sendTOS)
+	stateSinkObject.Save(55, &e.gso)
+	stateSinkObject.Save(56, &e.tcpLingerTimeout)
+	stateSinkObject.Save(57, &e.closed)
+	stateSinkObject.Save(58, &e.txHash)
+	stateSinkObject.Save(59, &e.owner)
+	stateSinkObject.Save(60, &e.ops)
+}
+
+// +checklocksignore
+func (e *endpoint) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &e.EndpointInfo)
+	stateSourceObject.Load(1, &e.DefaultSocketOptionsHandler)
+	stateSourceObject.LoadWait(2, &e.waiterQueue)
+	stateSourceObject.Load(3, &e.uniqueID)
+	stateSourceObject.Load(4, &e.hardError)
+	stateSourceObject.Load(5, &e.lastError)
+	stateSourceObject.LoadWait(6, &e.rcvList)
+	stateSourceObject.Load(7, &e.rcvClosed)
+	stateSourceObject.Load(8, &e.rcvBufSize)
+	stateSourceObject.Load(9, &e.rcvBufUsed)
+	stateSourceObject.Load(10, &e.rcvAutoParams)
+	stateSourceObject.Load(11, &e.rcvMemUsed)
+	stateSourceObject.Load(12, &e.ownedByUser)
+	stateSourceObject.Load(14, &e.boundNICID)
+	stateSourceObject.Load(15, &e.ttl)
+	stateSourceObject.Load(16, &e.isConnectNotified)
+	stateSourceObject.Load(17, &e.portFlags)
+	stateSourceObject.Load(18, &e.boundBindToDevice)
+	stateSourceObject.Load(19, &e.boundPortFlags)
+	stateSourceObject.Load(20, &e.boundDest)
+	stateSourceObject.Load(21, &e.effectiveNetProtos)
+	stateSourceObject.Load(22, &e.workerRunning)
+	stateSourceObject.Load(23, &e.workerCleanup)
+	stateSourceObject.Load(24, &e.sendTSOk)
+	stateSourceObject.Load(25, &e.recentTS)
+	stateSourceObject.Load(27, &e.tsOffset)
+	stateSourceObject.Load(28, &e.shutdownFlags)
+	stateSourceObject.Load(29, &e.tcpRecovery)
+	stateSourceObject.Load(30, &e.sackPermitted)
+	stateSourceObject.Load(31, &e.sack)
+	stateSourceObject.Load(32, &e.delay)
+	stateSourceObject.Load(33, &e.scoreboard)
+	stateSourceObject.LoadWait(34, &e.segmentQueue)
+	stateSourceObject.Load(35, &e.synRcvdCount)
+	stateSourceObject.Load(36, &e.userMSS)
+	stateSourceObject.Load(37, &e.maxSynRetries)
+	stateSourceObject.Load(38, &e.windowClamp)
+	stateSourceObject.Load(39, &e.sndBufUsed)
+	stateSourceObject.Load(40, &e.sndClosed)
+	stateSourceObject.Load(41, &e.sndBufInQueue)
+	stateSourceObject.LoadWait(42, &e.sndQueue)
+	stateSourceObject.Load(43, &e.cc)
+	stateSourceObject.Load(44, &e.packetTooBigCount)
+	stateSourceObject.Load(45, &e.sndMTU)
+	stateSourceObject.Load(46, &e.keepalive)
+	stateSourceObject.Load(47, &e.userTimeout)
+	stateSourceObject.Load(48, &e.deferAccept)
+	stateSourceObject.LoadWait(50, &e.rcv)
+	stateSourceObject.LoadWait(51, &e.snd)
+	stateSourceObject.Load(52, &e.connectingAddress)
+	stateSourceObject.Load(53, &e.amss)
+	stateSourceObject.Load(54, &e.sendTOS)
+	stateSourceObject.Load(55, &e.gso)
+	stateSourceObject.Load(56, &e.tcpLingerTimeout)
+	stateSourceObject.Load(57, &e.closed)
+	stateSourceObject.Load(58, &e.txHash)
+	stateSourceObject.Load(59, &e.owner)
+	stateSourceObject.Load(60, &e.ops)
+	stateSourceObject.LoadValue(13, new(EndpointState), func(y interface{}) { e.loadState(y.(EndpointState)) })
+	stateSourceObject.LoadValue(26, new(unixTime), func(y interface{}) { e.loadRecentTSTime(y.(unixTime)) })
+	stateSourceObject.LoadValue(49, new([]*endpoint), func(y interface{}) { e.loadAcceptedChan(y.([]*endpoint)) })
+	stateSourceObject.LoadValue(61, new(unixTime), func(y interface{}) { e.loadLastOutOfWindowAckTime(y.(unixTime)) })
+	stateSourceObject.AfterLoad(e.afterLoad)
+}
+
+func (k *keepalive) StateTypeName() string {
+	return "pkg/tcpip/transport/tcp.keepalive"
+}
+
+func (k *keepalive) StateFields() []string {
+	return []string{
+		"idle",
+		"interval",
+		"count",
+		"unacked",
+	}
+}
+
+func (k *keepalive) beforeSave() {}
+
+// +checklocksignore
+func (k *keepalive) StateSave(stateSinkObject state.Sink) {
+	k.beforeSave()
+	stateSinkObject.Save(0, &k.idle)
+	stateSinkObject.Save(1, &k.interval)
+	stateSinkObject.Save(2, &k.count)
+	stateSinkObject.Save(3, &k.unacked)
+}
+
+func (k *keepalive) afterLoad() {}
+
+// +checklocksignore
+func (k *keepalive) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &k.idle)
+	stateSourceObject.Load(1, &k.interval)
+	stateSourceObject.Load(2, &k.count)
+	stateSourceObject.Load(3, &k.unacked)
+}
+
+func (rc *rackControl) StateTypeName() string {
+	return "pkg/tcpip/transport/tcp.rackControl"
+}
+
+func (rc *rackControl) StateFields() []string {
+	return []string{
+		"dsackSeen",
+		"endSequence",
+		"exitedRecovery",
+		"fack",
+		"minRTT",
+		"reorderSeen",
+		"reoWnd",
+		"reoWndIncr",
+		"reoWndPersist",
+		"rtt",
+		"rttSeq",
+		"xmitTime",
+		"tlpRxtOut",
+		"tlpHighRxt",
+		"snd",
+	}
+}
+
+func (rc *rackControl) beforeSave() {}
+
+// +checklocksignore
+func (rc *rackControl) StateSave(stateSinkObject state.Sink) {
+	rc.beforeSave()
+	var xmitTimeValue unixTime = rc.saveXmitTime()
+	stateSinkObject.SaveValue(11, xmitTimeValue)
+	stateSinkObject.Save(0, &rc.dsackSeen)
+	stateSinkObject.Save(1, &rc.endSequence)
+	stateSinkObject.Save(2, &rc.exitedRecovery)
+	stateSinkObject.Save(3, &rc.fack)
+	stateSinkObject.Save(4, &rc.minRTT)
+	stateSinkObject.Save(5, &rc.reorderSeen)
+	stateSinkObject.Save(6, &rc.reoWnd)
+	stateSinkObject.Save(7, &rc.reoWndIncr)
+	stateSinkObject.Save(8, &rc.reoWndPersist)
+	stateSinkObject.Save(9, &rc.rtt)
+	stateSinkObject.Save(10, &rc.rttSeq)
+	stateSinkObject.Save(12, &rc.tlpRxtOut)
+	stateSinkObject.Save(13, &rc.tlpHighRxt)
+	stateSinkObject.Save(14, &rc.snd)
+}
+
+func (rc *rackControl) afterLoad() {}
+
+// +checklocksignore
+func (rc *rackControl) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &rc.dsackSeen)
+	stateSourceObject.Load(1, &rc.endSequence)
+	stateSourceObject.Load(2, &rc.exitedRecovery)
+	stateSourceObject.Load(3, &rc.fack)
+	stateSourceObject.Load(4, &rc.minRTT)
+	stateSourceObject.Load(5, &rc.reorderSeen)
+	stateSourceObject.Load(6, &rc.reoWnd)
+	stateSourceObject.Load(7, &rc.reoWndIncr)
+	stateSourceObject.Load(8, &rc.reoWndPersist)
+	stateSourceObject.Load(9, &rc.rtt)
+	stateSourceObject.Load(10, &rc.rttSeq)
+	stateSourceObject.Load(12, &rc.tlpRxtOut)
+	stateSourceObject.Load(13, &rc.tlpHighRxt)
+	stateSourceObject.Load(14, &rc.snd)
+	stateSourceObject.LoadValue(11, new(unixTime), func(y interface{}) { rc.loadXmitTime(y.(unixTime)) })
+}
+
+func (r *receiver) StateTypeName() string {
+	return "pkg/tcpip/transport/tcp.receiver"
+}
+
+func (r *receiver) StateFields() []string {
+	return []string{
+		"ep",
+		"rcvNxt",
+		"rcvAcc",
+		"rcvWnd",
+		"rcvWUP",
+		"rcvWndScale",
+		"prevBufUsed",
+		"closed",
+		"pendingRcvdSegments",
+		"pendingBufUsed",
+		"lastRcvdAckTime",
+	}
+}
+
+func (r *receiver) beforeSave() {}
+
+// +checklocksignore
+func (r *receiver) StateSave(stateSinkObject state.Sink) {
+	r.beforeSave()
+	var lastRcvdAckTimeValue unixTime = r.saveLastRcvdAckTime()
+	stateSinkObject.SaveValue(10, lastRcvdAckTimeValue)
+	stateSinkObject.Save(0, &r.ep)
+	stateSinkObject.Save(1, &r.rcvNxt)
+	stateSinkObject.Save(2, &r.rcvAcc)
+	stateSinkObject.Save(3, &r.rcvWnd)
+	stateSinkObject.Save(4, &r.rcvWUP)
+	stateSinkObject.Save(5, &r.rcvWndScale)
+	stateSinkObject.Save(6, &r.prevBufUsed)
+	stateSinkObject.Save(7, &r.closed)
+	stateSinkObject.Save(8, &r.pendingRcvdSegments)
+	stateSinkObject.Save(9, &r.pendingBufUsed)
+}
+
+func (r *receiver) afterLoad() {}
+
+// +checklocksignore
+func (r *receiver) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &r.ep)
+	stateSourceObject.Load(1, &r.rcvNxt)
+	stateSourceObject.Load(2, &r.rcvAcc)
+	stateSourceObject.Load(3, &r.rcvWnd)
+	stateSourceObject.Load(4, &r.rcvWUP)
+	stateSourceObject.Load(5, &r.rcvWndScale)
+	stateSourceObject.Load(6, &r.prevBufUsed)
+	stateSourceObject.Load(7, &r.closed)
+	stateSourceObject.Load(8, &r.pendingRcvdSegments)
+	stateSourceObject.Load(9, &r.pendingBufUsed)
+	stateSourceObject.LoadValue(10, new(unixTime), func(y interface{}) { r.loadLastRcvdAckTime(y.(unixTime)) })
+}
+
+func (r *renoState) StateTypeName() string {
+	return "pkg/tcpip/transport/tcp.renoState"
+}
+
+func (r *renoState) StateFields() []string {
+	return []string{
+		"s",
+	}
+}
+
+func (r *renoState) beforeSave() {}
+
+// +checklocksignore
+func (r *renoState) StateSave(stateSinkObject state.Sink) {
+	r.beforeSave()
+	stateSinkObject.Save(0, &r.s)
+}
+
+func (r *renoState) afterLoad() {}
+
+// +checklocksignore
+func (r *renoState) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &r.s)
+}
+
+func (rr *renoRecovery) StateTypeName() string {
+	return "pkg/tcpip/transport/tcp.renoRecovery"
+}
+
+func (rr *renoRecovery) StateFields() []string {
+	return []string{
+		"s",
+	}
+}
+
+func (rr *renoRecovery) beforeSave() {}
+
+// +checklocksignore
+func (rr *renoRecovery) StateSave(stateSinkObject state.Sink) {
+	rr.beforeSave()
+	stateSinkObject.Save(0, &rr.s)
+}
+
+func (rr *renoRecovery) afterLoad() {}
+
+// +checklocksignore
+func (rr *renoRecovery) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &rr.s)
+}
+
+func (sr *sackRecovery) StateTypeName() string {
+	return "pkg/tcpip/transport/tcp.sackRecovery"
+}
+
+func (sr *sackRecovery) StateFields() []string {
+	return []string{
+		"s",
+	}
+}
+
+func (sr *sackRecovery) beforeSave() {}
+
+// +checklocksignore
+func (sr *sackRecovery) StateSave(stateSinkObject state.Sink) {
+	sr.beforeSave()
+	stateSinkObject.Save(0, &sr.s)
+}
+
+func (sr *sackRecovery) afterLoad() {}
+
+// +checklocksignore
+func (sr *sackRecovery) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &sr.s)
+}
+
+func (s *SACKScoreboard) StateTypeName() string {
+	return "pkg/tcpip/transport/tcp.SACKScoreboard"
+}
+
+func (s *SACKScoreboard) StateFields() []string {
+	return []string{
+		"smss",
+		"maxSACKED",
+	}
+}
+
+func (s *SACKScoreboard) beforeSave() {}
+
+// +checklocksignore
+func (s *SACKScoreboard) StateSave(stateSinkObject state.Sink) {
+	s.beforeSave()
+	stateSinkObject.Save(0, &s.smss)
+	stateSinkObject.Save(1, &s.maxSACKED)
+}
+
+func (s *SACKScoreboard) afterLoad() {}
+
+// +checklocksignore
+func (s *SACKScoreboard) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &s.smss)
+	stateSourceObject.Load(1, &s.maxSACKED)
+}
+
+func (s *segment) StateTypeName() string {
+	return "pkg/tcpip/transport/tcp.segment"
+}
+
+func (s *segment) StateFields() []string {
+	return []string{
+		"segmentEntry",
+		"refCnt",
+		"ep",
+		"qFlags",
+		"srcAddr",
+		"dstAddr",
+		"netProto",
+		"nicID",
+		"data",
+		"hdr",
+		"sequenceNumber",
+		"ackNumber",
+		"flags",
+		"window",
+		"csum",
+		"csumValid",
+		"parsedOptions",
+		"options",
+		"hasNewSACKInfo",
+		"rcvdTime",
+		"xmitTime",
+		"xmitCount",
+		"acked",
+		"dataMemSize",
+		"lost",
+	}
+}
+
+func (s *segment) beforeSave() {}
+
+// +checklocksignore
+func (s *segment) StateSave(stateSinkObject state.Sink) {
+	s.beforeSave()
+	var dataValue buffer.VectorisedView = s.saveData()
+	stateSinkObject.SaveValue(8, dataValue)
+	var optionsValue []byte = s.saveOptions()
+	stateSinkObject.SaveValue(17, optionsValue)
+	var rcvdTimeValue unixTime = s.saveRcvdTime()
+	stateSinkObject.SaveValue(19, rcvdTimeValue)
+	var xmitTimeValue unixTime = s.saveXmitTime()
+	stateSinkObject.SaveValue(20, xmitTimeValue)
+	stateSinkObject.Save(0, &s.segmentEntry)
+	stateSinkObject.Save(1, &s.refCnt)
+	stateSinkObject.Save(2, &s.ep)
+	stateSinkObject.Save(3, &s.qFlags)
+	stateSinkObject.Save(4, &s.srcAddr)
+	stateSinkObject.Save(5, &s.dstAddr)
+	stateSinkObject.Save(6, &s.netProto)
+	stateSinkObject.Save(7, &s.nicID)
+	stateSinkObject.Save(9, &s.hdr)
+	stateSinkObject.Save(10, &s.sequenceNumber)
+	stateSinkObject.Save(11, &s.ackNumber)
+	stateSinkObject.Save(12, &s.flags)
+	stateSinkObject.Save(13, &s.window)
+	stateSinkObject.Save(14, &s.csum)
+	stateSinkObject.Save(15, &s.csumValid)
+	stateSinkObject.Save(16, &s.parsedOptions)
+	stateSinkObject.Save(18, &s.hasNewSACKInfo)
+	stateSinkObject.Save(21, &s.xmitCount)
+	stateSinkObject.Save(22, &s.acked)
+	stateSinkObject.Save(23, &s.dataMemSize)
+	stateSinkObject.Save(24, &s.lost)
+}
+
+func (s *segment) afterLoad() {}
+
+// +checklocksignore
+func (s *segment) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &s.segmentEntry)
+	stateSourceObject.Load(1, &s.refCnt)
+	stateSourceObject.Load(2, &s.ep)
+	stateSourceObject.Load(3, &s.qFlags)
+	stateSourceObject.Load(4, &s.srcAddr)
+	stateSourceObject.Load(5, &s.dstAddr)
+	stateSourceObject.Load(6, &s.netProto)
+	stateSourceObject.Load(7, &s.nicID)
+	stateSourceObject.Load(9, &s.hdr)
+	stateSourceObject.Load(10, &s.sequenceNumber)
+	stateSourceObject.Load(11, &s.ackNumber)
+	stateSourceObject.Load(12, &s.flags)
+	stateSourceObject.Load(13, &s.window)
+	stateSourceObject.Load(14, &s.csum)
+	stateSourceObject.Load(15, &s.csumValid)
+	stateSourceObject.Load(16, &s.parsedOptions)
+	stateSourceObject.Load(18, &s.hasNewSACKInfo)
+	stateSourceObject.Load(21, &s.xmitCount)
+	stateSourceObject.Load(22, &s.acked)
+	stateSourceObject.Load(23, &s.dataMemSize)
+	stateSourceObject.Load(24, &s.lost)
+	stateSourceObject.LoadValue(8, new(buffer.VectorisedView), func(y interface{}) { s.loadData(y.(buffer.VectorisedView)) })
+	stateSourceObject.LoadValue(17, new([]byte), func(y interface{}) { s.loadOptions(y.([]byte)) })
+	stateSourceObject.LoadValue(19, new(unixTime), func(y interface{}) { s.loadRcvdTime(y.(unixTime)) })
+	stateSourceObject.LoadValue(20, new(unixTime), func(y interface{}) { s.loadXmitTime(y.(unixTime)) })
+}
+
+func (q *segmentQueue) StateTypeName() string {
+	return "pkg/tcpip/transport/tcp.segmentQueue"
+}
+
+func (q *segmentQueue) StateFields() []string {
+	return []string{
+		"list",
+		"ep",
+		"frozen",
+	}
+}
+
+func (q *segmentQueue) beforeSave() {}
+
+// +checklocksignore
+func (q *segmentQueue) StateSave(stateSinkObject state.Sink) {
+	q.beforeSave()
+	stateSinkObject.Save(0, &q.list)
+	stateSinkObject.Save(1, &q.ep)
+	stateSinkObject.Save(2, &q.frozen)
+}
+
+func (q *segmentQueue) afterLoad() {}
+
+// +checklocksignore
+func (q *segmentQueue) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.LoadWait(0, &q.list)
+	stateSourceObject.Load(1, &q.ep)
+	stateSourceObject.Load(2, &q.frozen)
+}
+
+func (s *sender) StateTypeName() string {
+	return "pkg/tcpip/transport/tcp.sender"
+}
+
+func (s *sender) StateFields() []string {
+	return []string{
+		"ep",
+		"lastSendTime",
+		"dupAckCount",
+		"fr",
+		"lr",
+		"sndCwnd",
+		"sndSsthresh",
+		"sndCAAckCount",
+		"outstanding",
+		"sackedOut",
+		"sndWnd",
+		"sndUna",
+		"sndNxt",
+		"rttMeasureSeqNum",
+		"rttMeasureTime",
+		"firstRetransmittedSegXmitTime",
+		"closed",
+		"writeNext",
+		"writeList",
+		"rtt",
+		"rto",
+		"minRTO",
+		"maxRTO",
+		"maxRetries",
+		"maxPayloadSize",
+		"gso",
+		"sndWndScale",
+		"maxSentAck",
+		"state",
+		"cc",
+		"rc",
+	}
+}
+
+func (s *sender) beforeSave() {}
+
+// +checklocksignore
+func (s *sender) StateSave(stateSinkObject state.Sink) {
+	s.beforeSave()
+	var lastSendTimeValue unixTime = s.saveLastSendTime()
+	stateSinkObject.SaveValue(1, lastSendTimeValue)
+	var rttMeasureTimeValue unixTime = s.saveRttMeasureTime()
+	stateSinkObject.SaveValue(14, rttMeasureTimeValue)
+	var firstRetransmittedSegXmitTimeValue unixTime = s.saveFirstRetransmittedSegXmitTime()
+	stateSinkObject.SaveValue(15, firstRetransmittedSegXmitTimeValue)
+	stateSinkObject.Save(0, &s.ep)
+	stateSinkObject.Save(2, &s.dupAckCount)
+	stateSinkObject.Save(3, &s.fr)
+	stateSinkObject.Save(4, &s.lr)
+	stateSinkObject.Save(5, &s.sndCwnd)
+	stateSinkObject.Save(6, &s.sndSsthresh)
+	stateSinkObject.Save(7, &s.sndCAAckCount)
+	stateSinkObject.Save(8, &s.outstanding)
+	stateSinkObject.Save(9, &s.sackedOut)
+	stateSinkObject.Save(10, &s.sndWnd)
+	stateSinkObject.Save(11, &s.sndUna)
+	stateSinkObject.Save(12, &s.sndNxt)
+	stateSinkObject.Save(13, &s.rttMeasureSeqNum)
+	stateSinkObject.Save(16, &s.closed)
+	stateSinkObject.Save(17, &s.writeNext)
+	stateSinkObject.Save(18, &s.writeList)
+	stateSinkObject.Save(19, &s.rtt)
+	stateSinkObject.Save(20, &s.rto)
+	stateSinkObject.Save(21, &s.minRTO)
+	stateSinkObject.Save(22, &s.maxRTO)
+	stateSinkObject.Save(23, &s.maxRetries)
+	stateSinkObject.Save(24, &s.maxPayloadSize)
+	stateSinkObject.Save(25, &s.gso)
+	stateSinkObject.Save(26, &s.sndWndScale)
+	stateSinkObject.Save(27, &s.maxSentAck)
+	stateSinkObject.Save(28, &s.state)
+	stateSinkObject.Save(29, &s.cc)
+	stateSinkObject.Save(30, &s.rc)
+}
+
+// +checklocksignore
+func (s *sender) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &s.ep)
+	stateSourceObject.Load(2, &s.dupAckCount)
+	stateSourceObject.Load(3, &s.fr)
+	stateSourceObject.Load(4, &s.lr)
+	stateSourceObject.Load(5, &s.sndCwnd)
+	stateSourceObject.Load(6, &s.sndSsthresh)
+	stateSourceObject.Load(7, &s.sndCAAckCount)
+	stateSourceObject.Load(8, &s.outstanding)
+	stateSourceObject.Load(9, &s.sackedOut)
+	stateSourceObject.Load(10, &s.sndWnd)
+	stateSourceObject.Load(11, &s.sndUna)
+	stateSourceObject.Load(12, &s.sndNxt)
+	stateSourceObject.Load(13, &s.rttMeasureSeqNum)
+	stateSourceObject.Load(16, &s.closed)
+	stateSourceObject.Load(17, &s.writeNext)
+	stateSourceObject.Load(18, &s.writeList)
+	stateSourceObject.Load(19, &s.rtt)
+	stateSourceObject.Load(20, &s.rto)
+	stateSourceObject.Load(21, &s.minRTO)
+	stateSourceObject.Load(22, &s.maxRTO)
+	stateSourceObject.Load(23, &s.maxRetries)
+	stateSourceObject.Load(24, &s.maxPayloadSize)
+	stateSourceObject.Load(25, &s.gso)
+	stateSourceObject.Load(26, &s.sndWndScale)
+	stateSourceObject.Load(27, &s.maxSentAck)
+	stateSourceObject.Load(28, &s.state)
+	stateSourceObject.Load(29, &s.cc)
+	stateSourceObject.Load(30, &s.rc)
+	stateSourceObject.LoadValue(1, new(unixTime), func(y interface{}) { s.loadLastSendTime(y.(unixTime)) })
+	stateSourceObject.LoadValue(14, new(unixTime), func(y interface{}) { s.loadRttMeasureTime(y.(unixTime)) })
+	stateSourceObject.LoadValue(15, new(unixTime), func(y interface{}) { s.loadFirstRetransmittedSegXmitTime(y.(unixTime)) })
+	stateSourceObject.AfterLoad(s.afterLoad)
+}
+
+func (r *rtt) StateTypeName() string {
+	return "pkg/tcpip/transport/tcp.rtt"
+}
+
+func (r *rtt) StateFields() []string {
+	return []string{
+		"srtt",
+		"rttvar",
+		"srttInited",
+	}
+}
+
+func (r *rtt) beforeSave() {}
+
+// +checklocksignore
+func (r *rtt) StateSave(stateSinkObject state.Sink) {
+	r.beforeSave()
+	stateSinkObject.Save(0, &r.srtt)
+	stateSinkObject.Save(1, &r.rttvar)
+	stateSinkObject.Save(2, &r.srttInited)
+}
+
+func (r *rtt) afterLoad() {}
+
+// +checklocksignore
+func (r *rtt) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &r.srtt)
+	stateSourceObject.Load(1, &r.rttvar)
+	stateSourceObject.Load(2, &r.srttInited)
+}
+
+func (f *fastRecovery) StateTypeName() string {
+	return "pkg/tcpip/transport/tcp.fastRecovery"
+}
+
+func (f *fastRecovery) StateFields() []string {
+	return []string{
+		"active",
+		"first",
+		"last",
+		"maxCwnd",
+		"highRxt",
+		"rescueRxt",
+	}
+}
+
+func (f *fastRecovery) beforeSave() {}
+
+// +checklocksignore
+func (f *fastRecovery) StateSave(stateSinkObject state.Sink) {
+	f.beforeSave()
+	stateSinkObject.Save(0, &f.active)
+	stateSinkObject.Save(1, &f.first)
+	stateSinkObject.Save(2, &f.last)
+	stateSinkObject.Save(3, &f.maxCwnd)
+	stateSinkObject.Save(4, &f.highRxt)
+	stateSinkObject.Save(5, &f.rescueRxt)
+}
+
+func (f *fastRecovery) afterLoad() {}
+
+// +checklocksignore
+func (f *fastRecovery) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &f.active)
+	stateSourceObject.Load(1, &f.first)
+	stateSourceObject.Load(2, &f.last)
+	stateSourceObject.Load(3, &f.maxCwnd)
+	stateSourceObject.Load(4, &f.highRxt)
+	stateSourceObject.Load(5, &f.rescueRxt)
+}
+
+func (u *unixTime) StateTypeName() string {
+	return "pkg/tcpip/transport/tcp.unixTime"
+}
+
+func (u *unixTime) StateFields() []string {
+	return []string{
+		"second",
+		"nano",
+	}
+}
+
+func (u *unixTime) beforeSave() {}
+
+// +checklocksignore
+func (u *unixTime) StateSave(stateSinkObject state.Sink) {
+	u.beforeSave()
+	stateSinkObject.Save(0, &u.second)
+	stateSinkObject.Save(1, &u.nano)
+}
+
+func (u *unixTime) afterLoad() {}
+
+// +checklocksignore
+func (u *unixTime) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &u.second)
+	stateSourceObject.Load(1, &u.nano)
+}
+
+func (l *endpointList) StateTypeName() string {
+	return "pkg/tcpip/transport/tcp.endpointList"
+}
+
+func (l *endpointList) StateFields() []string {
+	return []string{
+		"head",
+		"tail",
+	}
+}
+
+func (l *endpointList) beforeSave() {}
+
+// +checklocksignore
+func (l *endpointList) StateSave(stateSinkObject state.Sink) {
+	l.beforeSave()
+	stateSinkObject.Save(0, &l.head)
+	stateSinkObject.Save(1, &l.tail)
+}
+
+func (l *endpointList) afterLoad() {}
+
+// +checklocksignore
+func (l *endpointList) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &l.head)
+	stateSourceObject.Load(1, &l.tail)
+}
+
+func (e *endpointEntry) StateTypeName() string {
+	return "pkg/tcpip/transport/tcp.endpointEntry"
+}
+
+func (e *endpointEntry) StateFields() []string {
+	return []string{
+		"next",
+		"prev",
+	}
+}
+
+func (e *endpointEntry) beforeSave() {}
+
+// +checklocksignore
+func (e *endpointEntry) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+	stateSinkObject.Save(0, &e.next)
+	stateSinkObject.Save(1, &e.prev)
+}
+
+func (e *endpointEntry) afterLoad() {}
+
+// +checklocksignore
+func (e *endpointEntry) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &e.next)
+	stateSourceObject.Load(1, &e.prev)
+}
+
+func (l *segmentList) StateTypeName() string {
+	return "pkg/tcpip/transport/tcp.segmentList"
+}
+
+func (l *segmentList) StateFields() []string {
+	return []string{
+		"head",
+		"tail",
+	}
+}
+
+func (l *segmentList) beforeSave() {}
+
+// +checklocksignore
+func (l *segmentList) StateSave(stateSinkObject state.Sink) {
+	l.beforeSave()
+	stateSinkObject.Save(0, &l.head)
+	stateSinkObject.Save(1, &l.tail)
+}
+
+func (l *segmentList) afterLoad() {}
+
+// +checklocksignore
+func (l *segmentList) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &l.head)
+	stateSourceObject.Load(1, &l.tail)
+}
+
+func (e *segmentEntry) StateTypeName() string {
+	return "pkg/tcpip/transport/tcp.segmentEntry"
+}
+
+func (e *segmentEntry) StateFields() []string {
+	return []string{
+		"next",
+		"prev",
+	}
+}
+
+func (e *segmentEntry) beforeSave() {}
+
+// +checklocksignore
+func (e *segmentEntry) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+	stateSinkObject.Save(0, &e.next)
+	stateSinkObject.Save(1, &e.prev)
+}
+
+func (e *segmentEntry) afterLoad() {}
+
+// +checklocksignore
+func (e *segmentEntry) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &e.next)
+	stateSourceObject.Load(1, &e.prev)
+}
+
+func init() {
+	state.Register((*cubicState)(nil))
+	state.Register((*SACKInfo)(nil))
+	state.Register((*rcvBufAutoTuneParams)(nil))
+	state.Register((*EndpointInfo)(nil))
+	state.Register((*endpoint)(nil))
+	state.Register((*keepalive)(nil))
+	state.Register((*rackControl)(nil))
+	state.Register((*receiver)(nil))
+	state.Register((*renoState)(nil))
+	state.Register((*renoRecovery)(nil))
+	state.Register((*sackRecovery)(nil))
+	state.Register((*SACKScoreboard)(nil))
+	state.Register((*segment)(nil))
+	state.Register((*segmentQueue)(nil))
+	state.Register((*sender)(nil))
+	state.Register((*rtt)(nil))
+	state.Register((*fastRecovery)(nil))
+	state.Register((*unixTime)(nil))
+	state.Register((*endpointList)(nil))
+	state.Register((*endpointEntry)(nil))
+	state.Register((*segmentList)(nil))
+	state.Register((*segmentEntry)(nil))
+}
diff --git a/pkg/tcpip/transport/tcp/tcp_test.go b/pkg/tcpip/transport/tcp/tcp_test.go
deleted file mode 100644
index 6c86ae1..0000000
--- a/pkg/tcpip/transport/tcp/tcp_test.go
+++ /dev/null
@@ -1,7814 +0,0 @@
-// 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 tcp_test
-
-import (
-	"bytes"
-	"fmt"
-	"io/ioutil"
-	"math"
-	"strings"
-	"testing"
-	"time"
-
-	"github.com/google/go-cmp/cmp"
-	"gvisor.dev/gvisor/pkg/rand"
-	"gvisor.dev/gvisor/pkg/sync"
-	"gvisor.dev/gvisor/pkg/tcpip"
-	"gvisor.dev/gvisor/pkg/tcpip/checker"
-	"gvisor.dev/gvisor/pkg/tcpip/header"
-	"gvisor.dev/gvisor/pkg/tcpip/link/loopback"
-	"gvisor.dev/gvisor/pkg/tcpip/link/sniffer"
-	"gvisor.dev/gvisor/pkg/tcpip/network/ipv4"
-	"gvisor.dev/gvisor/pkg/tcpip/network/ipv6"
-	"gvisor.dev/gvisor/pkg/tcpip/seqnum"
-	"gvisor.dev/gvisor/pkg/tcpip/stack"
-	"gvisor.dev/gvisor/pkg/tcpip/transport/tcp"
-	"gvisor.dev/gvisor/pkg/tcpip/transport/tcp/testing/context"
-	"gvisor.dev/gvisor/pkg/test/testutil"
-	"gvisor.dev/gvisor/pkg/waiter"
-)
-
-// endpointTester provides helper functions to test a tcpip.Endpoint.
-type endpointTester struct {
-	ep tcpip.Endpoint
-}
-
-// CheckReadError issues a read to the endpoint and checking for an error.
-func (e *endpointTester) CheckReadError(t *testing.T, want tcpip.Error) {
-	t.Helper()
-	res, got := e.ep.Read(ioutil.Discard, tcpip.ReadOptions{})
-	if got != want {
-		t.Fatalf("ep.Read = %s, want %s", got, want)
-	}
-	if diff := cmp.Diff(tcpip.ReadResult{}, res); diff != "" {
-		t.Errorf("ep.Read: unexpected non-zero result (-want +got):\n%s", diff)
-	}
-}
-
-// CheckRead issues a read to the endpoint and checking for a success, returning
-// the data read.
-func (e *endpointTester) CheckRead(t *testing.T) []byte {
-	t.Helper()
-	var buf bytes.Buffer
-	res, err := e.ep.Read(&buf, tcpip.ReadOptions{})
-	if err != nil {
-		t.Fatalf("ep.Read = _, %s; want _, nil", err)
-	}
-	if diff := cmp.Diff(tcpip.ReadResult{
-		Count: buf.Len(),
-		Total: buf.Len(),
-	}, res, checker.IgnoreCmpPath("ControlMessages")); diff != "" {
-		t.Errorf("ep.Read: unexpected result (-want +got):\n%s", diff)
-	}
-	return buf.Bytes()
-}
-
-// CheckReadFull reads from the endpoint for exactly count bytes.
-func (e *endpointTester) CheckReadFull(t *testing.T, count int, notifyRead <-chan struct{}, timeout time.Duration) []byte {
-	t.Helper()
-	var buf bytes.Buffer
-	w := tcpip.LimitedWriter{
-		W: &buf,
-		N: int64(count),
-	}
-	for w.N != 0 {
-		_, err := e.ep.Read(&w, tcpip.ReadOptions{})
-		if _, ok := err.(*tcpip.ErrWouldBlock); ok {
-			// Wait for receive to be notified.
-			select {
-			case <-notifyRead:
-			case <-time.After(timeout):
-				t.Fatalf("Timed out waiting for data to arrive")
-			}
-			continue
-		} else if err != nil {
-			t.Fatalf("ep.Read = _, %s; want _, nil", err)
-		}
-	}
-	return buf.Bytes()
-}
-
-const (
-	// defaultMTU is the MTU, in bytes, used throughout the tests, except
-	// where another value is explicitly used. It is chosen to match the MTU
-	// of loopback interfaces on linux systems.
-	defaultMTU = 65535
-
-	// defaultIPv4MSS is the MSS sent by the network stack in SYN/SYN-ACK for an
-	// IPv4 endpoint when the MTU is set to defaultMTU in the test.
-	defaultIPv4MSS = defaultMTU - header.IPv4MinimumSize - header.TCPMinimumSize
-)
-
-func TestGiveUpConnect(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	var wq waiter.Queue
-	ep, err := c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &wq)
-	if err != nil {
-		t.Fatalf("NewEndpoint failed: %s", err)
-	}
-
-	// Register for notification, then start connection attempt.
-	waitEntry, notifyCh := waiter.NewChannelEntry(nil)
-	wq.EventRegister(&waitEntry, waiter.EventHUp)
-	defer wq.EventUnregister(&waitEntry)
-
-	{
-		err := ep.Connect(tcpip.FullAddress{Addr: context.TestAddr, Port: context.TestPort})
-		if _, ok := err.(*tcpip.ErrConnectStarted); !ok {
-			t.Fatalf("got ep.Connect(...) = %v, want = %s", err, &tcpip.ErrConnectStarted{})
-		}
-	}
-
-	// Close the connection, wait for completion.
-	ep.Close()
-
-	// Wait for ep to become writable.
-	<-notifyCh
-
-	// Call Connect again to retreive the handshake failure status
-	// and stats updates.
-	{
-		err := ep.Connect(tcpip.FullAddress{Addr: context.TestAddr, Port: context.TestPort})
-		if _, ok := err.(*tcpip.ErrAborted); !ok {
-			t.Fatalf("got ep.Connect(...) = %v, want = %s", err, &tcpip.ErrAborted{})
-		}
-	}
-
-	if got := c.Stack().Stats().TCP.FailedConnectionAttempts.Value(); got != 1 {
-		t.Errorf("got stats.TCP.FailedConnectionAttempts.Value() = %d, want = 1", got)
-	}
-
-	if got := c.Stack().Stats().TCP.CurrentEstablished.Value(); got != 0 {
-		t.Errorf("got stats.TCP.CurrentEstablished.Value() = %d, want = 0", got)
-	}
-}
-
-func TestConnectIncrementActiveConnection(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	stats := c.Stack().Stats()
-	want := stats.TCP.ActiveConnectionOpenings.Value() + 1
-
-	c.CreateConnected(context.TestInitialSequenceNumber, 30000, -1 /* epRcvBuf */)
-	if got := stats.TCP.ActiveConnectionOpenings.Value(); got != want {
-		t.Errorf("got stats.TCP.ActtiveConnectionOpenings.Value() = %d, want = %d", got, want)
-	}
-}
-
-func TestConnectDoesNotIncrementFailedConnectionAttempts(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	stats := c.Stack().Stats()
-	want := stats.TCP.FailedConnectionAttempts.Value()
-
-	c.CreateConnected(context.TestInitialSequenceNumber, 30000, -1 /* epRcvBuf */)
-	if got := stats.TCP.FailedConnectionAttempts.Value(); got != want {
-		t.Errorf("got stats.TCP.FailedConnectionAttempts.Value() = %d, want = %d", got, want)
-	}
-	if got := c.EP.Stats().(*tcp.Stats).FailedConnectionAttempts.Value(); got != want {
-		t.Errorf("got EP stats.FailedConnectionAttempts = %d, want = %d", got, want)
-	}
-}
-
-func TestActiveFailedConnectionAttemptIncrement(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	stats := c.Stack().Stats()
-	ep, err := c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &c.WQ)
-	if err != nil {
-		t.Fatalf("NewEndpoint failed: %s", err)
-	}
-	c.EP = ep
-	want := stats.TCP.FailedConnectionAttempts.Value() + 1
-
-	{
-		err := c.EP.Connect(tcpip.FullAddress{NIC: 2, Addr: context.TestAddr, Port: context.TestPort})
-		if _, ok := err.(*tcpip.ErrNoRoute); !ok {
-			t.Errorf("got c.EP.Connect(...) = %v, want = %s", err, &tcpip.ErrNoRoute{})
-		}
-	}
-
-	if got := stats.TCP.FailedConnectionAttempts.Value(); got != want {
-		t.Errorf("got stats.TCP.FailedConnectionAttempts.Value() = %d, want = %d", got, want)
-	}
-	if got := c.EP.Stats().(*tcp.Stats).FailedConnectionAttempts.Value(); got != want {
-		t.Errorf("got EP stats FailedConnectionAttempts = %d, want = %d", got, want)
-	}
-}
-
-func TestCloseWithoutConnect(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	// Create TCP endpoint.
-	var err tcpip.Error
-	c.EP, err = c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &c.WQ)
-	if err != nil {
-		t.Fatalf("NewEndpoint failed: %s", err)
-	}
-
-	c.EP.Close()
-
-	if got := c.Stack().Stats().TCP.CurrentConnected.Value(); got != 0 {
-		t.Errorf("got stats.TCP.CurrentConnected.Value() = %d, want = 0", got)
-	}
-}
-
-func TestTCPSegmentsSentIncrement(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	stats := c.Stack().Stats()
-	// SYN and ACK
-	want := stats.TCP.SegmentsSent.Value() + 2
-	c.CreateConnected(context.TestInitialSequenceNumber, 30000, -1 /* epRcvBuf */)
-
-	if got := stats.TCP.SegmentsSent.Value(); got != want {
-		t.Errorf("got stats.TCP.SegmentsSent.Value() = %d, want = %d", got, want)
-	}
-	if got := c.EP.Stats().(*tcp.Stats).SegmentsSent.Value(); got != want {
-		t.Errorf("got EP stats SegmentsSent.Value() = %d, want = %d", got, want)
-	}
-}
-
-func TestTCPResetsSentIncrement(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-	stats := c.Stack().Stats()
-	wq := &waiter.Queue{}
-	ep, err := c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, wq)
-	if err != nil {
-		t.Fatalf("NewEndpoint failed: %s", err)
-	}
-	want := stats.TCP.SegmentsSent.Value() + 1
-
-	if err := ep.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %s", err)
-	}
-
-	if err := ep.Listen(10); err != nil {
-		t.Fatalf("Listen failed: %s", err)
-	}
-
-	// Send a SYN request.
-	iss := seqnum.Value(context.TestInitialSequenceNumber)
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagSyn,
-		SeqNum:  iss,
-	})
-
-	// Receive the SYN-ACK reply.
-	b := c.GetPacket()
-	tcpHdr := header.TCP(header.IPv4(b).Payload())
-	c.IRS = seqnum.Value(tcpHdr.SequenceNumber())
-
-	ackHeaders := &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss + 1,
-		// If the AckNum is not the increment of the last sequence number, a RST
-		// segment is sent back in response.
-		AckNum: c.IRS + 2,
-	}
-
-	// Send ACK.
-	c.SendPacket(nil, ackHeaders)
-
-	c.GetPacket()
-
-	metricPollFn := func() error {
-		if got := stats.TCP.ResetsSent.Value(); got != want {
-			return fmt.Errorf("got stats.TCP.ResetsSent.Value() = %d, want = %d", got, want)
-		}
-		return nil
-	}
-	if err := testutil.Poll(metricPollFn, 1*time.Second); err != nil {
-		t.Error(err)
-	}
-}
-
-// TestTCPResetsSentNoICMP confirms that we don't get an ICMP
-// DstUnreachable packet when we try send a packet which is not part
-// of an active session.
-func TestTCPResetsSentNoICMP(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-	stats := c.Stack().Stats()
-
-	// Send a SYN request for a closed port. This should elicit an RST
-	// but NOT an ICMPv4 DstUnreachable packet.
-	iss := seqnum.Value(context.TestInitialSequenceNumber)
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagSyn,
-		SeqNum:  iss,
-	})
-
-	// Receive whatever comes back.
-	b := c.GetPacket()
-	ipHdr := header.IPv4(b)
-	if got, want := ipHdr.Protocol(), uint8(header.TCPProtocolNumber); got != want {
-		t.Errorf("unexpected protocol, got = %d, want = %d", got, want)
-	}
-
-	// Read outgoing ICMP stats and check no ICMP DstUnreachable was recorded.
-	sent := stats.ICMP.V4.PacketsSent
-	if got, want := sent.DstUnreachable.Value(), uint64(0); got != want {
-		t.Errorf("got ICMP DstUnreachable.Value() = %d, want = %d", got, want)
-	}
-}
-
-// TestTCPResetSentForACKWhenNotUsingSynCookies checks that the stack generates
-// a RST if an ACK is received on the listening socket for which there is no
-// active handshake in progress and we are not using SYN cookies.
-func TestTCPResetSentForACKWhenNotUsingSynCookies(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	// Set TCPLingerTimeout to 5 seconds so that sockets are marked closed
-	wq := &waiter.Queue{}
-	ep, err := c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, wq)
-	if err != nil {
-		t.Fatalf("NewEndpoint failed: %s", err)
-	}
-	if err := ep.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %s", err)
-	}
-
-	if err := ep.Listen(10); err != nil {
-		t.Fatalf("Listen failed: %s", err)
-	}
-
-	// Send a SYN request.
-	iss := seqnum.Value(context.TestInitialSequenceNumber)
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagSyn,
-		SeqNum:  iss,
-	})
-
-	// Receive the SYN-ACK reply.
-	b := c.GetPacket()
-	tcpHdr := header.TCP(header.IPv4(b).Payload())
-	c.IRS = seqnum.Value(tcpHdr.SequenceNumber())
-
-	ackHeaders := &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss + 1,
-		AckNum:  c.IRS + 1,
-	}
-
-	// Send ACK.
-	c.SendPacket(nil, ackHeaders)
-
-	// Try to accept the connection.
-	we, ch := waiter.NewChannelEntry(nil)
-	wq.EventRegister(&we, waiter.EventIn)
-	defer wq.EventUnregister(&we)
-
-	c.EP, _, err = ep.Accept(nil)
-	if _, ok := err.(*tcpip.ErrWouldBlock); ok {
-		// Wait for connection to be established.
-		select {
-		case <-ch:
-			c.EP, _, err = ep.Accept(nil)
-			if err != nil {
-				t.Fatalf("Accept failed: %s", err)
-			}
-
-		case <-time.After(1 * time.Second):
-			t.Fatalf("Timed out waiting for accept")
-		}
-	}
-
-	// Lower stackwide TIME_WAIT timeout so that the reservations
-	// are released instantly on Close.
-	tcpTW := tcpip.TCPTimeWaitTimeoutOption(1 * time.Millisecond)
-	if err := c.Stack().SetTransportProtocolOption(tcp.ProtocolNumber, &tcpTW); err != nil {
-		t.Fatalf("SetTransportProtocolOption(%d, &%T(%d)): %s", tcp.ProtocolNumber, tcpTW, tcpTW, err)
-	}
-
-	c.EP.Close()
-	checker.IPv4(t, c.GetPacket(), checker.TCP(
-		checker.SrcPort(context.StackPort),
-		checker.DstPort(context.TestPort),
-		checker.TCPSeqNum(uint32(c.IRS+1)),
-		checker.TCPAckNum(uint32(iss)+1),
-		checker.TCPFlags(header.TCPFlagFin|header.TCPFlagAck)))
-	finHeaders := &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagAck | header.TCPFlagFin,
-		SeqNum:  iss + 1,
-		AckNum:  c.IRS + 2,
-	}
-
-	c.SendPacket(nil, finHeaders)
-
-	// Get the ACK to the FIN we just sent.
-	c.GetPacket()
-
-	// Since an active close was done we need to wait for a little more than
-	// tcpLingerTimeout for the port reservations to be released and the
-	// socket to move to a CLOSED state.
-	time.Sleep(20 * time.Millisecond)
-
-	// Now resend the same ACK, this ACK should generate a RST as there
-	// should be no endpoint in SYN-RCVD state and we are not using
-	// syn-cookies yet. The reason we send the same ACK is we need a valid
-	// cookie(IRS) generated by the netstack without which the ACK will be
-	// rejected.
-	c.SendPacket(nil, ackHeaders)
-
-	checker.IPv4(t, c.GetPacket(), checker.TCP(
-		checker.SrcPort(context.StackPort),
-		checker.DstPort(context.TestPort),
-		checker.TCPSeqNum(uint32(c.IRS+1)),
-		checker.TCPAckNum(0),
-		checker.TCPFlags(header.TCPFlagRst)))
-}
-
-func TestTCPResetsReceivedIncrement(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	stats := c.Stack().Stats()
-	want := stats.TCP.ResetsReceived.Value() + 1
-	iss := seqnum.Value(context.TestInitialSequenceNumber)
-	rcvWnd := seqnum.Size(30000)
-	c.CreateConnected(iss, rcvWnd, -1 /* epRcvBuf */)
-
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		SeqNum:  iss.Add(1),
-		AckNum:  c.IRS.Add(1),
-		RcvWnd:  rcvWnd,
-		Flags:   header.TCPFlagRst,
-	})
-
-	if got := stats.TCP.ResetsReceived.Value(); got != want {
-		t.Errorf("got stats.TCP.ResetsReceived.Value() = %d, want = %d", got, want)
-	}
-}
-
-func TestTCPResetsDoNotGenerateResets(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	stats := c.Stack().Stats()
-	want := stats.TCP.ResetsReceived.Value() + 1
-	iss := seqnum.Value(context.TestInitialSequenceNumber)
-	rcvWnd := seqnum.Size(30000)
-	c.CreateConnected(iss, rcvWnd, -1 /* epRcvBuf */)
-
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		SeqNum:  iss.Add(1),
-		AckNum:  c.IRS.Add(1),
-		RcvWnd:  rcvWnd,
-		Flags:   header.TCPFlagRst,
-	})
-
-	if got := stats.TCP.ResetsReceived.Value(); got != want {
-		t.Errorf("got stats.TCP.ResetsReceived.Value() = %d, want = %d", got, want)
-	}
-	c.CheckNoPacketTimeout("got an unexpected packet", 100*time.Millisecond)
-}
-
-func TestActiveHandshake(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateConnected(context.TestInitialSequenceNumber, 30000, -1 /* epRcvBuf */)
-}
-
-func TestNonBlockingClose(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateConnected(context.TestInitialSequenceNumber, 30000, -1 /* epRcvBuf */)
-	ep := c.EP
-	c.EP = nil
-
-	// Close the endpoint and measure how long it takes.
-	t0 := time.Now()
-	ep.Close()
-	if diff := time.Now().Sub(t0); diff > 3*time.Second {
-		t.Fatalf("Took too long to close: %s", diff)
-	}
-}
-
-func TestConnectResetAfterClose(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	// Set TCPLinger to 3 seconds so that sockets are marked closed
-	// after 3 second in FIN_WAIT2 state.
-	tcpLingerTimeout := 3 * time.Second
-	opt := tcpip.TCPLingerTimeoutOption(tcpLingerTimeout)
-	if err := c.Stack().SetTransportProtocolOption(tcp.ProtocolNumber, &opt); err != nil {
-		t.Fatalf("SetTransportProtocolOption(%d, &%T(%d)): %s", tcp.ProtocolNumber, opt, opt, err)
-	}
-
-	c.CreateConnected(context.TestInitialSequenceNumber, 30000, -1 /* epRcvBuf */)
-	ep := c.EP
-	c.EP = nil
-
-	// Close the endpoint, make sure we get a FIN segment, then acknowledge
-	// to complete closure of sender, but don't send our own FIN.
-	ep.Close()
-	iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	checker.IPv4(t, c.GetPacket(),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(c.IRS)+1),
-			checker.TCPAckNum(uint32(iss)),
-			checker.TCPFlags(header.TCPFlagAck|header.TCPFlagFin),
-		),
-	)
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss,
-		AckNum:  c.IRS.Add(2),
-		RcvWnd:  30000,
-	})
-
-	// Wait for the ep to give up waiting for a FIN.
-	time.Sleep(tcpLingerTimeout + 1*time.Second)
-
-	// Now send an ACK and it should trigger a RST as the endpoint should
-	// not exist anymore.
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss,
-		AckNum:  c.IRS.Add(2),
-		RcvWnd:  30000,
-	})
-
-	for {
-		b := c.GetPacket()
-		tcpHdr := header.TCP(header.IPv4(b).Payload())
-		if tcpHdr.Flags() == header.TCPFlagAck|header.TCPFlagFin {
-			// This is a retransmit of the FIN, ignore it.
-			continue
-		}
-
-		checker.IPv4(t, b,
-			checker.TCP(
-				checker.DstPort(context.TestPort),
-				// RST is always generated with sndNxt which if the FIN
-				// has been sent will be 1 higher than the sequence number
-				// of the FIN itself.
-				checker.TCPSeqNum(uint32(c.IRS)+2),
-				checker.TCPAckNum(0),
-				checker.TCPFlags(header.TCPFlagRst),
-			),
-		)
-		break
-	}
-}
-
-// TestCurrentConnectedIncrement tests increment of the current
-// established and connected counters.
-func TestCurrentConnectedIncrement(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	// Set TCPTimeWaitTimeout to 1 seconds so that sockets are marked closed
-	// after 1 second in TIME_WAIT state.
-	tcpTimeWaitTimeout := 1 * time.Second
-	opt := tcpip.TCPTimeWaitTimeoutOption(tcpTimeWaitTimeout)
-	if err := c.Stack().SetTransportProtocolOption(tcp.ProtocolNumber, &opt); err != nil {
-		t.Fatalf("SetTransportProtocolOption(%d, &%T(%d)): %s", tcp.ProtocolNumber, opt, opt, err)
-	}
-
-	c.CreateConnected(context.TestInitialSequenceNumber, 30000, -1 /* epRcvBuf */)
-	ep := c.EP
-	c.EP = nil
-
-	if got := c.Stack().Stats().TCP.CurrentEstablished.Value(); got != 1 {
-		t.Errorf("got stats.TCP.CurrentEstablished.Value() = %d, want = 1", got)
-	}
-	gotConnected := c.Stack().Stats().TCP.CurrentConnected.Value()
-	if gotConnected != 1 {
-		t.Errorf("got stats.TCP.CurrentConnected.Value() = %d, want = 1", gotConnected)
-	}
-
-	ep.Close()
-	iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	checker.IPv4(t, c.GetPacket(),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(c.IRS)+1),
-			checker.TCPAckNum(uint32(iss)),
-			checker.TCPFlags(header.TCPFlagAck|header.TCPFlagFin),
-		),
-	)
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss,
-		AckNum:  c.IRS.Add(2),
-		RcvWnd:  30000,
-	})
-
-	if got := c.Stack().Stats().TCP.CurrentEstablished.Value(); got != 0 {
-		t.Errorf("got stats.TCP.CurrentEstablished.Value() = %d, want = 0", got)
-	}
-	if got := c.Stack().Stats().TCP.CurrentConnected.Value(); got != gotConnected {
-		t.Errorf("got stats.TCP.CurrentConnected.Value() = %d, want = %d", got, gotConnected)
-	}
-
-	// Ack and send FIN as well.
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck | header.TCPFlagFin,
-		SeqNum:  iss,
-		AckNum:  c.IRS.Add(2),
-		RcvWnd:  30000,
-	})
-
-	// Check that the stack acks the FIN.
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(c.IRS)+2),
-			checker.TCPAckNum(uint32(iss)+1),
-			checker.TCPFlags(header.TCPFlagAck),
-		),
-	)
-
-	// Wait for a little more than the TIME-WAIT duration for the socket to
-	// transition to CLOSED state.
-	time.Sleep(1200 * time.Millisecond)
-
-	if got := c.Stack().Stats().TCP.CurrentEstablished.Value(); got != 0 {
-		t.Errorf("got stats.TCP.CurrentEstablished.Value() = %d, want = 0", got)
-	}
-	if got := c.Stack().Stats().TCP.CurrentConnected.Value(); got != 0 {
-		t.Errorf("got stats.TCP.CurrentConnected.Value() = %d, want = 0", got)
-	}
-}
-
-// TestClosingWithEnqueuedSegments tests handling of still enqueued segments
-// when the endpoint transitions to StateClose. The in-flight segments would be
-// re-enqueued to a any listening endpoint.
-func TestClosingWithEnqueuedSegments(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateConnected(context.TestInitialSequenceNumber, 30000, -1 /* epRcvBuf */)
-	ep := c.EP
-	c.EP = nil
-
-	if got, want := tcp.EndpointState(ep.State()), tcp.StateEstablished; got != want {
-		t.Errorf("unexpected endpoint state: want %d, got %d", want, got)
-	}
-
-	// Send a FIN for ESTABLISHED --> CLOSED-WAIT
-	iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagFin | header.TCPFlagAck,
-		SeqNum:  iss,
-		AckNum:  c.IRS.Add(1),
-		RcvWnd:  30000,
-	})
-
-	// Get the ACK for the FIN we sent.
-	checker.IPv4(t, c.GetPacket(),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(c.IRS)+1),
-			checker.TCPAckNum(uint32(iss)+1),
-			checker.TCPFlags(header.TCPFlagAck),
-		),
-	)
-
-	// Give the stack a few ms to transition the endpoint out of ESTABLISHED
-	// state.
-	time.Sleep(10 * time.Millisecond)
-
-	if got, want := tcp.EndpointState(ep.State()), tcp.StateCloseWait; got != want {
-		t.Errorf("unexpected endpoint state: want %d, got %d", want, got)
-	}
-
-	// Close the application endpoint for CLOSE_WAIT --> LAST_ACK
-	ep.Close()
-
-	// Get the FIN
-	checker.IPv4(t, c.GetPacket(),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(c.IRS)+1),
-			checker.TCPAckNum(uint32(iss)+1),
-			checker.TCPFlags(header.TCPFlagAck|header.TCPFlagFin),
-		),
-	)
-
-	if got, want := tcp.EndpointState(ep.State()), tcp.StateLastAck; got != want {
-		t.Errorf("unexpected endpoint state: want %s, got %s", want, got)
-	}
-
-	// Pause the endpoint`s protocolMainLoop.
-	ep.(interface{ StopWork() }).StopWork()
-
-	// Enqueue last ACK followed by an ACK matching the endpoint
-	//
-	// Send Last ACK for LAST_ACK --> CLOSED
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss.Add(1),
-		AckNum:  c.IRS.Add(2),
-		RcvWnd:  30000,
-	})
-
-	// Send a packet with ACK set, this would generate RST when
-	// not using SYN cookies as in this test.
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck | header.TCPFlagFin,
-		SeqNum:  iss.Add(2),
-		AckNum:  c.IRS.Add(2),
-		RcvWnd:  30000,
-	})
-
-	// Unpause endpoint`s protocolMainLoop.
-	ep.(interface{ ResumeWork() }).ResumeWork()
-
-	// Wait for the protocolMainLoop to resume and update state.
-	time.Sleep(10 * time.Millisecond)
-
-	// Expect the endpoint to be closed.
-	if got, want := tcp.EndpointState(ep.State()), tcp.StateClose; got != want {
-		t.Errorf("unexpected endpoint state: want %s, got %s", want, got)
-	}
-
-	if got := c.Stack().Stats().TCP.EstablishedClosed.Value(); got != 1 {
-		t.Errorf("got c.Stack().Stats().TCP.EstablishedClosed = %d, want = 1", got)
-	}
-
-	if got := c.Stack().Stats().TCP.CurrentEstablished.Value(); got != 0 {
-		t.Errorf("got stats.TCP.CurrentEstablished.Value() = %d, want = 0", got)
-	}
-
-	// Check if the endpoint was moved to CLOSED and netstack a reset in
-	// response to the ACK packet that we sent after last-ACK.
-	checker.IPv4(t, c.GetPacket(),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(c.IRS)+2),
-			checker.TCPAckNum(0),
-			checker.TCPFlags(header.TCPFlagRst),
-		),
-	)
-}
-
-func TestSimpleReceive(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateConnected(context.TestInitialSequenceNumber, 30000, -1 /* epRcvBuf */)
-
-	we, ch := waiter.NewChannelEntry(nil)
-	c.WQ.EventRegister(&we, waiter.EventIn)
-	defer c.WQ.EventUnregister(&we)
-
-	ept := endpointTester{c.EP}
-
-	data := []byte{1, 2, 3}
-	iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	c.SendPacket(data, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss,
-		AckNum:  c.IRS.Add(1),
-		RcvWnd:  30000,
-	})
-
-	// Wait for receive to be notified.
-	select {
-	case <-ch:
-	case <-time.After(1 * time.Second):
-		t.Fatalf("Timed out waiting for data to arrive")
-	}
-
-	// Receive data.
-	v := ept.CheckRead(t)
-	if !bytes.Equal(data, v) {
-		t.Fatalf("got data = %v, want = %v", v, data)
-	}
-
-	// Check that ACK is received.
-	checker.IPv4(t, c.GetPacket(),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(c.IRS)+1),
-			checker.TCPAckNum(uint32(iss)+uint32(len(data))),
-			checker.TCPFlags(header.TCPFlagAck),
-		),
-	)
-}
-
-// TestUserSuppliedMSSOnConnect tests that the user supplied MSS is used when
-// creating a new active TCP socket. It should be present in the sent TCP
-// SYN segment.
-func TestUserSuppliedMSSOnConnect(t *testing.T) {
-	const mtu = 5000
-
-	ips := []struct {
-		name        string
-		createEP    func(*context.Context)
-		connectAddr tcpip.Address
-		checker     func(*testing.T, *context.Context, uint16, int)
-		maxMSS      uint16
-	}{
-		{
-			name: "IPv4",
-			createEP: func(c *context.Context) {
-				c.Create(-1)
-			},
-			connectAddr: context.TestAddr,
-			checker: func(t *testing.T, c *context.Context, mss uint16, ws int) {
-				checker.IPv4(t, c.GetPacket(), checker.TCP(
-					checker.DstPort(context.TestPort),
-					checker.TCPFlags(header.TCPFlagSyn),
-					checker.TCPSynOptions(header.TCPSynOptions{MSS: mss, WS: ws})))
-			},
-			maxMSS: mtu - header.IPv4MinimumSize - header.TCPMinimumSize,
-		},
-		{
-			name: "IPv6",
-			createEP: func(c *context.Context) {
-				c.CreateV6Endpoint(true)
-			},
-			connectAddr: context.TestV6Addr,
-			checker: func(t *testing.T, c *context.Context, mss uint16, ws int) {
-				checker.IPv6(t, c.GetV6Packet(), checker.TCP(
-					checker.DstPort(context.TestPort),
-					checker.TCPFlags(header.TCPFlagSyn),
-					checker.TCPSynOptions(header.TCPSynOptions{MSS: mss, WS: ws})))
-			},
-			maxMSS: mtu - header.IPv6MinimumSize - header.TCPMinimumSize,
-		},
-	}
-
-	for _, ip := range ips {
-		t.Run(ip.name, func(t *testing.T) {
-			tests := []struct {
-				name   string
-				setMSS uint16
-				expMSS uint16
-			}{
-				{
-					name:   "EqualToMaxMSS",
-					setMSS: ip.maxMSS,
-					expMSS: ip.maxMSS,
-				},
-				{
-					name:   "LessThanMaxMSS",
-					setMSS: ip.maxMSS - 1,
-					expMSS: ip.maxMSS - 1,
-				},
-				{
-					name:   "GreaterThanMaxMSS",
-					setMSS: ip.maxMSS + 1,
-					expMSS: ip.maxMSS,
-				},
-			}
-
-			for _, test := range tests {
-				t.Run(test.name, func(t *testing.T) {
-					c := context.New(t, mtu)
-					defer c.Cleanup()
-
-					ip.createEP(c)
-
-					// Set the MSS socket option.
-					if err := c.EP.SetSockOptInt(tcpip.MaxSegOption, int(test.setMSS)); err != nil {
-						t.Fatalf("SetSockOptInt(MaxSegOption, %d): %s", test.setMSS, err)
-					}
-
-					// Get expected window size.
-					rcvBufSize, err := c.EP.GetSockOptInt(tcpip.ReceiveBufferSizeOption)
-					if err != nil {
-						t.Fatalf("GetSockOptInt(ReceiveBufferSizeOption): %s", err)
-					}
-					ws := tcp.FindWndScale(seqnum.Size(rcvBufSize))
-
-					connectAddr := tcpip.FullAddress{Addr: ip.connectAddr, Port: context.TestPort}
-					{
-						err := c.EP.Connect(connectAddr)
-						if _, ok := err.(*tcpip.ErrConnectStarted); !ok {
-							t.Fatalf("Connect(%+v): %s", connectAddr, err)
-						}
-					}
-
-					// Receive SYN packet with our user supplied MSS.
-					ip.checker(t, c, test.expMSS, ws)
-				})
-			}
-		})
-	}
-}
-
-// TestUserSuppliedMSSOnListenAccept tests that the user supplied MSS is used
-// when completing the handshake for a new TCP connection from a TCP
-// listening socket. It should be present in the sent TCP SYN-ACK segment.
-func TestUserSuppliedMSSOnListenAccept(t *testing.T) {
-	const (
-		nonSynCookieAccepts = 2
-		totalAccepts        = 4
-		mtu                 = 5000
-	)
-
-	ips := []struct {
-		name     string
-		createEP func(*context.Context)
-		sendPkt  func(*context.Context, *context.Headers)
-		checker  func(*testing.T, *context.Context, uint16, uint16)
-		maxMSS   uint16
-	}{
-		{
-			name: "IPv4",
-			createEP: func(c *context.Context) {
-				c.Create(-1)
-			},
-			sendPkt: func(c *context.Context, h *context.Headers) {
-				c.SendPacket(nil, h)
-			},
-			checker: func(t *testing.T, c *context.Context, srcPort, mss uint16) {
-				checker.IPv4(t, c.GetPacket(), checker.TCP(
-					checker.DstPort(srcPort),
-					checker.TCPFlags(header.TCPFlagSyn|header.TCPFlagAck),
-					checker.TCPSynOptions(header.TCPSynOptions{MSS: mss, WS: -1})))
-			},
-			maxMSS: mtu - header.IPv4MinimumSize - header.TCPMinimumSize,
-		},
-		{
-			name: "IPv6",
-			createEP: func(c *context.Context) {
-				c.CreateV6Endpoint(false)
-			},
-			sendPkt: func(c *context.Context, h *context.Headers) {
-				c.SendV6Packet(nil, h)
-			},
-			checker: func(t *testing.T, c *context.Context, srcPort, mss uint16) {
-				checker.IPv6(t, c.GetV6Packet(), checker.TCP(
-					checker.DstPort(srcPort),
-					checker.TCPFlags(header.TCPFlagSyn|header.TCPFlagAck),
-					checker.TCPSynOptions(header.TCPSynOptions{MSS: mss, WS: -1})))
-			},
-			maxMSS: mtu - header.IPv6MinimumSize - header.TCPMinimumSize,
-		},
-	}
-
-	for _, ip := range ips {
-		t.Run(ip.name, func(t *testing.T) {
-			tests := []struct {
-				name   string
-				setMSS uint16
-				expMSS uint16
-			}{
-				{
-					name:   "EqualToMaxMSS",
-					setMSS: ip.maxMSS,
-					expMSS: ip.maxMSS,
-				},
-				{
-					name:   "LessThanMaxMSS",
-					setMSS: ip.maxMSS - 1,
-					expMSS: ip.maxMSS - 1,
-				},
-				{
-					name:   "GreaterThanMaxMSS",
-					setMSS: ip.maxMSS + 1,
-					expMSS: ip.maxMSS,
-				},
-			}
-
-			for _, test := range tests {
-				t.Run(test.name, func(t *testing.T) {
-					c := context.New(t, mtu)
-					defer c.Cleanup()
-
-					ip.createEP(c)
-
-					// Set the SynRcvd threshold to force a syn cookie based accept to happen.
-					opt := tcpip.TCPSynRcvdCountThresholdOption(nonSynCookieAccepts)
-					if err := c.Stack().SetTransportProtocolOption(tcp.ProtocolNumber, &opt); err != nil {
-						t.Fatalf("SetTransportProtocolOption(%d, &%T(%d)): %s", tcp.ProtocolNumber, opt, opt, err)
-					}
-
-					if err := c.EP.SetSockOptInt(tcpip.MaxSegOption, int(test.setMSS)); err != nil {
-						t.Fatalf("SetSockOptInt(MaxSegOption, %d): %s", test.setMSS, err)
-					}
-
-					bindAddr := tcpip.FullAddress{Port: context.StackPort}
-					if err := c.EP.Bind(bindAddr); err != nil {
-						t.Fatalf("Bind(%+v): %s:", bindAddr, err)
-					}
-
-					if err := c.EP.Listen(totalAccepts); err != nil {
-						t.Fatalf("Listen(%d): %s:", totalAccepts, err)
-					}
-
-					// The first nonSynCookieAccepts packets sent will trigger a gorooutine
-					// based accept. The rest will trigger a cookie based accept.
-					for i := 0; i < totalAccepts; i++ {
-						// Send a SYN requests.
-						iss := seqnum.Value(i)
-						srcPort := context.TestPort + uint16(i)
-						ip.sendPkt(c, &context.Headers{
-							SrcPort: srcPort,
-							DstPort: context.StackPort,
-							Flags:   header.TCPFlagSyn,
-							SeqNum:  iss,
-						})
-
-						// Receive the SYN-ACK reply.
-						ip.checker(t, c, srcPort, test.expMSS)
-					}
-				})
-			}
-		})
-	}
-}
-func TestSendRstOnListenerRxSynAckV4(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.Create(-1)
-
-	if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatal("Bind failed:", err)
-	}
-
-	if err := c.EP.Listen(10); err != nil {
-		t.Fatal("Listen failed:", err)
-	}
-
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagSyn | header.TCPFlagAck,
-		SeqNum:  100,
-		AckNum:  200,
-	})
-
-	checker.IPv4(t, c.GetPacket(), checker.TCP(
-		checker.DstPort(context.TestPort),
-		checker.TCPFlags(header.TCPFlagRst),
-		checker.TCPSeqNum(200)))
-}
-
-func TestSendRstOnListenerRxSynAckV6(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateV6Endpoint(true)
-
-	if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatal("Bind failed:", err)
-	}
-
-	if err := c.EP.Listen(10); err != nil {
-		t.Fatal("Listen failed:", err)
-	}
-
-	c.SendV6Packet(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagSyn | header.TCPFlagAck,
-		SeqNum:  100,
-		AckNum:  200,
-	})
-
-	checker.IPv6(t, c.GetV6Packet(), checker.TCP(
-		checker.DstPort(context.TestPort),
-		checker.TCPFlags(header.TCPFlagRst),
-		checker.TCPSeqNum(200)))
-}
-
-// TestTCPAckBeforeAcceptV4 tests that once the 3-way handshake is complete,
-// peers can send data and expect a response within a reasonable ammount of time
-// without calling Accept on the listening endpoint first.
-//
-// This test uses IPv4.
-func TestTCPAckBeforeAcceptV4(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.Create(-1)
-
-	if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatal("Bind failed:", err)
-	}
-
-	if err := c.EP.Listen(10); err != nil {
-		t.Fatal("Listen failed:", err)
-	}
-
-	irs, iss := executeHandshake(t, c, context.TestPort, false /* synCookiesInUse */)
-
-	// Send data before accepting the connection.
-	c.SendPacket([]byte{1, 2, 3, 4}, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  irs + 1,
-		AckNum:  iss + 1,
-	})
-
-	// Receive ACK for the data we sent.
-	checker.IPv4(t, c.GetPacket(), checker.TCP(
-		checker.DstPort(context.TestPort),
-		checker.TCPFlags(header.TCPFlagAck),
-		checker.TCPSeqNum(uint32(iss+1)),
-		checker.TCPAckNum(uint32(irs+5))))
-}
-
-// TestTCPAckBeforeAcceptV6 tests that once the 3-way handshake is complete,
-// peers can send data and expect a response within a reasonable ammount of time
-// without calling Accept on the listening endpoint first.
-//
-// This test uses IPv6.
-func TestTCPAckBeforeAcceptV6(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateV6Endpoint(true)
-
-	if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatal("Bind failed:", err)
-	}
-
-	if err := c.EP.Listen(10); err != nil {
-		t.Fatal("Listen failed:", err)
-	}
-
-	irs, iss := executeV6Handshake(t, c, context.TestPort, false /* synCookiesInUse */)
-
-	// Send data before accepting the connection.
-	c.SendV6Packet([]byte{1, 2, 3, 4}, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  irs + 1,
-		AckNum:  iss + 1,
-	})
-
-	// Receive ACK for the data we sent.
-	checker.IPv6(t, c.GetV6Packet(), checker.TCP(
-		checker.DstPort(context.TestPort),
-		checker.TCPFlags(header.TCPFlagAck),
-		checker.TCPSeqNum(uint32(iss+1)),
-		checker.TCPAckNum(uint32(irs+5))))
-}
-
-func TestSendRstOnListenerRxAckV4(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.Create(-1 /* epRcvBuf */)
-
-	if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatal("Bind failed:", err)
-	}
-
-	if err := c.EP.Listen(10 /* backlog */); err != nil {
-		t.Fatal("Listen failed:", err)
-	}
-
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagFin | header.TCPFlagAck,
-		SeqNum:  100,
-		AckNum:  200,
-	})
-
-	checker.IPv4(t, c.GetPacket(), checker.TCP(
-		checker.DstPort(context.TestPort),
-		checker.TCPFlags(header.TCPFlagRst),
-		checker.TCPSeqNum(200)))
-}
-
-func TestSendRstOnListenerRxAckV6(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateV6Endpoint(true /* v6Only */)
-
-	if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatal("Bind failed:", err)
-	}
-
-	if err := c.EP.Listen(10 /* backlog */); err != nil {
-		t.Fatal("Listen failed:", err)
-	}
-
-	c.SendV6Packet(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagFin | header.TCPFlagAck,
-		SeqNum:  100,
-		AckNum:  200,
-	})
-
-	checker.IPv6(t, c.GetV6Packet(), checker.TCP(
-		checker.DstPort(context.TestPort),
-		checker.TCPFlags(header.TCPFlagRst),
-		checker.TCPSeqNum(200)))
-}
-
-// TestListenShutdown tests for the listening endpoint replying with RST
-// on read shutdown.
-func TestListenShutdown(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.Create(-1 /* epRcvBuf */)
-
-	if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatal("Bind failed:", err)
-	}
-
-	if err := c.EP.Listen(1 /* backlog */); err != nil {
-		t.Fatal("Listen failed:", err)
-	}
-
-	if err := c.EP.Shutdown(tcpip.ShutdownRead); err != nil {
-		t.Fatal("Shutdown failed:", err)
-	}
-
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagSyn,
-		SeqNum:  100,
-		AckNum:  200,
-	})
-
-	// Expect the listening endpoint to reset the connection.
-	checker.IPv4(t, c.GetPacket(),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPFlags(header.TCPFlagAck|header.TCPFlagRst),
-		))
-}
-
-// TestListenCloseWhileConnect tests for the listening endpoint to
-// drain the accept-queue when closed. This should reset all of the
-// pending connections that are waiting to be accepted.
-func TestListenCloseWhileConnect(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.Create(-1 /* epRcvBuf */)
-
-	if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatal("Bind failed:", err)
-	}
-
-	if err := c.EP.Listen(1 /* backlog */); err != nil {
-		t.Fatal("Listen failed:", err)
-	}
-
-	waitEntry, notifyCh := waiter.NewChannelEntry(nil)
-	c.WQ.EventRegister(&waitEntry, waiter.EventIn)
-	defer c.WQ.EventUnregister(&waitEntry)
-
-	executeHandshake(t, c, context.TestPort, false /* synCookiesInUse */)
-	// Wait for the new endpoint created because of handshake to be delivered
-	// to the listening endpoint's accept queue.
-	<-notifyCh
-
-	// Close the listening endpoint.
-	c.EP.Close()
-
-	// Expect the listening endpoint to reset the connection.
-	checker.IPv4(t, c.GetPacket(),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPFlags(header.TCPFlagAck|header.TCPFlagRst),
-		))
-}
-
-func TestTOSV4(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	ep, err := c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &c.WQ)
-	if err != nil {
-		t.Fatalf("NewEndpoint failed: %s", err)
-	}
-	c.EP = ep
-
-	const tos = 0xC0
-	if err := c.EP.SetSockOptInt(tcpip.IPv4TOSOption, tos); err != nil {
-		t.Errorf("SetSockOptInt(IPv4TOSOption, %d) failed: %s", tos, err)
-	}
-
-	v, err := c.EP.GetSockOptInt(tcpip.IPv4TOSOption)
-	if err != nil {
-		t.Errorf("GetSockoptInt(IPv4TOSOption) failed: %s", err)
-	}
-
-	if v != tos {
-		t.Errorf("got GetSockOptInt(IPv4TOSOption) = %d, want = %d", v, tos)
-	}
-
-	testV4Connect(t, c, checker.TOS(tos, 0))
-
-	data := []byte{1, 2, 3}
-	var r bytes.Reader
-	r.Reset(data)
-	if _, err := c.EP.Write(&r, tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %s", err)
-	}
-
-	// Check that data is received.
-	b := c.GetPacket()
-	iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	checker.IPv4(t, b,
-		checker.PayloadLen(len(data)+header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(c.IRS)+1),
-			checker.TCPAckNum(uint32(iss)), // Acknum is initial sequence number + 1
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
-		),
-		checker.TOS(tos, 0),
-	)
-
-	if p := b[header.IPv4MinimumSize+header.TCPMinimumSize:]; !bytes.Equal(data, p) {
-		t.Errorf("got data = %x, want = %x", p, data)
-	}
-}
-
-func TestTrafficClassV6(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateV6Endpoint(false)
-
-	const tos = 0xC0
-	if err := c.EP.SetSockOptInt(tcpip.IPv6TrafficClassOption, tos); err != nil {
-		t.Errorf("SetSockOpInt(IPv6TrafficClassOption, %d) failed: %s", tos, err)
-	}
-
-	v, err := c.EP.GetSockOptInt(tcpip.IPv6TrafficClassOption)
-	if err != nil {
-		t.Fatalf("GetSockoptInt(IPv6TrafficClassOption) failed: %s", err)
-	}
-
-	if v != tos {
-		t.Errorf("got GetSockOptInt(IPv6TrafficClassOption) = %d, want = %d", v, tos)
-	}
-
-	// Test the connection request.
-	testV6Connect(t, c, checker.TOS(tos, 0))
-
-	data := []byte{1, 2, 3}
-	var r bytes.Reader
-	r.Reset(data)
-	if _, err := c.EP.Write(&r, tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %s", err)
-	}
-
-	// Check that data is received.
-	b := c.GetV6Packet()
-	iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	checker.IPv6(t, b,
-		checker.PayloadLen(len(data)+header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(c.IRS)+1),
-			checker.TCPAckNum(uint32(iss)),
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
-		),
-		checker.TOS(tos, 0),
-	)
-
-	if p := b[header.IPv6MinimumSize+header.TCPMinimumSize:]; !bytes.Equal(data, p) {
-		t.Errorf("got data = %x, want = %x", p, data)
-	}
-}
-
-func TestConnectBindToDevice(t *testing.T) {
-	for _, test := range []struct {
-		name   string
-		device tcpip.NICID
-		want   tcp.EndpointState
-	}{
-		{"RightDevice", 1, tcp.StateEstablished},
-		{"WrongDevice", 2, tcp.StateSynSent},
-		{"AnyDevice", 0, tcp.StateEstablished},
-	} {
-		t.Run(test.name, func(t *testing.T) {
-			c := context.New(t, defaultMTU)
-			defer c.Cleanup()
-
-			c.Create(-1)
-			if err := c.EP.SocketOptions().SetBindToDevice(int32(test.device)); err != nil {
-				t.Fatalf("c.EP.SetSockOpt(&%T(%d)): %s", test.device, test.device, err)
-			}
-			// Start connection attempt.
-			waitEntry, _ := waiter.NewChannelEntry(nil)
-			c.WQ.EventRegister(&waitEntry, waiter.EventOut)
-			defer c.WQ.EventUnregister(&waitEntry)
-
-			err := c.EP.Connect(tcpip.FullAddress{Addr: context.TestAddr, Port: context.TestPort})
-			if _, ok := err.(*tcpip.ErrConnectStarted); !ok {
-				t.Fatalf("unexpected return value from Connect: %s", err)
-			}
-
-			// Receive SYN packet.
-			b := c.GetPacket()
-			checker.IPv4(t, b,
-				checker.TCP(
-					checker.DstPort(context.TestPort),
-					checker.TCPFlags(header.TCPFlagSyn),
-				),
-			)
-			if got, want := tcp.EndpointState(c.EP.State()), tcp.StateSynSent; got != want {
-				t.Fatalf("unexpected endpoint state: want %s, got %s", want, got)
-			}
-			tcpHdr := header.TCP(header.IPv4(b).Payload())
-			c.IRS = seqnum.Value(tcpHdr.SequenceNumber())
-
-			iss := seqnum.Value(context.TestInitialSequenceNumber)
-			rcvWnd := seqnum.Size(30000)
-			c.SendPacket(nil, &context.Headers{
-				SrcPort: tcpHdr.DestinationPort(),
-				DstPort: tcpHdr.SourcePort(),
-				Flags:   header.TCPFlagSyn | header.TCPFlagAck,
-				SeqNum:  iss,
-				AckNum:  c.IRS.Add(1),
-				RcvWnd:  rcvWnd,
-				TCPOpts: nil,
-			})
-
-			c.GetPacket()
-			if got, want := tcp.EndpointState(c.EP.State()), test.want; got != want {
-				t.Fatalf("unexpected endpoint state: want %s, got %s", want, got)
-			}
-		})
-	}
-}
-
-func TestSynSent(t *testing.T) {
-	for _, test := range []struct {
-		name  string
-		reset bool
-	}{
-		{"RstOnSynSent", true},
-		{"CloseOnSynSent", false},
-	} {
-		t.Run(test.name, func(t *testing.T) {
-			c := context.New(t, defaultMTU)
-			defer c.Cleanup()
-
-			// Create an endpoint, don't handshake because we want to interfere with the
-			// handshake process.
-			c.Create(-1)
-
-			// Start connection attempt.
-			waitEntry, ch := waiter.NewChannelEntry(nil)
-			c.WQ.EventRegister(&waitEntry, waiter.EventHUp)
-			defer c.WQ.EventUnregister(&waitEntry)
-
-			addr := tcpip.FullAddress{Addr: context.TestAddr, Port: context.TestPort}
-			err := c.EP.Connect(addr)
-			if _, ok := err.(*tcpip.ErrConnectStarted); !ok {
-				t.Fatalf("got Connect(%+v) = %v, want %s", addr, err, &tcpip.ErrConnectStarted{})
-			}
-
-			// Receive SYN packet.
-			b := c.GetPacket()
-			checker.IPv4(t, b,
-				checker.TCP(
-					checker.DstPort(context.TestPort),
-					checker.TCPFlags(header.TCPFlagSyn),
-				),
-			)
-
-			if got, want := tcp.EndpointState(c.EP.State()), tcp.StateSynSent; got != want {
-				t.Fatalf("got State() = %s, want %s", got, want)
-			}
-			tcpHdr := header.TCP(header.IPv4(b).Payload())
-			c.IRS = seqnum.Value(tcpHdr.SequenceNumber())
-
-			if test.reset {
-				// Send a packet with a proper ACK and a RST flag to cause the socket
-				// to error and close out.
-				iss := seqnum.Value(context.TestInitialSequenceNumber)
-				rcvWnd := seqnum.Size(30000)
-				c.SendPacket(nil, &context.Headers{
-					SrcPort: tcpHdr.DestinationPort(),
-					DstPort: tcpHdr.SourcePort(),
-					Flags:   header.TCPFlagRst | header.TCPFlagAck,
-					SeqNum:  iss,
-					AckNum:  c.IRS.Add(1),
-					RcvWnd:  rcvWnd,
-					TCPOpts: nil,
-				})
-			} else {
-				c.EP.Close()
-			}
-
-			// Wait for receive to be notified.
-			select {
-			case <-ch:
-			case <-time.After(3 * time.Second):
-				t.Fatal("timed out waiting for packet to arrive")
-			}
-
-			ept := endpointTester{c.EP}
-			if test.reset {
-				ept.CheckReadError(t, &tcpip.ErrConnectionRefused{})
-			} else {
-				ept.CheckReadError(t, &tcpip.ErrAborted{})
-			}
-
-			if got := c.Stack().Stats().TCP.CurrentConnected.Value(); got != 0 {
-				t.Errorf("got stats.TCP.CurrentConnected.Value() = %d, want = 0", got)
-			}
-
-			// Due to the RST the endpoint should be in an error state.
-			if got, want := tcp.EndpointState(c.EP.State()), tcp.StateError; got != want {
-				t.Fatalf("got State() = %s, want %s", got, want)
-			}
-		})
-	}
-}
-
-func TestOutOfOrderReceive(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateConnected(context.TestInitialSequenceNumber, 30000, -1 /* epRcvBuf */)
-
-	we, ch := waiter.NewChannelEntry(nil)
-	c.WQ.EventRegister(&we, waiter.EventIn)
-	defer c.WQ.EventUnregister(&we)
-
-	ept := endpointTester{c.EP}
-	ept.CheckReadError(t, &tcpip.ErrWouldBlock{})
-
-	// Send second half of data first, with seqnum 3 ahead of expected.
-	data := []byte{1, 2, 3, 4, 5, 6}
-	iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	c.SendPacket(data[3:], &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss.Add(3),
-		AckNum:  c.IRS.Add(1),
-		RcvWnd:  30000,
-	})
-
-	// Check that we get an ACK specifying which seqnum is expected.
-	checker.IPv4(t, c.GetPacket(),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(c.IRS)+1),
-			checker.TCPAckNum(uint32(iss)),
-			checker.TCPFlags(header.TCPFlagAck),
-		),
-	)
-
-	// Wait 200ms and check that no data has been received.
-	time.Sleep(200 * time.Millisecond)
-	ept.CheckReadError(t, &tcpip.ErrWouldBlock{})
-
-	// Send the first 3 bytes now.
-	c.SendPacket(data[:3], &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss,
-		AckNum:  c.IRS.Add(1),
-		RcvWnd:  30000,
-	})
-
-	// Receive data.
-	read := ept.CheckReadFull(t, 6, ch, 5*time.Second)
-
-	// Check that we received the data in proper order.
-	if !bytes.Equal(data, read) {
-		t.Fatalf("got data = %v, want = %v", read, data)
-	}
-
-	// Check that the whole data is acknowledged.
-	checker.IPv4(t, c.GetPacket(),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(c.IRS)+1),
-			checker.TCPAckNum(uint32(iss)+uint32(len(data))),
-			checker.TCPFlags(header.TCPFlagAck),
-		),
-	)
-}
-
-func TestOutOfOrderFlood(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	rcvBufSz := math.MaxUint16
-	c.CreateConnected(context.TestInitialSequenceNumber, 30000, rcvBufSz)
-
-	ept := endpointTester{c.EP}
-	ept.CheckReadError(t, &tcpip.ErrWouldBlock{})
-
-	// Send 100 packets before the actual one that is expected.
-	data := []byte{1, 2, 3, 4, 5, 6}
-	iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	for i := 0; i < 100; i++ {
-		c.SendPacket(data[3:], &context.Headers{
-			SrcPort: context.TestPort,
-			DstPort: c.Port,
-			Flags:   header.TCPFlagAck,
-			SeqNum:  iss.Add(6),
-			AckNum:  c.IRS.Add(1),
-			RcvWnd:  30000,
-		})
-
-		checker.IPv4(t, c.GetPacket(),
-			checker.TCP(
-				checker.DstPort(context.TestPort),
-				checker.TCPSeqNum(uint32(c.IRS)+1),
-				checker.TCPAckNum(uint32(iss)),
-				checker.TCPFlags(header.TCPFlagAck),
-			),
-		)
-	}
-
-	// Send packet with seqnum as initial + 3. It must be discarded because the
-	// out-of-order buffer was filled by the previous packets.
-	c.SendPacket(data[3:], &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss.Add(3),
-		AckNum:  c.IRS.Add(1),
-		RcvWnd:  30000,
-	})
-
-	checker.IPv4(t, c.GetPacket(),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(c.IRS)+1),
-			checker.TCPAckNum(uint32(iss)),
-			checker.TCPFlags(header.TCPFlagAck),
-		),
-	)
-
-	// Now send the expected packet with initial sequence number.
-	c.SendPacket(data[:3], &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss,
-		AckNum:  c.IRS.Add(1),
-		RcvWnd:  30000,
-	})
-
-	// Check that only packet with initial sequence number is acknowledged.
-	checker.IPv4(t, c.GetPacket(),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(c.IRS)+1),
-			checker.TCPAckNum(uint32(iss)+3),
-			checker.TCPFlags(header.TCPFlagAck),
-		),
-	)
-}
-
-func TestRstOnCloseWithUnreadData(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateConnected(context.TestInitialSequenceNumber, 30000, -1 /* epRcvBuf */)
-
-	we, ch := waiter.NewChannelEntry(nil)
-	c.WQ.EventRegister(&we, waiter.EventIn)
-	defer c.WQ.EventUnregister(&we)
-
-	ept := endpointTester{c.EP}
-	ept.CheckReadError(t, &tcpip.ErrWouldBlock{})
-
-	data := []byte{1, 2, 3}
-	iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	c.SendPacket(data, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss,
-		AckNum:  c.IRS.Add(1),
-		RcvWnd:  30000,
-	})
-
-	// Wait for receive to be notified.
-	select {
-	case <-ch:
-	case <-time.After(3 * time.Second):
-		t.Fatalf("Timed out waiting for data to arrive")
-	}
-
-	// Check that ACK is received, this happens regardless of the read.
-	checker.IPv4(t, c.GetPacket(),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(c.IRS)+1),
-			checker.TCPAckNum(uint32(iss)+uint32(len(data))),
-			checker.TCPFlags(header.TCPFlagAck),
-		),
-	)
-
-	// Now that we know we have unread data, let's just close the connection
-	// and verify that netstack sends an RST rather than a FIN.
-	c.EP.Close()
-
-	checker.IPv4(t, c.GetPacket(),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPFlags(header.TCPFlagAck|header.TCPFlagRst),
-			// We shouldn't consume a sequence number on RST.
-			checker.TCPSeqNum(uint32(c.IRS)+1),
-		))
-	// The RST puts the endpoint into an error state.
-	if got, want := tcp.EndpointState(c.EP.State()), tcp.StateError; got != want {
-		t.Errorf("unexpected endpoint state: want %s, got %s", want, got)
-	}
-
-	// This final ACK should be ignored because an ACK on a reset doesn't mean
-	// anything.
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss.Add(seqnum.Size(len(data))),
-		AckNum:  c.IRS.Add(seqnum.Size(2)),
-		RcvWnd:  30000,
-	})
-}
-
-func TestRstOnCloseWithUnreadDataFinConvertRst(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateConnected(context.TestInitialSequenceNumber, 30000, -1 /* epRcvBuf */)
-
-	we, ch := waiter.NewChannelEntry(nil)
-	c.WQ.EventRegister(&we, waiter.EventIn)
-	defer c.WQ.EventUnregister(&we)
-
-	ept := endpointTester{c.EP}
-	ept.CheckReadError(t, &tcpip.ErrWouldBlock{})
-
-	data := []byte{1, 2, 3}
-	iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	c.SendPacket(data, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss,
-		AckNum:  c.IRS.Add(1),
-		RcvWnd:  30000,
-	})
-
-	// Wait for receive to be notified.
-	select {
-	case <-ch:
-	case <-time.After(3 * time.Second):
-		t.Fatalf("Timed out waiting for data to arrive")
-	}
-
-	// Check that ACK is received, this happens regardless of the read.
-	checker.IPv4(t, c.GetPacket(),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(c.IRS)+1),
-			checker.TCPAckNum(uint32(iss)+uint32(len(data))),
-			checker.TCPFlags(header.TCPFlagAck),
-		),
-	)
-
-	// Cause a FIN to be generated.
-	c.EP.Shutdown(tcpip.ShutdownWrite)
-
-	// Make sure we get the FIN but DON't ACK IT.
-	checker.IPv4(t, c.GetPacket(),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPFlags(header.TCPFlagAck|header.TCPFlagFin),
-			checker.TCPSeqNum(uint32(c.IRS)+1),
-		))
-
-	if got, want := tcp.EndpointState(c.EP.State()), tcp.StateFinWait1; got != want {
-		t.Errorf("unexpected endpoint state: want %s, got %s", want, got)
-	}
-
-	// Cause a RST to be generated by closing the read end now since we have
-	// unread data.
-	c.EP.Shutdown(tcpip.ShutdownRead)
-
-	// Make sure we get the RST
-	checker.IPv4(t, c.GetPacket(),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPFlags(header.TCPFlagAck|header.TCPFlagRst),
-			// RST is always generated with sndNxt which if the FIN
-			// has been sent will be 1 higher than the sequence
-			// number of the FIN itself.
-			checker.TCPSeqNum(uint32(c.IRS)+2),
-		))
-	// The RST puts the endpoint into an error state.
-	if got, want := tcp.EndpointState(c.EP.State()), tcp.StateError; got != want {
-		t.Errorf("unexpected endpoint state: want %s, got %s", want, got)
-	}
-
-	// The ACK to the FIN should now be rejected since the connection has been
-	// closed by a RST.
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss.Add(seqnum.Size(len(data))),
-		AckNum:  c.IRS.Add(seqnum.Size(2)),
-		RcvWnd:  30000,
-	})
-}
-
-func TestShutdownRead(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateConnected(context.TestInitialSequenceNumber, 30000, -1 /* epRcvBuf */)
-
-	ept := endpointTester{c.EP}
-	ept.CheckReadError(t, &tcpip.ErrWouldBlock{})
-
-	if err := c.EP.Shutdown(tcpip.ShutdownRead); err != nil {
-		t.Fatalf("Shutdown failed: %s", err)
-	}
-
-	ept.CheckReadError(t, &tcpip.ErrClosedForReceive{})
-	var want uint64 = 1
-	if got := c.EP.Stats().(*tcp.Stats).ReadErrors.ReadClosed.Value(); got != want {
-		t.Fatalf("got EP stats Stats.ReadErrors.ReadClosed got %d want %d", got, want)
-	}
-}
-
-func TestFullWindowReceive(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	const rcvBufSz = 10
-	c.CreateConnected(context.TestInitialSequenceNumber, 30000, rcvBufSz)
-
-	we, ch := waiter.NewChannelEntry(nil)
-	c.WQ.EventRegister(&we, waiter.EventIn)
-	defer c.WQ.EventUnregister(&we)
-
-	ept := endpointTester{c.EP}
-	ept.CheckReadError(t, &tcpip.ErrWouldBlock{})
-
-	// Fill up the window w/ tcp.SegOverheadFactor*rcvBufSz as netstack multiplies
-	// the provided buffer value by tcp.SegOverheadFactor to calculate the actual
-	// receive buffer size.
-	data := make([]byte, tcp.SegOverheadFactor*rcvBufSz)
-	for i := range data {
-		data[i] = byte(i % 255)
-	}
-	iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	c.SendPacket(data, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss,
-		AckNum:  c.IRS.Add(1),
-		RcvWnd:  30000,
-	})
-
-	// Wait for receive to be notified.
-	select {
-	case <-ch:
-	case <-time.After(5 * time.Second):
-		t.Fatalf("Timed out waiting for data to arrive")
-	}
-
-	// Check that data is acknowledged, and window goes to zero.
-	checker.IPv4(t, c.GetPacket(),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(c.IRS)+1),
-			checker.TCPAckNum(uint32(iss)+uint32(len(data))),
-			checker.TCPFlags(header.TCPFlagAck),
-			checker.TCPWindow(0),
-		),
-	)
-
-	// Receive data and check it.
-	v := ept.CheckRead(t)
-	if !bytes.Equal(data, v) {
-		t.Fatalf("got data = %v, want = %v", v, data)
-	}
-
-	var want uint64 = 1
-	if got := c.EP.Stats().(*tcp.Stats).ReceiveErrors.ZeroRcvWindowState.Value(); got != want {
-		t.Fatalf("got EP stats ReceiveErrors.ZeroRcvWindowState got %d want %d", got, want)
-	}
-
-	// Check that we get an ACK for the newly non-zero window.
-	checker.IPv4(t, c.GetPacket(),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(c.IRS)+1),
-			checker.TCPAckNum(uint32(iss)+uint32(len(data))),
-			checker.TCPFlags(header.TCPFlagAck),
-			checker.TCPWindow(10),
-		),
-	)
-}
-
-// Test the stack receive window advertisement on receiving segments smaller than
-// segment overhead. It tests for the right edge of the window to not grow when
-// the endpoint is not being read from.
-func TestSmallSegReceiveWindowAdvertisement(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	opt := tcpip.TCPReceiveBufferSizeRangeOption{
-		Min:     1,
-		Default: tcp.DefaultReceiveBufferSize,
-		Max:     tcp.DefaultReceiveBufferSize << tcp.FindWndScale(seqnum.Size(tcp.DefaultReceiveBufferSize)),
-	}
-	if err := c.Stack().SetTransportProtocolOption(tcp.ProtocolNumber, &opt); err != nil {
-		t.Fatalf("SetTransportProtocolOption(%d, &%#v): %s", tcp.ProtocolNumber, opt, err)
-	}
-
-	c.AcceptWithOptions(tcp.FindWndScale(seqnum.Size(opt.Default)), header.TCPSynOptions{MSS: defaultIPv4MSS})
-
-	// Bump up the receive buffer size such that, when the receive window grows,
-	// the scaled window exceeds maxUint16.
-	if err := c.EP.SetSockOptInt(tcpip.ReceiveBufferSizeOption, opt.Max); err != nil {
-		t.Fatalf("SetSockOptInt(ReceiveBufferSizeOption, %d) failed: %s", opt.Max, err)
-	}
-
-	// Keep the payload size < segment overhead and such that it is a multiple
-	// of the window scaled value. This enables the test to perform equality
-	// checks on the incoming receive window.
-	payloadSize := 1 << c.RcvdWindowScale
-	if payloadSize >= tcp.SegSize {
-		t.Fatalf("payload size of %d is not less than the segment overhead of %d", payloadSize, tcp.SegSize)
-	}
-	payload := generateRandomPayload(t, payloadSize)
-	payloadLen := seqnum.Size(len(payload))
-	iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-
-	// Send payload to the endpoint and return the advertised receive window
-	// from the endpoint.
-	getIncomingRcvWnd := func() uint32 {
-		c.SendPacket(payload, &context.Headers{
-			SrcPort: context.TestPort,
-			DstPort: c.Port,
-			SeqNum:  iss,
-			AckNum:  c.IRS.Add(1),
-			Flags:   header.TCPFlagAck,
-			RcvWnd:  30000,
-		})
-		iss = iss.Add(payloadLen)
-
-		pkt := c.GetPacket()
-		return uint32(header.TCP(header.IPv4(pkt).Payload()).WindowSize()) << c.RcvdWindowScale
-	}
-
-	// Read the advertised receive window with the ACK for payload.
-	rcvWnd := getIncomingRcvWnd()
-
-	// Check if the subsequent ACK to our send has not grown the right edge of
-	// the window.
-	if got, want := getIncomingRcvWnd(), rcvWnd-uint32(len(payload)); got != want {
-		t.Fatalf("got incomingRcvwnd %d want %d", got, want)
-	}
-
-	// Read the data so that the subsequent ACK from the endpoint
-	// grows the right edge of the window.
-	var buf bytes.Buffer
-	if _, err := c.EP.Read(&buf, tcpip.ReadOptions{}); err != nil {
-		t.Fatalf("c.EP.Read: %s", err)
-	}
-
-	// Check if we have received max uint16 as our advertised
-	// scaled window now after a read above.
-	maxRcv := uint32(math.MaxUint16 << c.RcvdWindowScale)
-	if got, want := getIncomingRcvWnd(), maxRcv; got != want {
-		t.Fatalf("got incomingRcvwnd %d want %d", got, want)
-	}
-
-	// Check if the subsequent ACK to our send has not grown the right edge of
-	// the window.
-	if got, want := getIncomingRcvWnd(), maxRcv-uint32(len(payload)); got != want {
-		t.Fatalf("got incomingRcvwnd %d want %d", got, want)
-	}
-}
-
-func TestNoWindowShrinking(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	// Start off with a certain receive buffer then cut it in half and verify that
-	// the right edge of the window does not shrink.
-	// NOTE: Netstack doubles the value specified here.
-	rcvBufSize := 65536
-	// Enable window scaling with a scale of zero from our end.
-	c.CreateConnectedWithRawOptions(context.TestInitialSequenceNumber, 30000, rcvBufSize, []byte{
-		header.TCPOptionWS, 3, 0, header.TCPOptionNOP,
-	})
-
-	we, ch := waiter.NewChannelEntry(nil)
-	c.WQ.EventRegister(&we, waiter.EventIn)
-	defer c.WQ.EventUnregister(&we)
-
-	ept := endpointTester{c.EP}
-	ept.CheckReadError(t, &tcpip.ErrWouldBlock{})
-
-	// Send a 1 byte payload so that we can record the current receive window.
-	// Send a payload of half the size of rcvBufSize.
-	iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	payload := []byte{1}
-	c.SendPacket(payload, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss,
-		AckNum:  c.IRS.Add(1),
-		RcvWnd:  30000,
-	})
-
-	// Wait for receive to be notified.
-	select {
-	case <-ch:
-	case <-time.After(5 * time.Second):
-		t.Fatalf("Timed out waiting for data to arrive")
-	}
-
-	// Read the 1 byte payload we just sent.
-	if got, want := payload, ept.CheckRead(t); !bytes.Equal(got, want) {
-		t.Fatalf("got data: %v, want: %v", got, want)
-	}
-
-	// Verify that the ACK does not shrink the window.
-	pkt := c.GetPacket()
-	iss = iss.Add(1)
-	checker.IPv4(t, pkt,
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(c.IRS)+1),
-			checker.TCPAckNum(uint32(iss)),
-			checker.TCPFlags(header.TCPFlagAck),
-		),
-	)
-	// Stash the initial window.
-	initialWnd := header.TCP(header.IPv4(pkt).Payload()).WindowSize() << c.RcvdWindowScale
-	initialLastAcceptableSeq := iss.Add(seqnum.Size(initialWnd))
-	// Now shrink the receive buffer to half its original size.
-	if err := c.EP.SetSockOptInt(tcpip.ReceiveBufferSizeOption, rcvBufSize/2); err != nil {
-		t.Fatalf("SetSockOptInt(ReceiveBufferSizeOption, 5) failed: %s", err)
-	}
-
-	data := generateRandomPayload(t, rcvBufSize)
-	// Send a payload of half the size of rcvBufSize.
-	c.SendPacket(data[:rcvBufSize/2], &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss,
-		AckNum:  c.IRS.Add(1),
-		RcvWnd:  30000,
-	})
-	iss = iss.Add(seqnum.Size(rcvBufSize / 2))
-
-	// Verify that the ACK does not shrink the window.
-	pkt = c.GetPacket()
-	checker.IPv4(t, pkt,
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(c.IRS)+1),
-			checker.TCPAckNum(uint32(iss)),
-			checker.TCPFlags(header.TCPFlagAck),
-		),
-	)
-	newWnd := header.TCP(header.IPv4(pkt).Payload()).WindowSize() << c.RcvdWindowScale
-	newLastAcceptableSeq := iss.Add(seqnum.Size(newWnd))
-	if newLastAcceptableSeq.LessThan(initialLastAcceptableSeq) {
-		t.Fatalf("receive window shrunk unexpectedly got: %d, want >= %d", newLastAcceptableSeq, initialLastAcceptableSeq)
-	}
-
-	// Send another payload of half the size of rcvBufSize. This should fill up the
-	// socket receive buffer and we should see a zero window.
-	c.SendPacket(data[rcvBufSize/2:], &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss,
-		AckNum:  c.IRS.Add(1),
-		RcvWnd:  30000,
-	})
-	iss = iss.Add(seqnum.Size(rcvBufSize / 2))
-
-	checker.IPv4(t, c.GetPacket(),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(c.IRS)+1),
-			checker.TCPAckNum(uint32(iss)),
-			checker.TCPFlags(header.TCPFlagAck),
-			checker.TCPWindow(0),
-		),
-	)
-
-	// Receive data and check it.
-	read := ept.CheckReadFull(t, len(data), ch, 5*time.Second)
-	if !bytes.Equal(data, read) {
-		t.Fatalf("got data = %v, want = %v", read, data)
-	}
-
-	// Check that we get an ACK for the newly non-zero window, which is the new
-	// receive buffer size we set after the connection was established.
-	checker.IPv4(t, c.GetPacket(),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(c.IRS)+1),
-			checker.TCPAckNum(uint32(iss)),
-			checker.TCPFlags(header.TCPFlagAck),
-			checker.TCPWindow(uint16(rcvBufSize/2)>>c.RcvdWindowScale),
-		),
-	)
-}
-
-func TestSimpleSend(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateConnected(context.TestInitialSequenceNumber, 30000, -1 /* epRcvBuf */)
-
-	data := []byte{1, 2, 3}
-	var r bytes.Reader
-	r.Reset(data)
-	if _, err := c.EP.Write(&r, tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %s", err)
-	}
-
-	// Check that data is received.
-	b := c.GetPacket()
-	iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	checker.IPv4(t, b,
-		checker.PayloadLen(len(data)+header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(c.IRS)+1),
-			checker.TCPAckNum(uint32(iss)),
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
-		),
-	)
-
-	if p := b[header.IPv4MinimumSize+header.TCPMinimumSize:]; !bytes.Equal(data, p) {
-		t.Fatalf("got data = %v, want = %v", p, data)
-	}
-
-	// Acknowledge the data.
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss,
-		AckNum:  c.IRS.Add(1 + seqnum.Size(len(data))),
-		RcvWnd:  30000,
-	})
-}
-
-func TestZeroWindowSend(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateConnected(context.TestInitialSequenceNumber, 0 /* rcvWnd */, -1 /* epRcvBuf */)
-
-	data := []byte{1, 2, 3}
-	var r bytes.Reader
-	r.Reset(data)
-	if _, err := c.EP.Write(&r, tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %s", err)
-	}
-
-	// Check if we got a zero-window probe.
-	b := c.GetPacket()
-	iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	checker.IPv4(t, b,
-		checker.PayloadLen(header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(c.IRS)),
-			checker.TCPAckNum(uint32(iss)),
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
-		),
-	)
-
-	// Open up the window. Data should be received now.
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss,
-		AckNum:  c.IRS.Add(1),
-		RcvWnd:  30000,
-	})
-
-	// Check that data is received.
-	b = c.GetPacket()
-	checker.IPv4(t, b,
-		checker.PayloadLen(len(data)+header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(c.IRS)+1),
-			checker.TCPAckNum(uint32(iss)),
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
-		),
-	)
-
-	if p := b[header.IPv4MinimumSize+header.TCPMinimumSize:]; !bytes.Equal(data, p) {
-		t.Fatalf("got data = %v, want = %v", p, data)
-	}
-
-	// Acknowledge the data.
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss,
-		AckNum:  c.IRS.Add(1 + seqnum.Size(len(data))),
-		RcvWnd:  30000,
-	})
-}
-
-func TestScaledWindowConnect(t *testing.T) {
-	// This test ensures that window scaling is used when the peer
-	// does advertise it and connection is established with Connect().
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	// Set the window size greater than the maximum non-scaled window.
-	c.CreateConnectedWithRawOptions(context.TestInitialSequenceNumber, 30000, 65535*3, []byte{
-		header.TCPOptionWS, 3, 0, header.TCPOptionNOP,
-	})
-
-	data := []byte{1, 2, 3}
-	var r bytes.Reader
-	r.Reset(data)
-	if _, err := c.EP.Write(&r, tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %s", err)
-	}
-
-	// Check that data is received, and that advertised window is 0x5fff,
-	// that is, that it is scaled.
-	b := c.GetPacket()
-	iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	checker.IPv4(t, b,
-		checker.PayloadLen(len(data)+header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(c.IRS)+1),
-			checker.TCPAckNum(uint32(iss)),
-			checker.TCPWindow(0x5fff),
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
-		),
-	)
-}
-
-func TestNonScaledWindowConnect(t *testing.T) {
-	// This test ensures that window scaling is not used when the peer
-	// doesn't advertise it and connection is established with Connect().
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	// Set the window size greater than the maximum non-scaled window.
-	c.CreateConnected(context.TestInitialSequenceNumber, 30000, 65535*3)
-
-	data := []byte{1, 2, 3}
-	var r bytes.Reader
-	r.Reset(data)
-	if _, err := c.EP.Write(&r, tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %s", err)
-	}
-
-	// Check that data is received, and that advertised window is 0xffff,
-	// that is, that it's not scaled.
-	b := c.GetPacket()
-	iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	checker.IPv4(t, b,
-		checker.PayloadLen(len(data)+header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(c.IRS)+1),
-			checker.TCPAckNum(uint32(iss)),
-			checker.TCPWindow(0xffff),
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
-		),
-	)
-}
-
-func TestScaledWindowAccept(t *testing.T) {
-	// This test ensures that window scaling is used when the peer
-	// does advertise it and connection is established with Accept().
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	// Create EP and start listening.
-	wq := &waiter.Queue{}
-	ep, err := c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, wq)
-	if err != nil {
-		t.Fatalf("NewEndpoint failed: %s", err)
-	}
-	defer ep.Close()
-
-	// Set the window size greater than the maximum non-scaled window.
-	if err := ep.SetSockOptInt(tcpip.ReceiveBufferSizeOption, 65535*3); err != nil {
-		t.Fatalf("SetSockOptInt(ReceiveBufferSizeOption, 65535*3) failed failed: %s", err)
-	}
-
-	if err := ep.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %s", err)
-	}
-
-	if err := ep.Listen(10); err != nil {
-		t.Fatalf("Listen failed: %s", err)
-	}
-
-	// Do 3-way handshake.
-	// wndScale expected is 3 as 65535 * 3 * 2 < 65535 * 2^3 but > 65535 *2 *2
-	c.PassiveConnectWithOptions(100, 3 /* wndScale */, header.TCPSynOptions{MSS: defaultIPv4MSS})
-
-	// Try to accept the connection.
-	we, ch := waiter.NewChannelEntry(nil)
-	wq.EventRegister(&we, waiter.EventIn)
-	defer wq.EventUnregister(&we)
-
-	c.EP, _, err = ep.Accept(nil)
-	if _, ok := err.(*tcpip.ErrWouldBlock); ok {
-		// Wait for connection to be established.
-		select {
-		case <-ch:
-			c.EP, _, err = ep.Accept(nil)
-			if err != nil {
-				t.Fatalf("Accept failed: %s", err)
-			}
-
-		case <-time.After(1 * time.Second):
-			t.Fatalf("Timed out waiting for accept")
-		}
-	}
-
-	data := []byte{1, 2, 3}
-	var r bytes.Reader
-	r.Reset(data)
-	if _, err := c.EP.Write(&r, tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %s", err)
-	}
-
-	// Check that data is received, and that advertised window is 0x5fff,
-	// that is, that it is scaled.
-	b := c.GetPacket()
-	iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	checker.IPv4(t, b,
-		checker.PayloadLen(len(data)+header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(c.IRS)+1),
-			checker.TCPAckNum(uint32(iss)),
-			checker.TCPWindow(0x5fff),
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
-		),
-	)
-}
-
-func TestNonScaledWindowAccept(t *testing.T) {
-	// This test ensures that window scaling is not used when the peer
-	// doesn't advertise it and connection is established with Accept().
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	// Create EP and start listening.
-	wq := &waiter.Queue{}
-	ep, err := c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, wq)
-	if err != nil {
-		t.Fatalf("NewEndpoint failed: %s", err)
-	}
-	defer ep.Close()
-
-	// Set the window size greater than the maximum non-scaled window.
-	if err := ep.SetSockOptInt(tcpip.ReceiveBufferSizeOption, 65535*3); err != nil {
-		t.Fatalf("SetSockOptInt(ReceiveBufferSizeOption, 65535*3) failed failed: %s", err)
-	}
-
-	if err := ep.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %s", err)
-	}
-
-	if err := ep.Listen(10); err != nil {
-		t.Fatalf("Listen failed: %s", err)
-	}
-
-	// Do 3-way handshake w/ window scaling disabled. The SYN-ACK to the SYN
-	// should not carry the window scaling option.
-	c.PassiveConnect(100, -1, header.TCPSynOptions{MSS: defaultIPv4MSS})
-
-	// Try to accept the connection.
-	we, ch := waiter.NewChannelEntry(nil)
-	wq.EventRegister(&we, waiter.EventIn)
-	defer wq.EventUnregister(&we)
-
-	c.EP, _, err = ep.Accept(nil)
-	if _, ok := err.(*tcpip.ErrWouldBlock); ok {
-		// Wait for connection to be established.
-		select {
-		case <-ch:
-			c.EP, _, err = ep.Accept(nil)
-			if err != nil {
-				t.Fatalf("Accept failed: %s", err)
-			}
-
-		case <-time.After(1 * time.Second):
-			t.Fatalf("Timed out waiting for accept")
-		}
-	}
-
-	data := []byte{1, 2, 3}
-	var r bytes.Reader
-	r.Reset(data)
-	if _, err := c.EP.Write(&r, tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %s", err)
-	}
-
-	// Check that data is received, and that advertised window is 0xffff,
-	// that is, that it's not scaled.
-	b := c.GetPacket()
-	iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	checker.IPv4(t, b,
-		checker.PayloadLen(len(data)+header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(c.IRS)+1),
-			checker.TCPAckNum(uint32(iss)),
-			checker.TCPWindow(0xffff),
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
-		),
-	)
-}
-
-func TestZeroScaledWindowReceive(t *testing.T) {
-	// This test ensures that the endpoint sends a non-zero window size
-	// advertisement when the scaled window transitions from 0 to non-zero,
-	// but the actual window (not scaled) hasn't gotten to zero.
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	// Set the buffer size such that a window scale of 5 will be used.
-	const bufSz = 65535 * 10
-	const ws = uint32(5)
-	c.CreateConnectedWithRawOptions(context.TestInitialSequenceNumber, 30000, bufSz, []byte{
-		header.TCPOptionWS, 3, 0, header.TCPOptionNOP,
-	})
-
-	// Write chunks of 50000 bytes.
-	remain := 0
-	sent := 0
-	data := make([]byte, 50000)
-	iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	// Keep writing till the window drops below len(data).
-	for {
-		c.SendPacket(data, &context.Headers{
-			SrcPort: context.TestPort,
-			DstPort: c.Port,
-			Flags:   header.TCPFlagAck,
-			SeqNum:  iss.Add(seqnum.Size(sent)),
-			AckNum:  c.IRS.Add(1),
-			RcvWnd:  30000,
-		})
-		sent += len(data)
-		pkt := c.GetPacket()
-		checker.IPv4(t, pkt,
-			checker.PayloadLen(header.TCPMinimumSize),
-			checker.TCP(
-				checker.DstPort(context.TestPort),
-				checker.TCPSeqNum(uint32(c.IRS)+1),
-				checker.TCPAckNum(uint32(iss)+uint32(sent)),
-				checker.TCPFlags(header.TCPFlagAck),
-			),
-		)
-		// Don't reduce window to zero here.
-		if wnd := int(header.TCP(header.IPv4(pkt).Payload()).WindowSize()); wnd<<ws < len(data) {
-			remain = wnd << ws
-			break
-		}
-	}
-
-	// Make the window non-zero, but the scaled window zero.
-	for remain >= 16 {
-		data = data[:remain-15]
-		c.SendPacket(data, &context.Headers{
-			SrcPort: context.TestPort,
-			DstPort: c.Port,
-			Flags:   header.TCPFlagAck,
-			SeqNum:  iss.Add(seqnum.Size(sent)),
-			AckNum:  c.IRS.Add(1),
-			RcvWnd:  30000,
-		})
-		sent += len(data)
-		pkt := c.GetPacket()
-		checker.IPv4(t, pkt,
-			checker.PayloadLen(header.TCPMinimumSize),
-			checker.TCP(
-				checker.DstPort(context.TestPort),
-				checker.TCPSeqNum(uint32(c.IRS)+1),
-				checker.TCPAckNum(uint32(iss)+uint32(sent)),
-				checker.TCPFlags(header.TCPFlagAck),
-			),
-		)
-		// Since the receive buffer is split between window advertisement and
-		// application data buffer the window does not always reflect the space
-		// available and actual space available can be a bit more than what is
-		// advertised in the window.
-		wnd := int(header.TCP(header.IPv4(pkt).Payload()).WindowSize())
-		if wnd == 0 {
-			break
-		}
-		remain = wnd << ws
-	}
-
-	// Read at least 2MSS of data. An ack should be sent in response to that.
-	// Since buffer space is now split in half between window and application
-	// data we need to read more than 1 MSS(65536) of data for a non-zero window
-	// update to be sent. For 1MSS worth of window to be available we need to
-	// read at least 128KB. Since our segments above were 50KB each it means
-	// we need to read at 3 packets.
-	w := tcpip.LimitedWriter{
-		W: ioutil.Discard,
-		N: defaultMTU * 2,
-	}
-	for w.N != 0 {
-		res, err := c.EP.Read(&w, tcpip.ReadOptions{})
-		t.Logf("err=%v res=%#v", err, res)
-		if err != nil {
-			t.Fatalf("Read failed: %s", err)
-		}
-	}
-
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(c.IRS)+1),
-			checker.TCPAckNum(uint32(iss)+uint32(sent)),
-			checker.TCPWindowGreaterThanEq(uint16(defaultMTU>>ws)),
-			checker.TCPFlags(header.TCPFlagAck),
-		),
-	)
-}
-
-func TestSegmentMerging(t *testing.T) {
-	tests := []struct {
-		name   string
-		stop   func(tcpip.Endpoint)
-		resume func(tcpip.Endpoint)
-	}{
-		{
-			"stop work",
-			func(ep tcpip.Endpoint) {
-				ep.(interface{ StopWork() }).StopWork()
-			},
-			func(ep tcpip.Endpoint) {
-				ep.(interface{ ResumeWork() }).ResumeWork()
-			},
-		},
-		{
-			"cork",
-			func(ep tcpip.Endpoint) {
-				ep.SocketOptions().SetCorkOption(true)
-			},
-			func(ep tcpip.Endpoint) {
-				ep.SocketOptions().SetCorkOption(false)
-			},
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			c := context.New(t, defaultMTU)
-			defer c.Cleanup()
-
-			c.CreateConnected(context.TestInitialSequenceNumber, 30000, -1 /* epRcvBuf */)
-
-			// Send tcp.InitialCwnd number of segments to fill up
-			// InitialWindow but don't ACK. That should prevent
-			// anymore packets from going out.
-			var r bytes.Reader
-			for i := 0; i < tcp.InitialCwnd; i++ {
-				r.Reset([]byte{0})
-				if _, err := c.EP.Write(&r, tcpip.WriteOptions{}); err != nil {
-					t.Fatalf("Write #%d failed: %s", i+1, err)
-				}
-			}
-
-			// Now send the segments that should get merged as the congestion
-			// window is full and we won't be able to send any more packets.
-			var allData []byte
-			for i, data := range [][]byte{{1, 2, 3, 4}, {5, 6, 7}, {8, 9}, {10}, {11}} {
-				allData = append(allData, data...)
-				r.Reset(data)
-				if _, err := c.EP.Write(&r, tcpip.WriteOptions{}); err != nil {
-					t.Fatalf("Write #%d failed: %s", i+1, err)
-				}
-			}
-
-			// Check that we get tcp.InitialCwnd packets.
-			iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-			for i := 0; i < tcp.InitialCwnd; i++ {
-				b := c.GetPacket()
-				checker.IPv4(t, b,
-					checker.PayloadLen(header.TCPMinimumSize+1),
-					checker.TCP(
-						checker.DstPort(context.TestPort),
-						checker.TCPSeqNum(uint32(c.IRS)+uint32(i)+1),
-						checker.TCPAckNum(uint32(iss)),
-						checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
-					),
-				)
-			}
-
-			// Acknowledge the data.
-			c.SendPacket(nil, &context.Headers{
-				SrcPort: context.TestPort,
-				DstPort: c.Port,
-				Flags:   header.TCPFlagAck,
-				SeqNum:  iss,
-				AckNum:  c.IRS.Add(1 + 10), // 10 for the 10 bytes of payload.
-				RcvWnd:  30000,
-			})
-
-			// Check that data is received.
-			b := c.GetPacket()
-			checker.IPv4(t, b,
-				checker.PayloadLen(len(allData)+header.TCPMinimumSize),
-				checker.TCP(
-					checker.DstPort(context.TestPort),
-					checker.TCPSeqNum(uint32(c.IRS)+11),
-					checker.TCPAckNum(uint32(iss)),
-					checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
-				),
-			)
-
-			if got := b[header.IPv4MinimumSize+header.TCPMinimumSize:]; !bytes.Equal(got, allData) {
-				t.Fatalf("got data = %v, want = %v", got, allData)
-			}
-
-			// Acknowledge the data.
-			c.SendPacket(nil, &context.Headers{
-				SrcPort: context.TestPort,
-				DstPort: c.Port,
-				Flags:   header.TCPFlagAck,
-				SeqNum:  iss,
-				AckNum:  c.IRS.Add(11 + seqnum.Size(len(allData))),
-				RcvWnd:  30000,
-			})
-		})
-	}
-}
-
-func TestDelay(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateConnected(context.TestInitialSequenceNumber, 30000, -1 /* epRcvBuf */)
-
-	c.EP.SocketOptions().SetDelayOption(true)
-
-	var allData []byte
-	for i, data := range [][]byte{{0}, {1, 2, 3, 4}, {5, 6, 7}, {8, 9}, {10}, {11}} {
-		allData = append(allData, data...)
-		var r bytes.Reader
-		r.Reset(data)
-		if _, err := c.EP.Write(&r, tcpip.WriteOptions{}); err != nil {
-			t.Fatalf("Write #%d failed: %s", i+1, err)
-		}
-	}
-
-	seq := c.IRS.Add(1)
-	iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	for _, want := range [][]byte{allData[:1], allData[1:]} {
-		// Check that data is received.
-		b := c.GetPacket()
-		checker.IPv4(t, b,
-			checker.PayloadLen(len(want)+header.TCPMinimumSize),
-			checker.TCP(
-				checker.DstPort(context.TestPort),
-				checker.TCPSeqNum(uint32(seq)),
-				checker.TCPAckNum(uint32(iss)),
-				checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
-			),
-		)
-
-		if got := b[header.IPv4MinimumSize+header.TCPMinimumSize:]; !bytes.Equal(got, want) {
-			t.Fatalf("got data = %v, want = %v", got, want)
-		}
-
-		seq = seq.Add(seqnum.Size(len(want)))
-		// Acknowledge the data.
-		c.SendPacket(nil, &context.Headers{
-			SrcPort: context.TestPort,
-			DstPort: c.Port,
-			Flags:   header.TCPFlagAck,
-			SeqNum:  iss,
-			AckNum:  seq,
-			RcvWnd:  30000,
-		})
-	}
-}
-
-func TestUndelay(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateConnected(context.TestInitialSequenceNumber, 30000, -1 /* epRcvBuf */)
-
-	c.EP.SocketOptions().SetDelayOption(true)
-
-	allData := [][]byte{{0}, {1, 2, 3}}
-	for i, data := range allData {
-		var r bytes.Reader
-		r.Reset(data)
-		if _, err := c.EP.Write(&r, tcpip.WriteOptions{}); err != nil {
-			t.Fatalf("Write #%d failed: %s", i+1, err)
-		}
-	}
-
-	seq := c.IRS.Add(1)
-	iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	// Check that data is received.
-	first := c.GetPacket()
-	checker.IPv4(t, first,
-		checker.PayloadLen(len(allData[0])+header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(seq)),
-			checker.TCPAckNum(uint32(iss)),
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
-		),
-	)
-
-	if got, want := first[header.IPv4MinimumSize+header.TCPMinimumSize:], allData[0]; !bytes.Equal(got, want) {
-		t.Fatalf("got first packet's data = %v, want = %v", got, want)
-	}
-
-	seq = seq.Add(seqnum.Size(len(allData[0])))
-
-	// Check that we don't get the second packet yet.
-	c.CheckNoPacketTimeout("delayed second packet transmitted", 100*time.Millisecond)
-
-	c.EP.SocketOptions().SetDelayOption(false)
-
-	// Check that data is received.
-	second := c.GetPacket()
-	checker.IPv4(t, second,
-		checker.PayloadLen(len(allData[1])+header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(seq)),
-			checker.TCPAckNum(uint32(iss)),
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
-		),
-	)
-
-	if got, want := second[header.IPv4MinimumSize+header.TCPMinimumSize:], allData[1]; !bytes.Equal(got, want) {
-		t.Fatalf("got second packet's data = %v, want = %v", got, want)
-	}
-
-	seq = seq.Add(seqnum.Size(len(allData[1])))
-
-	// Acknowledge the data.
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss,
-		AckNum:  seq,
-		RcvWnd:  30000,
-	})
-}
-
-func TestMSSNotDelayed(t *testing.T) {
-	tests := []struct {
-		name string
-		fn   func(tcpip.Endpoint)
-	}{
-		{"no-op", func(tcpip.Endpoint) {}},
-		{"delay", func(ep tcpip.Endpoint) { ep.SocketOptions().SetDelayOption(true) }},
-		{"cork", func(ep tcpip.Endpoint) { ep.SocketOptions().SetCorkOption(true) }},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			const maxPayload = 100
-			c := context.New(t, defaultMTU)
-			defer c.Cleanup()
-
-			c.CreateConnectedWithRawOptions(context.TestInitialSequenceNumber, 30000, -1 /* epRcvBuf */, []byte{
-				header.TCPOptionMSS, 4, byte(maxPayload / 256), byte(maxPayload % 256),
-			})
-
-			test.fn(c.EP)
-
-			allData := [][]byte{{0}, make([]byte, maxPayload), make([]byte, maxPayload)}
-			for i, data := range allData {
-				var r bytes.Reader
-				r.Reset(data)
-				if _, err := c.EP.Write(&r, tcpip.WriteOptions{}); err != nil {
-					t.Fatalf("Write #%d failed: %s", i+1, err)
-				}
-			}
-
-			seq := c.IRS.Add(1)
-			iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-			for i, data := range allData {
-				// Check that data is received.
-				packet := c.GetPacket()
-				checker.IPv4(t, packet,
-					checker.PayloadLen(len(data)+header.TCPMinimumSize),
-					checker.TCP(
-						checker.DstPort(context.TestPort),
-						checker.TCPSeqNum(uint32(seq)),
-						checker.TCPAckNum(uint32(iss)),
-						checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
-					),
-				)
-
-				if got, want := packet[header.IPv4MinimumSize+header.TCPMinimumSize:], data; !bytes.Equal(got, want) {
-					t.Fatalf("got packet #%d's data = %v, want = %v", i+1, got, want)
-				}
-
-				seq = seq.Add(seqnum.Size(len(data)))
-			}
-
-			// Acknowledge the data.
-			c.SendPacket(nil, &context.Headers{
-				SrcPort: context.TestPort,
-				DstPort: c.Port,
-				Flags:   header.TCPFlagAck,
-				SeqNum:  iss,
-				AckNum:  seq,
-				RcvWnd:  30000,
-			})
-		})
-	}
-}
-
-func testBrokenUpWrite(t *testing.T, c *context.Context, maxPayload int) {
-	payloadMultiplier := 10
-	dataLen := payloadMultiplier * maxPayload
-	data := make([]byte, dataLen)
-	for i := range data {
-		data[i] = byte(i)
-	}
-
-	var r bytes.Reader
-	r.Reset(data)
-	if _, err := c.EP.Write(&r, tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %s", err)
-	}
-
-	// Check that data is received in chunks.
-	bytesReceived := 0
-	numPackets := 0
-	iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	for bytesReceived != dataLen {
-		b := c.GetPacket()
-		numPackets++
-		tcpHdr := header.TCP(header.IPv4(b).Payload())
-		payloadLen := len(tcpHdr.Payload())
-		checker.IPv4(t, b,
-			checker.TCP(
-				checker.DstPort(context.TestPort),
-				checker.TCPSeqNum(uint32(c.IRS)+1+uint32(bytesReceived)),
-				checker.TCPAckNum(uint32(iss)),
-				checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
-			),
-		)
-
-		pdata := data[bytesReceived : bytesReceived+payloadLen]
-		if p := tcpHdr.Payload(); !bytes.Equal(pdata, p) {
-			t.Fatalf("got data = %v, want = %v", p, pdata)
-		}
-		bytesReceived += payloadLen
-		var options []byte
-		if c.TimeStampEnabled {
-			// If timestamp option is enabled, echo back the timestamp and increment
-			// the TSEcr value included in the packet and send that back as the TSVal.
-			parsedOpts := tcpHdr.ParsedOptions()
-			tsOpt := [12]byte{header.TCPOptionNOP, header.TCPOptionNOP}
-			header.EncodeTSOption(parsedOpts.TSEcr+1, parsedOpts.TSVal, tsOpt[2:])
-			options = tsOpt[:]
-		}
-		// Acknowledge the data.
-		c.SendPacket(nil, &context.Headers{
-			SrcPort: context.TestPort,
-			DstPort: c.Port,
-			Flags:   header.TCPFlagAck,
-			SeqNum:  iss,
-			AckNum:  c.IRS.Add(1 + seqnum.Size(bytesReceived)),
-			RcvWnd:  30000,
-			TCPOpts: options,
-		})
-	}
-	if numPackets == 1 {
-		t.Fatalf("expected write to be broken up into multiple packets, but got 1 packet")
-	}
-}
-
-func TestSendGreaterThanMTU(t *testing.T) {
-	const maxPayload = 100
-	c := context.New(t, uint32(header.TCPMinimumSize+header.IPv4MinimumSize+maxPayload))
-	defer c.Cleanup()
-
-	c.CreateConnected(context.TestInitialSequenceNumber, 30000, -1 /* epRcvBuf */)
-	testBrokenUpWrite(t, c, maxPayload)
-}
-
-func TestSetTTL(t *testing.T) {
-	for _, wantTTL := range []uint8{1, 2, 50, 64, 128, 254, 255} {
-		t.Run(fmt.Sprintf("TTL:%d", wantTTL), func(t *testing.T) {
-			c := context.New(t, 65535)
-			defer c.Cleanup()
-
-			var err tcpip.Error
-			c.EP, err = c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &waiter.Queue{})
-			if err != nil {
-				t.Fatalf("NewEndpoint failed: %s", err)
-			}
-
-			if err := c.EP.SetSockOptInt(tcpip.TTLOption, int(wantTTL)); err != nil {
-				t.Fatalf("SetSockOptInt(TTLOption, %d) failed: %s", wantTTL, err)
-			}
-
-			{
-				err := c.EP.Connect(tcpip.FullAddress{Addr: context.TestAddr, Port: context.TestPort})
-				if _, ok := err.(*tcpip.ErrConnectStarted); !ok {
-					t.Fatalf("unexpected return value from Connect: %s", err)
-				}
-			}
-
-			// Receive SYN packet.
-			b := c.GetPacket()
-
-			checker.IPv4(t, b, checker.TTL(wantTTL))
-		})
-	}
-}
-
-func TestActiveSendMSSLessThanMTU(t *testing.T) {
-	const maxPayload = 100
-	c := context.New(t, 65535)
-	defer c.Cleanup()
-
-	c.CreateConnectedWithRawOptions(context.TestInitialSequenceNumber, 30000, -1 /* epRcvBuf */, []byte{
-		header.TCPOptionMSS, 4, byte(maxPayload / 256), byte(maxPayload % 256),
-	})
-	testBrokenUpWrite(t, c, maxPayload)
-}
-
-func TestPassiveSendMSSLessThanMTU(t *testing.T) {
-	const maxPayload = 100
-	const mtu = 1200
-	c := context.New(t, mtu)
-	defer c.Cleanup()
-
-	// Create EP and start listening.
-	wq := &waiter.Queue{}
-	ep, err := c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, wq)
-	if err != nil {
-		t.Fatalf("NewEndpoint failed: %s", err)
-	}
-	defer ep.Close()
-
-	// Set the buffer size to a deterministic size so that we can check the
-	// window scaling option.
-	const rcvBufferSize = 0x20000
-	if err := ep.SetSockOptInt(tcpip.ReceiveBufferSizeOption, rcvBufferSize); err != nil {
-		t.Fatalf("SetSockOptInt(ReceiveBufferSizeOption, %d) failed failed: %s", rcvBufferSize, err)
-	}
-
-	if err := ep.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %s", err)
-	}
-
-	if err := ep.Listen(10); err != nil {
-		t.Fatalf("Listen failed: %s", err)
-	}
-
-	// Do 3-way handshake.
-	c.PassiveConnect(maxPayload, -1, header.TCPSynOptions{MSS: mtu - header.IPv4MinimumSize - header.TCPMinimumSize})
-
-	// Try to accept the connection.
-	we, ch := waiter.NewChannelEntry(nil)
-	wq.EventRegister(&we, waiter.EventIn)
-	defer wq.EventUnregister(&we)
-
-	c.EP, _, err = ep.Accept(nil)
-	if _, ok := err.(*tcpip.ErrWouldBlock); ok {
-		// Wait for connection to be established.
-		select {
-		case <-ch:
-			c.EP, _, err = ep.Accept(nil)
-			if err != nil {
-				t.Fatalf("Accept failed: %s", err)
-			}
-
-		case <-time.After(1 * time.Second):
-			t.Fatalf("Timed out waiting for accept")
-		}
-	}
-
-	// Check that data gets properly segmented.
-	testBrokenUpWrite(t, c, maxPayload)
-}
-
-func TestSynCookiePassiveSendMSSLessThanMTU(t *testing.T) {
-	const maxPayload = 536
-	const mtu = 2000
-	c := context.New(t, mtu)
-	defer c.Cleanup()
-
-	// Set the SynRcvd threshold to zero to force a syn cookie based accept
-	// to happen.
-	opt := tcpip.TCPSynRcvdCountThresholdOption(0)
-	if err := c.Stack().SetTransportProtocolOption(tcp.ProtocolNumber, &opt); err != nil {
-		t.Fatalf("SetTransportProtocolOption(%d, &%T(%d)): %s", tcp.ProtocolNumber, opt, opt, err)
-	}
-
-	// Create EP and start listening.
-	wq := &waiter.Queue{}
-	ep, err := c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, wq)
-	if err != nil {
-		t.Fatalf("NewEndpoint failed: %s", err)
-	}
-	defer ep.Close()
-
-	if err := ep.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %s", err)
-	}
-
-	if err := ep.Listen(10); err != nil {
-		t.Fatalf("Listen failed: %s", err)
-	}
-
-	// Do 3-way handshake.
-	c.PassiveConnect(maxPayload, -1, header.TCPSynOptions{MSS: mtu - header.IPv4MinimumSize - header.TCPMinimumSize})
-
-	// Try to accept the connection.
-	we, ch := waiter.NewChannelEntry(nil)
-	wq.EventRegister(&we, waiter.EventIn)
-	defer wq.EventUnregister(&we)
-
-	c.EP, _, err = ep.Accept(nil)
-	if _, ok := err.(*tcpip.ErrWouldBlock); ok {
-		// Wait for connection to be established.
-		select {
-		case <-ch:
-			c.EP, _, err = ep.Accept(nil)
-			if err != nil {
-				t.Fatalf("Accept failed: %s", err)
-			}
-
-		case <-time.After(1 * time.Second):
-			t.Fatalf("Timed out waiting for accept")
-		}
-	}
-
-	// Check that data gets properly segmented.
-	testBrokenUpWrite(t, c, maxPayload)
-}
-
-func TestForwarderSendMSSLessThanMTU(t *testing.T) {
-	const maxPayload = 100
-	const mtu = 1200
-	c := context.New(t, mtu)
-	defer c.Cleanup()
-
-	s := c.Stack()
-	ch := make(chan tcpip.Error, 1)
-	f := tcp.NewForwarder(s, 65536, 10, func(r *tcp.ForwarderRequest) {
-		var err tcpip.Error
-		c.EP, err = r.CreateEndpoint(&c.WQ)
-		ch <- err
-	})
-	s.SetTransportProtocolHandler(tcp.ProtocolNumber, f.HandlePacket)
-
-	// Do 3-way handshake.
-	c.PassiveConnect(maxPayload, -1, header.TCPSynOptions{MSS: mtu - header.IPv4MinimumSize - header.TCPMinimumSize})
-
-	// Wait for connection to be available.
-	select {
-	case err := <-ch:
-		if err != nil {
-			t.Fatalf("Error creating endpoint: %s", err)
-		}
-	case <-time.After(2 * time.Second):
-		t.Fatalf("Timed out waiting for connection")
-	}
-
-	// Check that data gets properly segmented.
-	testBrokenUpWrite(t, c, maxPayload)
-}
-
-func TestSynOptionsOnActiveConnect(t *testing.T) {
-	const mtu = 1400
-	c := context.New(t, mtu)
-	defer c.Cleanup()
-
-	// Create TCP endpoint.
-	var err tcpip.Error
-	c.EP, err = c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &c.WQ)
-	if err != nil {
-		t.Fatalf("NewEndpoint failed: %s", err)
-	}
-
-	// Set the buffer size to a deterministic size so that we can check the
-	// window scaling option.
-	const rcvBufferSize = 0x20000
-	const wndScale = 3
-	if err := c.EP.SetSockOptInt(tcpip.ReceiveBufferSizeOption, rcvBufferSize); err != nil {
-		t.Fatalf("SetSockOptInt(ReceiveBufferSizeOption, %d) failed failed: %s", rcvBufferSize, err)
-	}
-
-	// Start connection attempt.
-	we, ch := waiter.NewChannelEntry(nil)
-	c.WQ.EventRegister(&we, waiter.EventOut)
-	defer c.WQ.EventUnregister(&we)
-
-	{
-		err := c.EP.Connect(tcpip.FullAddress{Addr: context.TestAddr, Port: context.TestPort})
-		if _, ok := err.(*tcpip.ErrConnectStarted); !ok {
-			t.Fatalf("got c.EP.Connect(...) = %v, want = %s", err, &tcpip.ErrConnectStarted{})
-		}
-	}
-
-	// Receive SYN packet.
-	b := c.GetPacket()
-	mss := uint16(mtu - header.IPv4MinimumSize - header.TCPMinimumSize)
-	checker.IPv4(t, b,
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPFlags(header.TCPFlagSyn),
-			checker.TCPSynOptions(header.TCPSynOptions{MSS: mss, WS: wndScale}),
-		),
-	)
-
-	tcpHdr := header.TCP(header.IPv4(b).Payload())
-	c.IRS = seqnum.Value(tcpHdr.SequenceNumber())
-
-	// Wait for retransmit.
-	time.Sleep(1 * time.Second)
-	checker.IPv4(t, c.GetPacket(),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPFlags(header.TCPFlagSyn),
-			checker.SrcPort(tcpHdr.SourcePort()),
-			checker.TCPSeqNum(tcpHdr.SequenceNumber()),
-			checker.TCPSynOptions(header.TCPSynOptions{MSS: mss, WS: wndScale}),
-		),
-	)
-
-	// Send SYN-ACK.
-	iss := seqnum.Value(context.TestInitialSequenceNumber)
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: tcpHdr.DestinationPort(),
-		DstPort: tcpHdr.SourcePort(),
-		Flags:   header.TCPFlagSyn | header.TCPFlagAck,
-		SeqNum:  iss,
-		AckNum:  c.IRS.Add(1),
-		RcvWnd:  30000,
-	})
-
-	// Receive ACK packet.
-	checker.IPv4(t, c.GetPacket(),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPFlags(header.TCPFlagAck),
-			checker.TCPSeqNum(uint32(c.IRS)+1),
-			checker.TCPAckNum(uint32(iss)+1),
-		),
-	)
-
-	// Wait for connection to be established.
-	select {
-	case <-ch:
-		if err := c.EP.LastError(); err != nil {
-			t.Fatalf("Connect failed: %s", err)
-		}
-	case <-time.After(1 * time.Second):
-		t.Fatalf("Timed out waiting for connection")
-	}
-}
-
-func TestCloseListener(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	// Create listener.
-	var wq waiter.Queue
-	ep, err := c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &wq)
-	if err != nil {
-		t.Fatalf("NewEndpoint failed: %s", err)
-	}
-
-	if err := ep.Bind(tcpip.FullAddress{}); err != nil {
-		t.Fatalf("Bind failed: %s", err)
-	}
-
-	if err := ep.Listen(10); err != nil {
-		t.Fatalf("Listen failed: %s", err)
-	}
-
-	// Close the listener and measure how long it takes.
-	t0 := time.Now()
-	ep.Close()
-	if diff := time.Now().Sub(t0); diff > 3*time.Second {
-		t.Fatalf("Took too long to close: %s", diff)
-	}
-}
-
-func TestReceiveOnResetConnection(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateConnected(context.TestInitialSequenceNumber, 30000, -1 /* epRcvBuf */)
-
-	iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	// Send RST segment.
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagRst,
-		SeqNum:  iss,
-		RcvWnd:  30000,
-	})
-
-	// Try to read.
-	we, ch := waiter.NewChannelEntry(nil)
-	c.WQ.EventRegister(&we, waiter.EventIn)
-	defer c.WQ.EventUnregister(&we)
-
-loop:
-	for {
-		switch _, err := c.EP.Read(ioutil.Discard, tcpip.ReadOptions{}); err.(type) {
-		case *tcpip.ErrWouldBlock:
-			select {
-			case <-ch:
-				// Expect the state to be StateError and subsequent Reads to fail with HardError.
-				_, err := c.EP.Read(ioutil.Discard, tcpip.ReadOptions{})
-				if _, ok := err.(*tcpip.ErrConnectionReset); !ok {
-					t.Fatalf("got c.EP.Read() = %v, want = %s", err, &tcpip.ErrConnectionReset{})
-				}
-				break loop
-			case <-time.After(1 * time.Second):
-				t.Fatalf("Timed out waiting for reset to arrive")
-			}
-		case *tcpip.ErrConnectionReset:
-			break loop
-		default:
-			t.Fatalf("got c.EP.Read(nil) = %v, want = %s", err, &tcpip.ErrConnectionReset{})
-		}
-	}
-
-	if tcp.EndpointState(c.EP.State()) != tcp.StateError {
-		t.Fatalf("got EP state is not StateError")
-	}
-	if got := c.Stack().Stats().TCP.EstablishedResets.Value(); got != 1 {
-		t.Errorf("got stats.TCP.EstablishedResets.Value() = %d, want = 1", got)
-	}
-	if got := c.Stack().Stats().TCP.CurrentEstablished.Value(); got != 0 {
-		t.Errorf("got stats.TCP.CurrentEstablished.Value() = %d, want = 0", got)
-	}
-	if got := c.Stack().Stats().TCP.CurrentConnected.Value(); got != 0 {
-		t.Errorf("got stats.TCP.CurrentConnected.Value() = %d, want = 0", got)
-	}
-}
-
-func TestSendOnResetConnection(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateConnected(context.TestInitialSequenceNumber, 30000, -1 /* epRcvBuf */)
-
-	// Send RST segment.
-	iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagRst,
-		SeqNum:  iss,
-		RcvWnd:  30000,
-	})
-
-	// Wait for the RST to be received.
-	time.Sleep(1 * time.Second)
-
-	// Try to write.
-	var r bytes.Reader
-	r.Reset(make([]byte, 10))
-	_, err := c.EP.Write(&r, tcpip.WriteOptions{})
-	if _, ok := err.(*tcpip.ErrConnectionReset); !ok {
-		t.Fatalf("got c.EP.Write(...) = %v, want = %s", err, &tcpip.ErrConnectionReset{})
-	}
-}
-
-// TestMaxRetransmitsTimeout tests if the connection is timed out after
-// a segment has been retransmitted MaxRetries times.
-func TestMaxRetransmitsTimeout(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	const numRetries = 2
-	opt := tcpip.TCPMaxRetriesOption(numRetries)
-	if err := c.Stack().SetTransportProtocolOption(tcp.ProtocolNumber, &opt); err != nil {
-		t.Fatalf("SetTransportProtocolOption(%d, &%T(%d)): %s", tcp.ProtocolNumber, opt, opt, err)
-	}
-
-	c.CreateConnected(context.TestInitialSequenceNumber, 30000 /* rcvWnd */, -1 /* epRcvBuf */)
-
-	waitEntry, notifyCh := waiter.NewChannelEntry(nil)
-	c.WQ.EventRegister(&waitEntry, waiter.EventHUp)
-	defer c.WQ.EventUnregister(&waitEntry)
-
-	var r bytes.Reader
-	r.Reset(make([]byte, 1))
-	_, err := c.EP.Write(&r, tcpip.WriteOptions{})
-	if err != nil {
-		t.Fatalf("Write failed: %s", err)
-	}
-
-	// Expect first transmit and MaxRetries retransmits.
-	for i := 0; i < numRetries+1; i++ {
-		checker.IPv4(t, c.GetPacket(),
-			checker.TCP(
-				checker.DstPort(context.TestPort),
-				checker.TCPFlags(header.TCPFlagAck|header.TCPFlagPsh),
-			),
-		)
-	}
-	// Wait for the connection to timeout after MaxRetries retransmits.
-	initRTO := 1 * time.Second
-	select {
-	case <-notifyCh:
-	case <-time.After((2 << numRetries) * initRTO):
-		t.Fatalf("connection still alive after maximum retransmits.\n")
-	}
-
-	// Send an ACK and expect a RST as the connection would have been closed.
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-	})
-
-	checker.IPv4(t, c.GetPacket(),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPFlags(header.TCPFlagRst),
-		),
-	)
-
-	if got := c.Stack().Stats().TCP.EstablishedTimedout.Value(); got != 1 {
-		t.Errorf("got c.Stack().Stats().TCP.EstablishedTimedout.Value() = %d, want = 1", got)
-	}
-	if got := c.Stack().Stats().TCP.CurrentConnected.Value(); got != 0 {
-		t.Errorf("got stats.TCP.CurrentConnected.Value() = %d, want = 0", got)
-	}
-}
-
-// TestMaxRTO tests if the retransmit interval caps to MaxRTO.
-func TestMaxRTO(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	rto := 1 * time.Second
-	opt := tcpip.TCPMaxRTOOption(rto)
-	if err := c.Stack().SetTransportProtocolOption(tcp.ProtocolNumber, &opt); err != nil {
-		t.Fatalf("SetTransportProtocolOption(%d, &%T(%d)): %s", tcp.ProtocolNumber, opt, opt, err)
-	}
-
-	c.CreateConnected(context.TestInitialSequenceNumber, 30000 /* rcvWnd */, -1 /* epRcvBuf */)
-
-	var r bytes.Reader
-	r.Reset(make([]byte, 1))
-	_, err := c.EP.Write(&r, tcpip.WriteOptions{})
-	if err != nil {
-		t.Fatalf("Write failed: %s", err)
-	}
-	checker.IPv4(t, c.GetPacket(),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
-		),
-	)
-	const numRetransmits = 2
-	for i := 0; i < numRetransmits; i++ {
-		start := time.Now()
-		checker.IPv4(t, c.GetPacket(),
-			checker.TCP(
-				checker.DstPort(context.TestPort),
-				checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
-			),
-		)
-		if time.Since(start).Round(time.Second).Seconds() != rto.Seconds() {
-			t.Errorf("Retransmit interval not capped to MaxRTO.\n")
-		}
-	}
-}
-
-// TestRetransmitIPv4IDUniqueness tests that the IPv4 Identification field is
-// unique on retransmits.
-func TestRetransmitIPv4IDUniqueness(t *testing.T) {
-	for _, tc := range []struct {
-		name string
-		size int
-	}{
-		{"1Byte", 1},
-		{"512Bytes", 512},
-	} {
-		t.Run(tc.name, func(t *testing.T) {
-			c := context.New(t, defaultMTU)
-			defer c.Cleanup()
-
-			c.CreateConnected(context.TestInitialSequenceNumber, 30000 /* rcvWnd */, -1 /* epRcvBuf */)
-
-			// Disabling PMTU discovery causes all packets sent from this socket to
-			// have DF=0. This needs to be done because the IPv4 ID uniqueness
-			// applies only to non-atomic IPv4 datagrams as defined in RFC 6864
-			// Section 4, and datagrams with DF=0 are non-atomic.
-			if err := c.EP.SetSockOptInt(tcpip.MTUDiscoverOption, tcpip.PMTUDiscoveryDont); err != nil {
-				t.Fatalf("disabling PMTU discovery via sockopt to force DF=0 failed: %s", err)
-			}
-
-			var r bytes.Reader
-			r.Reset(make([]byte, tc.size))
-			if _, err := c.EP.Write(&r, tcpip.WriteOptions{}); err != nil {
-				t.Fatalf("Write failed: %s", err)
-			}
-			pkt := c.GetPacket()
-			checker.IPv4(t, pkt,
-				checker.FragmentFlags(0),
-				checker.TCP(
-					checker.DstPort(context.TestPort),
-					checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
-				),
-			)
-			idSet := map[uint16]struct{}{header.IPv4(pkt).ID(): {}}
-			// Expect two retransmitted packets, and that all packets received have
-			// unique IPv4 ID values.
-			for i := 0; i <= 2; i++ {
-				pkt := c.GetPacket()
-				checker.IPv4(t, pkt,
-					checker.FragmentFlags(0),
-					checker.TCP(
-						checker.DstPort(context.TestPort),
-						checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
-					),
-				)
-				id := header.IPv4(pkt).ID()
-				if _, exists := idSet[id]; exists {
-					t.Fatalf("duplicate IPv4 ID=%d found in retransmitted packet", id)
-				}
-				idSet[id] = struct{}{}
-			}
-		})
-	}
-}
-
-func TestFinImmediately(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateConnected(context.TestInitialSequenceNumber, 30000, -1 /* epRcvBuf */)
-
-	// Shutdown immediately, check that we get a FIN.
-	if err := c.EP.Shutdown(tcpip.ShutdownWrite); err != nil {
-		t.Fatalf("Shutdown failed: %s", err)
-	}
-
-	iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(c.IRS)+1),
-			checker.TCPAckNum(uint32(iss)),
-			checker.TCPFlags(header.TCPFlagAck|header.TCPFlagFin),
-		),
-	)
-
-	// Ack and send FIN as well.
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck | header.TCPFlagFin,
-		SeqNum:  iss,
-		AckNum:  c.IRS.Add(2),
-		RcvWnd:  30000,
-	})
-
-	// Check that the stack acks the FIN.
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(c.IRS)+2),
-			checker.TCPAckNum(uint32(iss)+1),
-			checker.TCPFlags(header.TCPFlagAck),
-		),
-	)
-}
-
-func TestFinRetransmit(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateConnected(context.TestInitialSequenceNumber, 30000, -1 /* epRcvBuf */)
-
-	// Shutdown immediately, check that we get a FIN.
-	if err := c.EP.Shutdown(tcpip.ShutdownWrite); err != nil {
-		t.Fatalf("Shutdown failed: %s", err)
-	}
-
-	iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(c.IRS)+1),
-			checker.TCPAckNum(uint32(iss)),
-			checker.TCPFlags(header.TCPFlagAck|header.TCPFlagFin),
-		),
-	)
-
-	// Don't acknowledge yet. We should get a retransmit of the FIN.
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(c.IRS)+1),
-			checker.TCPAckNum(uint32(iss)),
-			checker.TCPFlags(header.TCPFlagAck|header.TCPFlagFin),
-		),
-	)
-
-	// Ack and send FIN as well.
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck | header.TCPFlagFin,
-		SeqNum:  iss,
-		AckNum:  c.IRS.Add(2),
-		RcvWnd:  30000,
-	})
-
-	// Check that the stack acks the FIN.
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(c.IRS)+2),
-			checker.TCPAckNum(uint32(iss)+1),
-			checker.TCPFlags(header.TCPFlagAck),
-		),
-	)
-}
-
-func TestFinWithNoPendingData(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateConnected(context.TestInitialSequenceNumber, 30000, -1 /* epRcvBuf */)
-
-	// Write something out, and have it acknowledged.
-	view := make([]byte, 10)
-	var r bytes.Reader
-	r.Reset(view)
-	if _, err := c.EP.Write(&r, tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %s", err)
-	}
-
-	next := uint32(c.IRS) + 1
-	iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(len(view)+header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(next),
-			checker.TCPAckNum(uint32(iss)),
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
-		),
-	)
-	next += uint32(len(view))
-
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss,
-		AckNum:  seqnum.Value(next),
-		RcvWnd:  30000,
-	})
-
-	// Shutdown, check that we get a FIN.
-	if err := c.EP.Shutdown(tcpip.ShutdownWrite); err != nil {
-		t.Fatalf("Shutdown failed: %s", err)
-	}
-
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(next),
-			checker.TCPAckNum(uint32(iss)),
-			checker.TCPFlags(header.TCPFlagAck|header.TCPFlagFin),
-		),
-	)
-	next++
-
-	// Ack and send FIN as well.
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck | header.TCPFlagFin,
-		SeqNum:  iss,
-		AckNum:  seqnum.Value(next),
-		RcvWnd:  30000,
-	})
-
-	// Check that the stack acks the FIN.
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(next),
-			checker.TCPAckNum(uint32(iss)+1),
-			checker.TCPFlags(header.TCPFlagAck),
-		),
-	)
-}
-
-func TestFinWithPendingDataCwndFull(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateConnected(context.TestInitialSequenceNumber, 30000, -1 /* epRcvBuf */)
-
-	// Write enough segments to fill the congestion window before ACK'ing
-	// any of them.
-	view := make([]byte, 10)
-	var r bytes.Reader
-	for i := tcp.InitialCwnd; i > 0; i-- {
-		r.Reset(view)
-		if _, err := c.EP.Write(&r, tcpip.WriteOptions{}); err != nil {
-			t.Fatalf("Write failed: %s", err)
-		}
-	}
-
-	next := uint32(c.IRS) + 1
-	iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	for i := tcp.InitialCwnd; i > 0; i-- {
-		checker.IPv4(t, c.GetPacket(),
-			checker.PayloadLen(len(view)+header.TCPMinimumSize),
-			checker.TCP(
-				checker.DstPort(context.TestPort),
-				checker.TCPSeqNum(next),
-				checker.TCPAckNum(uint32(iss)),
-				checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
-			),
-		)
-		next += uint32(len(view))
-	}
-
-	// Shutdown the connection, check that the FIN segment isn't sent
-	// because the congestion window doesn't allow it. Wait until a
-	// retransmit is received.
-	if err := c.EP.Shutdown(tcpip.ShutdownWrite); err != nil {
-		t.Fatalf("Shutdown failed: %s", err)
-	}
-
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(len(view)+header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(c.IRS)+1),
-			checker.TCPAckNum(uint32(iss)),
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
-		),
-	)
-
-	// Send the ACK that will allow the FIN to be sent as well.
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss,
-		AckNum:  seqnum.Value(next),
-		RcvWnd:  30000,
-	})
-
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(next),
-			checker.TCPAckNum(uint32(iss)),
-			checker.TCPFlags(header.TCPFlagAck|header.TCPFlagFin),
-		),
-	)
-	next++
-
-	// Send a FIN that acknowledges everything. Get an ACK back.
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck | header.TCPFlagFin,
-		SeqNum:  iss,
-		AckNum:  seqnum.Value(next),
-		RcvWnd:  30000,
-	})
-
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(next),
-			checker.TCPAckNum(uint32(iss)+1),
-			checker.TCPFlags(header.TCPFlagAck),
-		),
-	)
-}
-
-func TestFinWithPendingData(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateConnected(context.TestInitialSequenceNumber, 30000, -1 /* epRcvBuf */)
-
-	// Write something out, and acknowledge it to get cwnd to 2.
-	view := make([]byte, 10)
-	var r bytes.Reader
-	r.Reset(view)
-	if _, err := c.EP.Write(&r, tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %s", err)
-	}
-
-	next := uint32(c.IRS) + 1
-	iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(len(view)+header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(next),
-			checker.TCPAckNum(uint32(iss)),
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
-		),
-	)
-	next += uint32(len(view))
-
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss,
-		AckNum:  seqnum.Value(next),
-		RcvWnd:  30000,
-	})
-
-	// Write new data, but don't acknowledge it.
-	r.Reset(view)
-	if _, err := c.EP.Write(&r, tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %s", err)
-	}
-
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(len(view)+header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(next),
-			checker.TCPAckNum(uint32(iss)),
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
-		),
-	)
-	next += uint32(len(view))
-
-	// Shutdown the connection, check that we do get a FIN.
-	if err := c.EP.Shutdown(tcpip.ShutdownWrite); err != nil {
-		t.Fatalf("Shutdown failed: %s", err)
-	}
-
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(next),
-			checker.TCPAckNum(uint32(iss)),
-			checker.TCPFlags(header.TCPFlagAck|header.TCPFlagFin),
-		),
-	)
-	next++
-
-	// Send a FIN that acknowledges everything. Get an ACK back.
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck | header.TCPFlagFin,
-		SeqNum:  iss,
-		AckNum:  seqnum.Value(next),
-		RcvWnd:  30000,
-	})
-
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(next),
-			checker.TCPAckNum(uint32(iss)+1),
-			checker.TCPFlags(header.TCPFlagAck),
-		),
-	)
-}
-
-func TestFinWithPartialAck(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateConnected(context.TestInitialSequenceNumber, 30000, -1 /* epRcvBuf */)
-
-	// Write something out, and acknowledge it to get cwnd to 2. Also send
-	// FIN from the test side.
-	view := make([]byte, 10)
-	var r bytes.Reader
-	r.Reset(view)
-	if _, err := c.EP.Write(&r, tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %s", err)
-	}
-
-	next := uint32(c.IRS) + 1
-	iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(len(view)+header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(next),
-			checker.TCPAckNum(uint32(iss)),
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
-		),
-	)
-	next += uint32(len(view))
-
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck | header.TCPFlagFin,
-		SeqNum:  iss,
-		AckNum:  seqnum.Value(next),
-		RcvWnd:  30000,
-	})
-
-	// Check that we get an ACK for the fin.
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(next),
-			checker.TCPAckNum(uint32(iss)+1),
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
-		),
-	)
-
-	// Write new data, but don't acknowledge it.
-	r.Reset(view)
-	if _, err := c.EP.Write(&r, tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %s", err)
-	}
-
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(len(view)+header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(next),
-			checker.TCPAckNum(uint32(iss)+1),
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
-		),
-	)
-	next += uint32(len(view))
-
-	// Shutdown the connection, check that we do get a FIN.
-	if err := c.EP.Shutdown(tcpip.ShutdownWrite); err != nil {
-		t.Fatalf("Shutdown failed: %s", err)
-	}
-
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(next),
-			checker.TCPAckNum(uint32(iss)+1),
-			checker.TCPFlags(header.TCPFlagAck|header.TCPFlagFin),
-		),
-	)
-	next++
-
-	// Send an ACK for the data, but not for the FIN yet.
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss.Add(1),
-		AckNum:  seqnum.Value(next - 1),
-		RcvWnd:  30000,
-	})
-
-	// Check that we don't get a retransmit of the FIN.
-	c.CheckNoPacketTimeout("FIN retransmitted when data was ack'd", 100*time.Millisecond)
-
-	// Ack the FIN.
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck | header.TCPFlagFin,
-		SeqNum:  iss.Add(1),
-		AckNum:  seqnum.Value(next),
-		RcvWnd:  30000,
-	})
-}
-
-func TestUpdateListenBacklog(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	// Create listener.
-	var wq waiter.Queue
-	ep, err := c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &wq)
-	if err != nil {
-		t.Fatalf("NewEndpoint failed: %s", err)
-	}
-
-	if err := ep.Bind(tcpip.FullAddress{}); err != nil {
-		t.Fatalf("Bind failed: %s", err)
-	}
-
-	if err := ep.Listen(10); err != nil {
-		t.Fatalf("Listen failed: %s", err)
-	}
-
-	// Update the backlog with another Listen() on the same endpoint.
-	if err := ep.Listen(20); err != nil {
-		t.Fatalf("Listen failed to update backlog: %s", err)
-	}
-
-	ep.Close()
-}
-
-func scaledSendWindow(t *testing.T, scale uint8) {
-	// This test ensures that the endpoint is using the right scaling by
-	// sending a buffer that is larger than the window size, and ensuring
-	// that the endpoint doesn't send more than allowed.
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	maxPayload := defaultMTU - header.IPv4MinimumSize - header.TCPMinimumSize
-	c.CreateConnectedWithRawOptions(context.TestInitialSequenceNumber, 0, -1 /* epRcvBuf */, []byte{
-		header.TCPOptionMSS, 4, byte(maxPayload / 256), byte(maxPayload % 256),
-		header.TCPOptionWS, 3, scale, header.TCPOptionNOP,
-	})
-
-	// Open up the window with a scaled value.
-	iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss,
-		AckNum:  c.IRS.Add(1),
-		RcvWnd:  1,
-	})
-
-	// Send some data. Check that it's capped by the window size.
-	view := make([]byte, 65535)
-	var r bytes.Reader
-	r.Reset(view)
-	if _, err := c.EP.Write(&r, tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %s", err)
-	}
-
-	// Check that only data that fits in the scaled window is sent.
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen((1<<scale)+header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(c.IRS)+1),
-			checker.TCPAckNum(uint32(iss)),
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
-		),
-	)
-
-	// Reset the connection to free resources.
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagRst,
-		SeqNum:  iss,
-	})
-}
-
-func TestScaledSendWindow(t *testing.T) {
-	for scale := uint8(0); scale <= 14; scale++ {
-		scaledSendWindow(t, scale)
-	}
-}
-
-func TestReceivedValidSegmentCountIncrement(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-	c.CreateConnected(context.TestInitialSequenceNumber, 30000, -1 /* epRcvBuf */)
-	stats := c.Stack().Stats()
-	want := stats.TCP.ValidSegmentsReceived.Value() + 1
-
-	iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss,
-		AckNum:  c.IRS.Add(1),
-		RcvWnd:  30000,
-	})
-
-	if got := stats.TCP.ValidSegmentsReceived.Value(); got != want {
-		t.Errorf("got stats.TCP.ValidSegmentsReceived.Value() = %d, want = %d", got, want)
-	}
-	if got := c.EP.Stats().(*tcp.Stats).SegmentsReceived.Value(); got != want {
-		t.Errorf("got EP stats Stats.SegmentsReceived = %d, want = %d", got, want)
-	}
-	// Ensure there were no errors during handshake. If these stats have
-	// incremented, then the connection should not have been established.
-	if got := c.EP.Stats().(*tcp.Stats).SendErrors.NoRoute.Value(); got != 0 {
-		t.Errorf("got EP stats Stats.SendErrors.NoRoute = %d, want = %d", got, 0)
-	}
-}
-
-func TestReceivedInvalidSegmentCountIncrement(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-	c.CreateConnected(context.TestInitialSequenceNumber, 30000, -1 /* epRcvBuf */)
-	stats := c.Stack().Stats()
-	want := stats.TCP.InvalidSegmentsReceived.Value() + 1
-	iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	vv := c.BuildSegment(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  seqnum.Value(iss),
-		AckNum:  c.IRS.Add(1),
-		RcvWnd:  30000,
-	})
-	tcpbuf := vv.ToView()[header.IPv4MinimumSize:]
-	tcpbuf[header.TCPDataOffset] = ((header.TCPMinimumSize - 1) / 4) << 4
-
-	c.SendSegment(vv)
-
-	if got := stats.TCP.InvalidSegmentsReceived.Value(); got != want {
-		t.Errorf("got stats.TCP.InvalidSegmentsReceived.Value() = %d, want = %d", got, want)
-	}
-	if got := c.EP.Stats().(*tcp.Stats).ReceiveErrors.MalformedPacketsReceived.Value(); got != want {
-		t.Errorf("got EP Stats.ReceiveErrors.MalformedPacketsReceived stats = %d, want = %d", got, want)
-	}
-}
-
-func TestReceivedIncorrectChecksumIncrement(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-	c.CreateConnected(context.TestInitialSequenceNumber, 30000, -1 /* epRcvBuf */)
-	stats := c.Stack().Stats()
-	want := stats.TCP.ChecksumErrors.Value() + 1
-	iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	vv := c.BuildSegment([]byte{0x1, 0x2, 0x3}, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss,
-		AckNum:  c.IRS.Add(1),
-		RcvWnd:  30000,
-	})
-	tcpbuf := vv.ToView()[header.IPv4MinimumSize:]
-	// Overwrite a byte in the payload which should cause checksum
-	// verification to fail.
-	tcpbuf[(tcpbuf[header.TCPDataOffset]>>4)*4] = 0x4
-
-	c.SendSegment(vv)
-
-	if got := stats.TCP.ChecksumErrors.Value(); got != want {
-		t.Errorf("got stats.TCP.ChecksumErrors.Value() = %d, want = %d", got, want)
-	}
-	if got := c.EP.Stats().(*tcp.Stats).ReceiveErrors.ChecksumErrors.Value(); got != want {
-		t.Errorf("got EP stats Stats.ReceiveErrors.ChecksumErrors = %d, want = %d", got, want)
-	}
-}
-
-func TestReceivedSegmentQueuing(t *testing.T) {
-	// This test sends 200 segments containing a few bytes each to an
-	// endpoint and checks that they're all received and acknowledged by
-	// the endpoint, that is, that none of the segments are dropped by
-	// internal queues.
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateConnected(context.TestInitialSequenceNumber, 30000, -1 /* epRcvBuf */)
-
-	// Send 200 segments.
-	iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	data := []byte{1, 2, 3}
-	for i := 0; i < 200; i++ {
-		c.SendPacket(data, &context.Headers{
-			SrcPort: context.TestPort,
-			DstPort: c.Port,
-			Flags:   header.TCPFlagAck,
-			SeqNum:  iss.Add(seqnum.Size(i * len(data))),
-			AckNum:  c.IRS.Add(1),
-			RcvWnd:  30000,
-		})
-	}
-
-	// Receive ACKs for all segments.
-	last := iss.Add(seqnum.Size(200 * len(data)))
-	for {
-		b := c.GetPacket()
-		checker.IPv4(t, b,
-			checker.TCP(
-				checker.DstPort(context.TestPort),
-				checker.TCPSeqNum(uint32(c.IRS)+1),
-				checker.TCPFlags(header.TCPFlagAck),
-			),
-		)
-		tcpHdr := header.TCP(header.IPv4(b).Payload())
-		ack := seqnum.Value(tcpHdr.AckNumber())
-		if ack == last {
-			break
-		}
-
-		if last.LessThan(ack) {
-			t.Fatalf("Acknowledge (%v) beyond the expected (%v)", ack, last)
-		}
-	}
-}
-
-func TestReadAfterClosedState(t *testing.T) {
-	// This test ensures that calling Read() or Peek() after the endpoint
-	// has transitioned to closedState still works if there is pending
-	// data. To transition to stateClosed without calling Close(), we must
-	// shutdown the send path and the peer must send its own FIN.
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	// Set TCPTimeWaitTimeout to 1 seconds so that sockets are marked closed
-	// after 1 second in TIME_WAIT state.
-	tcpTimeWaitTimeout := 1 * time.Second
-	opt := tcpip.TCPTimeWaitTimeoutOption(tcpTimeWaitTimeout)
-	if err := c.Stack().SetTransportProtocolOption(tcp.ProtocolNumber, &opt); err != nil {
-		t.Fatalf("SetTransportProtocolOption(%d, &%T(%d)): %s", tcp.ProtocolNumber, opt, opt, err)
-	}
-
-	c.CreateConnected(context.TestInitialSequenceNumber, 30000, -1 /* epRcvBuf */)
-
-	we, ch := waiter.NewChannelEntry(nil)
-	c.WQ.EventRegister(&we, waiter.EventIn)
-	defer c.WQ.EventUnregister(&we)
-
-	ept := endpointTester{c.EP}
-	ept.CheckReadError(t, &tcpip.ErrWouldBlock{})
-
-	// Shutdown immediately for write, check that we get a FIN.
-	if err := c.EP.Shutdown(tcpip.ShutdownWrite); err != nil {
-		t.Fatalf("Shutdown failed: %s", err)
-	}
-
-	iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(c.IRS)+1),
-			checker.TCPAckNum(uint32(iss)),
-			checker.TCPFlags(header.TCPFlagAck|header.TCPFlagFin),
-		),
-	)
-
-	if got, want := tcp.EndpointState(c.EP.State()), tcp.StateFinWait1; got != want {
-		t.Errorf("unexpected endpoint state: want %s, got %s", want, got)
-	}
-
-	// Send some data and acknowledge the FIN.
-	data := []byte{1, 2, 3}
-	c.SendPacket(data, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck | header.TCPFlagFin,
-		SeqNum:  iss,
-		AckNum:  c.IRS.Add(2),
-		RcvWnd:  30000,
-	})
-
-	// Check that ACK is received.
-	checker.IPv4(t, c.GetPacket(),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(c.IRS)+2),
-			checker.TCPAckNum(uint32(iss)+uint32(len(data))+1),
-			checker.TCPFlags(header.TCPFlagAck),
-		),
-	)
-
-	// Give the stack the chance to transition to closed state from
-	// TIME_WAIT.
-	time.Sleep(tcpTimeWaitTimeout * 2)
-
-	if got, want := tcp.EndpointState(c.EP.State()), tcp.StateClose; got != want {
-		t.Errorf("unexpected endpoint state: want %s, got %s", want, got)
-	}
-
-	// Wait for receive to be notified.
-	select {
-	case <-ch:
-	case <-time.After(1 * time.Second):
-		t.Fatalf("Timed out waiting for data to arrive")
-	}
-
-	// Check that peek works.
-	var peekBuf bytes.Buffer
-	res, err := c.EP.Read(&peekBuf, tcpip.ReadOptions{Peek: true})
-	if err != nil {
-		t.Fatalf("Peek failed: %s", err)
-	}
-
-	if got, want := res.Count, len(data); got != want {
-		t.Fatalf("res.Count = %d, want %d", got, want)
-	}
-	if !bytes.Equal(data, peekBuf.Bytes()) {
-		t.Fatalf("got data = %v, want = %v", peekBuf.Bytes(), data)
-	}
-
-	// Receive data.
-	v := ept.CheckRead(t)
-	if !bytes.Equal(data, v) {
-		t.Fatalf("got data = %v, want = %v", v, data)
-	}
-
-	// Now that we drained the queue, check that functions fail with the
-	// right error code.
-	ept.CheckReadError(t, &tcpip.ErrClosedForReceive{})
-	var buf bytes.Buffer
-	{
-		_, err := c.EP.Read(&buf, tcpip.ReadOptions{Peek: true})
-		if _, ok := err.(*tcpip.ErrClosedForReceive); !ok {
-			t.Fatalf("c.EP.Read(_, {Peek: true}) = %v, %s; want _, %s", res, err, &tcpip.ErrClosedForReceive{})
-		}
-	}
-}
-
-func TestReusePort(t *testing.T) {
-	// This test ensures that ports are immediately available for reuse
-	// after Close on the endpoints using them returns.
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	// First case, just an endpoint that was bound.
-	var err tcpip.Error
-	c.EP, err = c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &waiter.Queue{})
-	if err != nil {
-		t.Fatalf("NewEndpoint failed; %s", err)
-	}
-	c.EP.SocketOptions().SetReuseAddress(true)
-	if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %s", err)
-	}
-
-	c.EP.Close()
-	c.EP, err = c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &waiter.Queue{})
-	if err != nil {
-		t.Fatalf("NewEndpoint failed; %s", err)
-	}
-	c.EP.SocketOptions().SetReuseAddress(true)
-	if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %s", err)
-	}
-	c.EP.Close()
-
-	// Second case, an endpoint that was bound and is connecting..
-	c.EP, err = c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &waiter.Queue{})
-	if err != nil {
-		t.Fatalf("NewEndpoint failed; %s", err)
-	}
-	c.EP.SocketOptions().SetReuseAddress(true)
-	if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %s", err)
-	}
-	{
-		err := c.EP.Connect(tcpip.FullAddress{Addr: context.TestAddr, Port: context.TestPort})
-		if _, ok := err.(*tcpip.ErrConnectStarted); !ok {
-			t.Fatalf("got c.EP.Connect(...) = %v, want = %s", err, &tcpip.ErrConnectStarted{})
-		}
-	}
-	c.EP.Close()
-
-	c.EP, err = c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &waiter.Queue{})
-	if err != nil {
-		t.Fatalf("NewEndpoint failed; %s", err)
-	}
-	c.EP.SocketOptions().SetReuseAddress(true)
-	if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %s", err)
-	}
-	c.EP.Close()
-
-	// Third case, an endpoint that was bound and is listening.
-	c.EP, err = c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &waiter.Queue{})
-	if err != nil {
-		t.Fatalf("NewEndpoint failed; %s", err)
-	}
-	c.EP.SocketOptions().SetReuseAddress(true)
-	if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %s", err)
-	}
-	if err := c.EP.Listen(10); err != nil {
-		t.Fatalf("Listen failed: %s", err)
-	}
-	c.EP.Close()
-
-	c.EP, err = c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &waiter.Queue{})
-	if err != nil {
-		t.Fatalf("NewEndpoint failed; %s", err)
-	}
-	c.EP.SocketOptions().SetReuseAddress(true)
-	if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %s", err)
-	}
-	if err := c.EP.Listen(10); err != nil {
-		t.Fatalf("Listen failed: %s", err)
-	}
-}
-
-func checkRecvBufferSize(t *testing.T, ep tcpip.Endpoint, v int) {
-	t.Helper()
-
-	s, err := ep.GetSockOptInt(tcpip.ReceiveBufferSizeOption)
-	if err != nil {
-		t.Fatalf("GetSockOpt failed: %s", err)
-	}
-
-	if int(s) != v {
-		t.Fatalf("got receive buffer size = %d, want = %d", s, v)
-	}
-}
-
-func checkSendBufferSize(t *testing.T, ep tcpip.Endpoint, v int) {
-	t.Helper()
-
-	if s := ep.SocketOptions().GetSendBufferSize(); int(s) != v {
-		t.Fatalf("got send buffer size = %d, want = %d", s, v)
-	}
-}
-
-func TestDefaultBufferSizes(t *testing.T) {
-	s := stack.New(stack.Options{
-		NetworkProtocols:   []stack.NetworkProtocolFactory{ipv4.NewProtocol},
-		TransportProtocols: []stack.TransportProtocolFactory{tcp.NewProtocol},
-	})
-
-	// Check the default values.
-	ep, err := s.NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &waiter.Queue{})
-	if err != nil {
-		t.Fatalf("NewEndpoint failed; %s", err)
-	}
-	defer func() {
-		if ep != nil {
-			ep.Close()
-		}
-	}()
-
-	checkSendBufferSize(t, ep, tcp.DefaultSendBufferSize)
-	checkRecvBufferSize(t, ep, tcp.DefaultReceiveBufferSize)
-
-	// Change the default send buffer size.
-	{
-		opt := tcpip.TCPSendBufferSizeRangeOption{
-			Min:     1,
-			Default: tcp.DefaultSendBufferSize * 2,
-			Max:     tcp.DefaultSendBufferSize * 20,
-		}
-		if err := s.SetTransportProtocolOption(tcp.ProtocolNumber, &opt); err != nil {
-			t.Fatalf("SetTransportProtocolOption(%d, &%#v): %s", tcp.ProtocolNumber, opt, err)
-		}
-	}
-
-	ep.Close()
-	ep, err = s.NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &waiter.Queue{})
-	if err != nil {
-		t.Fatalf("NewEndpoint failed; %s", err)
-	}
-
-	checkSendBufferSize(t, ep, tcp.DefaultSendBufferSize*2)
-	checkRecvBufferSize(t, ep, tcp.DefaultReceiveBufferSize)
-
-	// Change the default receive buffer size.
-	{
-		opt := tcpip.TCPReceiveBufferSizeRangeOption{
-			Min:     1,
-			Default: tcp.DefaultReceiveBufferSize * 3,
-			Max:     tcp.DefaultReceiveBufferSize * 30,
-		}
-		if err := s.SetTransportProtocolOption(tcp.ProtocolNumber, &opt); err != nil {
-			t.Fatalf("SetTransportProtocolOption(%d, &%#v): %s", tcp.ProtocolNumber, opt, err)
-		}
-	}
-
-	ep.Close()
-	ep, err = s.NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &waiter.Queue{})
-	if err != nil {
-		t.Fatalf("NewEndpoint failed; %s", err)
-	}
-
-	checkSendBufferSize(t, ep, tcp.DefaultSendBufferSize*2)
-	checkRecvBufferSize(t, ep, tcp.DefaultReceiveBufferSize*3)
-}
-
-func TestMinMaxBufferSizes(t *testing.T) {
-	s := stack.New(stack.Options{
-		NetworkProtocols:   []stack.NetworkProtocolFactory{ipv4.NewProtocol},
-		TransportProtocols: []stack.TransportProtocolFactory{tcp.NewProtocol},
-	})
-
-	// Check the default values.
-	ep, err := s.NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &waiter.Queue{})
-	if err != nil {
-		t.Fatalf("NewEndpoint failed; %s", err)
-	}
-	defer ep.Close()
-
-	// Change the min/max values for send/receive
-	{
-		opt := tcpip.TCPReceiveBufferSizeRangeOption{Min: 200, Default: tcp.DefaultReceiveBufferSize * 2, Max: tcp.DefaultReceiveBufferSize * 20}
-		if err := s.SetTransportProtocolOption(tcp.ProtocolNumber, &opt); err != nil {
-			t.Fatalf("SetTransportProtocolOption(%d, &%#v): %s", tcp.ProtocolNumber, opt, err)
-		}
-	}
-
-	{
-		opt := tcpip.TCPSendBufferSizeRangeOption{Min: 300, Default: tcp.DefaultSendBufferSize * 3, Max: tcp.DefaultSendBufferSize * 30}
-		if err := s.SetTransportProtocolOption(tcp.ProtocolNumber, &opt); err != nil {
-			t.Fatalf("SetTransportProtocolOption(%d, &%#v): %s", tcp.ProtocolNumber, opt, err)
-		}
-	}
-
-	// Set values below the min/2.
-	if err := ep.SetSockOptInt(tcpip.ReceiveBufferSizeOption, 99); err != nil {
-		t.Fatalf("SetSockOptInt(ReceiveBufferSizeOption, 199) failed: %s", err)
-	}
-
-	checkRecvBufferSize(t, ep, 200)
-
-	ep.SocketOptions().SetSendBufferSize(149, true)
-
-	checkSendBufferSize(t, ep, 300)
-
-	// Set values above the max.
-	if err := ep.SetSockOptInt(tcpip.ReceiveBufferSizeOption, 1+tcp.DefaultReceiveBufferSize*20); err != nil {
-		t.Fatalf("SetSockOptInt(ReceiveBufferSizeOption) failed: %s", err)
-	}
-
-	// Values above max are capped at max and then doubled.
-	checkRecvBufferSize(t, ep, tcp.DefaultReceiveBufferSize*20*2)
-
-	ep.SocketOptions().SetSendBufferSize(1+tcp.DefaultSendBufferSize*30, true)
-
-	// Values above max are capped at max and then doubled.
-	checkSendBufferSize(t, ep, tcp.DefaultSendBufferSize*30*2)
-}
-
-func TestBindToDeviceOption(t *testing.T) {
-	s := stack.New(stack.Options{
-		NetworkProtocols:   []stack.NetworkProtocolFactory{ipv4.NewProtocol},
-		TransportProtocols: []stack.TransportProtocolFactory{tcp.NewProtocol}})
-
-	ep, err := s.NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &waiter.Queue{})
-	if err != nil {
-		t.Fatalf("NewEndpoint failed; %s", err)
-	}
-	defer ep.Close()
-
-	if err := s.CreateNIC(321, loopback.New()); err != nil {
-		t.Errorf("CreateNIC failed: %s", err)
-	}
-
-	// nicIDPtr is used instead of taking the address of NICID literals, which is
-	// a compiler error.
-	nicIDPtr := func(s tcpip.NICID) *tcpip.NICID {
-		return &s
-	}
-
-	testActions := []struct {
-		name                 string
-		setBindToDevice      *tcpip.NICID
-		setBindToDeviceError tcpip.Error
-		getBindToDevice      int32
-	}{
-		{"GetDefaultValue", nil, nil, 0},
-		{"BindToNonExistent", nicIDPtr(999), &tcpip.ErrUnknownDevice{}, 0},
-		{"BindToExistent", nicIDPtr(321), nil, 321},
-		{"UnbindToDevice", nicIDPtr(0), nil, 0},
-	}
-	for _, testAction := range testActions {
-		t.Run(testAction.name, func(t *testing.T) {
-			if testAction.setBindToDevice != nil {
-				bindToDevice := int32(*testAction.setBindToDevice)
-				if gotErr, wantErr := ep.SocketOptions().SetBindToDevice(bindToDevice), testAction.setBindToDeviceError; gotErr != wantErr {
-					t.Errorf("got SetSockOpt(&%T(%d)) = %s, want = %s", bindToDevice, bindToDevice, gotErr, wantErr)
-				}
-			}
-			bindToDevice := ep.SocketOptions().GetBindToDevice()
-			if bindToDevice != testAction.getBindToDevice {
-				t.Errorf("got bindToDevice = %d, want %d", bindToDevice, testAction.getBindToDevice)
-			}
-		})
-	}
-}
-
-func makeStack() (*stack.Stack, tcpip.Error) {
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocolFactory{
-			ipv4.NewProtocol,
-			ipv6.NewProtocol,
-		},
-		TransportProtocols: []stack.TransportProtocolFactory{tcp.NewProtocol},
-	})
-
-	id := loopback.New()
-	if testing.Verbose() {
-		id = sniffer.New(id)
-	}
-
-	if err := s.CreateNIC(1, id); err != nil {
-		return nil, err
-	}
-
-	for _, ct := range []struct {
-		number  tcpip.NetworkProtocolNumber
-		address tcpip.Address
-	}{
-		{ipv4.ProtocolNumber, context.StackAddr},
-		{ipv6.ProtocolNumber, context.StackV6Addr},
-	} {
-		if err := s.AddAddress(1, ct.number, ct.address); err != nil {
-			return nil, err
-		}
-	}
-
-	s.SetRouteTable([]tcpip.Route{
-		{
-			Destination: header.IPv4EmptySubnet,
-			NIC:         1,
-		},
-		{
-			Destination: header.IPv6EmptySubnet,
-			NIC:         1,
-		},
-	})
-
-	return s, nil
-}
-
-func TestSelfConnect(t *testing.T) {
-	// This test ensures that intentional self-connects work. In particular,
-	// it checks that if an endpoint binds to say 127.0.0.1:1000 then
-	// connects to 127.0.0.1:1000, then it will be connected to itself, and
-	// is able to send and receive data through the same endpoint.
-	s, err := makeStack()
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	var wq waiter.Queue
-	ep, err := s.NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &wq)
-	if err != nil {
-		t.Fatalf("NewEndpoint failed: %s", err)
-	}
-	defer ep.Close()
-
-	if err := ep.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %s", err)
-	}
-
-	// Register for notification, then start connection attempt.
-	waitEntry, notifyCh := waiter.NewChannelEntry(nil)
-	wq.EventRegister(&waitEntry, waiter.EventOut)
-	defer wq.EventUnregister(&waitEntry)
-
-	{
-		err := ep.Connect(tcpip.FullAddress{Addr: context.StackAddr, Port: context.StackPort})
-		if _, ok := err.(*tcpip.ErrConnectStarted); !ok {
-			t.Fatalf("got ep.Connect(...) = %v, want = %s", err, &tcpip.ErrConnectStarted{})
-		}
-	}
-
-	<-notifyCh
-	if err := ep.LastError(); err != nil {
-		t.Fatalf("Connect failed: %s", err)
-	}
-
-	// Write something.
-	data := []byte{1, 2, 3}
-	var r bytes.Reader
-	r.Reset(data)
-	if _, err := ep.Write(&r, tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %s", err)
-	}
-
-	// Read back what was written.
-	wq.EventUnregister(&waitEntry)
-	wq.EventRegister(&waitEntry, waiter.EventIn)
-	ept := endpointTester{ep}
-	rd := ept.CheckReadFull(t, len(data), notifyCh, 5*time.Second)
-
-	if !bytes.Equal(data, rd) {
-		t.Fatalf("got data = %v, want = %v", rd, data)
-	}
-}
-
-func TestConnectAvoidsBoundPorts(t *testing.T) {
-	addressTypes := func(t *testing.T, network string) []string {
-		switch network {
-		case "ipv4":
-			return []string{"v4"}
-		case "ipv6":
-			return []string{"v6"}
-		case "dual":
-			return []string{"v6", "mapped"}
-		default:
-			t.Fatalf("unknown network: '%s'", network)
-		}
-
-		panic("unreachable")
-	}
-
-	address := func(t *testing.T, addressType string, isAny bool) tcpip.Address {
-		switch addressType {
-		case "v4":
-			if isAny {
-				return ""
-			}
-			return context.StackAddr
-		case "v6":
-			if isAny {
-				return ""
-			}
-			return context.StackV6Addr
-		case "mapped":
-			if isAny {
-				return context.V4MappedWildcardAddr
-			}
-			return context.StackV4MappedAddr
-		default:
-			t.Fatalf("unknown address type: '%s'", addressType)
-		}
-
-		panic("unreachable")
-	}
-	// This test ensures that Endpoint.Connect doesn't select already-bound ports.
-	networks := []string{"ipv4", "ipv6", "dual"}
-	for _, exhaustedNetwork := range networks {
-		t.Run(fmt.Sprintf("exhaustedNetwork=%s", exhaustedNetwork), func(t *testing.T) {
-			for _, exhaustedAddressType := range addressTypes(t, exhaustedNetwork) {
-				t.Run(fmt.Sprintf("exhaustedAddressType=%s", exhaustedAddressType), func(t *testing.T) {
-					for _, isAny := range []bool{false, true} {
-						t.Run(fmt.Sprintf("isAny=%t", isAny), func(t *testing.T) {
-							for _, candidateNetwork := range networks {
-								t.Run(fmt.Sprintf("candidateNetwork=%s", candidateNetwork), func(t *testing.T) {
-									for _, candidateAddressType := range addressTypes(t, candidateNetwork) {
-										t.Run(fmt.Sprintf("candidateAddressType=%s", candidateAddressType), func(t *testing.T) {
-											s, err := makeStack()
-											if err != nil {
-												t.Fatal(err)
-											}
-
-											var wq waiter.Queue
-											var eps []tcpip.Endpoint
-											defer func() {
-												for _, ep := range eps {
-													ep.Close()
-												}
-											}()
-											makeEP := func(network string) tcpip.Endpoint {
-												var networkProtocolNumber tcpip.NetworkProtocolNumber
-												switch network {
-												case "ipv4":
-													networkProtocolNumber = ipv4.ProtocolNumber
-												case "ipv6", "dual":
-													networkProtocolNumber = ipv6.ProtocolNumber
-												default:
-													t.Fatalf("unknown network: '%s'", network)
-												}
-												ep, err := s.NewEndpoint(tcp.ProtocolNumber, networkProtocolNumber, &wq)
-												if err != nil {
-													t.Fatalf("NewEndpoint failed: %s", err)
-												}
-												eps = append(eps, ep)
-												switch network {
-												case "ipv4":
-												case "ipv6":
-													ep.SocketOptions().SetV6Only(true)
-												case "dual":
-													ep.SocketOptions().SetV6Only(false)
-												default:
-													t.Fatalf("unknown network: '%s'", network)
-												}
-												return ep
-											}
-
-											var v4reserved, v6reserved bool
-											switch exhaustedAddressType {
-											case "v4", "mapped":
-												v4reserved = true
-											case "v6":
-												v6reserved = true
-												// Dual stack sockets bound to v6 any reserve on v4 as
-												// well.
-												if isAny {
-													switch exhaustedNetwork {
-													case "ipv6":
-													case "dual":
-														v4reserved = true
-													default:
-														t.Fatalf("unknown address type: '%s'", exhaustedNetwork)
-													}
-												}
-											default:
-												t.Fatalf("unknown address type: '%s'", exhaustedAddressType)
-											}
-											var collides bool
-											switch candidateAddressType {
-											case "v4", "mapped":
-												collides = v4reserved
-											case "v6":
-												collides = v6reserved
-											default:
-												t.Fatalf("unknown address type: '%s'", candidateAddressType)
-											}
-
-											start, end := s.PortRange()
-											for i := start; i <= end; i++ {
-												if makeEP(exhaustedNetwork).Bind(tcpip.FullAddress{Addr: address(t, exhaustedAddressType, isAny), Port: uint16(i)}); err != nil {
-													t.Fatalf("Bind(%d) failed: %s", i, err)
-												}
-											}
-											var want tcpip.Error = &tcpip.ErrConnectStarted{}
-											if collides {
-												want = &tcpip.ErrNoPortAvailable{}
-											}
-											if err := makeEP(candidateNetwork).Connect(tcpip.FullAddress{Addr: address(t, candidateAddressType, false), Port: 31337}); err != want {
-												t.Fatalf("got ep.Connect(..) = %s, want = %s", err, want)
-											}
-										})
-									}
-								})
-							}
-						})
-					}
-				})
-			}
-		})
-	}
-}
-
-func TestPathMTUDiscovery(t *testing.T) {
-	// This test verifies the stack retransmits packets after it receives an
-	// ICMP packet indicating that the path MTU has been exceeded.
-	c := context.New(t, 1500)
-	defer c.Cleanup()
-
-	// Create new connection with MSS of 1460.
-	const maxPayload = 1500 - header.TCPMinimumSize - header.IPv4MinimumSize
-	c.CreateConnectedWithRawOptions(context.TestInitialSequenceNumber, 30000, -1 /* epRcvBuf */, []byte{
-		header.TCPOptionMSS, 4, byte(maxPayload / 256), byte(maxPayload % 256),
-	})
-
-	// Send 3200 bytes of data.
-	const writeSize = 3200
-	data := make([]byte, writeSize)
-	for i := range data {
-		data[i] = byte(i)
-	}
-	var r bytes.Reader
-	r.Reset(data)
-	if _, err := c.EP.Write(&r, tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %s", err)
-	}
-
-	receivePackets := func(c *context.Context, sizes []int, which int, seqNum uint32) []byte {
-		var ret []byte
-		iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-		for i, size := range sizes {
-			p := c.GetPacket()
-			if i == which {
-				ret = p
-			}
-			checker.IPv4(t, p,
-				checker.PayloadLen(size+header.TCPMinimumSize),
-				checker.TCP(
-					checker.DstPort(context.TestPort),
-					checker.TCPSeqNum(seqNum),
-					checker.TCPAckNum(uint32(iss)),
-					checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
-				),
-			)
-			seqNum += uint32(size)
-		}
-		return ret
-	}
-
-	// Receive three packets.
-	sizes := []int{maxPayload, maxPayload, writeSize - 2*maxPayload}
-	first := receivePackets(c, sizes, 0, uint32(c.IRS)+1)
-
-	// Send "packet too big" messages back to netstack.
-	const newMTU = 1200
-	const newMaxPayload = newMTU - header.IPv4MinimumSize - header.TCPMinimumSize
-	mtu := []byte{0, 0, newMTU / 256, newMTU % 256}
-	c.SendICMPPacket(header.ICMPv4DstUnreachable, header.ICMPv4FragmentationNeeded, mtu, first, newMTU)
-
-	// See retransmitted packets. None exceeding the new max.
-	sizes = []int{newMaxPayload, maxPayload - newMaxPayload, newMaxPayload, maxPayload - newMaxPayload, writeSize - 2*maxPayload}
-	receivePackets(c, sizes, -1, uint32(c.IRS)+1)
-}
-
-func TestTCPEndpointProbe(t *testing.T) {
-	c := context.New(t, 1500)
-	defer c.Cleanup()
-
-	invoked := make(chan struct{})
-	c.Stack().AddTCPProbe(func(state stack.TCPEndpointState) {
-		// Validate that the endpoint ID is what we expect.
-		//
-		// We don't do an extensive validation of every field but a
-		// basic sanity test.
-		if got, want := state.ID.LocalAddress, tcpip.Address(context.StackAddr); got != want {
-			t.Fatalf("got LocalAddress: %q, want: %q", got, want)
-		}
-		if got, want := state.ID.LocalPort, c.Port; got != want {
-			t.Fatalf("got LocalPort: %d, want: %d", got, want)
-		}
-		if got, want := state.ID.RemoteAddress, tcpip.Address(context.TestAddr); got != want {
-			t.Fatalf("got RemoteAddress: %q, want: %q", got, want)
-		}
-		if got, want := state.ID.RemotePort, uint16(context.TestPort); got != want {
-			t.Fatalf("got RemotePort: %d, want: %d", got, want)
-		}
-
-		invoked <- struct{}{}
-	})
-
-	c.CreateConnected(context.TestInitialSequenceNumber, 30000, -1 /* epRcvBuf */)
-
-	data := []byte{1, 2, 3}
-	iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	c.SendPacket(data, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss,
-		AckNum:  c.IRS.Add(1),
-		RcvWnd:  30000,
-	})
-
-	select {
-	case <-invoked:
-	case <-time.After(100 * time.Millisecond):
-		t.Fatalf("TCP Probe function was not called")
-	}
-}
-
-func TestStackSetCongestionControl(t *testing.T) {
-	testCases := []struct {
-		cc  tcpip.CongestionControlOption
-		err tcpip.Error
-	}{
-		{"reno", nil},
-		{"cubic", nil},
-		{"blahblah", &tcpip.ErrNoSuchFile{}},
-	}
-
-	for _, tc := range testCases {
-		t.Run(fmt.Sprintf("SetTransportProtocolOption(.., %v)", tc.cc), func(t *testing.T) {
-			c := context.New(t, 1500)
-			defer c.Cleanup()
-
-			s := c.Stack()
-
-			var oldCC tcpip.CongestionControlOption
-			if err := s.TransportProtocolOption(tcp.ProtocolNumber, &oldCC); err != nil {
-				t.Fatalf("s.TransportProtocolOption(%v, %v) = %s", tcp.ProtocolNumber, &oldCC, err)
-			}
-
-			if err := s.SetTransportProtocolOption(tcp.ProtocolNumber, &tc.cc); err != tc.err {
-				t.Fatalf("s.SetTransportProtocolOption(%d, &%T(%s)) = %s, want = %s", tcp.ProtocolNumber, tc.cc, tc.cc, err, tc.err)
-			}
-
-			var cc tcpip.CongestionControlOption
-			if err := s.TransportProtocolOption(tcp.ProtocolNumber, &cc); err != nil {
-				t.Fatalf("s.TransportProtocolOption(%v, %v) = %v", tcp.ProtocolNumber, &cc, err)
-			}
-
-			got, want := cc, oldCC
-			// If SetTransportProtocolOption is expected to succeed
-			// then the returned value for congestion control should
-			// match the one specified in the
-			// SetTransportProtocolOption call above, else it should
-			// be what it was before the call to
-			// SetTransportProtocolOption.
-			if tc.err == nil {
-				want = tc.cc
-			}
-			if got != want {
-				t.Fatalf("got congestion control: %v, want: %v", got, want)
-			}
-		})
-	}
-}
-
-func TestStackAvailableCongestionControl(t *testing.T) {
-	c := context.New(t, 1500)
-	defer c.Cleanup()
-
-	s := c.Stack()
-
-	// Query permitted congestion control algorithms.
-	var aCC tcpip.TCPAvailableCongestionControlOption
-	if err := s.TransportProtocolOption(tcp.ProtocolNumber, &aCC); err != nil {
-		t.Fatalf("s.TransportProtocolOption(%v, %v) = %v", tcp.ProtocolNumber, &aCC, err)
-	}
-	if got, want := aCC, tcpip.TCPAvailableCongestionControlOption("reno cubic"); got != want {
-		t.Fatalf("got tcpip.TCPAvailableCongestionControlOption: %v, want: %v", got, want)
-	}
-}
-
-func TestStackSetAvailableCongestionControl(t *testing.T) {
-	c := context.New(t, 1500)
-	defer c.Cleanup()
-
-	s := c.Stack()
-
-	// Setting AvailableCongestionControlOption should fail.
-	aCC := tcpip.TCPAvailableCongestionControlOption("xyz")
-	if err := s.SetTransportProtocolOption(tcp.ProtocolNumber, &aCC); err == nil {
-		t.Fatalf("s.SetTransportProtocolOption(%d, &%T(%s)) = nil, want non-nil", tcp.ProtocolNumber, aCC, aCC)
-	}
-
-	// Verify that we still get the expected list of congestion control options.
-	var cc tcpip.TCPAvailableCongestionControlOption
-	if err := s.TransportProtocolOption(tcp.ProtocolNumber, &cc); err != nil {
-		t.Fatalf("s.TransportProtocolOptio(%d, &%T(%s)): %s", tcp.ProtocolNumber, cc, cc, err)
-	}
-	if got, want := cc, tcpip.TCPAvailableCongestionControlOption("reno cubic"); got != want {
-		t.Fatalf("got tcpip.TCPAvailableCongestionControlOption = %s, want = %s", got, want)
-	}
-}
-
-func TestEndpointSetCongestionControl(t *testing.T) {
-	testCases := []struct {
-		cc  tcpip.CongestionControlOption
-		err tcpip.Error
-	}{
-		{"reno", nil},
-		{"cubic", nil},
-		{"blahblah", &tcpip.ErrNoSuchFile{}},
-	}
-
-	for _, connected := range []bool{false, true} {
-		for _, tc := range testCases {
-			t.Run(fmt.Sprintf("SetSockOpt(.., %v) w/ connected = %v", tc.cc, connected), func(t *testing.T) {
-				c := context.New(t, 1500)
-				defer c.Cleanup()
-
-				// Create TCP endpoint.
-				var err tcpip.Error
-				c.EP, err = c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &c.WQ)
-				if err != nil {
-					t.Fatalf("NewEndpoint failed: %s", err)
-				}
-
-				var oldCC tcpip.CongestionControlOption
-				if err := c.EP.GetSockOpt(&oldCC); err != nil {
-					t.Fatalf("c.EP.GetSockOpt(&%T) = %s", oldCC, err)
-				}
-
-				if connected {
-					c.Connect(context.TestInitialSequenceNumber, 32768 /* rcvWnd */, nil)
-				}
-
-				if err := c.EP.SetSockOpt(&tc.cc); err != tc.err {
-					t.Fatalf("got c.EP.SetSockOpt(&%#v) = %s, want %s", tc.cc, err, tc.err)
-				}
-
-				var cc tcpip.CongestionControlOption
-				if err := c.EP.GetSockOpt(&cc); err != nil {
-					t.Fatalf("c.EP.GetSockOpt(&%T): %s", cc, err)
-				}
-
-				got, want := cc, oldCC
-				// If SetSockOpt is expected to succeed then the
-				// returned value for congestion control should match
-				// the one specified in the SetSockOpt above, else it
-				// should be what it was before the call to SetSockOpt.
-				if tc.err == nil {
-					want = tc.cc
-				}
-				if got != want {
-					t.Fatalf("got congestion control = %+v, want = %+v", got, want)
-				}
-			})
-		}
-	}
-}
-
-func enableCUBIC(t *testing.T, c *context.Context) {
-	t.Helper()
-	opt := tcpip.CongestionControlOption("cubic")
-	if err := c.Stack().SetTransportProtocolOption(tcp.ProtocolNumber, &opt); err != nil {
-		t.Fatalf("SetTransportProtocolOption(%d, &%T(%s)) %s", tcp.ProtocolNumber, opt, opt, err)
-	}
-}
-
-func TestKeepalive(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateConnected(context.TestInitialSequenceNumber, 30000, -1 /* epRcvBuf */)
-
-	const keepAliveIdle = 100 * time.Millisecond
-	const keepAliveInterval = 3 * time.Second
-	keepAliveIdleOpt := tcpip.KeepaliveIdleOption(keepAliveIdle)
-	if err := c.EP.SetSockOpt(&keepAliveIdleOpt); err != nil {
-		t.Fatalf("c.EP.SetSockOpt(&%T(%s)): %s", keepAliveIdleOpt, keepAliveIdle, err)
-	}
-	keepAliveIntervalOpt := tcpip.KeepaliveIntervalOption(keepAliveInterval)
-	if err := c.EP.SetSockOpt(&keepAliveIntervalOpt); err != nil {
-		t.Fatalf("c.EP.SetSockOpt(&%T(%s)): %s", keepAliveIntervalOpt, keepAliveInterval, err)
-	}
-	c.EP.SetSockOptInt(tcpip.KeepaliveCountOption, 5)
-	if err := c.EP.SetSockOptInt(tcpip.KeepaliveCountOption, 5); err != nil {
-		t.Fatalf("c.EP.SetSockOptInt(tcpip.KeepaliveCountOption, 5): %s", err)
-	}
-	c.EP.SocketOptions().SetKeepAlive(true)
-
-	// 5 unacked keepalives are sent. ACK each one, and check that the
-	// connection stays alive after 5.
-	iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	for i := 0; i < 10; i++ {
-		b := c.GetPacket()
-		checker.IPv4(t, b,
-			checker.TCP(
-				checker.DstPort(context.TestPort),
-				checker.TCPSeqNum(uint32(c.IRS)),
-				checker.TCPAckNum(uint32(iss)),
-				checker.TCPFlags(header.TCPFlagAck),
-			),
-		)
-
-		// Acknowledge the keepalive.
-		c.SendPacket(nil, &context.Headers{
-			SrcPort: context.TestPort,
-			DstPort: c.Port,
-			Flags:   header.TCPFlagAck,
-			SeqNum:  iss,
-			AckNum:  c.IRS,
-			RcvWnd:  30000,
-		})
-	}
-
-	// Check that the connection is still alive.
-	ept := endpointTester{c.EP}
-	ept.CheckReadError(t, &tcpip.ErrWouldBlock{})
-
-	// Send some data and wait before ACKing it. Keepalives should be disabled
-	// during this period.
-	view := make([]byte, 3)
-	var r bytes.Reader
-	r.Reset(view)
-	if _, err := c.EP.Write(&r, tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %s", err)
-	}
-
-	next := uint32(c.IRS) + 1
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(len(view)+header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(next),
-			checker.TCPAckNum(uint32(iss)),
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
-		),
-	)
-
-	// Wait for the packet to be retransmitted. Verify that no keepalives
-	// were sent.
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(len(view)+header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(next),
-			checker.TCPAckNum(uint32(iss)),
-			checker.TCPFlags(header.TCPFlagAck|header.TCPFlagPsh),
-		),
-	)
-	c.CheckNoPacket("Keepalive packet received while unACKed data is pending")
-
-	next += uint32(len(view))
-
-	// Send ACK. Keepalives should start sending again.
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss,
-		AckNum:  seqnum.Value(next),
-		RcvWnd:  30000,
-	})
-
-	// Now receive 5 keepalives, but don't ACK them. The connection
-	// should be reset after 5.
-	for i := 0; i < 5; i++ {
-		b := c.GetPacket()
-		checker.IPv4(t, b,
-			checker.TCP(
-				checker.DstPort(context.TestPort),
-				checker.TCPSeqNum(uint32(next-1)),
-				checker.TCPAckNum(uint32(iss)),
-				checker.TCPFlags(header.TCPFlagAck),
-			),
-		)
-	}
-
-	// Sleep for a litte over the KeepAlive interval to make sure
-	// the timer has time to fire after the last ACK and close the
-	// close the socket.
-	time.Sleep(keepAliveInterval + keepAliveInterval/2)
-
-	// The connection should be terminated after 5 unacked keepalives.
-	// Send an ACK to trigger a RST from the stack as the endpoint should
-	// be dead.
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss,
-		AckNum:  seqnum.Value(next),
-		RcvWnd:  30000,
-	})
-
-	checker.IPv4(t, c.GetPacket(),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(next)),
-			checker.TCPAckNum(uint32(0)),
-			checker.TCPFlags(header.TCPFlagRst),
-		),
-	)
-
-	if got := c.Stack().Stats().TCP.EstablishedTimedout.Value(); got != 1 {
-		t.Errorf("got c.Stack().Stats().TCP.EstablishedTimedout.Value() = %d, want = 1", got)
-	}
-
-	ept.CheckReadError(t, &tcpip.ErrTimeout{})
-
-	if got := c.Stack().Stats().TCP.CurrentEstablished.Value(); got != 0 {
-		t.Errorf("got stats.TCP.CurrentEstablished.Value() = %d, want = 0", got)
-	}
-	if got := c.Stack().Stats().TCP.CurrentConnected.Value(); got != 0 {
-		t.Errorf("got stats.TCP.CurrentConnected.Value() = %d, want = 0", got)
-	}
-}
-
-func executeHandshake(t *testing.T, c *context.Context, srcPort uint16, synCookieInUse bool) (irs, iss seqnum.Value) {
-	t.Helper()
-	// Send a SYN request.
-	irs = seqnum.Value(context.TestInitialSequenceNumber)
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: srcPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagSyn,
-		SeqNum:  irs,
-		RcvWnd:  30000,
-	})
-
-	// Receive the SYN-ACK reply.
-	b := c.GetPacket()
-	tcp := header.TCP(header.IPv4(b).Payload())
-	iss = seqnum.Value(tcp.SequenceNumber())
-	tcpCheckers := []checker.TransportChecker{
-		checker.SrcPort(context.StackPort),
-		checker.DstPort(srcPort),
-		checker.TCPFlags(header.TCPFlagAck | header.TCPFlagSyn),
-		checker.TCPAckNum(uint32(irs) + 1),
-	}
-
-	if synCookieInUse {
-		// When cookies are in use window scaling is disabled.
-		tcpCheckers = append(tcpCheckers, checker.TCPSynOptions(header.TCPSynOptions{
-			WS:  -1,
-			MSS: c.MSSWithoutOptions(),
-		}))
-	}
-
-	checker.IPv4(t, b, checker.TCP(tcpCheckers...))
-
-	// Send ACK.
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: srcPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  irs + 1,
-		AckNum:  iss + 1,
-		RcvWnd:  30000,
-	})
-	return irs, iss
-}
-
-func executeV6Handshake(t *testing.T, c *context.Context, srcPort uint16, synCookieInUse bool) (irs, iss seqnum.Value) {
-	t.Helper()
-	// Send a SYN request.
-	irs = seqnum.Value(context.TestInitialSequenceNumber)
-	c.SendV6Packet(nil, &context.Headers{
-		SrcPort: srcPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagSyn,
-		SeqNum:  irs,
-		RcvWnd:  30000,
-	})
-
-	// Receive the SYN-ACK reply.
-	b := c.GetV6Packet()
-	tcp := header.TCP(header.IPv6(b).Payload())
-	iss = seqnum.Value(tcp.SequenceNumber())
-	tcpCheckers := []checker.TransportChecker{
-		checker.SrcPort(context.StackPort),
-		checker.DstPort(srcPort),
-		checker.TCPFlags(header.TCPFlagAck | header.TCPFlagSyn),
-		checker.TCPAckNum(uint32(irs) + 1),
-	}
-
-	if synCookieInUse {
-		// When cookies are in use window scaling is disabled.
-		tcpCheckers = append(tcpCheckers, checker.TCPSynOptions(header.TCPSynOptions{
-			WS:  -1,
-			MSS: c.MSSWithoutOptionsV6(),
-		}))
-	}
-
-	checker.IPv6(t, b, checker.TCP(tcpCheckers...))
-
-	// Send ACK.
-	c.SendV6Packet(nil, &context.Headers{
-		SrcPort: srcPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  irs + 1,
-		AckNum:  iss + 1,
-		RcvWnd:  30000,
-	})
-	return irs, iss
-}
-
-// TestListenBacklogFull tests that netstack does not complete handshakes if the
-// listen backlog for the endpoint is full.
-func TestListenBacklogFull(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	// Create TCP endpoint.
-	var err tcpip.Error
-	c.EP, err = c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &c.WQ)
-	if err != nil {
-		t.Fatalf("NewEndpoint failed: %s", err)
-	}
-
-	// Bind to wildcard.
-	if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %s", err)
-	}
-
-	// Test acceptance.
-	// Start listening.
-	listenBacklog := 10
-	if err := c.EP.Listen(listenBacklog); err != nil {
-		t.Fatalf("Listen failed: %s", err)
-	}
-
-	lastPortOffset := uint16(0)
-	for ; int(lastPortOffset) < listenBacklog; lastPortOffset++ {
-		executeHandshake(t, c, context.TestPort+lastPortOffset, false /*synCookieInUse */)
-	}
-
-	time.Sleep(50 * time.Millisecond)
-
-	// Now execute send one more SYN. The stack should not respond as the backlog
-	// is full at this point.
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort + uint16(lastPortOffset),
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagSyn,
-		SeqNum:  seqnum.Value(context.TestInitialSequenceNumber),
-		RcvWnd:  30000,
-	})
-	c.CheckNoPacketTimeout("unexpected packet received", 50*time.Millisecond)
-
-	// Try to accept the connections in the backlog.
-	we, ch := waiter.NewChannelEntry(nil)
-	c.WQ.EventRegister(&we, waiter.EventIn)
-	defer c.WQ.EventUnregister(&we)
-
-	for i := 0; i < listenBacklog; i++ {
-		_, _, err = c.EP.Accept(nil)
-		if _, ok := err.(*tcpip.ErrWouldBlock); ok {
-			// Wait for connection to be established.
-			select {
-			case <-ch:
-				_, _, err = c.EP.Accept(nil)
-				if err != nil {
-					t.Fatalf("Accept failed: %s", err)
-				}
-
-			case <-time.After(1 * time.Second):
-				t.Fatalf("Timed out waiting for accept")
-			}
-		}
-	}
-
-	// Now verify that there are no more connections that can be accepted.
-	_, _, err = c.EP.Accept(nil)
-	if _, ok := err.(*tcpip.ErrWouldBlock); !ok {
-		select {
-		case <-ch:
-			t.Fatalf("unexpected endpoint delivered on Accept: %+v", c.EP)
-		case <-time.After(1 * time.Second):
-		}
-	}
-
-	// Now a new handshake must succeed.
-	executeHandshake(t, c, context.TestPort+lastPortOffset, false /*synCookieInUse */)
-
-	newEP, _, err := c.EP.Accept(nil)
-	if _, ok := err.(*tcpip.ErrWouldBlock); ok {
-		// Wait for connection to be established.
-		select {
-		case <-ch:
-			newEP, _, err = c.EP.Accept(nil)
-			if err != nil {
-				t.Fatalf("Accept failed: %s", err)
-			}
-
-		case <-time.After(1 * time.Second):
-			t.Fatalf("Timed out waiting for accept")
-		}
-	}
-
-	// Now verify that the TCP socket is usable and in a connected state.
-	data := "Don't panic"
-	var r strings.Reader
-	r.Reset(data)
-	newEP.Write(&r, tcpip.WriteOptions{})
-	b := c.GetPacket()
-	tcp := header.TCP(header.IPv4(b).Payload())
-	if string(tcp.Payload()) != data {
-		t.Fatalf("unexpected data: got %s, want %s", string(tcp.Payload()), data)
-	}
-}
-
-// TestListenNoAcceptMulticastBroadcastV4 makes sure that TCP segments with a
-// non unicast IPv4 address are not accepted.
-func TestListenNoAcceptNonUnicastV4(t *testing.T) {
-	multicastAddr := tcpip.Address("\xe0\x00\x01\x02")
-	otherMulticastAddr := tcpip.Address("\xe0\x00\x01\x03")
-	subnet := context.StackAddrWithPrefix.Subnet()
-	subnetBroadcastAddr := subnet.Broadcast()
-
-	tests := []struct {
-		name    string
-		srcAddr tcpip.Address
-		dstAddr tcpip.Address
-	}{
-		{
-			name:    "SourceUnspecified",
-			srcAddr: header.IPv4Any,
-			dstAddr: context.StackAddr,
-		},
-		{
-			name:    "SourceBroadcast",
-			srcAddr: header.IPv4Broadcast,
-			dstAddr: context.StackAddr,
-		},
-		{
-			name:    "SourceOurMulticast",
-			srcAddr: multicastAddr,
-			dstAddr: context.StackAddr,
-		},
-		{
-			name:    "SourceOtherMulticast",
-			srcAddr: otherMulticastAddr,
-			dstAddr: context.StackAddr,
-		},
-		{
-			name:    "DestUnspecified",
-			srcAddr: context.TestAddr,
-			dstAddr: header.IPv4Any,
-		},
-		{
-			name:    "DestBroadcast",
-			srcAddr: context.TestAddr,
-			dstAddr: header.IPv4Broadcast,
-		},
-		{
-			name:    "DestOurMulticast",
-			srcAddr: context.TestAddr,
-			dstAddr: multicastAddr,
-		},
-		{
-			name:    "DestOtherMulticast",
-			srcAddr: context.TestAddr,
-			dstAddr: otherMulticastAddr,
-		},
-		{
-			name:    "SrcSubnetBroadcast",
-			srcAddr: subnetBroadcastAddr,
-			dstAddr: context.StackAddr,
-		},
-		{
-			name:    "DestSubnetBroadcast",
-			srcAddr: context.TestAddr,
-			dstAddr: subnetBroadcastAddr,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			c := context.New(t, defaultMTU)
-			defer c.Cleanup()
-
-			c.Create(-1)
-
-			if err := c.Stack().JoinGroup(header.IPv4ProtocolNumber, 1, multicastAddr); err != nil {
-				t.Fatalf("JoinGroup failed: %s", err)
-			}
-
-			if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-				t.Fatalf("Bind failed: %s", err)
-			}
-
-			if err := c.EP.Listen(1); err != nil {
-				t.Fatalf("Listen failed: %s", err)
-			}
-
-			irs := seqnum.Value(context.TestInitialSequenceNumber)
-			c.SendPacketWithAddrs(nil, &context.Headers{
-				SrcPort: context.TestPort,
-				DstPort: context.StackPort,
-				Flags:   header.TCPFlagSyn,
-				SeqNum:  irs,
-				RcvWnd:  30000,
-			}, test.srcAddr, test.dstAddr)
-			c.CheckNoPacket("Should not have received a response")
-
-			// Handle normal packet.
-			c.SendPacketWithAddrs(nil, &context.Headers{
-				SrcPort: context.TestPort,
-				DstPort: context.StackPort,
-				Flags:   header.TCPFlagSyn,
-				SeqNum:  irs,
-				RcvWnd:  30000,
-			}, context.TestAddr, context.StackAddr)
-			checker.IPv4(t, c.GetPacket(),
-				checker.TCP(
-					checker.SrcPort(context.StackPort),
-					checker.DstPort(context.TestPort),
-					checker.TCPFlags(header.TCPFlagAck|header.TCPFlagSyn),
-					checker.TCPAckNum(uint32(irs)+1)))
-		})
-	}
-}
-
-// TestListenNoAcceptMulticastBroadcastV6 makes sure that TCP segments with a
-// non unicast IPv6 address are not accepted.
-func TestListenNoAcceptNonUnicastV6(t *testing.T) {
-	multicastAddr := tcpip.Address("\xff\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01")
-	otherMulticastAddr := tcpip.Address("\xff\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02")
-
-	tests := []struct {
-		name    string
-		srcAddr tcpip.Address
-		dstAddr tcpip.Address
-	}{
-		{
-			"SourceUnspecified",
-			header.IPv6Any,
-			context.StackV6Addr,
-		},
-		{
-			"SourceAllNodes",
-			header.IPv6AllNodesMulticastAddress,
-			context.StackV6Addr,
-		},
-		{
-			"SourceOurMulticast",
-			multicastAddr,
-			context.StackV6Addr,
-		},
-		{
-			"SourceOtherMulticast",
-			otherMulticastAddr,
-			context.StackV6Addr,
-		},
-		{
-			"DestUnspecified",
-			context.TestV6Addr,
-			header.IPv6Any,
-		},
-		{
-			"DestAllNodes",
-			context.TestV6Addr,
-			header.IPv6AllNodesMulticastAddress,
-		},
-		{
-			"DestOurMulticast",
-			context.TestV6Addr,
-			multicastAddr,
-		},
-		{
-			"DestOtherMulticast",
-			context.TestV6Addr,
-			otherMulticastAddr,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			c := context.New(t, defaultMTU)
-			defer c.Cleanup()
-
-			c.CreateV6Endpoint(true)
-
-			if err := c.Stack().JoinGroup(header.IPv6ProtocolNumber, 1, multicastAddr); err != nil {
-				t.Fatalf("JoinGroup failed: %s", err)
-			}
-
-			if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-				t.Fatalf("Bind failed: %s", err)
-			}
-
-			if err := c.EP.Listen(1); err != nil {
-				t.Fatalf("Listen failed: %s", err)
-			}
-
-			irs := seqnum.Value(context.TestInitialSequenceNumber)
-			c.SendV6PacketWithAddrs(nil, &context.Headers{
-				SrcPort: context.TestPort,
-				DstPort: context.StackPort,
-				Flags:   header.TCPFlagSyn,
-				SeqNum:  irs,
-				RcvWnd:  30000,
-			}, test.srcAddr, test.dstAddr)
-			c.CheckNoPacket("Should not have received a response")
-
-			// Handle normal packet.
-			c.SendV6PacketWithAddrs(nil, &context.Headers{
-				SrcPort: context.TestPort,
-				DstPort: context.StackPort,
-				Flags:   header.TCPFlagSyn,
-				SeqNum:  irs,
-				RcvWnd:  30000,
-			}, context.TestV6Addr, context.StackV6Addr)
-			checker.IPv6(t, c.GetV6Packet(),
-				checker.TCP(
-					checker.SrcPort(context.StackPort),
-					checker.DstPort(context.TestPort),
-					checker.TCPFlags(header.TCPFlagAck|header.TCPFlagSyn),
-					checker.TCPAckNum(uint32(irs)+1)))
-		})
-	}
-}
-
-func TestListenSynRcvdQueueFull(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	// Create TCP endpoint.
-	var err tcpip.Error
-	c.EP, err = c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &c.WQ)
-	if err != nil {
-		t.Fatalf("NewEndpoint failed: %s", err)
-	}
-
-	// Bind to wildcard.
-	if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %s", err)
-	}
-
-	// Test acceptance.
-	// Start listening.
-	listenBacklog := 1
-	if err := c.EP.Listen(listenBacklog); err != nil {
-		t.Fatalf("Listen failed: %s", err)
-	}
-
-	// Send two SYN's the first one should get a SYN-ACK, the
-	// second one should not get any response and is dropped as
-	// the synRcvd count will be equal to backlog.
-	irs := seqnum.Value(context.TestInitialSequenceNumber)
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagSyn,
-		SeqNum:  irs,
-		RcvWnd:  30000,
-	})
-
-	// Receive the SYN-ACK reply.
-	b := c.GetPacket()
-	tcp := header.TCP(header.IPv4(b).Payload())
-	iss := seqnum.Value(tcp.SequenceNumber())
-	tcpCheckers := []checker.TransportChecker{
-		checker.SrcPort(context.StackPort),
-		checker.DstPort(context.TestPort),
-		checker.TCPFlags(header.TCPFlagAck | header.TCPFlagSyn),
-		checker.TCPAckNum(uint32(irs) + 1),
-	}
-	checker.IPv4(t, b, checker.TCP(tcpCheckers...))
-
-	// Now execute send one more SYN. The stack should not respond as the backlog
-	// is full at this point.
-	//
-	// NOTE: we did not complete the handshake for the previous one so the
-	// accept backlog should be empty and there should be one connection in
-	// synRcvd state.
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort + 1,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagSyn,
-		SeqNum:  seqnum.Value(889),
-		RcvWnd:  30000,
-	})
-	c.CheckNoPacketTimeout("unexpected packet received", 50*time.Millisecond)
-
-	// Now complete the previous connection and verify that there is a connection
-	// to accept.
-	// Send ACK.
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  irs + 1,
-		AckNum:  iss + 1,
-		RcvWnd:  30000,
-	})
-
-	// Try to accept the connections in the backlog.
-	we, ch := waiter.NewChannelEntry(nil)
-	c.WQ.EventRegister(&we, waiter.EventIn)
-	defer c.WQ.EventUnregister(&we)
-
-	newEP, _, err := c.EP.Accept(nil)
-	if _, ok := err.(*tcpip.ErrWouldBlock); ok {
-		// Wait for connection to be established.
-		select {
-		case <-ch:
-			newEP, _, err = c.EP.Accept(nil)
-			if err != nil {
-				t.Fatalf("Accept failed: %s", err)
-			}
-
-		case <-time.After(1 * time.Second):
-			t.Fatalf("Timed out waiting for accept")
-		}
-	}
-
-	// Now verify that the TCP socket is usable and in a connected state.
-	data := "Don't panic"
-	var r strings.Reader
-	r.Reset(data)
-	newEP.Write(&r, tcpip.WriteOptions{})
-	pkt := c.GetPacket()
-	tcp = header.TCP(header.IPv4(pkt).Payload())
-	if string(tcp.Payload()) != data {
-		t.Fatalf("unexpected data: got %s, want %s", string(tcp.Payload()), data)
-	}
-}
-
-func TestListenBacklogFullSynCookieInUse(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	opt := tcpip.TCPSynRcvdCountThresholdOption(1)
-	if err := c.Stack().SetTransportProtocolOption(tcp.ProtocolNumber, &opt); err != nil {
-		t.Fatalf("SetTransportProtocolOption(%d, &%T(%d)): %s", tcp.ProtocolNumber, opt, opt, err)
-	}
-
-	// Create TCP endpoint.
-	var err tcpip.Error
-	c.EP, err = c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &c.WQ)
-	if err != nil {
-		t.Fatalf("NewEndpoint failed: %s", err)
-	}
-
-	// Bind to wildcard.
-	if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %s", err)
-	}
-
-	// Start listening.
-	listenBacklog := 1
-	if err := c.EP.Listen(listenBacklog); err != nil {
-		t.Fatalf("Listen failed: %s", err)
-	}
-
-	executeHandshake(t, c, context.TestPort, false)
-
-	// Wait for this to be delivered to the accept queue.
-	time.Sleep(50 * time.Millisecond)
-
-	// Send a SYN request.
-	irs := seqnum.Value(context.TestInitialSequenceNumber)
-	c.SendPacket(nil, &context.Headers{
-		// pick a different src port for new SYN.
-		SrcPort: context.TestPort + 1,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagSyn,
-		SeqNum:  irs,
-		RcvWnd:  30000,
-	})
-	// The Syn should be dropped as the endpoint's backlog is full.
-	c.CheckNoPacketTimeout("unexpected packet received", 50*time.Millisecond)
-
-	// Verify that there is only one acceptable connection at this point.
-	we, ch := waiter.NewChannelEntry(nil)
-	c.WQ.EventRegister(&we, waiter.EventIn)
-	defer c.WQ.EventUnregister(&we)
-
-	_, _, err = c.EP.Accept(nil)
-	if _, ok := err.(*tcpip.ErrWouldBlock); ok {
-		// Wait for connection to be established.
-		select {
-		case <-ch:
-			_, _, err = c.EP.Accept(nil)
-			if err != nil {
-				t.Fatalf("Accept failed: %s", err)
-			}
-
-		case <-time.After(1 * time.Second):
-			t.Fatalf("Timed out waiting for accept")
-		}
-	}
-
-	// Now verify that there are no more connections that can be accepted.
-	_, _, err = c.EP.Accept(nil)
-	if _, ok := err.(*tcpip.ErrWouldBlock); !ok {
-		select {
-		case <-ch:
-			t.Fatalf("unexpected endpoint delivered on Accept: %+v", c.EP)
-		case <-time.After(1 * time.Second):
-		}
-	}
-}
-
-func TestSYNRetransmit(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	// Create TCP endpoint.
-	var err tcpip.Error
-	c.EP, err = c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &c.WQ)
-	if err != nil {
-		t.Fatalf("NewEndpoint failed: %s", err)
-	}
-
-	// Bind to wildcard.
-	if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %s", err)
-	}
-
-	// Start listening.
-	if err := c.EP.Listen(10); err != nil {
-		t.Fatalf("Listen failed: %s", err)
-	}
-
-	// Send the same SYN packet multiple times. We should still get a valid SYN-ACK
-	// reply.
-	irs := seqnum.Value(context.TestInitialSequenceNumber)
-	for i := 0; i < 5; i++ {
-		c.SendPacket(nil, &context.Headers{
-			SrcPort: context.TestPort,
-			DstPort: context.StackPort,
-			Flags:   header.TCPFlagSyn,
-			SeqNum:  irs,
-			RcvWnd:  30000,
-		})
-	}
-
-	// Receive the SYN-ACK reply.
-	tcpCheckers := []checker.TransportChecker{
-		checker.SrcPort(context.StackPort),
-		checker.DstPort(context.TestPort),
-		checker.TCPFlags(header.TCPFlagAck | header.TCPFlagSyn),
-		checker.TCPAckNum(uint32(irs) + 1),
-	}
-	checker.IPv4(t, c.GetPacket(), checker.TCP(tcpCheckers...))
-}
-
-func TestSynRcvdBadSeqNumber(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	// Create TCP endpoint.
-	var err tcpip.Error
-	c.EP, err = c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &c.WQ)
-	if err != nil {
-		t.Fatalf("NewEndpoint failed: %s", err)
-	}
-
-	// Bind to wildcard.
-	if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %s", err)
-	}
-
-	// Start listening.
-	if err := c.EP.Listen(10); err != nil {
-		t.Fatalf("Listen failed: %s", err)
-	}
-
-	// Send a SYN to get a SYN-ACK. This should put the ep into SYN-RCVD state
-	irs := seqnum.Value(context.TestInitialSequenceNumber)
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagSyn,
-		SeqNum:  irs,
-		RcvWnd:  30000,
-	})
-
-	// Receive the SYN-ACK reply.
-	b := c.GetPacket()
-	tcpHdr := header.TCP(header.IPv4(b).Payload())
-	iss := seqnum.Value(tcpHdr.SequenceNumber())
-	tcpCheckers := []checker.TransportChecker{
-		checker.SrcPort(context.StackPort),
-		checker.DstPort(context.TestPort),
-		checker.TCPFlags(header.TCPFlagAck | header.TCPFlagSyn),
-		checker.TCPAckNum(uint32(irs) + 1),
-	}
-	checker.IPv4(t, b, checker.TCP(tcpCheckers...))
-
-	// Now send a packet with an out-of-window sequence number
-	largeSeqnum := irs + seqnum.Value(tcpHdr.WindowSize()) + 1
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  largeSeqnum,
-		AckNum:  iss + 1,
-		RcvWnd:  30000,
-	})
-
-	// Should receive an ACK with the expected SEQ number
-	b = c.GetPacket()
-	tcpCheckers = []checker.TransportChecker{
-		checker.SrcPort(context.StackPort),
-		checker.DstPort(context.TestPort),
-		checker.TCPFlags(header.TCPFlagAck),
-		checker.TCPAckNum(uint32(irs) + 1),
-		checker.TCPSeqNum(uint32(iss + 1)),
-	}
-	checker.IPv4(t, b, checker.TCP(tcpCheckers...))
-
-	// Now that the socket replied appropriately with the ACK,
-	// complete the connection to test that the large SEQ num
-	// did not change the state from SYN-RCVD.
-
-	// Send ACK to move to ESTABLISHED state.
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  irs + 1,
-		AckNum:  iss + 1,
-		RcvWnd:  30000,
-	})
-
-	newEP, _, err := c.EP.Accept(nil)
-	switch err.(type) {
-	case nil, *tcpip.ErrWouldBlock:
-	default:
-		t.Fatalf("Accept failed: %s", err)
-	}
-
-	if _, ok := err.(*tcpip.ErrWouldBlock); ok {
-		// Try to accept the connections in the backlog.
-		we, ch := waiter.NewChannelEntry(nil)
-		c.WQ.EventRegister(&we, waiter.EventIn)
-		defer c.WQ.EventUnregister(&we)
-
-		// Wait for connection to be established.
-		select {
-		case <-ch:
-			newEP, _, err = c.EP.Accept(nil)
-			if err != nil {
-				t.Fatalf("Accept failed: %s", err)
-			}
-
-		case <-time.After(1 * time.Second):
-			t.Fatalf("Timed out waiting for accept")
-		}
-	}
-
-	// Now verify that the TCP socket is usable and in a connected state.
-	data := "Don't panic"
-	var r strings.Reader
-	r.Reset(data)
-	if _, err := newEP.Write(&r, tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %s", err)
-	}
-
-	pkt := c.GetPacket()
-	tcpHdr = header.TCP(header.IPv4(pkt).Payload())
-	if string(tcpHdr.Payload()) != data {
-		t.Fatalf("unexpected data: got %s, want %s", string(tcpHdr.Payload()), data)
-	}
-}
-
-func TestPassiveConnectionAttemptIncrement(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	ep, err := c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &c.WQ)
-	if err != nil {
-		t.Fatalf("NewEndpoint failed: %s", err)
-	}
-	c.EP = ep
-	if err := ep.Bind(tcpip.FullAddress{Addr: context.StackAddr, Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %s", err)
-	}
-	if got, want := tcp.EndpointState(ep.State()), tcp.StateBound; got != want {
-		t.Errorf("unexpected endpoint state: want %s, got %s", want, got)
-	}
-	if err := c.EP.Listen(1); err != nil {
-		t.Fatalf("Listen failed: %s", err)
-	}
-	if got, want := tcp.EndpointState(c.EP.State()), tcp.StateListen; got != want {
-		t.Errorf("unexpected endpoint state: want %s, got %s", want, got)
-	}
-
-	stats := c.Stack().Stats()
-	want := stats.TCP.PassiveConnectionOpenings.Value() + 1
-
-	srcPort := uint16(context.TestPort)
-	executeHandshake(t, c, srcPort+1, false)
-
-	we, ch := waiter.NewChannelEntry(nil)
-	c.WQ.EventRegister(&we, waiter.EventIn)
-	defer c.WQ.EventUnregister(&we)
-
-	// Verify that there is only one acceptable connection at this point.
-	_, _, err = c.EP.Accept(nil)
-	if _, ok := err.(*tcpip.ErrWouldBlock); ok {
-		// Wait for connection to be established.
-		select {
-		case <-ch:
-			_, _, err = c.EP.Accept(nil)
-			if err != nil {
-				t.Fatalf("Accept failed: %s", err)
-			}
-
-		case <-time.After(1 * time.Second):
-			t.Fatalf("Timed out waiting for accept")
-		}
-	}
-
-	if got := stats.TCP.PassiveConnectionOpenings.Value(); got != want {
-		t.Errorf("got stats.TCP.PassiveConnectionOpenings.Value() = %d, want = %d", got, want)
-	}
-}
-
-func TestPassiveFailedConnectionAttemptIncrement(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	stats := c.Stack().Stats()
-	ep, err := c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &c.WQ)
-	if err != nil {
-		t.Fatalf("NewEndpoint failed: %s", err)
-	}
-	c.EP = ep
-	if err := c.EP.Bind(tcpip.FullAddress{Addr: context.StackAddr, Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %s", err)
-	}
-	if err := c.EP.Listen(1); err != nil {
-		t.Fatalf("Listen failed: %s", err)
-	}
-
-	srcPort := uint16(context.TestPort)
-	// Now attempt a handshakes it will fill up the accept backlog.
-	executeHandshake(t, c, srcPort, false)
-
-	// Give time for the final ACK to be processed as otherwise the next handshake could
-	// get accepted before the previous one based on goroutine scheduling.
-	time.Sleep(50 * time.Millisecond)
-
-	want := stats.TCP.ListenOverflowSynDrop.Value() + 1
-
-	// Now we will send one more SYN and this one should get dropped
-	// Send a SYN request.
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: srcPort + 2,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagSyn,
-		SeqNum:  seqnum.Value(context.TestInitialSequenceNumber),
-		RcvWnd:  30000,
-	})
-
-	time.Sleep(50 * time.Millisecond)
-	if got := stats.TCP.ListenOverflowSynDrop.Value(); got != want {
-		t.Errorf("got stats.TCP.ListenOverflowSynDrop.Value() = %d, want = %d", got, want)
-	}
-	if got := c.EP.Stats().(*tcp.Stats).ReceiveErrors.ListenOverflowSynDrop.Value(); got != want {
-		t.Errorf("got EP stats Stats.ReceiveErrors.ListenOverflowSynDrop = %d, want = %d", got, want)
-	}
-
-	we, ch := waiter.NewChannelEntry(nil)
-	c.WQ.EventRegister(&we, waiter.EventIn)
-	defer c.WQ.EventUnregister(&we)
-
-	// Now check that there is one acceptable connections.
-	_, _, err = c.EP.Accept(nil)
-	if _, ok := err.(*tcpip.ErrWouldBlock); ok {
-		// Wait for connection to be established.
-		select {
-		case <-ch:
-			_, _, err = c.EP.Accept(nil)
-			if err != nil {
-				t.Fatalf("Accept failed: %s", err)
-			}
-
-		case <-time.After(1 * time.Second):
-			t.Fatalf("Timed out waiting for accept")
-		}
-	}
-}
-
-func TestEndpointBindListenAcceptState(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-	wq := &waiter.Queue{}
-	ep, err := c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, wq)
-	if err != nil {
-		t.Fatalf("NewEndpoint failed: %s", err)
-	}
-
-	if err := ep.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %s", err)
-	}
-	if got, want := tcp.EndpointState(ep.State()), tcp.StateBound; got != want {
-		t.Errorf("unexpected endpoint state: want %s, got %s", want, got)
-	}
-
-	ept := endpointTester{ep}
-	ept.CheckReadError(t, &tcpip.ErrNotConnected{})
-	if got := ep.Stats().(*tcp.Stats).ReadErrors.NotConnected.Value(); got != 1 {
-		t.Errorf("got EP stats Stats.ReadErrors.NotConnected got %d want %d", got, 1)
-	}
-
-	if err := ep.Listen(10); err != nil {
-		t.Fatalf("Listen failed: %s", err)
-	}
-	if got, want := tcp.EndpointState(ep.State()), tcp.StateListen; got != want {
-		t.Errorf("unexpected endpoint state: want %s, got %s", want, got)
-	}
-
-	c.PassiveConnectWithOptions(100, 5, header.TCPSynOptions{MSS: defaultIPv4MSS})
-
-	// Try to accept the connection.
-	we, ch := waiter.NewChannelEntry(nil)
-	wq.EventRegister(&we, waiter.EventIn)
-	defer wq.EventUnregister(&we)
-
-	aep, _, err := ep.Accept(nil)
-	if _, ok := err.(*tcpip.ErrWouldBlock); ok {
-		// Wait for connection to be established.
-		select {
-		case <-ch:
-			aep, _, err = ep.Accept(nil)
-			if err != nil {
-				t.Fatalf("Accept failed: %s", err)
-			}
-
-		case <-time.After(1 * time.Second):
-			t.Fatalf("Timed out waiting for accept")
-		}
-	}
-	if got, want := tcp.EndpointState(aep.State()), tcp.StateEstablished; got != want {
-		t.Errorf("unexpected endpoint state: want %s, got %s", want, got)
-	}
-	{
-		err := aep.Connect(tcpip.FullAddress{Addr: context.TestAddr, Port: context.TestPort})
-		if _, ok := err.(*tcpip.ErrAlreadyConnected); !ok {
-			t.Errorf("unexpected error attempting to call connect on an established endpoint, got: %v, want: %s", err, &tcpip.ErrAlreadyConnected{})
-		}
-	}
-	// Listening endpoint remains in listen state.
-	if got, want := tcp.EndpointState(ep.State()), tcp.StateListen; got != want {
-		t.Errorf("unexpected endpoint state: want %s, got %s", want, got)
-	}
-
-	ep.Close()
-	// Give worker goroutines time to receive the close notification.
-	time.Sleep(1 * time.Second)
-	if got, want := tcp.EndpointState(ep.State()), tcp.StateClose; got != want {
-		t.Errorf("unexpected endpoint state: want %s, got %s", want, got)
-	}
-	// Accepted endpoint remains open when the listen endpoint is closed.
-	if got, want := tcp.EndpointState(aep.State()), tcp.StateEstablished; got != want {
-		t.Errorf("unexpected endpoint state: want %s, got %s", want, got)
-	}
-
-}
-
-// This test verifies that the auto tuning does not grow the receive buffer if
-// the application is not reading the data actively.
-func TestReceiveBufferAutoTuningApplicationLimited(t *testing.T) {
-	const mtu = 1500
-	const mss = mtu - header.IPv4MinimumSize - header.TCPMinimumSize
-
-	c := context.New(t, mtu)
-	defer c.Cleanup()
-
-	stk := c.Stack()
-	// Set lower limits for auto-tuning tests. This is required because the
-	// test stops the worker which can cause packets to be dropped because
-	// the segment queue holding unprocessed packets is limited to 500.
-	const receiveBufferSize = 80 << 10 // 80KB.
-	const maxReceiveBufferSize = receiveBufferSize * 10
-	{
-		opt := tcpip.TCPReceiveBufferSizeRangeOption{Min: 1, Default: receiveBufferSize, Max: maxReceiveBufferSize}
-		if err := stk.SetTransportProtocolOption(tcp.ProtocolNumber, &opt); err != nil {
-			t.Fatalf("SetTransportProtocolOption(%d, &%#v): %s", tcp.ProtocolNumber, opt, err)
-		}
-	}
-
-	// Enable auto-tuning.
-	{
-		opt := tcpip.TCPModerateReceiveBufferOption(true)
-		if err := stk.SetTransportProtocolOption(tcp.ProtocolNumber, &opt); err != nil {
-			t.Fatalf("SetTransportProtocolOption(%d, &%T(%t)): %s", tcp.ProtocolNumber, opt, opt, err)
-		}
-	}
-	// Change the expected window scale to match the value needed for the
-	// maximum buffer size defined above.
-	c.WindowScale = uint8(tcp.FindWndScale(maxReceiveBufferSize))
-
-	rawEP := c.CreateConnectedWithOptions(header.TCPSynOptions{TS: true, WS: 4})
-
-	// NOTE: The timestamp values in the sent packets are meaningless to the
-	// peer so we just increment the timestamp value by 1 every batch as we
-	// are not really using them for anything. Send a single byte to verify
-	// the advertised window.
-	tsVal := rawEP.TSVal + 1
-
-	// Introduce a 25ms latency by delaying the first byte.
-	latency := 25 * time.Millisecond
-	time.Sleep(latency)
-	// Send an initial payload with atleast segment overhead size. The receive
-	// window would not grow for smaller segments.
-	rawEP.SendPacketWithTS(make([]byte, tcp.SegSize), tsVal)
-
-	pkt := rawEP.VerifyAndReturnACKWithTS(tsVal)
-	rcvWnd := header.TCP(header.IPv4(pkt).Payload()).WindowSize()
-
-	time.Sleep(25 * time.Millisecond)
-
-	// Allocate a large enough payload for the test.
-	payloadSize := receiveBufferSize * 2
-	b := make([]byte, int(payloadSize))
-
-	worker := (c.EP).(interface {
-		StopWork()
-		ResumeWork()
-	})
-	tsVal++
-
-	// Stop the worker goroutine.
-	worker.StopWork()
-	start := 0
-	end := payloadSize / 2
-	packetsSent := 0
-	for ; start < end; start += mss {
-		packetEnd := start + mss
-		if start+mss > end {
-			packetEnd = end
-		}
-		rawEP.SendPacketWithTS(b[start:packetEnd], tsVal)
-		packetsSent++
-	}
-
-	// Resume the worker so that it only sees the packets once all of them
-	// are waiting to be read.
-	worker.ResumeWork()
-
-	// Since we sent almost the full receive buffer worth of data (some may have
-	// been dropped due to segment overheads), we should get a zero window back.
-	pkt = c.GetPacket()
-	tcpHdr := header.TCP(header.IPv4(pkt).Payload())
-	gotRcvWnd := tcpHdr.WindowSize()
-	wantAckNum := tcpHdr.AckNumber()
-	if got, want := int(gotRcvWnd), 0; got != want {
-		t.Fatalf("got rcvWnd: %d, want: %d", got, want)
-	}
-
-	time.Sleep(25 * time.Millisecond)
-	// Verify that sending more data when receiveBuffer is exhausted.
-	rawEP.SendPacketWithTS(b[start:start+mss], tsVal)
-
-	// Now read all the data from the endpoint and verify that advertised
-	// window increases to the full available buffer size.
-	for {
-		_, err := c.EP.Read(ioutil.Discard, tcpip.ReadOptions{})
-		if _, ok := err.(*tcpip.ErrWouldBlock); ok {
-			break
-		}
-	}
-
-	// Verify that we receive a non-zero window update ACK. When running
-	// under thread santizer this test can end up sending more than 1
-	// ack, 1 for the non-zero window
-	p := c.GetPacket()
-	checker.IPv4(t, p, checker.TCP(
-		checker.TCPAckNum(uint32(wantAckNum)),
-		func(t *testing.T, h header.Transport) {
-			tcp, ok := h.(header.TCP)
-			if !ok {
-				return
-			}
-			// We use 10% here as the error margin upwards as the initial window we
-			// got was afer 1 segment was already in the receive buffer queue.
-			tolerance := 1.1
-			if w := tcp.WindowSize(); w == 0 || w > uint16(float64(rcvWnd)*tolerance) {
-				t.Errorf("expected a non-zero window: got %d, want <= %d", w, uint16(float64(rcvWnd)*tolerance))
-			}
-		},
-	))
-}
-
-// This test verifies that the advertised window is auto-tuned up as the
-// application is reading the data that is being received.
-func TestReceiveBufferAutoTuning(t *testing.T) {
-	const mtu = 1500
-	const mss = mtu - header.IPv4MinimumSize - header.TCPMinimumSize
-
-	c := context.New(t, mtu)
-	defer c.Cleanup()
-
-	// Enable Auto-tuning.
-	stk := c.Stack()
-	// Disable out of window rate limiting for this test by setting it to 0 as we
-	// use out of window ACKs to measure the advertised window.
-	var tcpInvalidRateLimit stack.TCPInvalidRateLimitOption
-	if err := stk.SetOption(tcpInvalidRateLimit); err != nil {
-		t.Fatalf("e.stack.SetOption(%#v) = %s", tcpInvalidRateLimit, err)
-	}
-
-	const receiveBufferSize = 80 << 10 // 80KB.
-	const maxReceiveBufferSize = receiveBufferSize * 10
-	{
-		opt := tcpip.TCPReceiveBufferSizeRangeOption{Min: 1, Default: receiveBufferSize, Max: maxReceiveBufferSize}
-		if err := stk.SetTransportProtocolOption(tcp.ProtocolNumber, &opt); err != nil {
-			t.Fatalf("SetTransportProtocolOption(%d, &%#v): %s", tcp.ProtocolNumber, opt, err)
-		}
-	}
-
-	// Enable auto-tuning.
-	{
-		opt := tcpip.TCPModerateReceiveBufferOption(true)
-		if err := stk.SetTransportProtocolOption(tcp.ProtocolNumber, &opt); err != nil {
-			t.Fatalf("SetTransportProtocolOption(%d, &%T(%t)): %s", tcp.ProtocolNumber, opt, opt, err)
-		}
-	}
-	// Change the expected window scale to match the value needed for the
-	// maximum buffer size used by stack.
-	c.WindowScale = uint8(tcp.FindWndScale(maxReceiveBufferSize))
-
-	rawEP := c.CreateConnectedWithOptions(header.TCPSynOptions{TS: true, WS: 4})
-	tsVal := uint32(rawEP.TSVal)
-	rawEP.NextSeqNum--
-	rawEP.SendPacketWithTS(nil, tsVal)
-	rawEP.NextSeqNum++
-	pkt := rawEP.VerifyAndReturnACKWithTS(tsVal)
-	curRcvWnd := int(header.TCP(header.IPv4(pkt).Payload()).WindowSize()) << c.WindowScale
-	scaleRcvWnd := func(rcvWnd int) uint16 {
-		return uint16(rcvWnd >> uint16(c.WindowScale))
-	}
-	// Allocate a large array to send to the endpoint.
-	b := make([]byte, receiveBufferSize*48)
-
-	// In every iteration we will send double the number of bytes sent in
-	// the previous iteration and read the same from the app. The received
-	// window should grow by at least 2x of bytes read by the app in every
-	// RTT.
-	offset := 0
-	payloadSize := receiveBufferSize / 8
-	worker := (c.EP).(interface {
-		StopWork()
-		ResumeWork()
-	})
-	latency := 1 * time.Millisecond
-	for i := 0; i < 5; i++ {
-		tsVal++
-
-		// Stop the worker goroutine.
-		worker.StopWork()
-		start := offset
-		end := offset + payloadSize
-		totalSent := 0
-		packetsSent := 0
-		for ; start < end; start += mss {
-			rawEP.SendPacketWithTS(b[start:start+mss], tsVal)
-			totalSent += mss
-			packetsSent++
-		}
-
-		// Resume it so that it only sees the packets once all of them
-		// are waiting to be read.
-		worker.ResumeWork()
-
-		// Give 1ms for the worker to process the packets.
-		time.Sleep(1 * time.Millisecond)
-
-		lastACK := c.GetPacket()
-		// Discard any intermediate ACKs and only check the last ACK we get in a
-		// short time period of few ms.
-		for {
-			time.Sleep(1 * time.Millisecond)
-			pkt := c.GetPacketNonBlocking()
-			if pkt == nil {
-				break
-			}
-			lastACK = pkt
-		}
-		if got, want := int(header.TCP(header.IPv4(lastACK).Payload()).WindowSize()), int(scaleRcvWnd(curRcvWnd)); got > want {
-			t.Fatalf("advertised window got: %d, want <= %d", got, want)
-		}
-
-		// Now read all the data from the endpoint and invoke the
-		// moderation API to allow for receive buffer auto-tuning
-		// to happen before we measure the new window.
-		totalCopied := 0
-		for {
-			res, err := c.EP.Read(ioutil.Discard, tcpip.ReadOptions{})
-			if _, ok := err.(*tcpip.ErrWouldBlock); ok {
-				break
-			}
-			totalCopied += res.Count
-		}
-
-		// Invoke the moderation API. This is required for auto-tuning
-		// to happen. This method is normally expected to be invoked
-		// from a higher layer than tcpip.Endpoint. So we simulate
-		// copying to userspace by invoking it explicitly here.
-		c.EP.ModerateRecvBuf(totalCopied)
-
-		// Now send a keep-alive packet to trigger an ACK so that we can
-		// measure the new window.
-		rawEP.NextSeqNum--
-		rawEP.SendPacketWithTS(nil, tsVal)
-		rawEP.NextSeqNum++
-
-		if i == 0 {
-			// In the first iteration the receiver based RTT is not
-			// yet known as a result the moderation code should not
-			// increase the advertised window.
-			rawEP.VerifyACKRcvWnd(scaleRcvWnd(curRcvWnd))
-		} else {
-			// Read loop above could generate an ACK if the window had dropped to
-			// zero and then read had opened it up.
-			lastACK := c.GetPacket()
-			// Discard any intermediate ACKs and only check the last ACK we get in a
-			// short time period of few ms.
-			for {
-				time.Sleep(1 * time.Millisecond)
-				pkt := c.GetPacketNonBlocking()
-				if pkt == nil {
-					break
-				}
-				lastACK = pkt
-			}
-			curRcvWnd = int(header.TCP(header.IPv4(lastACK).Payload()).WindowSize()) << c.WindowScale
-			// If thew new current window is close maxReceiveBufferSize then terminate
-			// the loop. This can happen before all iterations are done due to timing
-			// differences when running the test.
-			if int(float64(curRcvWnd)*1.1) > maxReceiveBufferSize/2 {
-				break
-			}
-			// Increase the latency after first two iterations to
-			// establish a low RTT value in the receiver since it
-			// only tracks the lowest value. This ensures that when
-			// ModerateRcvBuf is called the elapsed time is always >
-			// rtt. Without this the test is flaky due to delays due
-			// to scheduling/wakeup etc.
-			latency += 50 * time.Millisecond
-		}
-		time.Sleep(latency)
-		offset += payloadSize
-		payloadSize *= 2
-	}
-	// Check that at the end of our iterations the receive window grew close to the maximum
-	// permissible size of maxReceiveBufferSize/2
-	if got, want := int(float64(curRcvWnd)*1.1), maxReceiveBufferSize/2; got < want {
-		t.Fatalf("unexpected rcvWnd got: %d, want > %d", got, want)
-	}
-
-}
-
-func TestDelayEnabled(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-	checkDelayOption(t, c, false, false) // Delay is disabled by default.
-
-	for _, v := range []struct {
-		delayEnabled    tcpip.TCPDelayEnabled
-		wantDelayOption bool
-	}{
-		{delayEnabled: false, wantDelayOption: false},
-		{delayEnabled: true, wantDelayOption: true},
-	} {
-		c := context.New(t, defaultMTU)
-		defer c.Cleanup()
-		if err := c.Stack().SetTransportProtocolOption(tcp.ProtocolNumber, &v.delayEnabled); err != nil {
-			t.Fatalf("SetTransportProtocolOption(%d, &%T(%t)): %s", tcp.ProtocolNumber, v.delayEnabled, v.delayEnabled, err)
-		}
-		checkDelayOption(t, c, v.delayEnabled, v.wantDelayOption)
-	}
-}
-
-func checkDelayOption(t *testing.T, c *context.Context, wantDelayEnabled tcpip.TCPDelayEnabled, wantDelayOption bool) {
-	t.Helper()
-
-	var gotDelayEnabled tcpip.TCPDelayEnabled
-	if err := c.Stack().TransportProtocolOption(tcp.ProtocolNumber, &gotDelayEnabled); err != nil {
-		t.Fatalf("TransportProtocolOption(tcp, &gotDelayEnabled) failed: %s", err)
-	}
-	if gotDelayEnabled != wantDelayEnabled {
-		t.Errorf("TransportProtocolOption(tcp, &gotDelayEnabled) got %t, want %t", gotDelayEnabled, wantDelayEnabled)
-	}
-
-	ep, err := c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, new(waiter.Queue))
-	if err != nil {
-		t.Fatalf("NewEndPoint(tcp, ipv4, new(waiter.Queue)) failed: %s", err)
-	}
-	gotDelayOption := ep.SocketOptions().GetDelayOption()
-	if gotDelayOption != wantDelayOption {
-		t.Errorf("ep.GetSockOptBool(tcpip.DelayOption) got: %t, want: %t", gotDelayOption, wantDelayOption)
-	}
-}
-
-func TestTCPLingerTimeout(t *testing.T) {
-	c := context.New(t, 1500 /* mtu */)
-	defer c.Cleanup()
-
-	c.CreateConnected(context.TestInitialSequenceNumber, 30000, -1 /* epRcvBuf */)
-
-	testCases := []struct {
-		name             string
-		tcpLingerTimeout time.Duration
-		want             time.Duration
-	}{
-		{"NegativeLingerTimeout", -123123, -1},
-		// Zero is treated same as the stack's default TCP_LINGER2 timeout.
-		{"ZeroLingerTimeout", 0, tcp.DefaultTCPLingerTimeout},
-		{"InRangeLingerTimeout", 10 * time.Second, 10 * time.Second},
-		// Values > stack's TCPLingerTimeout are capped to the stack's
-		// value. Defaults to tcp.DefaultTCPLingerTimeout(60 seconds)
-		{"AboveMaxLingerTimeout", tcp.MaxTCPLingerTimeout + 5*time.Second, tcp.MaxTCPLingerTimeout},
-	}
-	for _, tc := range testCases {
-		t.Run(tc.name, func(t *testing.T) {
-			v := tcpip.TCPLingerTimeoutOption(tc.tcpLingerTimeout)
-			if err := c.EP.SetSockOpt(&v); err != nil {
-				t.Fatalf("SetSockOpt(&%T(%s)) = %s", v, tc.tcpLingerTimeout, err)
-			}
-
-			v = 0
-			if err := c.EP.GetSockOpt(&v); err != nil {
-				t.Fatalf("GetSockOpt(&%T) = %s", v, err)
-			}
-			if got, want := time.Duration(v), tc.want; got != want {
-				t.Fatalf("got linger timeout = %s, want = %s", got, want)
-			}
-		})
-	}
-}
-
-func TestTCPTimeWaitRSTIgnored(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	wq := &waiter.Queue{}
-	ep, err := c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, wq)
-	if err != nil {
-		t.Fatalf("NewEndpoint failed: %s", err)
-	}
-	if err := ep.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %s", err)
-	}
-
-	if err := ep.Listen(10); err != nil {
-		t.Fatalf("Listen failed: %s", err)
-	}
-
-	// Send a SYN request.
-	iss := seqnum.Value(context.TestInitialSequenceNumber)
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagSyn,
-		SeqNum:  iss,
-		RcvWnd:  30000,
-	})
-
-	// Receive the SYN-ACK reply.
-	b := c.GetPacket()
-	tcpHdr := header.TCP(header.IPv4(b).Payload())
-	c.IRS = seqnum.Value(tcpHdr.SequenceNumber())
-
-	ackHeaders := &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss + 1,
-		AckNum:  c.IRS + 1,
-	}
-
-	// Send ACK.
-	c.SendPacket(nil, ackHeaders)
-
-	// Try to accept the connection.
-	we, ch := waiter.NewChannelEntry(nil)
-	wq.EventRegister(&we, waiter.EventIn)
-	defer wq.EventUnregister(&we)
-
-	c.EP, _, err = ep.Accept(nil)
-	if _, ok := err.(*tcpip.ErrWouldBlock); ok {
-		// Wait for connection to be established.
-		select {
-		case <-ch:
-			c.EP, _, err = ep.Accept(nil)
-			if err != nil {
-				t.Fatalf("Accept failed: %s", err)
-			}
-
-		case <-time.After(1 * time.Second):
-			t.Fatalf("Timed out waiting for accept")
-		}
-	}
-
-	c.EP.Close()
-	checker.IPv4(t, c.GetPacket(), checker.TCP(
-		checker.SrcPort(context.StackPort),
-		checker.DstPort(context.TestPort),
-		checker.TCPSeqNum(uint32(c.IRS+1)),
-		checker.TCPAckNum(uint32(iss)+1),
-		checker.TCPFlags(header.TCPFlagFin|header.TCPFlagAck)))
-
-	finHeaders := &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagAck | header.TCPFlagFin,
-		SeqNum:  iss + 1,
-		AckNum:  c.IRS + 2,
-	}
-
-	c.SendPacket(nil, finHeaders)
-
-	// Get the ACK to the FIN we just sent.
-	checker.IPv4(t, c.GetPacket(), checker.TCP(
-		checker.SrcPort(context.StackPort),
-		checker.DstPort(context.TestPort),
-		checker.TCPSeqNum(uint32(c.IRS+2)),
-		checker.TCPAckNum(uint32(iss)+2),
-		checker.TCPFlags(header.TCPFlagAck)))
-
-	// Now send a RST and this should be ignored and not
-	// generate an ACK.
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagRst,
-		SeqNum:  iss + 1,
-		AckNum:  c.IRS + 2,
-	})
-
-	c.CheckNoPacketTimeout("unexpected packet received in TIME_WAIT state", 1*time.Second)
-
-	// Out of order ACK should generate an immediate ACK in
-	// TIME_WAIT.
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss + 1,
-		AckNum:  c.IRS + 3,
-	})
-
-	checker.IPv4(t, c.GetPacket(), checker.TCP(
-		checker.SrcPort(context.StackPort),
-		checker.DstPort(context.TestPort),
-		checker.TCPSeqNum(uint32(c.IRS+2)),
-		checker.TCPAckNum(uint32(iss)+2),
-		checker.TCPFlags(header.TCPFlagAck)))
-}
-
-func TestTCPTimeWaitOutOfOrder(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	wq := &waiter.Queue{}
-	ep, err := c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, wq)
-	if err != nil {
-		t.Fatalf("NewEndpoint failed: %s", err)
-	}
-	if err := ep.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %s", err)
-	}
-
-	if err := ep.Listen(10); err != nil {
-		t.Fatalf("Listen failed: %s", err)
-	}
-
-	// Send a SYN request.
-	iss := seqnum.Value(context.TestInitialSequenceNumber)
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagSyn,
-		SeqNum:  iss,
-		RcvWnd:  30000,
-	})
-
-	// Receive the SYN-ACK reply.
-	b := c.GetPacket()
-	tcpHdr := header.TCP(header.IPv4(b).Payload())
-	c.IRS = seqnum.Value(tcpHdr.SequenceNumber())
-
-	ackHeaders := &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss + 1,
-		AckNum:  c.IRS + 1,
-	}
-
-	// Send ACK.
-	c.SendPacket(nil, ackHeaders)
-
-	// Try to accept the connection.
-	we, ch := waiter.NewChannelEntry(nil)
-	wq.EventRegister(&we, waiter.EventIn)
-	defer wq.EventUnregister(&we)
-
-	c.EP, _, err = ep.Accept(nil)
-	if _, ok := err.(*tcpip.ErrWouldBlock); ok {
-		// Wait for connection to be established.
-		select {
-		case <-ch:
-			c.EP, _, err = ep.Accept(nil)
-			if err != nil {
-				t.Fatalf("Accept failed: %s", err)
-			}
-
-		case <-time.After(1 * time.Second):
-			t.Fatalf("Timed out waiting for accept")
-		}
-	}
-
-	c.EP.Close()
-	checker.IPv4(t, c.GetPacket(), checker.TCP(
-		checker.SrcPort(context.StackPort),
-		checker.DstPort(context.TestPort),
-		checker.TCPSeqNum(uint32(c.IRS+1)),
-		checker.TCPAckNum(uint32(iss)+1),
-		checker.TCPFlags(header.TCPFlagFin|header.TCPFlagAck)))
-
-	finHeaders := &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagAck | header.TCPFlagFin,
-		SeqNum:  iss + 1,
-		AckNum:  c.IRS + 2,
-	}
-
-	c.SendPacket(nil, finHeaders)
-
-	// Get the ACK to the FIN we just sent.
-	checker.IPv4(t, c.GetPacket(), checker.TCP(
-		checker.SrcPort(context.StackPort),
-		checker.DstPort(context.TestPort),
-		checker.TCPSeqNum(uint32(c.IRS+2)),
-		checker.TCPAckNum(uint32(iss)+2),
-		checker.TCPFlags(header.TCPFlagAck)))
-
-	// Out of order ACK should generate an immediate ACK in
-	// TIME_WAIT.
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss + 1,
-		AckNum:  c.IRS + 3,
-	})
-
-	checker.IPv4(t, c.GetPacket(), checker.TCP(
-		checker.SrcPort(context.StackPort),
-		checker.DstPort(context.TestPort),
-		checker.TCPSeqNum(uint32(c.IRS+2)),
-		checker.TCPAckNum(uint32(iss)+2),
-		checker.TCPFlags(header.TCPFlagAck)))
-}
-
-func TestTCPTimeWaitNewSyn(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	wq := &waiter.Queue{}
-	ep, err := c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, wq)
-	if err != nil {
-		t.Fatalf("NewEndpoint failed: %s", err)
-	}
-	if err := ep.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %s", err)
-	}
-
-	if err := ep.Listen(10); err != nil {
-		t.Fatalf("Listen failed: %s", err)
-	}
-
-	// Send a SYN request.
-	iss := seqnum.Value(context.TestInitialSequenceNumber)
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagSyn,
-		SeqNum:  iss,
-		RcvWnd:  30000,
-	})
-
-	// Receive the SYN-ACK reply.
-	b := c.GetPacket()
-	tcpHdr := header.TCP(header.IPv4(b).Payload())
-	c.IRS = seqnum.Value(tcpHdr.SequenceNumber())
-
-	ackHeaders := &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss + 1,
-		AckNum:  c.IRS + 1,
-	}
-
-	// Send ACK.
-	c.SendPacket(nil, ackHeaders)
-
-	// Try to accept the connection.
-	we, ch := waiter.NewChannelEntry(nil)
-	wq.EventRegister(&we, waiter.EventIn)
-	defer wq.EventUnregister(&we)
-
-	c.EP, _, err = ep.Accept(nil)
-	if _, ok := err.(*tcpip.ErrWouldBlock); ok {
-		// Wait for connection to be established.
-		select {
-		case <-ch:
-			c.EP, _, err = ep.Accept(nil)
-			if err != nil {
-				t.Fatalf("Accept failed: %s", err)
-			}
-
-		case <-time.After(1 * time.Second):
-			t.Fatalf("Timed out waiting for accept")
-		}
-	}
-
-	c.EP.Close()
-	checker.IPv4(t, c.GetPacket(), checker.TCP(
-		checker.SrcPort(context.StackPort),
-		checker.DstPort(context.TestPort),
-		checker.TCPSeqNum(uint32(c.IRS+1)),
-		checker.TCPAckNum(uint32(iss)+1),
-		checker.TCPFlags(header.TCPFlagFin|header.TCPFlagAck)))
-
-	finHeaders := &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagAck | header.TCPFlagFin,
-		SeqNum:  iss + 1,
-		AckNum:  c.IRS + 2,
-	}
-
-	c.SendPacket(nil, finHeaders)
-
-	// Get the ACK to the FIN we just sent.
-	checker.IPv4(t, c.GetPacket(), checker.TCP(
-		checker.SrcPort(context.StackPort),
-		checker.DstPort(context.TestPort),
-		checker.TCPSeqNum(uint32(c.IRS+2)),
-		checker.TCPAckNum(uint32(iss)+2),
-		checker.TCPFlags(header.TCPFlagAck)))
-
-	// Send a SYN request w/ sequence number lower than
-	// the highest sequence number sent. We just reuse
-	// the same number.
-	iss = seqnum.Value(context.TestInitialSequenceNumber)
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagSyn,
-		SeqNum:  iss,
-		RcvWnd:  30000,
-	})
-
-	c.CheckNoPacketTimeout("unexpected packet received in response to SYN", 1*time.Second)
-
-	// drain any older notifications from the notification channel before attempting
-	// 2nd connection.
-	select {
-	case <-ch:
-	default:
-	}
-
-	// Send a SYN request w/ sequence number higher than
-	// the highest sequence number sent.
-	iss = iss.Add(3)
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagSyn,
-		SeqNum:  iss,
-		RcvWnd:  30000,
-	})
-
-	// Receive the SYN-ACK reply.
-	b = c.GetPacket()
-	tcpHdr = header.TCP(header.IPv4(b).Payload())
-	c.IRS = seqnum.Value(tcpHdr.SequenceNumber())
-
-	ackHeaders = &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss + 1,
-		AckNum:  c.IRS + 1,
-	}
-
-	// Send ACK.
-	c.SendPacket(nil, ackHeaders)
-
-	// Try to accept the connection.
-	c.EP, _, err = ep.Accept(nil)
-	if _, ok := err.(*tcpip.ErrWouldBlock); ok {
-		// Wait for connection to be established.
-		select {
-		case <-ch:
-			c.EP, _, err = ep.Accept(nil)
-			if err != nil {
-				t.Fatalf("Accept failed: %s", err)
-			}
-
-		case <-time.After(1 * time.Second):
-			t.Fatalf("Timed out waiting for accept")
-		}
-	}
-}
-
-func TestTCPTimeWaitDuplicateFINExtendsTimeWait(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	// Set TCPTimeWaitTimeout to 5 seconds so that sockets are marked closed
-	// after 5 seconds in TIME_WAIT state.
-	tcpTimeWaitTimeout := 5 * time.Second
-	opt := tcpip.TCPTimeWaitTimeoutOption(tcpTimeWaitTimeout)
-	if err := c.Stack().SetTransportProtocolOption(tcp.ProtocolNumber, &opt); err != nil {
-		t.Fatalf("SetTransportProtocolOption(%d, &%T(%s)): %s", tcp.ProtocolNumber, opt, tcpTimeWaitTimeout, err)
-	}
-
-	want := c.Stack().Stats().TCP.EstablishedClosed.Value() + 1
-
-	wq := &waiter.Queue{}
-	ep, err := c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, wq)
-	if err != nil {
-		t.Fatalf("NewEndpoint failed: %s", err)
-	}
-	if err := ep.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %s", err)
-	}
-
-	if err := ep.Listen(10); err != nil {
-		t.Fatalf("Listen failed: %s", err)
-	}
-
-	// Send a SYN request.
-	iss := seqnum.Value(context.TestInitialSequenceNumber)
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagSyn,
-		SeqNum:  iss,
-		RcvWnd:  30000,
-	})
-
-	// Receive the SYN-ACK reply.
-	b := c.GetPacket()
-	tcpHdr := header.TCP(header.IPv4(b).Payload())
-	c.IRS = seqnum.Value(tcpHdr.SequenceNumber())
-
-	ackHeaders := &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss + 1,
-		AckNum:  c.IRS + 1,
-	}
-
-	// Send ACK.
-	c.SendPacket(nil, ackHeaders)
-
-	// Try to accept the connection.
-	we, ch := waiter.NewChannelEntry(nil)
-	wq.EventRegister(&we, waiter.EventIn)
-	defer wq.EventUnregister(&we)
-
-	c.EP, _, err = ep.Accept(nil)
-	if _, ok := err.(*tcpip.ErrWouldBlock); ok {
-		// Wait for connection to be established.
-		select {
-		case <-ch:
-			c.EP, _, err = ep.Accept(nil)
-			if err != nil {
-				t.Fatalf("Accept failed: %s", err)
-			}
-
-		case <-time.After(1 * time.Second):
-			t.Fatalf("Timed out waiting for accept")
-		}
-	}
-
-	c.EP.Close()
-	checker.IPv4(t, c.GetPacket(), checker.TCP(
-		checker.SrcPort(context.StackPort),
-		checker.DstPort(context.TestPort),
-		checker.TCPSeqNum(uint32(c.IRS+1)),
-		checker.TCPAckNum(uint32(iss)+1),
-		checker.TCPFlags(header.TCPFlagFin|header.TCPFlagAck)))
-
-	finHeaders := &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagAck | header.TCPFlagFin,
-		SeqNum:  iss + 1,
-		AckNum:  c.IRS + 2,
-	}
-
-	c.SendPacket(nil, finHeaders)
-
-	// Get the ACK to the FIN we just sent.
-	checker.IPv4(t, c.GetPacket(), checker.TCP(
-		checker.SrcPort(context.StackPort),
-		checker.DstPort(context.TestPort),
-		checker.TCPSeqNum(uint32(c.IRS+2)),
-		checker.TCPAckNum(uint32(iss)+2),
-		checker.TCPFlags(header.TCPFlagAck)))
-
-	time.Sleep(2 * time.Second)
-
-	// Now send a duplicate FIN. This should cause the TIME_WAIT to extend
-	// by another 5 seconds and also send us a duplicate ACK as it should
-	// indicate that the final ACK was potentially lost.
-	c.SendPacket(nil, finHeaders)
-
-	// Get the ACK to the FIN we just sent.
-	checker.IPv4(t, c.GetPacket(), checker.TCP(
-		checker.SrcPort(context.StackPort),
-		checker.DstPort(context.TestPort),
-		checker.TCPSeqNum(uint32(c.IRS+2)),
-		checker.TCPAckNum(uint32(iss)+2),
-		checker.TCPFlags(header.TCPFlagAck)))
-
-	// Sleep for 4 seconds so at this point we are 1 second past the
-	// original tcpLingerTimeout of 5 seconds.
-	time.Sleep(4 * time.Second)
-
-	// Send an ACK and it should not generate any packet as the socket
-	// should still be in TIME_WAIT for another another 5 seconds due
-	// to the duplicate FIN we sent earlier.
-	*ackHeaders = *finHeaders
-	ackHeaders.SeqNum = ackHeaders.SeqNum + 1
-	ackHeaders.Flags = header.TCPFlagAck
-	c.SendPacket(nil, ackHeaders)
-
-	c.CheckNoPacketTimeout("unexpected packet received from endpoint in TIME_WAIT", 1*time.Second)
-	// Now sleep for another 2 seconds so that we are past the
-	// extended TIME_WAIT of 7 seconds (2 + 5).
-	time.Sleep(2 * time.Second)
-
-	// Resend the same ACK.
-	c.SendPacket(nil, ackHeaders)
-
-	// Receive the RST that should be generated as there is no valid
-	// endpoint.
-	checker.IPv4(t, c.GetPacket(), checker.TCP(
-		checker.SrcPort(context.StackPort),
-		checker.DstPort(context.TestPort),
-		checker.TCPSeqNum(uint32(ackHeaders.AckNum)),
-		checker.TCPAckNum(0),
-		checker.TCPFlags(header.TCPFlagRst)))
-
-	if got := c.Stack().Stats().TCP.EstablishedClosed.Value(); got != want {
-		t.Errorf("got c.Stack().Stats().TCP.EstablishedClosed = %d, want = %d", got, want)
-	}
-	if got := c.Stack().Stats().TCP.CurrentEstablished.Value(); got != 0 {
-		t.Errorf("got stats.TCP.CurrentEstablished.Value() = %d, want = 0", got)
-	}
-}
-
-func TestTCPCloseWithData(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	// Set TCPTimeWaitTimeout to 5 seconds so that sockets are marked closed
-	// after 5 seconds in TIME_WAIT state.
-	tcpTimeWaitTimeout := 5 * time.Second
-	opt := tcpip.TCPTimeWaitTimeoutOption(tcpTimeWaitTimeout)
-	if err := c.Stack().SetTransportProtocolOption(tcp.ProtocolNumber, &opt); err != nil {
-		t.Fatalf("SetTransportProtocolOption(%d, &%T(%s)): %s", tcp.ProtocolNumber, opt, tcpTimeWaitTimeout, err)
-	}
-
-	wq := &waiter.Queue{}
-	ep, err := c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, wq)
-	if err != nil {
-		t.Fatalf("NewEndpoint failed: %s", err)
-	}
-	if err := ep.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %s", err)
-	}
-
-	if err := ep.Listen(10); err != nil {
-		t.Fatalf("Listen failed: %s", err)
-	}
-
-	// Send a SYN request.
-	iss := seqnum.Value(context.TestInitialSequenceNumber)
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagSyn,
-		SeqNum:  iss,
-		RcvWnd:  30000,
-	})
-
-	// Receive the SYN-ACK reply.
-	b := c.GetPacket()
-	tcpHdr := header.TCP(header.IPv4(b).Payload())
-	c.IRS = seqnum.Value(tcpHdr.SequenceNumber())
-
-	ackHeaders := &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss + 1,
-		AckNum:  c.IRS + 1,
-		RcvWnd:  30000,
-	}
-
-	// Send ACK.
-	c.SendPacket(nil, ackHeaders)
-
-	// Try to accept the connection.
-	we, ch := waiter.NewChannelEntry(nil)
-	wq.EventRegister(&we, waiter.EventIn)
-	defer wq.EventUnregister(&we)
-
-	c.EP, _, err = ep.Accept(nil)
-	if _, ok := err.(*tcpip.ErrWouldBlock); ok {
-		// Wait for connection to be established.
-		select {
-		case <-ch:
-			c.EP, _, err = ep.Accept(nil)
-			if err != nil {
-				t.Fatalf("Accept failed: %s", err)
-			}
-
-		case <-time.After(1 * time.Second):
-			t.Fatalf("Timed out waiting for accept")
-		}
-	}
-
-	// Now trigger a passive close by sending a FIN.
-	finHeaders := &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagAck | header.TCPFlagFin,
-		SeqNum:  iss + 1,
-		AckNum:  c.IRS + 2,
-		RcvWnd:  30000,
-	}
-
-	c.SendPacket(nil, finHeaders)
-
-	// Get the ACK to the FIN we just sent.
-	checker.IPv4(t, c.GetPacket(), checker.TCP(
-		checker.SrcPort(context.StackPort),
-		checker.DstPort(context.TestPort),
-		checker.TCPSeqNum(uint32(c.IRS+1)),
-		checker.TCPAckNum(uint32(iss)+2),
-		checker.TCPFlags(header.TCPFlagAck)))
-
-	// Now write a few bytes and then close the endpoint.
-	data := []byte{1, 2, 3}
-
-	var r bytes.Reader
-	r.Reset(data)
-	if _, err := c.EP.Write(&r, tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %s", err)
-	}
-
-	// Check that data is received.
-	b = c.GetPacket()
-	checker.IPv4(t, b,
-		checker.PayloadLen(len(data)+header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(c.IRS)+1),
-			checker.TCPAckNum(uint32(iss)+2), // Acknum is initial sequence number + 1
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
-		),
-	)
-
-	if p := b[header.IPv4MinimumSize+header.TCPMinimumSize:]; !bytes.Equal(data, p) {
-		t.Errorf("got data = %x, want = %x", p, data)
-	}
-
-	c.EP.Close()
-	// Check the FIN.
-	checker.IPv4(t, c.GetPacket(), checker.TCP(
-		checker.SrcPort(context.StackPort),
-		checker.DstPort(context.TestPort),
-		checker.TCPSeqNum(uint32(c.IRS+1)+uint32(len(data))),
-		checker.TCPAckNum(uint32(iss+2)),
-		checker.TCPFlags(header.TCPFlagFin|header.TCPFlagAck)))
-
-	// First send a partial ACK.
-	ackHeaders = &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss + 2,
-		AckNum:  c.IRS + 1 + seqnum.Value(len(data)-1),
-		RcvWnd:  30000,
-	}
-	c.SendPacket(nil, ackHeaders)
-
-	// Now send a full ACK.
-	ackHeaders = &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss + 2,
-		AckNum:  c.IRS + 1 + seqnum.Value(len(data)),
-		RcvWnd:  30000,
-	}
-	c.SendPacket(nil, ackHeaders)
-
-	// Now ACK the FIN.
-	ackHeaders.AckNum++
-	c.SendPacket(nil, ackHeaders)
-
-	// Now send an ACK and we should get a RST back as the endpoint should
-	// be in CLOSED state.
-	ackHeaders = &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss + 2,
-		AckNum:  c.IRS + 1 + seqnum.Value(len(data)),
-		RcvWnd:  30000,
-	}
-	c.SendPacket(nil, ackHeaders)
-
-	// Check the RST.
-	checker.IPv4(t, c.GetPacket(), checker.TCP(
-		checker.SrcPort(context.StackPort),
-		checker.DstPort(context.TestPort),
-		checker.TCPSeqNum(uint32(ackHeaders.AckNum)),
-		checker.TCPAckNum(0),
-		checker.TCPFlags(header.TCPFlagRst)))
-}
-
-func TestTCPUserTimeout(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateConnected(context.TestInitialSequenceNumber, 30000, -1 /* epRcvBuf */)
-
-	waitEntry, notifyCh := waiter.NewChannelEntry(nil)
-	c.WQ.EventRegister(&waitEntry, waiter.EventHUp)
-	defer c.WQ.EventUnregister(&waitEntry)
-
-	origEstablishedTimedout := c.Stack().Stats().TCP.EstablishedTimedout.Value()
-
-	// Ensure that on the next retransmit timer fire, the user timeout has
-	// expired.
-	initRTO := 1 * time.Second
-	userTimeout := initRTO / 2
-	v := tcpip.TCPUserTimeoutOption(userTimeout)
-	if err := c.EP.SetSockOpt(&v); err != nil {
-		t.Fatalf("c.EP.SetSockOpt(&%T(%s): %s", v, userTimeout, err)
-	}
-
-	// Send some data and wait before ACKing it.
-	view := make([]byte, 3)
-	var r bytes.Reader
-	r.Reset(view)
-	if _, err := c.EP.Write(&r, tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %s", err)
-	}
-
-	next := uint32(c.IRS) + 1
-	iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(len(view)+header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(next),
-			checker.TCPAckNum(uint32(iss)),
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
-		),
-	)
-
-	// Wait for the retransmit timer to be fired and the user timeout to cause
-	// close of the connection.
-	select {
-	case <-notifyCh:
-	case <-time.After(2 * initRTO):
-		t.Fatalf("connection still alive after %s, should have been closed after :%s", 2*initRTO, userTimeout)
-	}
-
-	// No packet should be received as the connection should be silently
-	// closed due to timeout.
-	c.CheckNoPacket("unexpected packet received after userTimeout has expired")
-
-	next += uint32(len(view))
-
-	// The connection should be terminated after userTimeout has expired.
-	// Send an ACK to trigger a RST from the stack as the endpoint should
-	// be dead.
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss,
-		AckNum:  seqnum.Value(next),
-		RcvWnd:  30000,
-	})
-
-	checker.IPv4(t, c.GetPacket(),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(next)),
-			checker.TCPAckNum(uint32(0)),
-			checker.TCPFlags(header.TCPFlagRst),
-		),
-	)
-
-	ept := endpointTester{c.EP}
-	ept.CheckReadError(t, &tcpip.ErrTimeout{})
-
-	if got, want := c.Stack().Stats().TCP.EstablishedTimedout.Value(), origEstablishedTimedout+1; got != want {
-		t.Errorf("got c.Stack().Stats().TCP.EstablishedTimedout = %d, want = %d", got, want)
-	}
-	if got := c.Stack().Stats().TCP.CurrentConnected.Value(); got != 0 {
-		t.Errorf("got stats.TCP.CurrentConnected.Value() = %d, want = 0", got)
-	}
-}
-
-func TestKeepaliveWithUserTimeout(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateConnected(context.TestInitialSequenceNumber, 30000, -1 /* epRcvBuf */)
-
-	origEstablishedTimedout := c.Stack().Stats().TCP.EstablishedTimedout.Value()
-
-	const keepAliveIdle = 100 * time.Millisecond
-	const keepAliveInterval = 3 * time.Second
-	keepAliveIdleOption := tcpip.KeepaliveIdleOption(keepAliveIdle)
-	if err := c.EP.SetSockOpt(&keepAliveIdleOption); err != nil {
-		t.Fatalf("c.EP.SetSockOpt(&%T(%s)): %s", keepAliveIdleOption, keepAliveIdle, err)
-	}
-	keepAliveIntervalOption := tcpip.KeepaliveIntervalOption(keepAliveInterval)
-	if err := c.EP.SetSockOpt(&keepAliveIntervalOption); err != nil {
-		t.Fatalf("c.EP.SetSockOpt(&%T(%s)): %s", keepAliveIntervalOption, keepAliveInterval, err)
-	}
-	if err := c.EP.SetSockOptInt(tcpip.KeepaliveCountOption, 10); err != nil {
-		t.Fatalf("c.EP.SetSockOptInt(tcpip.KeepaliveCountOption, 10): %s", err)
-	}
-	c.EP.SocketOptions().SetKeepAlive(true)
-
-	// Set userTimeout to be the duration to be 1 keepalive
-	// probes. Which means that after the first probe is sent
-	// the second one should cause the connection to be
-	// closed due to userTimeout being hit.
-	userTimeout := tcpip.TCPUserTimeoutOption(keepAliveInterval)
-	if err := c.EP.SetSockOpt(&userTimeout); err != nil {
-		t.Fatalf("c.EP.SetSockOpt(&%T(%s)): %s", userTimeout, keepAliveInterval, err)
-	}
-
-	// Check that the connection is still alive.
-	ept := endpointTester{c.EP}
-	ept.CheckReadError(t, &tcpip.ErrWouldBlock{})
-
-	// Now receive 1 keepalives, but don't ACK it.
-	b := c.GetPacket()
-	iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	checker.IPv4(t, b,
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(c.IRS)),
-			checker.TCPAckNum(uint32(iss)),
-			checker.TCPFlags(header.TCPFlagAck),
-		),
-	)
-
-	// Sleep for a litte over the KeepAlive interval to make sure
-	// the timer has time to fire after the last ACK and close the
-	// close the socket.
-	time.Sleep(keepAliveInterval + keepAliveInterval/2)
-
-	// The connection should be closed with a timeout.
-	// Send an ACK to trigger a RST from the stack as the endpoint should
-	// be dead.
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss,
-		AckNum:  seqnum.Value(c.IRS + 1),
-		RcvWnd:  30000,
-	})
-
-	checker.IPv4(t, c.GetPacket(),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(c.IRS+1)),
-			checker.TCPAckNum(uint32(0)),
-			checker.TCPFlags(header.TCPFlagRst),
-		),
-	)
-
-	ept.CheckReadError(t, &tcpip.ErrTimeout{})
-	if got, want := c.Stack().Stats().TCP.EstablishedTimedout.Value(), origEstablishedTimedout+1; got != want {
-		t.Errorf("got c.Stack().Stats().TCP.EstablishedTimedout = %d, want = %d", got, want)
-	}
-	if got := c.Stack().Stats().TCP.CurrentConnected.Value(); got != 0 {
-		t.Errorf("got stats.TCP.CurrentConnected.Value() = %d, want = 0", got)
-	}
-}
-
-func TestIncreaseWindowOnRead(t *testing.T) {
-	// This test ensures that the endpoint sends an ack,
-	// after read() when the window grows by more than 1 MSS.
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	const rcvBuf = 65535 * 10
-	c.CreateConnected(context.TestInitialSequenceNumber, 30000, rcvBuf)
-
-	// Write chunks of ~30000 bytes. It's important that two
-	// payloads make it equal or longer than MSS.
-	remain := rcvBuf * 2
-	sent := 0
-	data := make([]byte, defaultMTU/2)
-	iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	for remain > len(data) {
-		c.SendPacket(data, &context.Headers{
-			SrcPort: context.TestPort,
-			DstPort: c.Port,
-			Flags:   header.TCPFlagAck,
-			SeqNum:  iss.Add(seqnum.Size(sent)),
-			AckNum:  c.IRS.Add(1),
-			RcvWnd:  30000,
-		})
-		sent += len(data)
-		remain -= len(data)
-		pkt := c.GetPacket()
-		checker.IPv4(t, pkt,
-			checker.PayloadLen(header.TCPMinimumSize),
-			checker.TCP(
-				checker.DstPort(context.TestPort),
-				checker.TCPSeqNum(uint32(c.IRS)+1),
-				checker.TCPAckNum(uint32(iss)+uint32(sent)),
-				checker.TCPFlags(header.TCPFlagAck),
-			),
-		)
-		// Break once the window drops below defaultMTU/2
-		if wnd := header.TCP(header.IPv4(pkt).Payload()).WindowSize(); wnd < defaultMTU/2 {
-			break
-		}
-	}
-
-	// We now have < 1 MSS in the buffer space. Read at least > 2 MSS
-	// worth of data as receive buffer space
-	w := tcpip.LimitedWriter{
-		W: ioutil.Discard,
-		// defaultMTU is a good enough estimate for the MSS used for this
-		// connection.
-		N: defaultMTU * 2,
-	}
-	for w.N != 0 {
-		_, err := c.EP.Read(&w, tcpip.ReadOptions{})
-		if err != nil {
-			t.Fatalf("Read failed: %s", err)
-		}
-	}
-
-	// After reading > MSS worth of data, we surely crossed MSS. See the ack:
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(c.IRS)+1),
-			checker.TCPAckNum(uint32(iss)+uint32(sent)),
-			checker.TCPWindow(uint16(0xffff)),
-			checker.TCPFlags(header.TCPFlagAck),
-		),
-	)
-}
-
-func TestIncreaseWindowOnBufferResize(t *testing.T) {
-	// This test ensures that the endpoint sends an ack,
-	// after available recv buffer grows to more than 1 MSS.
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	const rcvBuf = 65535 * 10
-	c.CreateConnected(context.TestInitialSequenceNumber, 30000, rcvBuf)
-
-	// Write chunks of ~30000 bytes. It's important that two
-	// payloads make it equal or longer than MSS.
-	remain := rcvBuf
-	sent := 0
-	data := make([]byte, defaultMTU/2)
-	iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	for remain > len(data) {
-		c.SendPacket(data, &context.Headers{
-			SrcPort: context.TestPort,
-			DstPort: c.Port,
-			Flags:   header.TCPFlagAck,
-			SeqNum:  iss.Add(seqnum.Size(sent)),
-			AckNum:  c.IRS.Add(1),
-			RcvWnd:  30000,
-		})
-		sent += len(data)
-		remain -= len(data)
-		checker.IPv4(t, c.GetPacket(),
-			checker.PayloadLen(header.TCPMinimumSize),
-			checker.TCP(
-				checker.DstPort(context.TestPort),
-				checker.TCPSeqNum(uint32(c.IRS)+1),
-				checker.TCPAckNum(uint32(iss)+uint32(sent)),
-				checker.TCPWindowLessThanEq(0xffff),
-				checker.TCPFlags(header.TCPFlagAck),
-			),
-		)
-	}
-
-	// Increasing the buffer from should generate an ACK,
-	// since window grew from small value to larger equal MSS
-	c.EP.SetSockOptInt(tcpip.ReceiveBufferSizeOption, rcvBuf*2)
-
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(c.IRS)+1),
-			checker.TCPAckNum(uint32(iss)+uint32(sent)),
-			checker.TCPWindow(uint16(0xffff)),
-			checker.TCPFlags(header.TCPFlagAck),
-		),
-	)
-}
-
-func TestTCPDeferAccept(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.Create(-1)
-
-	if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatal("Bind failed:", err)
-	}
-
-	if err := c.EP.Listen(10); err != nil {
-		t.Fatal("Listen failed:", err)
-	}
-
-	const tcpDeferAccept = 1 * time.Second
-	tcpDeferAcceptOption := tcpip.TCPDeferAcceptOption(tcpDeferAccept)
-	if err := c.EP.SetSockOpt(&tcpDeferAcceptOption); err != nil {
-		t.Fatalf("c.EP.SetSockOpt(&%T(%s)): %s", tcpDeferAcceptOption, tcpDeferAccept, err)
-	}
-
-	irs, iss := executeHandshake(t, c, context.TestPort, false /* synCookiesInUse */)
-
-	_, _, err := c.EP.Accept(nil)
-	if _, ok := err.(*tcpip.ErrWouldBlock); !ok {
-		t.Fatalf("got c.EP.Accept(nil) = %v, want: %s", err, &tcpip.ErrWouldBlock{})
-	}
-
-	// Send data. This should result in an acceptable endpoint.
-	c.SendPacket([]byte{1, 2, 3, 4}, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  irs + 1,
-		AckNum:  iss + 1,
-	})
-
-	// Receive ACK for the data we sent.
-	checker.IPv4(t, c.GetPacket(), checker.TCP(
-		checker.DstPort(context.TestPort),
-		checker.TCPFlags(header.TCPFlagAck),
-		checker.TCPSeqNum(uint32(iss+1)),
-		checker.TCPAckNum(uint32(irs+5))))
-
-	// Give a bit of time for the socket to be delivered to the accept queue.
-	time.Sleep(50 * time.Millisecond)
-	aep, _, err := c.EP.Accept(nil)
-	if err != nil {
-		t.Fatalf("got c.EP.Accept(nil) = %s, want: nil", err)
-	}
-
-	aep.Close()
-	// Closing aep without reading the data should trigger a RST.
-	checker.IPv4(t, c.GetPacket(), checker.TCP(
-		checker.DstPort(context.TestPort),
-		checker.TCPFlags(header.TCPFlagRst|header.TCPFlagAck),
-		checker.TCPSeqNum(uint32(iss+1)),
-		checker.TCPAckNum(uint32(irs+5))))
-}
-
-func TestTCPDeferAcceptTimeout(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.Create(-1)
-
-	if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatal("Bind failed:", err)
-	}
-
-	if err := c.EP.Listen(10); err != nil {
-		t.Fatal("Listen failed:", err)
-	}
-
-	const tcpDeferAccept = 1 * time.Second
-	tcpDeferAcceptOpt := tcpip.TCPDeferAcceptOption(tcpDeferAccept)
-	if err := c.EP.SetSockOpt(&tcpDeferAcceptOpt); err != nil {
-		t.Fatalf("c.EP.SetSockOpt(&%T(%s)) failed: %s", tcpDeferAcceptOpt, tcpDeferAccept, err)
-	}
-
-	irs, iss := executeHandshake(t, c, context.TestPort, false /* synCookiesInUse */)
-
-	_, _, err := c.EP.Accept(nil)
-	if _, ok := err.(*tcpip.ErrWouldBlock); !ok {
-		t.Fatalf("got c.EP.Accept(nil) = %v, want: %s", err, &tcpip.ErrWouldBlock{})
-	}
-
-	// Sleep for a little of the tcpDeferAccept timeout.
-	time.Sleep(tcpDeferAccept + 100*time.Millisecond)
-
-	// On timeout expiry we should get a SYN-ACK retransmission.
-	checker.IPv4(t, c.GetPacket(), checker.TCP(
-		checker.SrcPort(context.StackPort),
-		checker.DstPort(context.TestPort),
-		checker.TCPFlags(header.TCPFlagAck|header.TCPFlagSyn),
-		checker.TCPAckNum(uint32(irs)+1)))
-
-	// Send data. This should result in an acceptable endpoint.
-	c.SendPacket([]byte{1, 2, 3, 4}, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  irs + 1,
-		AckNum:  iss + 1,
-	})
-
-	// Receive ACK for the data we sent.
-	checker.IPv4(t, c.GetPacket(), checker.TCP(
-		checker.SrcPort(context.StackPort),
-		checker.DstPort(context.TestPort),
-		checker.TCPFlags(header.TCPFlagAck),
-		checker.TCPSeqNum(uint32(iss+1)),
-		checker.TCPAckNum(uint32(irs+5))))
-
-	// Give sometime for the endpoint to be delivered to the accept queue.
-	time.Sleep(50 * time.Millisecond)
-	aep, _, err := c.EP.Accept(nil)
-	if err != nil {
-		t.Fatalf("got c.EP.Accept(nil) = %s, want: nil", err)
-	}
-
-	aep.Close()
-	// Closing aep without reading the data should trigger a RST.
-	checker.IPv4(t, c.GetPacket(), checker.TCP(
-		checker.SrcPort(context.StackPort),
-		checker.DstPort(context.TestPort),
-		checker.TCPFlags(header.TCPFlagRst|header.TCPFlagAck),
-		checker.TCPSeqNum(uint32(iss+1)),
-		checker.TCPAckNum(uint32(irs+5))))
-}
-
-func TestResetDuringClose(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateConnected(context.TestInitialSequenceNumber, 30000, -1 /* epRecvBuf */)
-	// Send some data to make sure there is some unread
-	// data to trigger a reset on c.Close.
-	irs := c.IRS
-	iss := seqnum.Value(context.TestInitialSequenceNumber).Add(1)
-	c.SendPacket([]byte{1, 2, 3, 4}, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss,
-		AckNum:  irs.Add(1),
-		RcvWnd:  30000,
-	})
-
-	// Receive ACK for the data we sent.
-	checker.IPv4(t, c.GetPacket(), checker.TCP(
-		checker.DstPort(context.TestPort),
-		checker.TCPFlags(header.TCPFlagAck),
-		checker.TCPSeqNum(uint32(irs.Add(1))),
-		checker.TCPAckNum(uint32(iss)+4)))
-
-	// Close in a separate goroutine so that we can trigger
-	// a race with the RST we send below. This should not
-	// panic due to the route being released depeding on
-	// whether Close() sends an active RST or the RST sent
-	// below is processed by the worker first.
-	var wg sync.WaitGroup
-
-	wg.Add(1)
-	go func() {
-		defer wg.Done()
-		c.SendPacket(nil, &context.Headers{
-			SrcPort: context.TestPort,
-			DstPort: c.Port,
-			SeqNum:  iss.Add(4),
-			AckNum:  c.IRS.Add(5),
-			RcvWnd:  30000,
-			Flags:   header.TCPFlagRst,
-		})
-	}()
-
-	wg.Add(1)
-	go func() {
-		defer wg.Done()
-		c.EP.Close()
-	}()
-
-	wg.Wait()
-}
-
-func TestStackTimeWaitReuse(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	s := c.Stack()
-	var twReuse tcpip.TCPTimeWaitReuseOption
-	if err := s.TransportProtocolOption(tcp.ProtocolNumber, &twReuse); err != nil {
-		t.Fatalf("s.TransportProtocolOption(%v, %v) = %v", tcp.ProtocolNumber, &twReuse, err)
-	}
-	if got, want := twReuse, tcpip.TCPTimeWaitReuseLoopbackOnly; got != want {
-		t.Fatalf("got tcpip.TCPTimeWaitReuseOption: %v, want: %v", got, want)
-	}
-}
-
-func TestSetStackTimeWaitReuse(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	s := c.Stack()
-	testCases := []struct {
-		v   int
-		err tcpip.Error
-	}{
-		{int(tcpip.TCPTimeWaitReuseDisabled), nil},
-		{int(tcpip.TCPTimeWaitReuseGlobal), nil},
-		{int(tcpip.TCPTimeWaitReuseLoopbackOnly), nil},
-		{int(tcpip.TCPTimeWaitReuseLoopbackOnly) + 1, &tcpip.ErrInvalidOptionValue{}},
-		{int(tcpip.TCPTimeWaitReuseDisabled) - 1, &tcpip.ErrInvalidOptionValue{}},
-	}
-
-	for _, tc := range testCases {
-		opt := tcpip.TCPTimeWaitReuseOption(tc.v)
-		err := s.SetTransportProtocolOption(tcp.ProtocolNumber, &opt)
-		if got, want := err, tc.err; got != want {
-			t.Fatalf("s.SetTransportProtocolOption(%d, &%T(%d)) = %s, want = %s", tcp.ProtocolNumber, tc.v, tc.v, err, tc.err)
-		}
-		if tc.err != nil {
-			continue
-		}
-
-		var twReuse tcpip.TCPTimeWaitReuseOption
-		if err := s.TransportProtocolOption(tcp.ProtocolNumber, &twReuse); err != nil {
-			t.Fatalf("s.TransportProtocolOption(%v, %v) = %v, want nil", tcp.ProtocolNumber, &twReuse, err)
-		}
-
-		if got, want := twReuse, tcpip.TCPTimeWaitReuseOption(tc.v); got != want {
-			t.Fatalf("got tcpip.TCPTimeWaitReuseOption: %v, want: %v", got, want)
-		}
-	}
-}
-
-// generateRandomPayload generates a random byte slice of the specified length
-// causing a fatal test failure if it is unable to do so.
-func generateRandomPayload(t *testing.T, n int) []byte {
-	t.Helper()
-	buf := make([]byte, n)
-	if _, err := rand.Read(buf); err != nil {
-		t.Fatalf("rand.Read(buf) failed: %s", err)
-	}
-	return buf
-}
diff --git a/pkg/tcpip/transport/tcp/tcp_timestamp_test.go b/pkg/tcpip/transport/tcp/tcp_timestamp_test.go
deleted file mode 100644
index cb4f829..0000000
--- a/pkg/tcpip/transport/tcp/tcp_timestamp_test.go
+++ /dev/null
@@ -1,311 +0,0 @@
-// 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 tcp_test
-
-import (
-	"bytes"
-	"math/rand"
-	"testing"
-	"time"
-
-	"github.com/google/go-cmp/cmp"
-	"gvisor.dev/gvisor/pkg/tcpip"
-	"gvisor.dev/gvisor/pkg/tcpip/checker"
-	"gvisor.dev/gvisor/pkg/tcpip/header"
-	"gvisor.dev/gvisor/pkg/tcpip/transport/tcp"
-	"gvisor.dev/gvisor/pkg/tcpip/transport/tcp/testing/context"
-	"gvisor.dev/gvisor/pkg/waiter"
-)
-
-// createConnectedWithTimestampOption creates and connects c.ep with the
-// timestamp option enabled.
-func createConnectedWithTimestampOption(c *context.Context) *context.RawEndpoint {
-	return c.CreateConnectedWithOptions(header.TCPSynOptions{TS: true, TSVal: 1})
-}
-
-// TestTimeStampEnabledConnect tests that netstack sends the timestamp option on
-// an active connect and sets the TS Echo Reply fields correctly when the
-// SYN-ACK also indicates support for the TS option and provides a TSVal.
-func TestTimeStampEnabledConnect(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	rep := createConnectedWithTimestampOption(c)
-
-	// Register for read and validate that we have data to read.
-	we, ch := waiter.NewChannelEntry(nil)
-	c.WQ.EventRegister(&we, waiter.EventIn)
-	defer c.WQ.EventUnregister(&we)
-
-	// The following tests ensure that TS option once enabled behaves
-	// correctly as described in
-	// https://tools.ietf.org/html/rfc7323#section-4.3.
-	//
-	// We are not testing delayed ACKs here, but we do test out of order
-	// packet delivery and filling the sequence number hole created due to
-	// the out of order packet.
-	//
-	// The test also verifies that the sequence numbers and timestamps are
-	// as expected.
-	data := []byte{1, 2, 3}
-
-	// First we increment tsVal by a small amount.
-	tsVal := rep.TSVal + 100
-	rep.SendPacketWithTS(data, tsVal)
-	rep.VerifyACKWithTS(tsVal)
-
-	// Next we send an out of order packet.
-	rep.NextSeqNum += 3
-	tsVal += 200
-	rep.SendPacketWithTS(data, tsVal)
-
-	// The ACK should contain the original sequenceNumber and an older TS.
-	rep.NextSeqNum -= 6
-	rep.VerifyACKWithTS(tsVal - 200)
-
-	// Next we fill the hole and the returned ACK should contain the
-	// cumulative sequence number acking all data sent till now and have the
-	// latest timestamp sent below in its TSEcr field.
-	tsVal -= 100
-	rep.SendPacketWithTS(data, tsVal)
-	rep.NextSeqNum += 3
-	rep.VerifyACKWithTS(tsVal)
-
-	// Increment tsVal by a large value that doesn't result in a wrap around.
-	tsVal += 0x7fffffff
-	rep.SendPacketWithTS(data, tsVal)
-	rep.VerifyACKWithTS(tsVal)
-
-	// Increment tsVal again by a large value which should cause the
-	// timestamp value to wrap around. The returned ACK should contain the
-	// wrapped around timestamp in its tsEcr field and not the tsVal from
-	// the previous packet sent above.
-	tsVal += 0x7fffffff
-	rep.SendPacketWithTS(data, tsVal)
-	rep.VerifyACKWithTS(tsVal)
-
-	select {
-	case <-ch:
-	case <-time.After(1 * time.Second):
-		t.Fatalf("Timed out waiting for data to arrive")
-	}
-
-	// There should be 5 views to read and each of them should
-	// contain the same data.
-	for i := 0; i < 5; i++ {
-		buf := make([]byte, len(data))
-		w := tcpip.SliceWriter(buf)
-		result, err := c.EP.Read(&w, tcpip.ReadOptions{})
-		if err != nil {
-			t.Fatalf("Unexpected error from Read: %v", err)
-		}
-		if diff := cmp.Diff(tcpip.ReadResult{
-			Count: len(buf),
-			Total: len(buf),
-		}, result, checker.IgnoreCmpPath("ControlMessages")); diff != "" {
-			t.Errorf("Read: unexpected result (-want +got):\n%s", diff)
-		}
-		if got, want := buf, data; bytes.Compare(got, want) != 0 {
-			t.Fatalf("Data is different: got: %v, want: %v", got, want)
-		}
-	}
-}
-
-// TestTimeStampDisabledConnect tests that netstack sends timestamp option on an
-// active connect but if the SYN-ACK doesn't specify the TS option then
-// timestamp option is not enabled and future packets do not contain a
-// timestamp.
-func TestTimeStampDisabledConnect(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateConnectedWithOptions(header.TCPSynOptions{})
-}
-
-func timeStampEnabledAccept(t *testing.T, cookieEnabled bool, wndScale int, wndSize uint16) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	if cookieEnabled {
-		var opt tcpip.TCPSynRcvdCountThresholdOption
-		if err := c.Stack().SetTransportProtocolOption(tcp.ProtocolNumber, &opt); err != nil {
-			t.Fatalf("SetTransportProtocolOption(%d, &%T(%d)): %s", tcp.ProtocolNumber, opt, opt, err)
-		}
-	}
-
-	t.Logf("Test w/ CookieEnabled = %v", cookieEnabled)
-	tsVal := rand.Uint32()
-	c.AcceptWithOptions(wndScale, header.TCPSynOptions{MSS: defaultIPv4MSS, TS: true, TSVal: tsVal})
-
-	// Now send some data and validate that timestamp is echoed correctly in the ACK.
-	data := []byte{1, 2, 3}
-
-	var r bytes.Reader
-	r.Reset(data)
-	if _, err := c.EP.Write(&r, tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Unexpected error from Write: %s", err)
-	}
-
-	// Check that data is received and that the timestamp option TSEcr field
-	// matches the expected value.
-	b := c.GetPacket()
-	checker.IPv4(t, b,
-		// Add 12 bytes for the timestamp option + 2 NOPs to align at 4
-		// byte boundary.
-		checker.PayloadLen(len(data)+header.TCPMinimumSize+12),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(c.IRS)+1),
-			checker.TCPAckNum(790),
-			checker.TCPWindow(wndSize),
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
-			checker.TCPTimestampChecker(true, 0, tsVal+1),
-		),
-	)
-}
-
-// TestTimeStampEnabledAccept tests that if the SYN on a passive connect
-// specifies the Timestamp option then the Timestamp option is sent on a SYN-ACK
-// and echoes the tsVal field of the original SYN in the tcEcr field of the
-// SYN-ACK. We cover the cases where SYN cookies are enabled/disabled and verify
-// that Timestamp option is enabled in both cases if requested in the original
-// SYN.
-func TestTimeStampEnabledAccept(t *testing.T) {
-	testCases := []struct {
-		cookieEnabled bool
-		wndScale      int
-		wndSize       uint16
-	}{
-		{true, -1, 0xffff}, // When cookie is used window scaling is disabled.
-		// DefaultReceiveBufferSize is 1MB >> 5. Advertised window will be 1/2 of that.
-		{false, 5, 0x4000},
-	}
-	for _, tc := range testCases {
-		timeStampEnabledAccept(t, tc.cookieEnabled, tc.wndScale, tc.wndSize)
-	}
-}
-
-func timeStampDisabledAccept(t *testing.T, cookieEnabled bool, wndScale int, wndSize uint16) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	if cookieEnabled {
-		var opt tcpip.TCPSynRcvdCountThresholdOption
-		if err := c.Stack().SetTransportProtocolOption(tcp.ProtocolNumber, &opt); err != nil {
-			t.Fatalf("SetTransportProtocolOption(%d, &%T(%d)): %s", tcp.ProtocolNumber, opt, opt, err)
-		}
-	}
-
-	t.Logf("Test w/ CookieEnabled = %v", cookieEnabled)
-	c.AcceptWithOptions(wndScale, header.TCPSynOptions{MSS: defaultIPv4MSS})
-
-	// Now send some data with the accepted connection endpoint and validate
-	// that no timestamp option is sent in the TCP segment.
-	data := []byte{1, 2, 3}
-
-	var r bytes.Reader
-	r.Reset(data)
-	if _, err := c.EP.Write(&r, tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Unexpected error from Write: %s", err)
-	}
-
-	// Check that data is received and that the timestamp option is disabled
-	// when SYN cookies are enabled/disabled.
-	b := c.GetPacket()
-	checker.IPv4(t, b,
-		checker.PayloadLen(len(data)+header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.TCPSeqNum(uint32(c.IRS)+1),
-			checker.TCPAckNum(790),
-			checker.TCPWindow(wndSize),
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
-			checker.TCPTimestampChecker(false, 0, 0),
-		),
-	)
-}
-
-// TestTimeStampDisabledAccept tests that Timestamp option is not used when the
-// peer doesn't advertise it and connection is established with Accept().
-func TestTimeStampDisabledAccept(t *testing.T) {
-	testCases := []struct {
-		cookieEnabled bool
-		wndScale      int
-		wndSize       uint16
-	}{
-		{true, -1, 0xffff}, // When cookie is used window scaling is disabled.
-		// DefaultReceiveBufferSize is 1MB >> 5. Advertised window will be half of
-		// that.
-		{false, 5, 0x4000},
-	}
-	for _, tc := range testCases {
-		timeStampDisabledAccept(t, tc.cookieEnabled, tc.wndScale, tc.wndSize)
-	}
-}
-
-func TestSendGreaterThanMTUWithOptions(t *testing.T) {
-	const maxPayload = 100
-	c := context.New(t, uint32(header.TCPMinimumSize+header.IPv4MinimumSize+maxPayload))
-	defer c.Cleanup()
-
-	createConnectedWithTimestampOption(c)
-	testBrokenUpWrite(t, c, maxPayload)
-}
-
-func TestSegmentNotDroppedWhenTimestampMissing(t *testing.T) {
-	const maxPayload = 100
-	c := context.New(t, uint32(header.TCPMinimumSize+header.IPv4MinimumSize+maxPayload))
-	defer c.Cleanup()
-
-	rep := createConnectedWithTimestampOption(c)
-
-	// Register for read.
-	we, ch := waiter.NewChannelEntry(nil)
-	c.WQ.EventRegister(&we, waiter.EventIn)
-	defer c.WQ.EventUnregister(&we)
-
-	droppedPacketsStat := c.Stack().Stats().DroppedPackets
-	droppedPackets := droppedPacketsStat.Value()
-	data := []byte{1, 2, 3}
-	// Send a packet with no TCP options/timestamp.
-	rep.SendPacket(data, nil)
-
-	select {
-	case <-ch:
-	case <-time.After(1 * time.Second):
-		t.Fatalf("Timed out waiting for data to arrive")
-	}
-
-	// Assert that DroppedPackets was not incremented.
-	if got, want := droppedPacketsStat.Value(), droppedPackets; got != want {
-		t.Fatalf("incorrect number of dropped packets, got: %v, want: %v", got, want)
-	}
-
-	// Issue a read and we should data.
-	var buf bytes.Buffer
-	result, err := c.EP.Read(&buf, tcpip.ReadOptions{})
-	if err != nil {
-		t.Fatalf("Unexpected error from Read: %v", err)
-	}
-	if diff := cmp.Diff(tcpip.ReadResult{
-		Count: buf.Len(),
-		Total: buf.Len(),
-	}, result, checker.IgnoreCmpPath("ControlMessages")); diff != "" {
-		t.Errorf("Read: unexpected result (-want +got):\n%s", diff)
-	}
-	if got, want := buf.Bytes(), data; bytes.Compare(got, want) != 0 {
-		t.Fatalf("Data is different: got: %v, want: %v", got, want)
-	}
-}
diff --git a/pkg/tcpip/transport/tcp/tcp_unsafe_state_autogen.go b/pkg/tcpip/transport/tcp/tcp_unsafe_state_autogen.go
new file mode 100644
index 0000000..4cb82fc
--- /dev/null
+++ b/pkg/tcpip/transport/tcp/tcp_unsafe_state_autogen.go
@@ -0,0 +1,3 @@
+// automatically generated by stateify.
+
+package tcp
diff --git a/pkg/tcpip/transport/tcp/timer_test.go b/pkg/tcpip/transport/tcp/timer_test.go
deleted file mode 100644
index dbd6dff..0000000
--- a/pkg/tcpip/transport/tcp/timer_test.go
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2020 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 tcp
-
-import (
-	"testing"
-	"time"
-
-	"gvisor.dev/gvisor/pkg/sleep"
-)
-
-func TestCleanup(t *testing.T) {
-	const (
-		timerDurationSeconds     = 2
-		isAssertedTimeoutSeconds = timerDurationSeconds + 1
-	)
-
-	tmr := timer{}
-	w := sleep.Waker{}
-	tmr.init(&w)
-	tmr.enable(timerDurationSeconds * time.Second)
-	tmr.cleanup()
-
-	if want := (timer{}); tmr != want {
-		t.Errorf("got tmr = %+v, want = %+v", tmr, want)
-	}
-
-	// The waker should not be asserted.
-	for i := 0; i < isAssertedTimeoutSeconds; i++ {
-		time.Sleep(time.Second)
-		if w.IsAsserted() {
-			t.Fatalf("waker asserted unexpectedly")
-		}
-	}
-}
diff --git a/pkg/tcpip/transport/tcpconntrack/tcp_conntrack_test.go b/pkg/tcpip/transport/tcpconntrack/tcp_conntrack_test.go
deleted file mode 100644
index 6c5ddc3..0000000
--- a/pkg/tcpip/transport/tcpconntrack/tcp_conntrack_test.go
+++ /dev/null
@@ -1,511 +0,0 @@
-// 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 tcpconntrack_test
-
-import (
-	"testing"
-
-	"gvisor.dev/gvisor/pkg/tcpip/header"
-	"gvisor.dev/gvisor/pkg/tcpip/transport/tcpconntrack"
-)
-
-// connected creates a connection tracker TCB and sets it to a connected state
-// by performing a 3-way handshake.
-func connected(t *testing.T, iss, irs uint32, isw, irw uint16) *tcpconntrack.TCB {
-	// Send SYN.
-	tcp := make(header.TCP, header.TCPMinimumSize)
-	tcp.Encode(&header.TCPFields{
-		SeqNum:     iss,
-		AckNum:     0,
-		DataOffset: header.TCPMinimumSize,
-		Flags:      header.TCPFlagSyn,
-		WindowSize: irw,
-	})
-
-	tcb := tcpconntrack.TCB{}
-	tcb.Init(tcp)
-
-	// Receive SYN-ACK.
-	tcp.Encode(&header.TCPFields{
-		SeqNum:     irs,
-		AckNum:     iss + 1,
-		DataOffset: header.TCPMinimumSize,
-		Flags:      header.TCPFlagSyn | header.TCPFlagAck,
-		WindowSize: isw,
-	})
-
-	if r := tcb.UpdateStateInbound(tcp); r != tcpconntrack.ResultAlive {
-		t.Fatalf("Bad result: got %v, want %v", r, tcpconntrack.ResultAlive)
-	}
-
-	// Send ACK.
-	tcp.Encode(&header.TCPFields{
-		SeqNum:     iss + 1,
-		AckNum:     irs + 1,
-		DataOffset: header.TCPMinimumSize,
-		Flags:      header.TCPFlagAck,
-		WindowSize: irw,
-	})
-
-	if r := tcb.UpdateStateOutbound(tcp); r != tcpconntrack.ResultAlive {
-		t.Fatalf("Bad result: got %v, want %v", r, tcpconntrack.ResultAlive)
-	}
-
-	return &tcb
-}
-
-func TestConnectionRefused(t *testing.T) {
-	// Send SYN.
-	tcp := make(header.TCP, header.TCPMinimumSize)
-	tcp.Encode(&header.TCPFields{
-		SeqNum:     1234,
-		AckNum:     0,
-		DataOffset: header.TCPMinimumSize,
-		Flags:      header.TCPFlagSyn,
-		WindowSize: 30000,
-	})
-
-	tcb := tcpconntrack.TCB{}
-	tcb.Init(tcp)
-
-	// Receive RST.
-	tcp.Encode(&header.TCPFields{
-		SeqNum:     789,
-		AckNum:     1235,
-		DataOffset: header.TCPMinimumSize,
-		Flags:      header.TCPFlagRst | header.TCPFlagAck,
-		WindowSize: 50000,
-	})
-
-	if r := tcb.UpdateStateInbound(tcp); r != tcpconntrack.ResultReset {
-		t.Fatalf("Bad result: got %v, want %v", r, tcpconntrack.ResultReset)
-	}
-}
-
-func TestConnectionRefusedInSynRcvd(t *testing.T) {
-	// Send SYN.
-	tcp := make(header.TCP, header.TCPMinimumSize)
-	tcp.Encode(&header.TCPFields{
-		SeqNum:     1234,
-		AckNum:     0,
-		DataOffset: header.TCPMinimumSize,
-		Flags:      header.TCPFlagSyn,
-		WindowSize: 30000,
-	})
-
-	tcb := tcpconntrack.TCB{}
-	tcb.Init(tcp)
-
-	// Receive SYN.
-	tcp.Encode(&header.TCPFields{
-		SeqNum:     789,
-		AckNum:     0,
-		DataOffset: header.TCPMinimumSize,
-		Flags:      header.TCPFlagSyn,
-		WindowSize: 50000,
-	})
-
-	if r := tcb.UpdateStateInbound(tcp); r != tcpconntrack.ResultAlive {
-		t.Fatalf("Bad result: got %v, want %v", r, tcpconntrack.ResultAlive)
-	}
-
-	// Receive RST with no ACK.
-	tcp.Encode(&header.TCPFields{
-		SeqNum:     790,
-		AckNum:     0,
-		DataOffset: header.TCPMinimumSize,
-		Flags:      header.TCPFlagRst,
-		WindowSize: 50000,
-	})
-
-	if r := tcb.UpdateStateInbound(tcp); r != tcpconntrack.ResultReset {
-		t.Fatalf("Bad result: got %v, want %v", r, tcpconntrack.ResultReset)
-	}
-}
-
-func TestConnectionResetInSynRcvd(t *testing.T) {
-	// Send SYN.
-	tcp := make(header.TCP, header.TCPMinimumSize)
-	tcp.Encode(&header.TCPFields{
-		SeqNum:     1234,
-		AckNum:     0,
-		DataOffset: header.TCPMinimumSize,
-		Flags:      header.TCPFlagSyn,
-		WindowSize: 30000,
-	})
-
-	tcb := tcpconntrack.TCB{}
-	tcb.Init(tcp)
-
-	// Receive SYN.
-	tcp.Encode(&header.TCPFields{
-		SeqNum:     789,
-		AckNum:     0,
-		DataOffset: header.TCPMinimumSize,
-		Flags:      header.TCPFlagSyn,
-		WindowSize: 50000,
-	})
-
-	if r := tcb.UpdateStateInbound(tcp); r != tcpconntrack.ResultAlive {
-		t.Fatalf("Bad result: got %v, want %v", r, tcpconntrack.ResultAlive)
-	}
-
-	// Send RST with no ACK.
-	tcp.Encode(&header.TCPFields{
-		SeqNum:     1235,
-		AckNum:     0,
-		DataOffset: header.TCPMinimumSize,
-		Flags:      header.TCPFlagRst,
-	})
-
-	if r := tcb.UpdateStateOutbound(tcp); r != tcpconntrack.ResultReset {
-		t.Fatalf("Bad result: got %v, want %v", r, tcpconntrack.ResultReset)
-	}
-}
-
-func TestRetransmitOnSynSent(t *testing.T) {
-	// Send initial SYN.
-	tcp := make(header.TCP, header.TCPMinimumSize)
-	tcp.Encode(&header.TCPFields{
-		SeqNum:     1234,
-		AckNum:     0,
-		DataOffset: header.TCPMinimumSize,
-		Flags:      header.TCPFlagSyn,
-		WindowSize: 30000,
-	})
-
-	tcb := tcpconntrack.TCB{}
-	tcb.Init(tcp)
-
-	// Retransmit the same SYN.
-	if r := tcb.UpdateStateOutbound(tcp); r != tcpconntrack.ResultConnecting {
-		t.Fatalf("Bad result: got %v, want %v", r, tcpconntrack.ResultConnecting)
-	}
-}
-
-func TestRetransmitOnSynRcvd(t *testing.T) {
-	// Send initial SYN.
-	tcp := make(header.TCP, header.TCPMinimumSize)
-	tcp.Encode(&header.TCPFields{
-		SeqNum:     1234,
-		AckNum:     0,
-		DataOffset: header.TCPMinimumSize,
-		Flags:      header.TCPFlagSyn,
-		WindowSize: 30000,
-	})
-
-	tcb := tcpconntrack.TCB{}
-	tcb.Init(tcp)
-
-	// Receive SYN. This will cause the state to go to SYN-RCVD.
-	tcp.Encode(&header.TCPFields{
-		SeqNum:     789,
-		AckNum:     0,
-		DataOffset: header.TCPMinimumSize,
-		Flags:      header.TCPFlagSyn,
-		WindowSize: 50000,
-	})
-
-	if r := tcb.UpdateStateInbound(tcp); r != tcpconntrack.ResultAlive {
-		t.Fatalf("Bad result: got %v, want %v", r, tcpconntrack.ResultAlive)
-	}
-
-	// Retransmit the original SYN.
-	tcp.Encode(&header.TCPFields{
-		SeqNum:     1234,
-		AckNum:     0,
-		DataOffset: header.TCPMinimumSize,
-		Flags:      header.TCPFlagSyn,
-		WindowSize: 30000,
-	})
-
-	if r := tcb.UpdateStateOutbound(tcp); r != tcpconntrack.ResultAlive {
-		t.Fatalf("Bad result: got %v, want %v", r, tcpconntrack.ResultAlive)
-	}
-
-	// Transmit a SYN-ACK.
-	tcp.Encode(&header.TCPFields{
-		SeqNum:     1234,
-		AckNum:     790,
-		DataOffset: header.TCPMinimumSize,
-		Flags:      header.TCPFlagSyn | header.TCPFlagAck,
-		WindowSize: 30000,
-	})
-
-	if r := tcb.UpdateStateOutbound(tcp); r != tcpconntrack.ResultAlive {
-		t.Fatalf("Bad result: got %v, want %v", r, tcpconntrack.ResultAlive)
-	}
-}
-
-func TestClosedBySelf(t *testing.T) {
-	tcb := connected(t, 1234, 789, 30000, 50000)
-
-	// Send FIN.
-	tcp := make(header.TCP, header.TCPMinimumSize)
-	tcp.Encode(&header.TCPFields{
-		SeqNum:     1235,
-		AckNum:     790,
-		DataOffset: header.TCPMinimumSize,
-		Flags:      header.TCPFlagAck | header.TCPFlagFin,
-		WindowSize: 30000,
-	})
-
-	if r := tcb.UpdateStateOutbound(tcp); r != tcpconntrack.ResultAlive {
-		t.Fatalf("Bad result: got %v, want %v", r, tcpconntrack.ResultAlive)
-	}
-
-	// Receive FIN/ACK.
-	tcp.Encode(&header.TCPFields{
-		SeqNum:     790,
-		AckNum:     1236,
-		DataOffset: header.TCPMinimumSize,
-		Flags:      header.TCPFlagAck | header.TCPFlagFin,
-		WindowSize: 50000,
-	})
-
-	if r := tcb.UpdateStateInbound(tcp); r != tcpconntrack.ResultAlive {
-		t.Fatalf("Bad result: got %v, want %v", r, tcpconntrack.ResultAlive)
-	}
-
-	// Send ACK.
-	tcp.Encode(&header.TCPFields{
-		SeqNum:     1236,
-		AckNum:     791,
-		DataOffset: header.TCPMinimumSize,
-		Flags:      header.TCPFlagAck,
-		WindowSize: 30000,
-	})
-
-	if r := tcb.UpdateStateOutbound(tcp); r != tcpconntrack.ResultClosedBySelf {
-		t.Fatalf("Bad result: got %v, want %v", r, tcpconntrack.ResultClosedBySelf)
-	}
-}
-
-func TestClosedByPeer(t *testing.T) {
-	tcb := connected(t, 1234, 789, 30000, 50000)
-
-	// Receive FIN.
-	tcp := make(header.TCP, header.TCPMinimumSize)
-	tcp.Encode(&header.TCPFields{
-		SeqNum:     790,
-		AckNum:     1235,
-		DataOffset: header.TCPMinimumSize,
-		Flags:      header.TCPFlagAck | header.TCPFlagFin,
-		WindowSize: 50000,
-	})
-
-	if r := tcb.UpdateStateInbound(tcp); r != tcpconntrack.ResultAlive {
-		t.Fatalf("Bad result: got %v, want %v", r, tcpconntrack.ResultAlive)
-	}
-
-	// Send FIN/ACK.
-	tcp.Encode(&header.TCPFields{
-		SeqNum:     1235,
-		AckNum:     791,
-		DataOffset: header.TCPMinimumSize,
-		Flags:      header.TCPFlagAck | header.TCPFlagFin,
-		WindowSize: 30000,
-	})
-
-	if r := tcb.UpdateStateOutbound(tcp); r != tcpconntrack.ResultAlive {
-		t.Fatalf("Bad result: got %v, want %v", r, tcpconntrack.ResultAlive)
-	}
-
-	// Receive ACK.
-	tcp.Encode(&header.TCPFields{
-		SeqNum:     791,
-		AckNum:     1236,
-		DataOffset: header.TCPMinimumSize,
-		Flags:      header.TCPFlagAck,
-		WindowSize: 50000,
-	})
-
-	if r := tcb.UpdateStateInbound(tcp); r != tcpconntrack.ResultClosedByPeer {
-		t.Fatalf("Bad result: got %v, want %v", r, tcpconntrack.ResultClosedByPeer)
-	}
-}
-
-func TestSendAndReceiveDataClosedBySelf(t *testing.T) {
-	sseq := uint32(1234)
-	rseq := uint32(789)
-	tcb := connected(t, sseq, rseq, 30000, 50000)
-	sseq++
-	rseq++
-
-	// Send some data.
-	tcp := make(header.TCP, header.TCPMinimumSize+1024)
-
-	for i := uint32(0); i < 10; i++ {
-		// Send some data.
-		tcp.Encode(&header.TCPFields{
-			SeqNum:     sseq,
-			AckNum:     rseq,
-			DataOffset: header.TCPMinimumSize,
-			Flags:      header.TCPFlagAck,
-			WindowSize: 30000,
-		})
-		sseq += uint32(len(tcp)) - header.TCPMinimumSize
-
-		if r := tcb.UpdateStateOutbound(tcp); r != tcpconntrack.ResultAlive {
-			t.Fatalf("Bad result: got %v, want %v", r, tcpconntrack.ResultAlive)
-		}
-
-		// Receive ack for data.
-		tcp.Encode(&header.TCPFields{
-			SeqNum:     rseq,
-			AckNum:     sseq,
-			DataOffset: header.TCPMinimumSize,
-			Flags:      header.TCPFlagAck,
-			WindowSize: 50000,
-		})
-
-		if r := tcb.UpdateStateInbound(tcp[:header.TCPMinimumSize]); r != tcpconntrack.ResultAlive {
-			t.Fatalf("Bad result: got %v, want %v", r, tcpconntrack.ResultAlive)
-		}
-	}
-
-	for i := uint32(0); i < 10; i++ {
-		// Receive some data.
-		tcp.Encode(&header.TCPFields{
-			SeqNum:     rseq,
-			AckNum:     sseq,
-			DataOffset: header.TCPMinimumSize,
-			Flags:      header.TCPFlagAck,
-			WindowSize: 50000,
-		})
-		rseq += uint32(len(tcp)) - header.TCPMinimumSize
-
-		if r := tcb.UpdateStateInbound(tcp); r != tcpconntrack.ResultAlive {
-			t.Fatalf("Bad result: got %v, want %v", r, tcpconntrack.ResultAlive)
-		}
-
-		// Send ack for data.
-		tcp.Encode(&header.TCPFields{
-			SeqNum:     sseq,
-			AckNum:     rseq,
-			DataOffset: header.TCPMinimumSize,
-			Flags:      header.TCPFlagAck,
-			WindowSize: 30000,
-		})
-
-		if r := tcb.UpdateStateOutbound(tcp[:header.TCPMinimumSize]); r != tcpconntrack.ResultAlive {
-			t.Fatalf("Bad result: got %v, want %v", r, tcpconntrack.ResultAlive)
-		}
-	}
-
-	// Send FIN.
-	tcp = tcp[:header.TCPMinimumSize]
-	tcp.Encode(&header.TCPFields{
-		SeqNum:     sseq,
-		AckNum:     rseq,
-		DataOffset: header.TCPMinimumSize,
-		Flags:      header.TCPFlagAck | header.TCPFlagFin,
-		WindowSize: 30000,
-	})
-	sseq++
-
-	if r := tcb.UpdateStateOutbound(tcp); r != tcpconntrack.ResultAlive {
-		t.Fatalf("Bad result: got %v, want %v", r, tcpconntrack.ResultAlive)
-	}
-
-	// Receive FIN/ACK.
-	tcp.Encode(&header.TCPFields{
-		SeqNum:     rseq,
-		AckNum:     sseq,
-		DataOffset: header.TCPMinimumSize,
-		Flags:      header.TCPFlagAck | header.TCPFlagFin,
-		WindowSize: 50000,
-	})
-	rseq++
-
-	if r := tcb.UpdateStateInbound(tcp); r != tcpconntrack.ResultAlive {
-		t.Fatalf("Bad result: got %v, want %v", r, tcpconntrack.ResultAlive)
-	}
-
-	// Send ACK.
-	tcp.Encode(&header.TCPFields{
-		SeqNum:     sseq,
-		AckNum:     rseq,
-		DataOffset: header.TCPMinimumSize,
-		Flags:      header.TCPFlagAck,
-		WindowSize: 30000,
-	})
-
-	if r := tcb.UpdateStateOutbound(tcp); r != tcpconntrack.ResultClosedBySelf {
-		t.Fatalf("Bad result: got %v, want %v", r, tcpconntrack.ResultClosedBySelf)
-	}
-}
-
-func TestIgnoreBadResetOnSynSent(t *testing.T) {
-	// Send SYN.
-	tcp := make(header.TCP, header.TCPMinimumSize)
-	tcp.Encode(&header.TCPFields{
-		SeqNum:     1234,
-		AckNum:     0,
-		DataOffset: header.TCPMinimumSize,
-		Flags:      header.TCPFlagSyn,
-		WindowSize: 30000,
-	})
-
-	tcb := tcpconntrack.TCB{}
-	tcb.Init(tcp)
-
-	// Receive a RST with a bad ACK, it should not cause the connection to
-	// be reset.
-	acks := []uint32{1234, 1236, 1000, 5000}
-	flags := []header.TCPFlags{header.TCPFlagRst, header.TCPFlagRst | header.TCPFlagAck}
-	for _, a := range acks {
-		for _, f := range flags {
-			tcp.Encode(&header.TCPFields{
-				SeqNum:     789,
-				AckNum:     a,
-				DataOffset: header.TCPMinimumSize,
-				Flags:      f,
-				WindowSize: 50000,
-			})
-
-			if r := tcb.UpdateStateInbound(tcp); r != tcpconntrack.ResultConnecting {
-				t.Fatalf("Bad result: got %v, want %v", r, tcpconntrack.ResultAlive)
-			}
-		}
-	}
-
-	// Complete the handshake.
-	// Receive SYN-ACK.
-	tcp.Encode(&header.TCPFields{
-		SeqNum:     789,
-		AckNum:     1235,
-		DataOffset: header.TCPMinimumSize,
-		Flags:      header.TCPFlagSyn | header.TCPFlagAck,
-		WindowSize: 50000,
-	})
-
-	if r := tcb.UpdateStateInbound(tcp); r != tcpconntrack.ResultAlive {
-		t.Fatalf("Bad result: got %v, want %v", r, tcpconntrack.ResultAlive)
-	}
-
-	// Send ACK.
-	tcp.Encode(&header.TCPFields{
-		SeqNum:     1235,
-		AckNum:     790,
-		DataOffset: header.TCPMinimumSize,
-		Flags:      header.TCPFlagAck,
-		WindowSize: 30000,
-	})
-
-	if r := tcb.UpdateStateOutbound(tcp); r != tcpconntrack.ResultAlive {
-		t.Fatalf("Bad result: got %v, want %v", r, tcpconntrack.ResultAlive)
-	}
-}
diff --git a/pkg/tcpip/transport/tcpconntrack/tcpconntrack_state_autogen.go b/pkg/tcpip/transport/tcpconntrack/tcpconntrack_state_autogen.go
new file mode 100644
index 0000000..ff53204
--- /dev/null
+++ b/pkg/tcpip/transport/tcpconntrack/tcpconntrack_state_autogen.go
@@ -0,0 +1,3 @@
+// automatically generated by stateify.
+
+package tcpconntrack
diff --git a/pkg/tcpip/transport/udp/udp_packet_list.go b/pkg/tcpip/transport/udp/udp_packet_list.go
new file mode 100644
index 0000000..c396f77
--- /dev/null
+++ b/pkg/tcpip/transport/udp/udp_packet_list.go
@@ -0,0 +1,221 @@
+package udp
+
+// ElementMapper provides an identity mapping by default.
+//
+// This can be replaced to provide a struct that maps elements to linker
+// objects, if they are not the same. An ElementMapper is not typically
+// required if: Linker is left as is, Element is left as is, or Linker and
+// Element are the same type.
+type udpPacketElementMapper struct{}
+
+// linkerFor maps an Element to a Linker.
+//
+// This default implementation should be inlined.
+//
+//go:nosplit
+func (udpPacketElementMapper) linkerFor(elem *udpPacket) *udpPacket { return elem }
+
+// List is an intrusive list. Entries can be added to or removed from the list
+// in O(1) time and with no additional memory allocations.
+//
+// The zero value for List is an empty list ready to use.
+//
+// To iterate over a list (where l is a List):
+//      for e := l.Front(); e != nil; e = e.Next() {
+// 		// do something with e.
+//      }
+//
+// +stateify savable
+type udpPacketList struct {
+	head *udpPacket
+	tail *udpPacket
+}
+
+// Reset resets list l to the empty state.
+func (l *udpPacketList) Reset() {
+	l.head = nil
+	l.tail = nil
+}
+
+// Empty returns true iff the list is empty.
+//
+//go:nosplit
+func (l *udpPacketList) Empty() bool {
+	return l.head == nil
+}
+
+// Front returns the first element of list l or nil.
+//
+//go:nosplit
+func (l *udpPacketList) Front() *udpPacket {
+	return l.head
+}
+
+// Back returns the last element of list l or nil.
+//
+//go:nosplit
+func (l *udpPacketList) Back() *udpPacket {
+	return l.tail
+}
+
+// Len returns the number of elements in the list.
+//
+// NOTE: This is an O(n) operation.
+//
+//go:nosplit
+func (l *udpPacketList) Len() (count int) {
+	for e := l.Front(); e != nil; e = (udpPacketElementMapper{}.linkerFor(e)).Next() {
+		count++
+	}
+	return count
+}
+
+// PushFront inserts the element e at the front of list l.
+//
+//go:nosplit
+func (l *udpPacketList) PushFront(e *udpPacket) {
+	linker := udpPacketElementMapper{}.linkerFor(e)
+	linker.SetNext(l.head)
+	linker.SetPrev(nil)
+	if l.head != nil {
+		udpPacketElementMapper{}.linkerFor(l.head).SetPrev(e)
+	} else {
+		l.tail = e
+	}
+
+	l.head = e
+}
+
+// PushBack inserts the element e at the back of list l.
+//
+//go:nosplit
+func (l *udpPacketList) PushBack(e *udpPacket) {
+	linker := udpPacketElementMapper{}.linkerFor(e)
+	linker.SetNext(nil)
+	linker.SetPrev(l.tail)
+	if l.tail != nil {
+		udpPacketElementMapper{}.linkerFor(l.tail).SetNext(e)
+	} else {
+		l.head = e
+	}
+
+	l.tail = e
+}
+
+// PushBackList inserts list m at the end of list l, emptying m.
+//
+//go:nosplit
+func (l *udpPacketList) PushBackList(m *udpPacketList) {
+	if l.head == nil {
+		l.head = m.head
+		l.tail = m.tail
+	} else if m.head != nil {
+		udpPacketElementMapper{}.linkerFor(l.tail).SetNext(m.head)
+		udpPacketElementMapper{}.linkerFor(m.head).SetPrev(l.tail)
+
+		l.tail = m.tail
+	}
+	m.head = nil
+	m.tail = nil
+}
+
+// InsertAfter inserts e after b.
+//
+//go:nosplit
+func (l *udpPacketList) InsertAfter(b, e *udpPacket) {
+	bLinker := udpPacketElementMapper{}.linkerFor(b)
+	eLinker := udpPacketElementMapper{}.linkerFor(e)
+
+	a := bLinker.Next()
+
+	eLinker.SetNext(a)
+	eLinker.SetPrev(b)
+	bLinker.SetNext(e)
+
+	if a != nil {
+		udpPacketElementMapper{}.linkerFor(a).SetPrev(e)
+	} else {
+		l.tail = e
+	}
+}
+
+// InsertBefore inserts e before a.
+//
+//go:nosplit
+func (l *udpPacketList) InsertBefore(a, e *udpPacket) {
+	aLinker := udpPacketElementMapper{}.linkerFor(a)
+	eLinker := udpPacketElementMapper{}.linkerFor(e)
+
+	b := aLinker.Prev()
+	eLinker.SetNext(a)
+	eLinker.SetPrev(b)
+	aLinker.SetPrev(e)
+
+	if b != nil {
+		udpPacketElementMapper{}.linkerFor(b).SetNext(e)
+	} else {
+		l.head = e
+	}
+}
+
+// Remove removes e from l.
+//
+//go:nosplit
+func (l *udpPacketList) Remove(e *udpPacket) {
+	linker := udpPacketElementMapper{}.linkerFor(e)
+	prev := linker.Prev()
+	next := linker.Next()
+
+	if prev != nil {
+		udpPacketElementMapper{}.linkerFor(prev).SetNext(next)
+	} else if l.head == e {
+		l.head = next
+	}
+
+	if next != nil {
+		udpPacketElementMapper{}.linkerFor(next).SetPrev(prev)
+	} else if l.tail == e {
+		l.tail = prev
+	}
+
+	linker.SetNext(nil)
+	linker.SetPrev(nil)
+}
+
+// Entry is a default implementation of Linker. Users can add anonymous fields
+// of this type to their structs to make them automatically implement the
+// methods needed by List.
+//
+// +stateify savable
+type udpPacketEntry struct {
+	next *udpPacket
+	prev *udpPacket
+}
+
+// Next returns the entry that follows e in the list.
+//
+//go:nosplit
+func (e *udpPacketEntry) Next() *udpPacket {
+	return e.next
+}
+
+// Prev returns the entry that precedes e in the list.
+//
+//go:nosplit
+func (e *udpPacketEntry) Prev() *udpPacket {
+	return e.prev
+}
+
+// SetNext assigns 'entry' as the entry that follows e in the list.
+//
+//go:nosplit
+func (e *udpPacketEntry) SetNext(elem *udpPacket) {
+	e.next = elem
+}
+
+// SetPrev assigns 'entry' as the entry that precedes e in the list.
+//
+//go:nosplit
+func (e *udpPacketEntry) SetPrev(elem *udpPacket) {
+	e.prev = elem
+}
diff --git a/pkg/tcpip/transport/udp/udp_state_autogen.go b/pkg/tcpip/transport/udp/udp_state_autogen.go
new file mode 100644
index 0000000..5d7859a
--- /dev/null
+++ b/pkg/tcpip/transport/udp/udp_state_autogen.go
@@ -0,0 +1,239 @@
+// automatically generated by stateify.
+
+package udp
+
+import (
+	"gvisor.dev/gvisor/pkg/state"
+	"gvisor.dev/gvisor/pkg/tcpip/buffer"
+)
+
+func (u *udpPacket) StateTypeName() string {
+	return "pkg/tcpip/transport/udp.udpPacket"
+}
+
+func (u *udpPacket) StateFields() []string {
+	return []string{
+		"udpPacketEntry",
+		"senderAddress",
+		"destinationAddress",
+		"packetInfo",
+		"data",
+		"timestamp",
+		"tos",
+	}
+}
+
+func (u *udpPacket) beforeSave() {}
+
+// +checklocksignore
+func (u *udpPacket) StateSave(stateSinkObject state.Sink) {
+	u.beforeSave()
+	var dataValue buffer.VectorisedView = u.saveData()
+	stateSinkObject.SaveValue(4, dataValue)
+	stateSinkObject.Save(0, &u.udpPacketEntry)
+	stateSinkObject.Save(1, &u.senderAddress)
+	stateSinkObject.Save(2, &u.destinationAddress)
+	stateSinkObject.Save(3, &u.packetInfo)
+	stateSinkObject.Save(5, &u.timestamp)
+	stateSinkObject.Save(6, &u.tos)
+}
+
+func (u *udpPacket) afterLoad() {}
+
+// +checklocksignore
+func (u *udpPacket) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &u.udpPacketEntry)
+	stateSourceObject.Load(1, &u.senderAddress)
+	stateSourceObject.Load(2, &u.destinationAddress)
+	stateSourceObject.Load(3, &u.packetInfo)
+	stateSourceObject.Load(5, &u.timestamp)
+	stateSourceObject.Load(6, &u.tos)
+	stateSourceObject.LoadValue(4, new(buffer.VectorisedView), func(y interface{}) { u.loadData(y.(buffer.VectorisedView)) })
+}
+
+func (e *endpoint) StateTypeName() string {
+	return "pkg/tcpip/transport/udp.endpoint"
+}
+
+func (e *endpoint) StateFields() []string {
+	return []string{
+		"TransportEndpointInfo",
+		"DefaultSocketOptionsHandler",
+		"waiterQueue",
+		"uniqueID",
+		"rcvReady",
+		"rcvList",
+		"rcvBufSizeMax",
+		"rcvBufSize",
+		"rcvClosed",
+		"state",
+		"dstPort",
+		"ttl",
+		"multicastTTL",
+		"multicastAddr",
+		"multicastNICID",
+		"portFlags",
+		"lastError",
+		"boundBindToDevice",
+		"boundPortFlags",
+		"sendTOS",
+		"shutdownFlags",
+		"multicastMemberships",
+		"effectiveNetProtos",
+		"owner",
+		"ops",
+	}
+}
+
+// +checklocksignore
+func (e *endpoint) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+	var rcvBufSizeMaxValue int = e.saveRcvBufSizeMax()
+	stateSinkObject.SaveValue(6, rcvBufSizeMaxValue)
+	stateSinkObject.Save(0, &e.TransportEndpointInfo)
+	stateSinkObject.Save(1, &e.DefaultSocketOptionsHandler)
+	stateSinkObject.Save(2, &e.waiterQueue)
+	stateSinkObject.Save(3, &e.uniqueID)
+	stateSinkObject.Save(4, &e.rcvReady)
+	stateSinkObject.Save(5, &e.rcvList)
+	stateSinkObject.Save(7, &e.rcvBufSize)
+	stateSinkObject.Save(8, &e.rcvClosed)
+	stateSinkObject.Save(9, &e.state)
+	stateSinkObject.Save(10, &e.dstPort)
+	stateSinkObject.Save(11, &e.ttl)
+	stateSinkObject.Save(12, &e.multicastTTL)
+	stateSinkObject.Save(13, &e.multicastAddr)
+	stateSinkObject.Save(14, &e.multicastNICID)
+	stateSinkObject.Save(15, &e.portFlags)
+	stateSinkObject.Save(16, &e.lastError)
+	stateSinkObject.Save(17, &e.boundBindToDevice)
+	stateSinkObject.Save(18, &e.boundPortFlags)
+	stateSinkObject.Save(19, &e.sendTOS)
+	stateSinkObject.Save(20, &e.shutdownFlags)
+	stateSinkObject.Save(21, &e.multicastMemberships)
+	stateSinkObject.Save(22, &e.effectiveNetProtos)
+	stateSinkObject.Save(23, &e.owner)
+	stateSinkObject.Save(24, &e.ops)
+}
+
+// +checklocksignore
+func (e *endpoint) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &e.TransportEndpointInfo)
+	stateSourceObject.Load(1, &e.DefaultSocketOptionsHandler)
+	stateSourceObject.Load(2, &e.waiterQueue)
+	stateSourceObject.Load(3, &e.uniqueID)
+	stateSourceObject.Load(4, &e.rcvReady)
+	stateSourceObject.Load(5, &e.rcvList)
+	stateSourceObject.Load(7, &e.rcvBufSize)
+	stateSourceObject.Load(8, &e.rcvClosed)
+	stateSourceObject.Load(9, &e.state)
+	stateSourceObject.Load(10, &e.dstPort)
+	stateSourceObject.Load(11, &e.ttl)
+	stateSourceObject.Load(12, &e.multicastTTL)
+	stateSourceObject.Load(13, &e.multicastAddr)
+	stateSourceObject.Load(14, &e.multicastNICID)
+	stateSourceObject.Load(15, &e.portFlags)
+	stateSourceObject.Load(16, &e.lastError)
+	stateSourceObject.Load(17, &e.boundBindToDevice)
+	stateSourceObject.Load(18, &e.boundPortFlags)
+	stateSourceObject.Load(19, &e.sendTOS)
+	stateSourceObject.Load(20, &e.shutdownFlags)
+	stateSourceObject.Load(21, &e.multicastMemberships)
+	stateSourceObject.Load(22, &e.effectiveNetProtos)
+	stateSourceObject.Load(23, &e.owner)
+	stateSourceObject.Load(24, &e.ops)
+	stateSourceObject.LoadValue(6, new(int), func(y interface{}) { e.loadRcvBufSizeMax(y.(int)) })
+	stateSourceObject.AfterLoad(e.afterLoad)
+}
+
+func (m *multicastMembership) StateTypeName() string {
+	return "pkg/tcpip/transport/udp.multicastMembership"
+}
+
+func (m *multicastMembership) StateFields() []string {
+	return []string{
+		"nicID",
+		"multicastAddr",
+	}
+}
+
+func (m *multicastMembership) beforeSave() {}
+
+// +checklocksignore
+func (m *multicastMembership) StateSave(stateSinkObject state.Sink) {
+	m.beforeSave()
+	stateSinkObject.Save(0, &m.nicID)
+	stateSinkObject.Save(1, &m.multicastAddr)
+}
+
+func (m *multicastMembership) afterLoad() {}
+
+// +checklocksignore
+func (m *multicastMembership) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &m.nicID)
+	stateSourceObject.Load(1, &m.multicastAddr)
+}
+
+func (l *udpPacketList) StateTypeName() string {
+	return "pkg/tcpip/transport/udp.udpPacketList"
+}
+
+func (l *udpPacketList) StateFields() []string {
+	return []string{
+		"head",
+		"tail",
+	}
+}
+
+func (l *udpPacketList) beforeSave() {}
+
+// +checklocksignore
+func (l *udpPacketList) StateSave(stateSinkObject state.Sink) {
+	l.beforeSave()
+	stateSinkObject.Save(0, &l.head)
+	stateSinkObject.Save(1, &l.tail)
+}
+
+func (l *udpPacketList) afterLoad() {}
+
+// +checklocksignore
+func (l *udpPacketList) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &l.head)
+	stateSourceObject.Load(1, &l.tail)
+}
+
+func (e *udpPacketEntry) StateTypeName() string {
+	return "pkg/tcpip/transport/udp.udpPacketEntry"
+}
+
+func (e *udpPacketEntry) StateFields() []string {
+	return []string{
+		"next",
+		"prev",
+	}
+}
+
+func (e *udpPacketEntry) beforeSave() {}
+
+// +checklocksignore
+func (e *udpPacketEntry) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+	stateSinkObject.Save(0, &e.next)
+	stateSinkObject.Save(1, &e.prev)
+}
+
+func (e *udpPacketEntry) afterLoad() {}
+
+// +checklocksignore
+func (e *udpPacketEntry) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &e.next)
+	stateSourceObject.Load(1, &e.prev)
+}
+
+func init() {
+	state.Register((*udpPacket)(nil))
+	state.Register((*endpoint)(nil))
+	state.Register((*multicastMembership)(nil))
+	state.Register((*udpPacketList)(nil))
+	state.Register((*udpPacketEntry)(nil))
+}
diff --git a/pkg/tcpip/transport/udp/udp_test.go b/pkg/tcpip/transport/udp/udp_test.go
deleted file mode 100644
index c8126b5..0000000
--- a/pkg/tcpip/transport/udp/udp_test.go
+++ /dev/null
@@ -1,2565 +0,0 @@
-// 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 udp_test
-
-import (
-	"bytes"
-	"context"
-	"fmt"
-	"io/ioutil"
-	"math/rand"
-	"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/loopback"
-	"gvisor.dev/gvisor/pkg/tcpip/link/sniffer"
-	"gvisor.dev/gvisor/pkg/tcpip/network/ipv4"
-	"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"
-)
-
-// Addresses and ports used for testing. It is recommended that tests stick to
-// using these addresses as it allows using the testFlow helper.
-// Naming rules: 'stack*'' denotes local addresses and ports, while 'test*'
-// represents the remote endpoint.
-const (
-	v4MappedAddrPrefix    = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff"
-	stackV6Addr           = "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"
-	testV6Addr            = "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02"
-	stackV4MappedAddr     = v4MappedAddrPrefix + stackAddr
-	testV4MappedAddr      = v4MappedAddrPrefix + testAddr
-	multicastV4MappedAddr = v4MappedAddrPrefix + multicastAddr
-	broadcastV4MappedAddr = v4MappedAddrPrefix + broadcastAddr
-	v4MappedWildcardAddr  = v4MappedAddrPrefix + "\x00\x00\x00\x00"
-
-	stackAddr       = "\x0a\x00\x00\x01"
-	stackPort       = 1234
-	testAddr        = "\x0a\x00\x00\x02"
-	testPort        = 4096
-	invalidPort     = 8192
-	multicastAddr   = "\xe8\x2b\xd3\xea"
-	multicastV6Addr = "\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
-	broadcastAddr   = header.IPv4Broadcast
-	testTOS         = 0x80
-
-	// defaultMTU is the MTU, in bytes, used throughout the tests, except
-	// where another value is explicitly used. It is chosen to match the MTU
-	// of loopback interfaces on linux systems.
-	defaultMTU = 65536
-)
-
-// header4Tuple stores the 4-tuple {src-IP, src-port, dst-IP, dst-port} used in
-// a packet header. These values are used to populate a header or verify one.
-// Note that because they are used in packet headers, the addresses are never in
-// a V4-mapped format.
-type header4Tuple struct {
-	srcAddr tcpip.FullAddress
-	dstAddr tcpip.FullAddress
-}
-
-// testFlow implements a helper type used for sending and receiving test
-// packets. A given test flow value defines 1) the socket endpoint used for the
-// test and 2) the type of packet send or received on the endpoint. E.g., a
-// multicastV6Only flow is a V6 multicast packet passing through a V6-only
-// endpoint. The type provides helper methods to characterize the flow (e.g.,
-// isV4) as well as return a proper header4Tuple for it.
-type testFlow int
-
-const (
-	unicastV4         testFlow = iota // V4 unicast on a V4 socket
-	unicastV4in6                      // V4-mapped unicast on a V6-dual socket
-	unicastV6                         // V6 unicast on a V6 socket
-	unicastV6Only                     // V6 unicast on a V6-only socket
-	multicastV4                       // V4 multicast on a V4 socket
-	multicastV4in6                    // V4-mapped multicast on a V6-dual socket
-	multicastV6                       // V6 multicast on a V6 socket
-	multicastV6Only                   // V6 multicast on a V6-only socket
-	broadcast                         // V4 broadcast on a V4 socket
-	broadcastIn6                      // V4-mapped broadcast on a V6-dual socket
-	reverseMulticast4                 // V4 multicast src. Must fail.
-	reverseMulticast6                 // V6 multicast src. Must fail.
-)
-
-func (flow testFlow) String() string {
-	switch flow {
-	case unicastV4:
-		return "unicastV4"
-	case unicastV6:
-		return "unicastV6"
-	case unicastV6Only:
-		return "unicastV6Only"
-	case unicastV4in6:
-		return "unicastV4in6"
-	case multicastV4:
-		return "multicastV4"
-	case multicastV6:
-		return "multicastV6"
-	case multicastV6Only:
-		return "multicastV6Only"
-	case multicastV4in6:
-		return "multicastV4in6"
-	case broadcast:
-		return "broadcast"
-	case broadcastIn6:
-		return "broadcastIn6"
-	case reverseMulticast4:
-		return "reverseMulticast4"
-	case reverseMulticast6:
-		return "reverseMulticast6"
-	default:
-		return "unknown"
-	}
-}
-
-// packetDirection explains if a flow is incoming (read) or outgoing (write).
-type packetDirection int
-
-const (
-	incoming packetDirection = iota
-	outgoing
-)
-
-// header4Tuple returns the header4Tuple for the given flow and direction. Note
-// that the tuple contains no mapped addresses as those only exist at the socket
-// level but not at the packet header level.
-func (flow testFlow) header4Tuple(d packetDirection) header4Tuple {
-	var h header4Tuple
-	if flow.isV4() {
-		if d == outgoing {
-			h = header4Tuple{
-				srcAddr: tcpip.FullAddress{Addr: stackAddr, Port: stackPort},
-				dstAddr: tcpip.FullAddress{Addr: testAddr, Port: testPort},
-			}
-		} else {
-			h = header4Tuple{
-				srcAddr: tcpip.FullAddress{Addr: testAddr, Port: testPort},
-				dstAddr: tcpip.FullAddress{Addr: stackAddr, Port: stackPort},
-			}
-		}
-		if flow.isMulticast() {
-			h.dstAddr.Addr = multicastAddr
-		} else if flow.isBroadcast() {
-			h.dstAddr.Addr = broadcastAddr
-		}
-	} else { // IPv6
-		if d == outgoing {
-			h = header4Tuple{
-				srcAddr: tcpip.FullAddress{Addr: stackV6Addr, Port: stackPort},
-				dstAddr: tcpip.FullAddress{Addr: testV6Addr, Port: testPort},
-			}
-		} else {
-			h = header4Tuple{
-				srcAddr: tcpip.FullAddress{Addr: testV6Addr, Port: testPort},
-				dstAddr: tcpip.FullAddress{Addr: stackV6Addr, Port: stackPort},
-			}
-		}
-		if flow.isMulticast() {
-			h.dstAddr.Addr = multicastV6Addr
-		}
-	}
-	if flow.isReverseMulticast() {
-		h.srcAddr.Addr = flow.getMcastAddr()
-	}
-	return h
-}
-
-func (flow testFlow) getMcastAddr() tcpip.Address {
-	if flow.isV4() {
-		return multicastAddr
-	}
-	return multicastV6Addr
-}
-
-// mapAddrIfApplicable converts the given V4 address into its V4-mapped version
-// if it is applicable to the flow.
-func (flow testFlow) mapAddrIfApplicable(v4Addr tcpip.Address) tcpip.Address {
-	if flow.isMapped() {
-		return v4MappedAddrPrefix + v4Addr
-	}
-	return v4Addr
-}
-
-// netProto returns the protocol number used for the network packet.
-func (flow testFlow) netProto() tcpip.NetworkProtocolNumber {
-	if flow.isV4() {
-		return ipv4.ProtocolNumber
-	}
-	return ipv6.ProtocolNumber
-}
-
-// sockProto returns the protocol number used when creating the socket
-// endpoint for this flow.
-func (flow testFlow) sockProto() tcpip.NetworkProtocolNumber {
-	switch flow {
-	case unicastV4in6, unicastV6, unicastV6Only, multicastV4in6, multicastV6, multicastV6Only, broadcastIn6, reverseMulticast6:
-		return ipv6.ProtocolNumber
-	case unicastV4, multicastV4, broadcast, reverseMulticast4:
-		return ipv4.ProtocolNumber
-	default:
-		panic(fmt.Sprintf("invalid testFlow given: %d", flow))
-	}
-}
-
-func (flow testFlow) checkerFn() func(*testing.T, []byte, ...checker.NetworkChecker) {
-	if flow.isV4() {
-		return checker.IPv4
-	}
-	return checker.IPv6
-}
-
-func (flow testFlow) isV6() bool { return !flow.isV4() }
-func (flow testFlow) isV4() bool {
-	return flow.sockProto() == ipv4.ProtocolNumber || flow.isMapped()
-}
-
-func (flow testFlow) isV6Only() bool {
-	switch flow {
-	case unicastV6Only, multicastV6Only:
-		return true
-	case unicastV4, unicastV4in6, unicastV6, multicastV4, multicastV4in6, multicastV6, broadcast, broadcastIn6, reverseMulticast4, reverseMulticast6:
-		return false
-	default:
-		panic(fmt.Sprintf("invalid testFlow given: %d", flow))
-	}
-}
-
-func (flow testFlow) isMulticast() bool {
-	switch flow {
-	case multicastV4, multicastV4in6, multicastV6, multicastV6Only:
-		return true
-	case unicastV4, unicastV4in6, unicastV6, unicastV6Only, broadcast, broadcastIn6, reverseMulticast4, reverseMulticast6:
-		return false
-	default:
-		panic(fmt.Sprintf("invalid testFlow given: %d", flow))
-	}
-}
-
-func (flow testFlow) isBroadcast() bool {
-	switch flow {
-	case broadcast, broadcastIn6:
-		return true
-	case unicastV4, unicastV4in6, unicastV6, unicastV6Only, multicastV4, multicastV4in6, multicastV6, multicastV6Only, reverseMulticast4, reverseMulticast6:
-		return false
-	default:
-		panic(fmt.Sprintf("invalid testFlow given: %d", flow))
-	}
-}
-
-func (flow testFlow) isMapped() bool {
-	switch flow {
-	case unicastV4in6, multicastV4in6, broadcastIn6:
-		return true
-	case unicastV4, unicastV6, unicastV6Only, multicastV4, multicastV6, multicastV6Only, broadcast, reverseMulticast4, reverseMulticast6:
-		return false
-	default:
-		panic(fmt.Sprintf("invalid testFlow given: %d", flow))
-	}
-}
-
-func (flow testFlow) isReverseMulticast() bool {
-	switch flow {
-	case reverseMulticast4, reverseMulticast6:
-		return true
-	default:
-		return false
-	}
-}
-
-type testContext struct {
-	t      *testing.T
-	linkEP *channel.Endpoint
-	s      *stack.Stack
-
-	ep tcpip.Endpoint
-	wq waiter.Queue
-}
-
-func newDualTestContext(t *testing.T, mtu uint32) *testContext {
-	t.Helper()
-	return newDualTestContextWithOptions(t, mtu, stack.Options{
-		NetworkProtocols:   []stack.NetworkProtocolFactory{ipv4.NewProtocol, ipv6.NewProtocol},
-		TransportProtocols: []stack.TransportProtocolFactory{udp.NewProtocol, icmp.NewProtocol6, icmp.NewProtocol4},
-		HandleLocal:        true,
-	})
-}
-
-func newDualTestContextWithOptions(t *testing.T, mtu uint32, options stack.Options) *testContext {
-	t.Helper()
-
-	s := stack.New(options)
-	ep := channel.New(256, mtu, "")
-	wep := stack.LinkEndpoint(ep)
-
-	if testing.Verbose() {
-		wep = sniffer.New(ep)
-	}
-	if err := s.CreateNIC(1, wep); err != nil {
-		t.Fatalf("CreateNIC failed: %s", err)
-	}
-
-	if err := s.AddAddress(1, ipv4.ProtocolNumber, stackAddr); err != nil {
-		t.Fatalf("AddAddress failed: %s", err)
-	}
-
-	if err := s.AddAddress(1, ipv6.ProtocolNumber, stackV6Addr); err != nil {
-		t.Fatalf("AddAddress failed: %s", err)
-	}
-
-	s.SetRouteTable([]tcpip.Route{
-		{
-			Destination: header.IPv4EmptySubnet,
-			NIC:         1,
-		},
-		{
-			Destination: header.IPv6EmptySubnet,
-			NIC:         1,
-		},
-	})
-
-	return &testContext{
-		t:      t,
-		s:      s,
-		linkEP: ep,
-	}
-}
-
-func (c *testContext) cleanup() {
-	if c.ep != nil {
-		c.ep.Close()
-	}
-}
-
-func (c *testContext) createEndpoint(proto tcpip.NetworkProtocolNumber) {
-	c.t.Helper()
-
-	var err tcpip.Error
-	c.ep, err = c.s.NewEndpoint(udp.ProtocolNumber, proto, &c.wq)
-	if err != nil {
-		c.t.Fatal("NewEndpoint failed: ", err)
-	}
-}
-
-func (c *testContext) createEndpointForFlow(flow testFlow) {
-	c.t.Helper()
-
-	c.createEndpoint(flow.sockProto())
-	if flow.isV6Only() {
-		c.ep.SocketOptions().SetV6Only(true)
-	} else if flow.isBroadcast() {
-		c.ep.SocketOptions().SetBroadcast(true)
-	}
-}
-
-// getPacketAndVerify reads a packet from the link endpoint and verifies the
-// header against expected values from the given test flow. In addition, it
-// calls any extra checker functions provided.
-func (c *testContext) getPacketAndVerify(flow testFlow, checkers ...checker.NetworkChecker) []byte {
-	c.t.Helper()
-
-	ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
-	defer cancel()
-	p, ok := c.linkEP.ReadContext(ctx)
-	if !ok {
-		c.t.Fatalf("Packet wasn't written out")
-		return nil
-	}
-
-	if p.Proto != flow.netProto() {
-		c.t.Fatalf("Bad network protocol: got %v, wanted %v", p.Proto, flow.netProto())
-	}
-
-	if got, want := p.Pkt.TransportProtocolNumber, header.UDPProtocolNumber; got != want {
-		c.t.Errorf("got p.Pkt.TransportProtocolNumber = %d, want = %d", got, want)
-	}
-
-	vv := buffer.NewVectorisedView(p.Pkt.Size(), p.Pkt.Views())
-	b := vv.ToView()
-
-	h := flow.header4Tuple(outgoing)
-	checkers = append(
-		checkers,
-		checker.SrcAddr(h.srcAddr.Addr),
-		checker.DstAddr(h.dstAddr.Addr),
-		checker.UDP(checker.DstPort(h.dstAddr.Port)),
-	)
-	flow.checkerFn()(c.t, b, checkers...)
-	return b
-}
-
-// injectPacket creates a packet of the given flow and with the given payload,
-// and injects it into the link endpoint. If badChecksum is true, the packet has
-// a bad checksum in the UDP header.
-func (c *testContext) injectPacket(flow testFlow, payload []byte, badChecksum bool) {
-	c.t.Helper()
-
-	h := flow.header4Tuple(incoming)
-	if flow.isV4() {
-		buf := c.buildV4Packet(payload, &h)
-		if badChecksum {
-			// Invalidate the UDP header checksum field, taking care to avoid
-			// overflow to zero, which would disable checksum validation.
-			for u := header.UDP(buf[header.IPv4MinimumSize:]); ; {
-				u.SetChecksum(u.Checksum() + 1)
-				if u.Checksum() != 0 {
-					break
-				}
-			}
-		}
-		c.linkEP.InjectInbound(ipv4.ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
-			Data: buf.ToVectorisedView(),
-		}))
-	} else {
-		buf := c.buildV6Packet(payload, &h)
-		if badChecksum {
-			// Invalidate the UDP header checksum field (Unlike IPv4, zero is
-			// a valid checksum value for IPv6 so no need to avoid it).
-			u := header.UDP(buf[header.IPv6MinimumSize:])
-			u.SetChecksum(u.Checksum() + 1)
-		}
-		c.linkEP.InjectInbound(ipv6.ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
-			Data: buf.ToVectorisedView(),
-		}))
-	}
-}
-
-// buildV6Packet creates a V6 test packet with the given payload and header
-// values in a buffer.
-func (c *testContext) buildV6Packet(payload []byte, h *header4Tuple) buffer.View {
-	// Allocate a buffer for data and headers.
-	buf := buffer.NewView(header.UDPMinimumSize + header.IPv6MinimumSize + len(payload))
-	payloadStart := len(buf) - len(payload)
-	copy(buf[payloadStart:], payload)
-
-	// Initialize the IP header.
-	ip := header.IPv6(buf)
-	ip.Encode(&header.IPv6Fields{
-		TrafficClass:      testTOS,
-		PayloadLength:     uint16(header.UDPMinimumSize + len(payload)),
-		TransportProtocol: udp.ProtocolNumber,
-		HopLimit:          65,
-		SrcAddr:           h.srcAddr.Addr,
-		DstAddr:           h.dstAddr.Addr,
-	})
-
-	// Initialize the UDP header.
-	u := header.UDP(buf[header.IPv6MinimumSize:])
-	u.Encode(&header.UDPFields{
-		SrcPort: h.srcAddr.Port,
-		DstPort: h.dstAddr.Port,
-		Length:  uint16(header.UDPMinimumSize + len(payload)),
-	})
-
-	// Calculate the UDP pseudo-header checksum.
-	xsum := header.PseudoHeaderChecksum(udp.ProtocolNumber, h.srcAddr.Addr, h.dstAddr.Addr, uint16(len(u)))
-
-	// Calculate the UDP checksum and set it.
-	xsum = header.Checksum(payload, xsum)
-	u.SetChecksum(^u.CalculateChecksum(xsum))
-
-	return buf
-}
-
-// buildV4Packet creates a V4 test packet with the given payload and header
-// values in a buffer.
-func (c *testContext) buildV4Packet(payload []byte, h *header4Tuple) buffer.View {
-	// Allocate a buffer for data and headers.
-	buf := buffer.NewView(header.UDPMinimumSize + header.IPv4MinimumSize + len(payload))
-	payloadStart := len(buf) - len(payload)
-	copy(buf[payloadStart:], payload)
-
-	// Initialize the IP header.
-	ip := header.IPv4(buf)
-	ip.Encode(&header.IPv4Fields{
-		TOS:         testTOS,
-		TotalLength: uint16(len(buf)),
-		TTL:         65,
-		Protocol:    uint8(udp.ProtocolNumber),
-		SrcAddr:     h.srcAddr.Addr,
-		DstAddr:     h.dstAddr.Addr,
-	})
-	ip.SetChecksum(^ip.CalculateChecksum())
-
-	// Initialize the UDP header.
-	u := header.UDP(buf[header.IPv4MinimumSize:])
-	u.Encode(&header.UDPFields{
-		SrcPort: h.srcAddr.Port,
-		DstPort: h.dstAddr.Port,
-		Length:  uint16(header.UDPMinimumSize + len(payload)),
-	})
-
-	// Calculate the UDP pseudo-header checksum.
-	xsum := header.PseudoHeaderChecksum(udp.ProtocolNumber, h.srcAddr.Addr, h.dstAddr.Addr, uint16(len(u)))
-
-	// Calculate the UDP checksum and set it.
-	xsum = header.Checksum(payload, xsum)
-	u.SetChecksum(^u.CalculateChecksum(xsum))
-
-	return buf
-}
-
-func newPayload() []byte {
-	return newMinPayload(30)
-}
-
-func newMinPayload(minSize int) []byte {
-	b := make([]byte, minSize+rand.Intn(100))
-	for i := range b {
-		b[i] = byte(rand.Intn(256))
-	}
-	return b
-}
-
-func TestBindToDeviceOption(t *testing.T) {
-	s := stack.New(stack.Options{
-		NetworkProtocols:   []stack.NetworkProtocolFactory{ipv4.NewProtocol},
-		TransportProtocols: []stack.TransportProtocolFactory{udp.NewProtocol}})
-
-	ep, err := s.NewEndpoint(udp.ProtocolNumber, ipv4.ProtocolNumber, &waiter.Queue{})
-	if err != nil {
-		t.Fatalf("NewEndpoint failed; %s", err)
-	}
-	defer ep.Close()
-
-	opts := stack.NICOptions{Name: "my_device"}
-	if err := s.CreateNICWithOptions(321, loopback.New(), opts); err != nil {
-		t.Errorf("CreateNICWithOptions(_, _, %+v) failed: %s", opts, err)
-	}
-
-	// nicIDPtr is used instead of taking the address of NICID literals, which is
-	// a compiler error.
-	nicIDPtr := func(s tcpip.NICID) *tcpip.NICID {
-		return &s
-	}
-
-	testActions := []struct {
-		name                 string
-		setBindToDevice      *tcpip.NICID
-		setBindToDeviceError tcpip.Error
-		getBindToDevice      int32
-	}{
-		{"GetDefaultValue", nil, nil, 0},
-		{"BindToNonExistent", nicIDPtr(999), &tcpip.ErrUnknownDevice{}, 0},
-		{"BindToExistent", nicIDPtr(321), nil, 321},
-		{"UnbindToDevice", nicIDPtr(0), nil, 0},
-	}
-	for _, testAction := range testActions {
-		t.Run(testAction.name, func(t *testing.T) {
-			if testAction.setBindToDevice != nil {
-				bindToDevice := int32(*testAction.setBindToDevice)
-				if gotErr, wantErr := ep.SocketOptions().SetBindToDevice(bindToDevice), testAction.setBindToDeviceError; gotErr != wantErr {
-					t.Errorf("got SetSockOpt(&%T(%d)) = %s, want = %s", bindToDevice, bindToDevice, gotErr, wantErr)
-				}
-			}
-			bindToDevice := ep.SocketOptions().GetBindToDevice()
-			if bindToDevice != testAction.getBindToDevice {
-				t.Errorf("got bindToDevice = %d, want = %d", bindToDevice, testAction.getBindToDevice)
-			}
-		})
-	}
-}
-
-// testReadInternal sends a packet of the given test flow into the stack by
-// injecting it into the link endpoint. It then attempts to read it from the
-// UDP endpoint and depending on if this was expected to succeed verifies its
-// correctness including any additional checker functions provided.
-func testReadInternal(c *testContext, flow testFlow, packetShouldBeDropped, expectReadError bool, checkers ...checker.ControlMessagesChecker) {
-	c.t.Helper()
-
-	payload := newPayload()
-	c.injectPacket(flow, payload, false)
-
-	// Try to receive the data.
-	we, ch := waiter.NewChannelEntry(nil)
-	c.wq.EventRegister(&we, waiter.EventIn)
-	defer c.wq.EventUnregister(&we)
-
-	// Take a snapshot of the stats to validate them at the end of the test.
-	epstats := c.ep.Stats().(*tcpip.TransportEndpointStats).Clone()
-
-	var buf bytes.Buffer
-	res, err := c.ep.Read(&buf, tcpip.ReadOptions{NeedRemoteAddr: true})
-	if _, ok := err.(*tcpip.ErrWouldBlock); ok {
-		// Wait for data to become available.
-		select {
-		case <-ch:
-			res, err = c.ep.Read(&buf, tcpip.ReadOptions{NeedRemoteAddr: true})
-
-		case <-time.After(300 * time.Millisecond):
-			if packetShouldBeDropped {
-				return // expected to time out
-			}
-			c.t.Fatal("timed out waiting for data")
-		}
-	}
-
-	if expectReadError && err != nil {
-		c.checkEndpointReadStats(1, epstats, err)
-		return
-	}
-
-	if err != nil {
-		c.t.Fatal("Read failed:", err)
-	}
-
-	if packetShouldBeDropped {
-		c.t.Fatalf("Read unexpectedly received data from %s", res.RemoteAddr.Addr)
-	}
-
-	// Check the read result.
-	h := flow.header4Tuple(incoming)
-	if diff := cmp.Diff(tcpip.ReadResult{
-		Count:      buf.Len(),
-		Total:      buf.Len(),
-		RemoteAddr: tcpip.FullAddress{Addr: h.srcAddr.Addr},
-	}, res, checker.IgnoreCmpPath(
-		"ControlMessages", // ControlMessages will be checked later.
-		"RemoteAddr.NIC",
-		"RemoteAddr.Port",
-	)); diff != "" {
-		c.t.Fatalf("Read: unexpected result (-want +got):\n%s", diff)
-	}
-
-	// Check the payload.
-	v := buf.Bytes()
-	if !bytes.Equal(payload, v) {
-		c.t.Fatalf("got payload = %x, want = %x", v, payload)
-	}
-
-	// Run any checkers against the ControlMessages.
-	for _, f := range checkers {
-		f(c.t, res.ControlMessages)
-	}
-
-	c.checkEndpointReadStats(1, epstats, err)
-}
-
-// testRead sends a packet of the given test flow into the stack by injecting it
-// into the link endpoint. It then reads it from the UDP endpoint and verifies
-// its correctness including any additional checker functions provided.
-func testRead(c *testContext, flow testFlow, checkers ...checker.ControlMessagesChecker) {
-	c.t.Helper()
-	testReadInternal(c, flow, false /* packetShouldBeDropped */, false /* expectReadError */, checkers...)
-}
-
-// testFailingRead sends a packet of the given test flow into the stack by
-// injecting it into the link endpoint. It then tries to read it from the UDP
-// endpoint and expects this to fail.
-func testFailingRead(c *testContext, flow testFlow, expectReadError bool) {
-	c.t.Helper()
-	testReadInternal(c, flow, true /* packetShouldBeDropped */, expectReadError)
-}
-
-func TestBindEphemeralPort(t *testing.T) {
-	c := newDualTestContext(t, defaultMTU)
-	defer c.cleanup()
-
-	c.createEndpoint(ipv6.ProtocolNumber)
-
-	if err := c.ep.Bind(tcpip.FullAddress{}); err != nil {
-		t.Fatalf("ep.Bind(...) failed: %s", err)
-	}
-}
-
-func TestBindReservedPort(t *testing.T) {
-	c := newDualTestContext(t, defaultMTU)
-	defer c.cleanup()
-
-	c.createEndpoint(ipv6.ProtocolNumber)
-
-	if err := c.ep.Connect(tcpip.FullAddress{Addr: testV6Addr, Port: testPort}); err != nil {
-		c.t.Fatalf("Connect failed: %s", err)
-	}
-
-	addr, err := c.ep.GetLocalAddress()
-	if err != nil {
-		t.Fatalf("GetLocalAddress failed: %s", err)
-	}
-
-	// We can't bind the address reserved by the connected endpoint above.
-	{
-		ep, err := c.s.NewEndpoint(udp.ProtocolNumber, ipv6.ProtocolNumber, &c.wq)
-		if err != nil {
-			t.Fatalf("NewEndpoint failed: %s", err)
-		}
-		defer ep.Close()
-		{
-			err := ep.Bind(addr)
-			if _, ok := err.(*tcpip.ErrPortInUse); !ok {
-				t.Fatalf("got ep.Bind(...) = %s, want = %s", err, &tcpip.ErrPortInUse{})
-			}
-		}
-	}
-
-	func() {
-		ep, err := c.s.NewEndpoint(udp.ProtocolNumber, ipv4.ProtocolNumber, &c.wq)
-		if err != nil {
-			t.Fatalf("NewEndpoint failed: %s", err)
-		}
-		defer ep.Close()
-		// We can't bind ipv4-any on the port reserved by the connected endpoint
-		// above, since the endpoint is dual-stack.
-		{
-			err := ep.Bind(tcpip.FullAddress{Port: addr.Port})
-			if _, ok := err.(*tcpip.ErrPortInUse); !ok {
-				t.Fatalf("got ep.Bind(...) = %s, want = %s", err, &tcpip.ErrPortInUse{})
-			}
-		}
-		// We can bind an ipv4 address on this port, though.
-		if err := ep.Bind(tcpip.FullAddress{Addr: stackAddr, Port: addr.Port}); err != nil {
-			t.Fatalf("ep.Bind(...) failed: %s", err)
-		}
-	}()
-
-	// Once the connected endpoint releases its port reservation, we are able to
-	// bind ipv4-any once again.
-	c.ep.Close()
-	func() {
-		ep, err := c.s.NewEndpoint(udp.ProtocolNumber, ipv4.ProtocolNumber, &c.wq)
-		if err != nil {
-			t.Fatalf("NewEndpoint failed: %s", err)
-		}
-		defer ep.Close()
-		if err := ep.Bind(tcpip.FullAddress{Port: addr.Port}); err != nil {
-			t.Fatalf("ep.Bind(...) failed: %s", err)
-		}
-	}()
-}
-
-func TestV4ReadOnV6(t *testing.T) {
-	c := newDualTestContext(t, defaultMTU)
-	defer c.cleanup()
-
-	c.createEndpointForFlow(unicastV4in6)
-
-	// Bind to wildcard.
-	if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}); err != nil {
-		c.t.Fatalf("Bind failed: %s", err)
-	}
-
-	// Test acceptance.
-	testRead(c, unicastV4in6)
-}
-
-func TestV4ReadOnBoundToV4MappedWildcard(t *testing.T) {
-	c := newDualTestContext(t, defaultMTU)
-	defer c.cleanup()
-
-	c.createEndpointForFlow(unicastV4in6)
-
-	// Bind to v4 mapped wildcard.
-	if err := c.ep.Bind(tcpip.FullAddress{Addr: v4MappedWildcardAddr, Port: stackPort}); err != nil {
-		c.t.Fatalf("Bind failed: %s", err)
-	}
-
-	// Test acceptance.
-	testRead(c, unicastV4in6)
-}
-
-func TestV4ReadOnBoundToV4Mapped(t *testing.T) {
-	c := newDualTestContext(t, defaultMTU)
-	defer c.cleanup()
-
-	c.createEndpointForFlow(unicastV4in6)
-
-	// Bind to local address.
-	if err := c.ep.Bind(tcpip.FullAddress{Addr: stackV4MappedAddr, Port: stackPort}); err != nil {
-		c.t.Fatalf("Bind failed: %s", err)
-	}
-
-	// Test acceptance.
-	testRead(c, unicastV4in6)
-}
-
-func TestV6ReadOnV6(t *testing.T) {
-	c := newDualTestContext(t, defaultMTU)
-	defer c.cleanup()
-
-	c.createEndpointForFlow(unicastV6)
-
-	// Bind to wildcard.
-	if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}); err != nil {
-		c.t.Fatalf("Bind failed: %s", err)
-	}
-
-	// Test acceptance.
-	testRead(c, unicastV6)
-}
-
-// TestV4ReadSelfSource checks that packets coming from a local IP address are
-// correctly dropped when handleLocal is true and not otherwise.
-func TestV4ReadSelfSource(t *testing.T) {
-	for _, tt := range []struct {
-		name              string
-		handleLocal       bool
-		wantErr           tcpip.Error
-		wantInvalidSource uint64
-	}{
-		{"HandleLocal", false, nil, 0},
-		{"NoHandleLocal", true, &tcpip.ErrWouldBlock{}, 1},
-	} {
-		t.Run(tt.name, func(t *testing.T) {
-			c := newDualTestContextWithOptions(t, defaultMTU, stack.Options{
-				NetworkProtocols:   []stack.NetworkProtocolFactory{ipv4.NewProtocol, ipv6.NewProtocol},
-				TransportProtocols: []stack.TransportProtocolFactory{udp.NewProtocol},
-				HandleLocal:        tt.handleLocal,
-			})
-			defer c.cleanup()
-
-			c.createEndpointForFlow(unicastV4)
-
-			if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}); err != nil {
-				t.Fatalf("Bind failed: %s", err)
-			}
-
-			payload := newPayload()
-			h := unicastV4.header4Tuple(incoming)
-			h.srcAddr = h.dstAddr
-
-			buf := c.buildV4Packet(payload, &h)
-			c.linkEP.InjectInbound(ipv4.ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
-				Data: buf.ToVectorisedView(),
-			}))
-
-			if got := c.s.Stats().IP.InvalidSourceAddressesReceived.Value(); got != tt.wantInvalidSource {
-				t.Errorf("c.s.Stats().IP.InvalidSourceAddressesReceived got %d, want %d", got, tt.wantInvalidSource)
-			}
-
-			if _, err := c.ep.Read(ioutil.Discard, tcpip.ReadOptions{}); err != tt.wantErr {
-				t.Errorf("got c.ep.Read = %s, want = %s", err, tt.wantErr)
-			}
-		})
-	}
-}
-
-func TestV4ReadOnV4(t *testing.T) {
-	c := newDualTestContext(t, defaultMTU)
-	defer c.cleanup()
-
-	c.createEndpointForFlow(unicastV4)
-
-	// Bind to wildcard.
-	if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}); err != nil {
-		c.t.Fatalf("Bind failed: %s", err)
-	}
-
-	// Test acceptance.
-	testRead(c, unicastV4)
-}
-
-// TestReadOnBoundToMulticast checks that an endpoint can bind to a multicast
-// address and receive data sent to that address.
-func TestReadOnBoundToMulticast(t *testing.T) {
-	// FIXME(b/128189410): multicastV4in6 currently doesn't work as
-	// AddMembershipOption doesn't handle V4in6 addresses.
-	for _, flow := range []testFlow{multicastV4, multicastV6, multicastV6Only} {
-		t.Run(fmt.Sprintf("flow:%s", flow), func(t *testing.T) {
-			c := newDualTestContext(t, defaultMTU)
-			defer c.cleanup()
-
-			c.createEndpointForFlow(flow)
-
-			// Bind to multicast address.
-			mcastAddr := flow.mapAddrIfApplicable(flow.getMcastAddr())
-			if err := c.ep.Bind(tcpip.FullAddress{Addr: mcastAddr, Port: stackPort}); err != nil {
-				c.t.Fatal("Bind failed:", err)
-			}
-
-			// Join multicast group.
-			ifoptSet := tcpip.AddMembershipOption{NIC: 1, MulticastAddr: mcastAddr}
-			if err := c.ep.SetSockOpt(&ifoptSet); err != nil {
-				c.t.Fatalf("SetSockOpt(&%#v): %s", ifoptSet, err)
-			}
-
-			// Check that we receive multicast packets but not unicast or broadcast
-			// ones.
-			testRead(c, flow)
-			testFailingRead(c, broadcast, false /* expectReadError */)
-			testFailingRead(c, unicastV4, false /* expectReadError */)
-		})
-	}
-}
-
-// TestV4ReadOnBoundToBroadcast checks that an endpoint can bind to a broadcast
-// address and can receive only broadcast data.
-func TestV4ReadOnBoundToBroadcast(t *testing.T) {
-	for _, flow := range []testFlow{broadcast, broadcastIn6} {
-		t.Run(fmt.Sprintf("flow:%s", flow), func(t *testing.T) {
-			c := newDualTestContext(t, defaultMTU)
-			defer c.cleanup()
-
-			c.createEndpointForFlow(flow)
-
-			// Bind to broadcast address.
-			bcastAddr := flow.mapAddrIfApplicable(broadcastAddr)
-			if err := c.ep.Bind(tcpip.FullAddress{Addr: bcastAddr, Port: stackPort}); err != nil {
-				c.t.Fatalf("Bind failed: %s", err)
-			}
-
-			// Check that we receive broadcast packets but not unicast ones.
-			testRead(c, flow)
-			testFailingRead(c, unicastV4, false /* expectReadError */)
-		})
-	}
-}
-
-// TestReadFromMulticast checks that an endpoint will NOT receive a packet
-// that was sent with multicast SOURCE address.
-func TestReadFromMulticast(t *testing.T) {
-	for _, flow := range []testFlow{reverseMulticast4, reverseMulticast6} {
-		t.Run(fmt.Sprintf("flow:%s", flow), func(t *testing.T) {
-			c := newDualTestContext(t, defaultMTU)
-			defer c.cleanup()
-
-			c.createEndpointForFlow(flow)
-
-			if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}); err != nil {
-				t.Fatalf("Bind failed: %s", err)
-			}
-			testFailingRead(c, flow, false /* expectReadError */)
-		})
-	}
-}
-
-// TestV4ReadBroadcastOnBoundToWildcard checks that an endpoint can bind to ANY
-// and receive broadcast and unicast data.
-func TestV4ReadBroadcastOnBoundToWildcard(t *testing.T) {
-	for _, flow := range []testFlow{broadcast, broadcastIn6} {
-		t.Run(fmt.Sprintf("flow:%s", flow), func(t *testing.T) {
-			c := newDualTestContext(t, defaultMTU)
-			defer c.cleanup()
-
-			c.createEndpointForFlow(flow)
-
-			// Bind to wildcard.
-			if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}); err != nil {
-				c.t.Fatalf("Bind failed: %s (", err)
-			}
-
-			// Check that we receive both broadcast and unicast packets.
-			testRead(c, flow)
-			testRead(c, unicastV4)
-		})
-	}
-}
-
-// testFailingWrite sends a packet of the given test flow into the UDP endpoint
-// and verifies it fails with the provided error code.
-func testFailingWrite(c *testContext, flow testFlow, wantErr tcpip.Error) {
-	c.t.Helper()
-	// Take a snapshot of the stats to validate them at the end of the test.
-	epstats := c.ep.Stats().(*tcpip.TransportEndpointStats).Clone()
-	h := flow.header4Tuple(outgoing)
-	writeDstAddr := flow.mapAddrIfApplicable(h.dstAddr.Addr)
-
-	var r bytes.Reader
-	r.Reset(newPayload())
-	_, gotErr := c.ep.Write(&r, tcpip.WriteOptions{
-		To: &tcpip.FullAddress{Addr: writeDstAddr, Port: h.dstAddr.Port},
-	})
-	c.checkEndpointWriteStats(1, epstats, gotErr)
-	if gotErr != wantErr {
-		c.t.Fatalf("Write returned unexpected error: got %v, want %v", gotErr, wantErr)
-	}
-}
-
-// testWrite sends a packet of the given test flow from the UDP endpoint to the
-// flow's destination address:port. It then receives it from the link endpoint
-// and verifies its correctness including any additional checker functions
-// provided.
-func testWrite(c *testContext, flow testFlow, checkers ...checker.NetworkChecker) uint16 {
-	c.t.Helper()
-	return testWriteAndVerifyInternal(c, flow, true, checkers...)
-}
-
-// testWriteWithoutDestination sends a packet of the given test flow from the
-// UDP endpoint without giving a destination address:port. It then receives it
-// from the link endpoint and verifies its correctness including any additional
-// checker functions provided.
-func testWriteWithoutDestination(c *testContext, flow testFlow, checkers ...checker.NetworkChecker) uint16 {
-	c.t.Helper()
-	return testWriteAndVerifyInternal(c, flow, false, checkers...)
-}
-
-func testWriteNoVerify(c *testContext, flow testFlow, setDest bool) buffer.View {
-	c.t.Helper()
-	// Take a snapshot of the stats to validate them at the end of the test.
-	epstats := c.ep.Stats().(*tcpip.TransportEndpointStats).Clone()
-
-	writeOpts := tcpip.WriteOptions{}
-	if setDest {
-		h := flow.header4Tuple(outgoing)
-		writeDstAddr := flow.mapAddrIfApplicable(h.dstAddr.Addr)
-		writeOpts = tcpip.WriteOptions{
-			To: &tcpip.FullAddress{Addr: writeDstAddr, Port: h.dstAddr.Port},
-		}
-	}
-	var r bytes.Reader
-	payload := newPayload()
-	r.Reset(payload)
-	n, err := c.ep.Write(&r, writeOpts)
-	if err != nil {
-		c.t.Fatalf("Write failed: %s", err)
-	}
-	if n != int64(len(payload)) {
-		c.t.Fatalf("Bad number of bytes written: got %v, want %v", n, len(payload))
-	}
-	c.checkEndpointWriteStats(1, epstats, err)
-	return payload
-}
-
-func testWriteAndVerifyInternal(c *testContext, flow testFlow, setDest bool, checkers ...checker.NetworkChecker) uint16 {
-	c.t.Helper()
-	payload := testWriteNoVerify(c, flow, setDest)
-	// Received the packet and check the payload.
-	b := c.getPacketAndVerify(flow, checkers...)
-	var udp header.UDP
-	if flow.isV4() {
-		udp = header.UDP(header.IPv4(b).Payload())
-	} else {
-		udp = header.UDP(header.IPv6(b).Payload())
-	}
-	if !bytes.Equal(payload, udp.Payload()) {
-		c.t.Fatalf("Bad payload: got %x, want %x", udp.Payload(), payload)
-	}
-
-	return udp.SourcePort()
-}
-
-func testDualWrite(c *testContext) uint16 {
-	c.t.Helper()
-
-	v4Port := testWrite(c, unicastV4in6)
-	v6Port := testWrite(c, unicastV6)
-	if v4Port != v6Port {
-		c.t.Fatalf("expected v4 and v6 ports to be equal: got v4Port = %d, v6Port = %d", v4Port, v6Port)
-	}
-
-	return v4Port
-}
-
-func TestDualWriteUnbound(t *testing.T) {
-	c := newDualTestContext(t, defaultMTU)
-	defer c.cleanup()
-
-	c.createEndpoint(ipv6.ProtocolNumber)
-
-	testDualWrite(c)
-}
-
-func TestDualWriteBoundToWildcard(t *testing.T) {
-	c := newDualTestContext(t, defaultMTU)
-	defer c.cleanup()
-
-	c.createEndpoint(ipv6.ProtocolNumber)
-
-	// Bind to wildcard.
-	if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}); err != nil {
-		c.t.Fatalf("Bind failed: %s", err)
-	}
-
-	p := testDualWrite(c)
-	if p != stackPort {
-		c.t.Fatalf("Bad port: got %v, want %v", p, stackPort)
-	}
-}
-
-func TestDualWriteConnectedToV6(t *testing.T) {
-	c := newDualTestContext(t, defaultMTU)
-	defer c.cleanup()
-
-	c.createEndpoint(ipv6.ProtocolNumber)
-
-	// Connect to v6 address.
-	if err := c.ep.Connect(tcpip.FullAddress{Addr: testV6Addr, Port: testPort}); err != nil {
-		c.t.Fatalf("Bind failed: %s", err)
-	}
-
-	testWrite(c, unicastV6)
-
-	// Write to V4 mapped address.
-	testFailingWrite(c, unicastV4in6, &tcpip.ErrNetworkUnreachable{})
-	const want = 1
-	if got := c.ep.Stats().(*tcpip.TransportEndpointStats).SendErrors.NoRoute.Value(); got != want {
-		c.t.Fatalf("Endpoint stat not updated. got %d want %d", got, want)
-	}
-}
-
-func TestDualWriteConnectedToV4Mapped(t *testing.T) {
-	c := newDualTestContext(t, defaultMTU)
-	defer c.cleanup()
-
-	c.createEndpoint(ipv6.ProtocolNumber)
-
-	// Connect to v4 mapped address.
-	if err := c.ep.Connect(tcpip.FullAddress{Addr: testV4MappedAddr, Port: testPort}); err != nil {
-		c.t.Fatalf("Bind failed: %s", err)
-	}
-
-	testWrite(c, unicastV4in6)
-
-	// Write to v6 address.
-	testFailingWrite(c, unicastV6, &tcpip.ErrInvalidEndpointState{})
-}
-
-func TestV4WriteOnV6Only(t *testing.T) {
-	c := newDualTestContext(t, defaultMTU)
-	defer c.cleanup()
-
-	c.createEndpointForFlow(unicastV6Only)
-
-	// Write to V4 mapped address.
-	testFailingWrite(c, unicastV4in6, &tcpip.ErrNoRoute{})
-}
-
-func TestV6WriteOnBoundToV4Mapped(t *testing.T) {
-	c := newDualTestContext(t, defaultMTU)
-	defer c.cleanup()
-
-	c.createEndpoint(ipv6.ProtocolNumber)
-
-	// Bind to v4 mapped address.
-	if err := c.ep.Bind(tcpip.FullAddress{Addr: stackV4MappedAddr, Port: stackPort}); err != nil {
-		c.t.Fatalf("Bind failed: %s", err)
-	}
-
-	// Write to v6 address.
-	testFailingWrite(c, unicastV6, &tcpip.ErrInvalidEndpointState{})
-}
-
-func TestV6WriteOnConnected(t *testing.T) {
-	c := newDualTestContext(t, defaultMTU)
-	defer c.cleanup()
-
-	c.createEndpoint(ipv6.ProtocolNumber)
-
-	// Connect to v6 address.
-	if err := c.ep.Connect(tcpip.FullAddress{Addr: testV6Addr, Port: testPort}); err != nil {
-		c.t.Fatalf("Connect failed: %s", err)
-	}
-
-	testWriteWithoutDestination(c, unicastV6)
-}
-
-func TestV4WriteOnConnected(t *testing.T) {
-	c := newDualTestContext(t, defaultMTU)
-	defer c.cleanup()
-
-	c.createEndpoint(ipv6.ProtocolNumber)
-
-	// Connect to v4 mapped address.
-	if err := c.ep.Connect(tcpip.FullAddress{Addr: testV4MappedAddr, Port: testPort}); err != nil {
-		c.t.Fatalf("Connect failed: %s", err)
-	}
-
-	testWriteWithoutDestination(c, unicastV4)
-}
-
-func TestWriteOnConnectedInvalidPort(t *testing.T) {
-	protocols := map[string]tcpip.NetworkProtocolNumber{
-		"ipv4": ipv4.ProtocolNumber,
-		"ipv6": ipv6.ProtocolNumber,
-	}
-	for name, pn := range protocols {
-		t.Run(name, func(t *testing.T) {
-			c := newDualTestContext(t, defaultMTU)
-			defer c.cleanup()
-
-			c.createEndpoint(pn)
-			if err := c.ep.Connect(tcpip.FullAddress{Addr: stackAddr, Port: invalidPort}); err != nil {
-				c.t.Fatalf("Connect failed: %s", err)
-			}
-			writeOpts := tcpip.WriteOptions{
-				To: &tcpip.FullAddress{Addr: stackAddr, Port: invalidPort},
-			}
-			var r bytes.Reader
-			payload := newPayload()
-			r.Reset(payload)
-			n, err := c.ep.Write(&r, writeOpts)
-			if err != nil {
-				c.t.Fatalf("c.ep.Write(...) = %+s, want nil", err)
-			}
-			if got, want := n, int64(len(payload)); got != want {
-				c.t.Fatalf("c.ep.Write(...) wrote %d bytes, want %d bytes", got, want)
-			}
-
-			{
-				err := c.ep.LastError()
-				if _, ok := err.(*tcpip.ErrConnectionRefused); !ok {
-					c.t.Fatalf("expected c.ep.LastError() == ErrConnectionRefused, got: %+v", err)
-				}
-			}
-		})
-	}
-}
-
-// TestWriteOnBoundToV4Multicast checks that we can send packets out of a socket
-// that is bound to a V4 multicast address.
-func TestWriteOnBoundToV4Multicast(t *testing.T) {
-	for _, flow := range []testFlow{unicastV4, multicastV4, broadcast} {
-		t.Run(fmt.Sprintf("%s", flow), func(t *testing.T) {
-			c := newDualTestContext(t, defaultMTU)
-			defer c.cleanup()
-
-			c.createEndpointForFlow(flow)
-
-			// Bind to V4 mcast address.
-			if err := c.ep.Bind(tcpip.FullAddress{Addr: multicastAddr, Port: stackPort}); err != nil {
-				c.t.Fatal("Bind failed:", err)
-			}
-
-			testWrite(c, flow)
-		})
-	}
-}
-
-// TestWriteOnBoundToV4MappedMulticast checks that we can send packets out of a
-// socket that is bound to a V4-mapped multicast address.
-func TestWriteOnBoundToV4MappedMulticast(t *testing.T) {
-	for _, flow := range []testFlow{unicastV4in6, multicastV4in6, broadcastIn6} {
-		t.Run(fmt.Sprintf("%s", flow), func(t *testing.T) {
-			c := newDualTestContext(t, defaultMTU)
-			defer c.cleanup()
-
-			c.createEndpointForFlow(flow)
-
-			// Bind to V4Mapped mcast address.
-			if err := c.ep.Bind(tcpip.FullAddress{Addr: multicastV4MappedAddr, Port: stackPort}); err != nil {
-				c.t.Fatalf("Bind failed: %s", err)
-			}
-
-			testWrite(c, flow)
-		})
-	}
-}
-
-// TestWriteOnBoundToV6Multicast checks that we can send packets out of a
-// socket that is bound to a V6 multicast address.
-func TestWriteOnBoundToV6Multicast(t *testing.T) {
-	for _, flow := range []testFlow{unicastV6, multicastV6} {
-		t.Run(fmt.Sprintf("%s", flow), func(t *testing.T) {
-			c := newDualTestContext(t, defaultMTU)
-			defer c.cleanup()
-
-			c.createEndpointForFlow(flow)
-
-			// Bind to V6 mcast address.
-			if err := c.ep.Bind(tcpip.FullAddress{Addr: multicastV6Addr, Port: stackPort}); err != nil {
-				c.t.Fatalf("Bind failed: %s", err)
-			}
-
-			testWrite(c, flow)
-		})
-	}
-}
-
-// TestWriteOnBoundToV6Multicast checks that we can send packets out of a
-// V6-only socket that is bound to a V6 multicast address.
-func TestWriteOnBoundToV6OnlyMulticast(t *testing.T) {
-	for _, flow := range []testFlow{unicastV6Only, multicastV6Only} {
-		t.Run(fmt.Sprintf("%s", flow), func(t *testing.T) {
-			c := newDualTestContext(t, defaultMTU)
-			defer c.cleanup()
-
-			c.createEndpointForFlow(flow)
-
-			// Bind to V6 mcast address.
-			if err := c.ep.Bind(tcpip.FullAddress{Addr: multicastV6Addr, Port: stackPort}); err != nil {
-				c.t.Fatalf("Bind failed: %s", err)
-			}
-
-			testWrite(c, flow)
-		})
-	}
-}
-
-// TestWriteOnBoundToBroadcast checks that we can send packets out of a
-// socket that is bound to the broadcast address.
-func TestWriteOnBoundToBroadcast(t *testing.T) {
-	for _, flow := range []testFlow{unicastV4, multicastV4, broadcast} {
-		t.Run(fmt.Sprintf("%s", flow), func(t *testing.T) {
-			c := newDualTestContext(t, defaultMTU)
-			defer c.cleanup()
-
-			c.createEndpointForFlow(flow)
-
-			// Bind to V4 broadcast address.
-			if err := c.ep.Bind(tcpip.FullAddress{Addr: broadcastAddr, Port: stackPort}); err != nil {
-				c.t.Fatal("Bind failed:", err)
-			}
-
-			testWrite(c, flow)
-		})
-	}
-}
-
-// TestWriteOnBoundToV4MappedBroadcast checks that we can send packets out of a
-// socket that is bound to the V4-mapped broadcast address.
-func TestWriteOnBoundToV4MappedBroadcast(t *testing.T) {
-	for _, flow := range []testFlow{unicastV4in6, multicastV4in6, broadcastIn6} {
-		t.Run(fmt.Sprintf("%s", flow), func(t *testing.T) {
-			c := newDualTestContext(t, defaultMTU)
-			defer c.cleanup()
-
-			c.createEndpointForFlow(flow)
-
-			// Bind to V4Mapped mcast address.
-			if err := c.ep.Bind(tcpip.FullAddress{Addr: broadcastV4MappedAddr, Port: stackPort}); err != nil {
-				c.t.Fatalf("Bind failed: %s", err)
-			}
-
-			testWrite(c, flow)
-		})
-	}
-}
-
-func TestReadIncrementsPacketsReceived(t *testing.T) {
-	c := newDualTestContext(t, defaultMTU)
-	defer c.cleanup()
-
-	// Create IPv4 UDP endpoint
-	c.createEndpoint(ipv6.ProtocolNumber)
-
-	// Bind to wildcard.
-	if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}); err != nil {
-		c.t.Fatalf("Bind failed: %s", err)
-	}
-
-	testRead(c, unicastV4)
-
-	var want uint64 = 1
-	if got := c.s.Stats().UDP.PacketsReceived.Value(); got != want {
-		c.t.Fatalf("Read did not increment PacketsReceived: got %v, want %v", got, want)
-	}
-}
-
-func TestReadIPPacketInfo(t *testing.T) {
-	tests := []struct {
-		name              string
-		proto             tcpip.NetworkProtocolNumber
-		flow              testFlow
-		expectedLocalAddr tcpip.Address
-		expectedDestAddr  tcpip.Address
-	}{
-		{
-			name:              "IPv4 unicast",
-			proto:             header.IPv4ProtocolNumber,
-			flow:              unicastV4,
-			expectedLocalAddr: stackAddr,
-			expectedDestAddr:  stackAddr,
-		},
-		{
-			name:  "IPv4 multicast",
-			proto: header.IPv4ProtocolNumber,
-			flow:  multicastV4,
-			// This should actually be a unicast address assigned to the interface.
-			//
-			// TODO(gvisor.dev/issue/3556): This check is validating incorrect
-			// behaviour. We still include the test so that once the bug is
-			// resolved, this test will start to fail and the individual tasked
-			// with fixing this bug knows to also fix this test :).
-			expectedLocalAddr: multicastAddr,
-			expectedDestAddr:  multicastAddr,
-		},
-		{
-			name:  "IPv4 broadcast",
-			proto: header.IPv4ProtocolNumber,
-			flow:  broadcast,
-			// This should actually be a unicast address assigned to the interface.
-			//
-			// TODO(gvisor.dev/issue/3556): This check is validating incorrect
-			// behaviour. We still include the test so that once the bug is
-			// resolved, this test will start to fail and the individual tasked
-			// with fixing this bug knows to also fix this test :).
-			expectedLocalAddr: broadcastAddr,
-			expectedDestAddr:  broadcastAddr,
-		},
-		{
-			name:              "IPv6 unicast",
-			proto:             header.IPv6ProtocolNumber,
-			flow:              unicastV6,
-			expectedLocalAddr: stackV6Addr,
-			expectedDestAddr:  stackV6Addr,
-		},
-		{
-			name:  "IPv6 multicast",
-			proto: header.IPv6ProtocolNumber,
-			flow:  multicastV6,
-			// This should actually be a unicast address assigned to the interface.
-			//
-			// TODO(gvisor.dev/issue/3556): This check is validating incorrect
-			// behaviour. We still include the test so that once the bug is
-			// resolved, this test will start to fail and the individual tasked
-			// with fixing this bug knows to also fix this test :).
-			expectedLocalAddr: multicastV6Addr,
-			expectedDestAddr:  multicastV6Addr,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			c := newDualTestContext(t, defaultMTU)
-			defer c.cleanup()
-
-			c.createEndpoint(test.proto)
-
-			bindAddr := tcpip.FullAddress{Port: stackPort}
-			if err := c.ep.Bind(bindAddr); err != nil {
-				t.Fatalf("Bind(%+v): %s", bindAddr, err)
-			}
-
-			if test.flow.isMulticast() {
-				ifoptSet := tcpip.AddMembershipOption{NIC: 1, MulticastAddr: test.flow.getMcastAddr()}
-				if err := c.ep.SetSockOpt(&ifoptSet); err != nil {
-					c.t.Fatalf("SetSockOpt(&%#v): %s:", ifoptSet, err)
-				}
-			}
-
-			c.ep.SocketOptions().SetReceivePacketInfo(true)
-
-			testRead(c, test.flow, checker.ReceiveIPPacketInfo(tcpip.IPPacketInfo{
-				NIC:             1,
-				LocalAddr:       test.expectedLocalAddr,
-				DestinationAddr: test.expectedDestAddr,
-			}))
-
-			if got := c.s.Stats().UDP.PacketsReceived.Value(); got != 1 {
-				t.Fatalf("Read did not increment PacketsReceived: got = %d, want = 1", got)
-			}
-		})
-	}
-}
-
-func TestReadRecvOriginalDstAddr(t *testing.T) {
-	tests := []struct {
-		name                    string
-		proto                   tcpip.NetworkProtocolNumber
-		flow                    testFlow
-		expectedOriginalDstAddr tcpip.FullAddress
-	}{
-		{
-			name:                    "IPv4 unicast",
-			proto:                   header.IPv4ProtocolNumber,
-			flow:                    unicastV4,
-			expectedOriginalDstAddr: tcpip.FullAddress{1, stackAddr, stackPort},
-		},
-		{
-			name:  "IPv4 multicast",
-			proto: header.IPv4ProtocolNumber,
-			flow:  multicastV4,
-			// This should actually be a unicast address assigned to the interface.
-			//
-			// TODO(gvisor.dev/issue/3556): This check is validating incorrect
-			// behaviour. We still include the test so that once the bug is
-			// resolved, this test will start to fail and the individual tasked
-			// with fixing this bug knows to also fix this test :).
-			expectedOriginalDstAddr: tcpip.FullAddress{1, multicastAddr, stackPort},
-		},
-		{
-			name:  "IPv4 broadcast",
-			proto: header.IPv4ProtocolNumber,
-			flow:  broadcast,
-			// This should actually be a unicast address assigned to the interface.
-			//
-			// TODO(gvisor.dev/issue/3556): This check is validating incorrect
-			// behaviour. We still include the test so that once the bug is
-			// resolved, this test will start to fail and the individual tasked
-			// with fixing this bug knows to also fix this test :).
-			expectedOriginalDstAddr: tcpip.FullAddress{1, broadcastAddr, stackPort},
-		},
-		{
-			name:                    "IPv6 unicast",
-			proto:                   header.IPv6ProtocolNumber,
-			flow:                    unicastV6,
-			expectedOriginalDstAddr: tcpip.FullAddress{1, stackV6Addr, stackPort},
-		},
-		{
-			name:  "IPv6 multicast",
-			proto: header.IPv6ProtocolNumber,
-			flow:  multicastV6,
-			// This should actually be a unicast address assigned to the interface.
-			//
-			// TODO(gvisor.dev/issue/3556): This check is validating incorrect
-			// behaviour. We still include the test so that once the bug is
-			// resolved, this test will start to fail and the individual tasked
-			// with fixing this bug knows to also fix this test :).
-			expectedOriginalDstAddr: tcpip.FullAddress{1, multicastV6Addr, stackPort},
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			c := newDualTestContext(t, defaultMTU)
-			defer c.cleanup()
-
-			c.createEndpoint(test.proto)
-
-			bindAddr := tcpip.FullAddress{Port: stackPort}
-			if err := c.ep.Bind(bindAddr); err != nil {
-				t.Fatalf("Bind(%#v): %s", bindAddr, err)
-			}
-
-			if test.flow.isMulticast() {
-				ifoptSet := tcpip.AddMembershipOption{NIC: 1, MulticastAddr: test.flow.getMcastAddr()}
-				if err := c.ep.SetSockOpt(&ifoptSet); err != nil {
-					c.t.Fatalf("SetSockOpt(&%#v): %s:", ifoptSet, err)
-				}
-			}
-
-			c.ep.SocketOptions().SetReceiveOriginalDstAddress(true)
-
-			testRead(c, test.flow, checker.ReceiveOriginalDstAddr(test.expectedOriginalDstAddr))
-
-			if got := c.s.Stats().UDP.PacketsReceived.Value(); got != 1 {
-				t.Fatalf("Read did not increment PacketsReceived: got = %d, want = 1", got)
-			}
-		})
-	}
-}
-
-func TestWriteIncrementsPacketsSent(t *testing.T) {
-	c := newDualTestContext(t, defaultMTU)
-	defer c.cleanup()
-
-	c.createEndpoint(ipv6.ProtocolNumber)
-
-	testDualWrite(c)
-
-	var want uint64 = 2
-	if got := c.s.Stats().UDP.PacketsSent.Value(); got != want {
-		c.t.Fatalf("Write did not increment PacketsSent: got %v, want %v", got, want)
-	}
-}
-
-func TestNoChecksum(t *testing.T) {
-	for _, flow := range []testFlow{unicastV4, unicastV6} {
-		t.Run(fmt.Sprintf("flow:%s", flow), func(t *testing.T) {
-			c := newDualTestContext(t, defaultMTU)
-			defer c.cleanup()
-
-			c.createEndpointForFlow(flow)
-
-			// Disable the checksum generation.
-			c.ep.SocketOptions().SetNoChecksum(true)
-			// This option is effective on IPv4 only.
-			testWrite(c, flow, checker.UDP(checker.NoChecksum(flow.isV4())))
-
-			// Enable the checksum generation.
-			c.ep.SocketOptions().SetNoChecksum(false)
-			testWrite(c, flow, checker.UDP(checker.NoChecksum(false)))
-		})
-	}
-}
-
-var _ stack.NetworkInterface = (*testInterface)(nil)
-
-type testInterface struct {
-	stack.NetworkInterface
-}
-
-func (*testInterface) ID() tcpip.NICID {
-	return 0
-}
-
-func (*testInterface) Enabled() bool {
-	return true
-}
-
-func TestTTL(t *testing.T) {
-	for _, flow := range []testFlow{unicastV4, unicastV4in6, unicastV6, unicastV6Only, multicastV4, multicastV4in6, multicastV6, broadcast, broadcastIn6} {
-		t.Run(fmt.Sprintf("flow:%s", flow), func(t *testing.T) {
-			c := newDualTestContext(t, defaultMTU)
-			defer c.cleanup()
-
-			c.createEndpointForFlow(flow)
-
-			const multicastTTL = 42
-			if err := c.ep.SetSockOptInt(tcpip.MulticastTTLOption, multicastTTL); err != nil {
-				c.t.Fatalf("SetSockOptInt failed: %s", err)
-			}
-
-			var wantTTL uint8
-			if flow.isMulticast() {
-				wantTTL = multicastTTL
-			} else {
-				var p stack.NetworkProtocolFactory
-				var n tcpip.NetworkProtocolNumber
-				if flow.isV4() {
-					p = ipv4.NewProtocol
-					n = ipv4.ProtocolNumber
-				} else {
-					p = ipv6.NewProtocol
-					n = ipv6.ProtocolNumber
-				}
-				s := stack.New(stack.Options{
-					NetworkProtocols: []stack.NetworkProtocolFactory{p},
-				})
-				ep := s.NetworkProtocolInstance(n).NewEndpoint(&testInterface{}, nil)
-				wantTTL = ep.DefaultTTL()
-				ep.Close()
-			}
-
-			testWrite(c, flow, checker.TTL(wantTTL))
-		})
-	}
-}
-
-func TestSetTTL(t *testing.T) {
-	for _, flow := range []testFlow{unicastV4, unicastV4in6, unicastV6, unicastV6Only, broadcast, broadcastIn6} {
-		t.Run(fmt.Sprintf("flow:%s", flow), func(t *testing.T) {
-			for _, wantTTL := range []uint8{1, 2, 50, 64, 128, 254, 255} {
-				t.Run(fmt.Sprintf("TTL:%d", wantTTL), func(t *testing.T) {
-					c := newDualTestContext(t, defaultMTU)
-					defer c.cleanup()
-
-					c.createEndpointForFlow(flow)
-
-					if err := c.ep.SetSockOptInt(tcpip.TTLOption, int(wantTTL)); err != nil {
-						c.t.Fatalf("SetSockOptInt(TTLOption, %d) failed: %s", wantTTL, err)
-					}
-
-					testWrite(c, flow, checker.TTL(wantTTL))
-				})
-			}
-		})
-	}
-}
-
-func TestSetTOS(t *testing.T) {
-	for _, flow := range []testFlow{unicastV4, multicastV4, broadcast} {
-		t.Run(fmt.Sprintf("flow:%s", flow), func(t *testing.T) {
-			c := newDualTestContext(t, defaultMTU)
-			defer c.cleanup()
-
-			c.createEndpointForFlow(flow)
-
-			const tos = testTOS
-			v, err := c.ep.GetSockOptInt(tcpip.IPv4TOSOption)
-			if err != nil {
-				c.t.Errorf("GetSockOptInt(IPv4TOSOption) failed: %s", err)
-			}
-			// Test for expected default value.
-			if v != 0 {
-				c.t.Errorf("got GetSockOptInt(IPv4TOSOption) = 0x%x, want = 0x%x", v, 0)
-			}
-
-			if err := c.ep.SetSockOptInt(tcpip.IPv4TOSOption, tos); err != nil {
-				c.t.Errorf("SetSockOptInt(IPv4TOSOption, 0x%x) failed: %s", tos, err)
-			}
-
-			v, err = c.ep.GetSockOptInt(tcpip.IPv4TOSOption)
-			if err != nil {
-				c.t.Errorf("GetSockOptInt(IPv4TOSOption) failed: %s", err)
-			}
-
-			if v != tos {
-				c.t.Errorf("got GetSockOptInt(IPv4TOSOption) = 0x%x, want = 0x%x", v, tos)
-			}
-
-			testWrite(c, flow, checker.TOS(tos, 0))
-		})
-	}
-}
-
-func TestSetTClass(t *testing.T) {
-	for _, flow := range []testFlow{unicastV4in6, unicastV6, unicastV6Only, multicastV4in6, multicastV6, broadcastIn6} {
-		t.Run(fmt.Sprintf("flow:%s", flow), func(t *testing.T) {
-			c := newDualTestContext(t, defaultMTU)
-			defer c.cleanup()
-
-			c.createEndpointForFlow(flow)
-
-			const tClass = testTOS
-			v, err := c.ep.GetSockOptInt(tcpip.IPv6TrafficClassOption)
-			if err != nil {
-				c.t.Errorf("GetSockOptInt(IPv6TrafficClassOption) failed: %s", err)
-			}
-			// Test for expected default value.
-			if v != 0 {
-				c.t.Errorf("got GetSockOptInt(IPv6TrafficClassOption) = 0x%x, want = 0x%x", v, 0)
-			}
-
-			if err := c.ep.SetSockOptInt(tcpip.IPv6TrafficClassOption, tClass); err != nil {
-				c.t.Errorf("SetSockOptInt(IPv6TrafficClassOption, 0x%x) failed: %s", tClass, err)
-			}
-
-			v, err = c.ep.GetSockOptInt(tcpip.IPv6TrafficClassOption)
-			if err != nil {
-				c.t.Errorf("GetSockOptInt(IPv6TrafficClassOption) failed: %s", err)
-			}
-
-			if v != tClass {
-				c.t.Errorf("got GetSockOptInt(IPv6TrafficClassOption) = 0x%x, want = 0x%x", v, tClass)
-			}
-
-			// The header getter for TClass is called TOS, so use that checker.
-			testWrite(c, flow, checker.TOS(tClass, 0))
-		})
-	}
-}
-
-func TestReceiveTosTClass(t *testing.T) {
-	const RcvTOSOpt = "ReceiveTosOption"
-	const RcvTClassOpt = "ReceiveTClassOption"
-
-	testCases := []struct {
-		name  string
-		tests []testFlow
-	}{
-		{RcvTOSOpt, []testFlow{unicastV4, broadcast}},
-		{RcvTClassOpt, []testFlow{unicastV4in6, unicastV6, unicastV6Only, broadcastIn6}},
-	}
-	for _, testCase := range testCases {
-		for _, flow := range testCase.tests {
-			t.Run(fmt.Sprintf("%s:flow:%s", testCase.name, flow), func(t *testing.T) {
-				c := newDualTestContext(t, defaultMTU)
-				defer c.cleanup()
-
-				c.createEndpointForFlow(flow)
-				name := testCase.name
-
-				var optionGetter func() bool
-				var optionSetter func(bool)
-				switch name {
-				case RcvTOSOpt:
-					optionGetter = c.ep.SocketOptions().GetReceiveTOS
-					optionSetter = c.ep.SocketOptions().SetReceiveTOS
-				case RcvTClassOpt:
-					optionGetter = c.ep.SocketOptions().GetReceiveTClass
-					optionSetter = c.ep.SocketOptions().SetReceiveTClass
-				default:
-					t.Fatalf("unkown test variant: %s", name)
-				}
-
-				// Verify that setting and reading the option works.
-				v := optionGetter()
-				// Test for expected default value.
-				if v != false {
-					c.t.Errorf("got GetSockOptBool(%s) = %t, want = %t", name, v, false)
-				}
-
-				want := true
-				optionSetter(want)
-
-				got := optionGetter()
-				if got != want {
-					c.t.Errorf("got GetSockOptBool(%s) = %t, want = %t", name, got, want)
-				}
-
-				// Verify that the correct received TOS or TClass is handed through as
-				// ancillary data to the ControlMessages struct.
-				if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}); err != nil {
-					c.t.Fatalf("Bind failed: %s", err)
-				}
-				switch name {
-				case RcvTClassOpt:
-					testRead(c, flow, checker.ReceiveTClass(testTOS))
-				case RcvTOSOpt:
-					testRead(c, flow, checker.ReceiveTOS(testTOS))
-				default:
-					t.Fatalf("unknown test variant: %s", name)
-				}
-			})
-		}
-	}
-}
-
-func TestMulticastInterfaceOption(t *testing.T) {
-	for _, flow := range []testFlow{multicastV4, multicastV4in6, multicastV6, multicastV6Only} {
-		t.Run(fmt.Sprintf("flow:%s", flow), func(t *testing.T) {
-			for _, bindTyp := range []string{"bound", "unbound"} {
-				t.Run(bindTyp, func(t *testing.T) {
-					for _, optTyp := range []string{"use local-addr", "use NICID", "use local-addr and NIC"} {
-						t.Run(optTyp, func(t *testing.T) {
-							h := flow.header4Tuple(outgoing)
-							mcastAddr := h.dstAddr.Addr
-							localIfAddr := h.srcAddr.Addr
-
-							var ifoptSet tcpip.MulticastInterfaceOption
-							switch optTyp {
-							case "use local-addr":
-								ifoptSet.InterfaceAddr = localIfAddr
-							case "use NICID":
-								ifoptSet.NIC = 1
-							case "use local-addr and NIC":
-								ifoptSet.InterfaceAddr = localIfAddr
-								ifoptSet.NIC = 1
-							default:
-								t.Fatal("unknown test variant")
-							}
-
-							c := newDualTestContext(t, defaultMTU)
-							defer c.cleanup()
-
-							c.createEndpoint(flow.sockProto())
-
-							if bindTyp == "bound" {
-								// Bind the socket by connecting to the multicast address.
-								// This may have an influence on how the multicast interface
-								// is set.
-								addr := tcpip.FullAddress{
-									Addr: flow.mapAddrIfApplicable(mcastAddr),
-									Port: stackPort,
-								}
-								if err := c.ep.Connect(addr); err != nil {
-									c.t.Fatalf("Connect failed: %s", err)
-								}
-							}
-
-							if err := c.ep.SetSockOpt(&ifoptSet); err != nil {
-								c.t.Fatalf("SetSockOpt(&%#v): %s", ifoptSet, err)
-							}
-
-							// Verify multicast interface addr and NIC were set correctly.
-							// Note that NIC must be 1 since this is our outgoing interface.
-							var ifoptGot tcpip.MulticastInterfaceOption
-							if err := c.ep.GetSockOpt(&ifoptGot); err != nil {
-								c.t.Fatalf("GetSockOpt(&%T): %s", ifoptGot, err)
-							} else if ifoptWant := (tcpip.MulticastInterfaceOption{NIC: 1, InterfaceAddr: ifoptSet.InterfaceAddr}); ifoptGot != ifoptWant {
-								c.t.Errorf("got multicast interface option = %#v, want = %#v", ifoptGot, ifoptWant)
-							}
-						})
-					}
-				})
-			}
-		})
-	}
-}
-
-// TestV4UnknownDestination verifies that we generate an ICMPv4 Destination
-// Unreachable message when a udp datagram is received on ports for which there
-// is no bound udp socket.
-func TestV4UnknownDestination(t *testing.T) {
-	c := newDualTestContext(t, defaultMTU)
-	defer c.cleanup()
-
-	testCases := []struct {
-		flow         testFlow
-		icmpRequired bool
-		// largePayload if true, will result in a payload large enough
-		// so that the final generated IPv4 packet is larger than
-		// header.IPv4MinimumProcessableDatagramSize.
-		largePayload bool
-		// badChecksum if true, will set an invalid checksum in the
-		// header.
-		badChecksum bool
-	}{
-		{unicastV4, true, false, false},
-		{unicastV4, true, true, false},
-		{unicastV4, false, false, true},
-		{unicastV4, false, true, true},
-		{multicastV4, false, false, false},
-		{multicastV4, false, true, false},
-		{broadcast, false, false, false},
-		{broadcast, false, true, false},
-	}
-	checksumErrors := uint64(0)
-	for _, tc := range testCases {
-		t.Run(fmt.Sprintf("flow:%s icmpRequired:%t largePayload:%t badChecksum:%t", tc.flow, tc.icmpRequired, tc.largePayload, tc.badChecksum), func(t *testing.T) {
-			payload := newPayload()
-			if tc.largePayload {
-				payload = newMinPayload(576)
-			}
-			c.injectPacket(tc.flow, payload, tc.badChecksum)
-			if tc.badChecksum {
-				checksumErrors++
-				if got, want := c.s.Stats().UDP.ChecksumErrors.Value(), checksumErrors; got != want {
-					t.Fatalf("got stats.UDP.ChecksumErrors.Value() = %d, want = %d", got, want)
-				}
-			}
-			if !tc.icmpRequired {
-				ctx, cancel := context.WithTimeout(context.Background(), time.Second)
-				defer cancel()
-				if p, ok := c.linkEP.ReadContext(ctx); ok {
-					t.Fatalf("unexpected packet received: %+v", p)
-				}
-				return
-			}
-
-			// ICMP required.
-			ctx, cancel := context.WithTimeout(context.Background(), time.Second)
-			defer cancel()
-			p, ok := c.linkEP.ReadContext(ctx)
-			if !ok {
-				t.Fatalf("packet wasn't written out")
-				return
-			}
-
-			vv := buffer.NewVectorisedView(p.Pkt.Size(), p.Pkt.Views())
-			pkt := vv.ToView()
-			if got, want := len(pkt), header.IPv4MinimumProcessableDatagramSize; got > want {
-				t.Fatalf("got an ICMP packet of size: %d, want: sz <= %d", got, want)
-			}
-
-			hdr := header.IPv4(pkt)
-			checker.IPv4(t, hdr, checker.ICMPv4(
-				checker.ICMPv4Type(header.ICMPv4DstUnreachable),
-				checker.ICMPv4Code(header.ICMPv4PortUnreachable)))
-
-			// We need to compare the included data part of the UDP packet that is in
-			// the ICMP packet with the matching original data.
-			icmpPkt := header.ICMPv4(hdr.Payload())
-			payloadIPHeader := header.IPv4(icmpPkt.Payload())
-			incomingHeaderLength := header.IPv4MinimumSize + header.UDPMinimumSize
-			wantLen := len(payload)
-			if tc.largePayload {
-				// To work out the data size we need to simulate what the sender would
-				// have done. The wanted size is the total available minus the sum of
-				// the headers in the UDP AND ICMP packets, given that we know the test
-				// had only a minimal IP header but the ICMP sender will have allowed
-				// for a maximally sized packet header.
-				wantLen = header.IPv4MinimumProcessableDatagramSize - header.IPv4MaximumHeaderSize - header.ICMPv4MinimumSize - incomingHeaderLength
-			}
-
-			// In the case of large payloads the IP packet may be truncated. Update
-			// the length field before retrieving the udp datagram payload.
-			// Add back the two headers within the payload.
-			payloadIPHeader.SetTotalLength(uint16(wantLen + incomingHeaderLength))
-
-			origDgram := header.UDP(payloadIPHeader.Payload())
-			if got, want := len(origDgram.Payload()), wantLen; got != want {
-				t.Fatalf("unexpected payload length got: %d, want: %d", got, want)
-			}
-			if got, want := origDgram.Payload(), payload[:wantLen]; !bytes.Equal(got, want) {
-				t.Fatalf("unexpected payload got: %d, want: %d", got, want)
-			}
-		})
-	}
-}
-
-// TestV6UnknownDestination verifies that we generate an ICMPv6 Destination
-// Unreachable message when a udp datagram is received on ports for which there
-// is no bound udp socket.
-func TestV6UnknownDestination(t *testing.T) {
-	c := newDualTestContext(t, defaultMTU)
-	defer c.cleanup()
-
-	testCases := []struct {
-		flow         testFlow
-		icmpRequired bool
-		// largePayload if true will result in a payload large enough to
-		// create an IPv6 packet > header.IPv6MinimumMTU bytes.
-		largePayload bool
-		// badChecksum if true, will set an invalid checksum in the
-		// header.
-		badChecksum bool
-	}{
-		{unicastV6, true, false, false},
-		{unicastV6, true, true, false},
-		{unicastV6, false, false, true},
-		{unicastV6, false, true, true},
-		{multicastV6, false, false, false},
-		{multicastV6, false, true, false},
-	}
-	checksumErrors := uint64(0)
-	for _, tc := range testCases {
-		t.Run(fmt.Sprintf("flow:%s icmpRequired:%t largePayload:%t badChecksum:%t", tc.flow, tc.icmpRequired, tc.largePayload, tc.badChecksum), func(t *testing.T) {
-			payload := newPayload()
-			if tc.largePayload {
-				payload = newMinPayload(1280)
-			}
-			c.injectPacket(tc.flow, payload, tc.badChecksum)
-			if tc.badChecksum {
-				checksumErrors++
-				if got, want := c.s.Stats().UDP.ChecksumErrors.Value(), checksumErrors; got != want {
-					t.Fatalf("got stats.UDP.ChecksumErrors.Value() = %d, want = %d", got, want)
-				}
-			}
-			if !tc.icmpRequired {
-				ctx, cancel := context.WithTimeout(context.Background(), time.Second)
-				defer cancel()
-				if p, ok := c.linkEP.ReadContext(ctx); ok {
-					t.Fatalf("unexpected packet received: %+v", p)
-				}
-				return
-			}
-
-			// ICMP required.
-			ctx, cancel := context.WithTimeout(context.Background(), time.Second)
-			defer cancel()
-			p, ok := c.linkEP.ReadContext(ctx)
-			if !ok {
-				t.Fatalf("packet wasn't written out")
-				return
-			}
-
-			vv := buffer.NewVectorisedView(p.Pkt.Size(), p.Pkt.Views())
-			pkt := vv.ToView()
-			if got, want := len(pkt), header.IPv6MinimumMTU; got > want {
-				t.Fatalf("got an ICMP packet of size: %d, want: sz <= %d", got, want)
-			}
-
-			hdr := header.IPv6(pkt)
-			checker.IPv6(t, hdr, checker.ICMPv6(
-				checker.ICMPv6Type(header.ICMPv6DstUnreachable),
-				checker.ICMPv6Code(header.ICMPv6PortUnreachable)))
-
-			icmpPkt := header.ICMPv6(hdr.Payload())
-			payloadIPHeader := header.IPv6(icmpPkt.Payload())
-			wantLen := len(payload)
-			if tc.largePayload {
-				wantLen = header.IPv6MinimumMTU - header.IPv6MinimumSize*2 - header.ICMPv6MinimumSize - header.UDPMinimumSize
-			}
-			// In case of large payloads the IP packet may be truncated. Update
-			// the length field before retrieving the udp datagram payload.
-			payloadIPHeader.SetPayloadLength(uint16(wantLen + header.UDPMinimumSize))
-
-			origDgram := header.UDP(payloadIPHeader.Payload())
-			if got, want := len(origDgram.Payload()), wantLen; got != want {
-				t.Fatalf("unexpected payload length got: %d, want: %d", got, want)
-			}
-			if got, want := origDgram.Payload(), payload[:wantLen]; !bytes.Equal(got, want) {
-				t.Fatalf("unexpected payload got: %v, want: %v", got, want)
-			}
-		})
-	}
-}
-
-// TestIncrementMalformedPacketsReceived verifies if the malformed received
-// global and endpoint stats are incremented.
-func TestIncrementMalformedPacketsReceived(t *testing.T) {
-	c := newDualTestContext(t, defaultMTU)
-	defer c.cleanup()
-
-	c.createEndpoint(ipv6.ProtocolNumber)
-	// Bind to wildcard.
-	if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}); err != nil {
-		c.t.Fatalf("Bind failed: %s", err)
-	}
-
-	payload := newPayload()
-	h := unicastV6.header4Tuple(incoming)
-	buf := c.buildV6Packet(payload, &h)
-
-	// Invalidate the UDP header length field.
-	u := header.UDP(buf[header.IPv6MinimumSize:])
-	u.SetLength(u.Length() + 1)
-
-	c.linkEP.InjectInbound(ipv6.ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
-		Data: buf.ToVectorisedView(),
-	}))
-
-	const want = 1
-	if got := c.s.Stats().UDP.MalformedPacketsReceived.Value(); got != want {
-		t.Errorf("got stats.UDP.MalformedPacketsReceived.Value() = %d, want = %d", got, want)
-	}
-	if got := c.ep.Stats().(*tcpip.TransportEndpointStats).ReceiveErrors.MalformedPacketsReceived.Value(); got != want {
-		t.Errorf("got EP Stats.ReceiveErrors.MalformedPacketsReceived stats = %d, want = %d", got, want)
-	}
-}
-
-// TestShortHeader verifies that when a packet with a too-short UDP header is
-// received, the malformed received global stat gets incremented.
-func TestShortHeader(t *testing.T) {
-	c := newDualTestContext(t, defaultMTU)
-	defer c.cleanup()
-
-	c.createEndpoint(ipv6.ProtocolNumber)
-	// Bind to wildcard.
-	if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}); err != nil {
-		c.t.Fatalf("Bind failed: %s", err)
-	}
-
-	h := unicastV6.header4Tuple(incoming)
-
-	// Allocate a buffer for an IPv6 and too-short UDP header.
-	const udpSize = header.UDPMinimumSize - 1
-	buf := buffer.NewView(header.IPv6MinimumSize + udpSize)
-	// Initialize the IP header.
-	ip := header.IPv6(buf)
-	ip.Encode(&header.IPv6Fields{
-		TrafficClass:      testTOS,
-		PayloadLength:     uint16(udpSize),
-		TransportProtocol: udp.ProtocolNumber,
-		HopLimit:          65,
-		SrcAddr:           h.srcAddr.Addr,
-		DstAddr:           h.dstAddr.Addr,
-	})
-
-	// Initialize the UDP header.
-	udpHdr := header.UDP(buffer.NewView(header.UDPMinimumSize))
-	udpHdr.Encode(&header.UDPFields{
-		SrcPort: h.srcAddr.Port,
-		DstPort: h.dstAddr.Port,
-		Length:  header.UDPMinimumSize,
-	})
-	// Calculate the UDP pseudo-header checksum.
-	xsum := header.PseudoHeaderChecksum(udp.ProtocolNumber, h.srcAddr.Addr, h.dstAddr.Addr, uint16(len(udpHdr)))
-	udpHdr.SetChecksum(^udpHdr.CalculateChecksum(xsum))
-	// Copy all but the last byte of the UDP header into the packet.
-	copy(buf[header.IPv6MinimumSize:], udpHdr)
-
-	// Inject packet.
-	c.linkEP.InjectInbound(ipv6.ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
-		Data: buf.ToVectorisedView(),
-	}))
-
-	if got, want := c.s.Stats().MalformedRcvdPackets.Value(), uint64(1); got != want {
-		t.Errorf("got c.s.Stats().MalformedRcvdPackets.Value() = %d, want = %d", got, want)
-	}
-}
-
-// TestBadChecksumErrors verifies if a checksum error is detected,
-// global and endpoint stats are incremented.
-func TestBadChecksumErrors(t *testing.T) {
-	for _, flow := range []testFlow{unicastV4, unicastV6} {
-		c := newDualTestContext(t, defaultMTU)
-		defer c.cleanup()
-
-		c.createEndpoint(flow.sockProto())
-		// Bind to wildcard.
-		if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}); err != nil {
-			c.t.Fatalf("Bind failed: %s", err)
-		}
-
-		payload := newPayload()
-		c.injectPacket(flow, payload, true /* badChecksum */)
-
-		const want = 1
-		if got := c.s.Stats().UDP.ChecksumErrors.Value(); got != want {
-			t.Errorf("got stats.UDP.ChecksumErrors.Value() = %d, want = %d", got, want)
-		}
-		if got := c.ep.Stats().(*tcpip.TransportEndpointStats).ReceiveErrors.ChecksumErrors.Value(); got != want {
-			t.Errorf("got EP Stats.ReceiveErrors.ChecksumErrors stats = %d, want = %d", got, want)
-		}
-	}
-}
-
-// TestPayloadModifiedV4 verifies if a checksum error is detected,
-// global and endpoint stats are incremented.
-func TestPayloadModifiedV4(t *testing.T) {
-	c := newDualTestContext(t, defaultMTU)
-	defer c.cleanup()
-
-	c.createEndpoint(ipv4.ProtocolNumber)
-	// Bind to wildcard.
-	if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}); err != nil {
-		c.t.Fatalf("Bind failed: %s", err)
-	}
-
-	payload := newPayload()
-	h := unicastV4.header4Tuple(incoming)
-	buf := c.buildV4Packet(payload, &h)
-	// Modify the payload so that the checksum value in the UDP header will be
-	// incorrect.
-	buf[len(buf)-1]++
-	c.linkEP.InjectInbound(ipv4.ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
-		Data: buf.ToVectorisedView(),
-	}))
-
-	const want = 1
-	if got := c.s.Stats().UDP.ChecksumErrors.Value(); got != want {
-		t.Errorf("got stats.UDP.ChecksumErrors.Value() = %d, want = %d", got, want)
-	}
-	if got := c.ep.Stats().(*tcpip.TransportEndpointStats).ReceiveErrors.ChecksumErrors.Value(); got != want {
-		t.Errorf("got EP Stats.ReceiveErrors.ChecksumErrors stats = %d, want = %d", got, want)
-	}
-}
-
-// TestPayloadModifiedV6 verifies if a checksum error is detected,
-// global and endpoint stats are incremented.
-func TestPayloadModifiedV6(t *testing.T) {
-	c := newDualTestContext(t, defaultMTU)
-	defer c.cleanup()
-
-	c.createEndpoint(ipv6.ProtocolNumber)
-	// Bind to wildcard.
-	if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}); err != nil {
-		c.t.Fatalf("Bind failed: %s", err)
-	}
-
-	payload := newPayload()
-	h := unicastV6.header4Tuple(incoming)
-	buf := c.buildV6Packet(payload, &h)
-	// Modify the payload so that the checksum value in the UDP header will be
-	// incorrect.
-	buf[len(buf)-1]++
-	c.linkEP.InjectInbound(ipv6.ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
-		Data: buf.ToVectorisedView(),
-	}))
-
-	const want = 1
-	if got := c.s.Stats().UDP.ChecksumErrors.Value(); got != want {
-		t.Errorf("got stats.UDP.ChecksumErrors.Value() = %d, want = %d", got, want)
-	}
-	if got := c.ep.Stats().(*tcpip.TransportEndpointStats).ReceiveErrors.ChecksumErrors.Value(); got != want {
-		t.Errorf("got EP Stats.ReceiveErrors.ChecksumErrors stats = %d, want = %d", got, want)
-	}
-}
-
-// TestChecksumZeroV4 verifies if the checksum value is zero, global and
-// endpoint states are *not* incremented (UDP checksum is optional on IPv4).
-func TestChecksumZeroV4(t *testing.T) {
-	c := newDualTestContext(t, defaultMTU)
-	defer c.cleanup()
-
-	c.createEndpoint(ipv4.ProtocolNumber)
-	// Bind to wildcard.
-	if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}); err != nil {
-		c.t.Fatalf("Bind failed: %s", err)
-	}
-
-	payload := newPayload()
-	h := unicastV4.header4Tuple(incoming)
-	buf := c.buildV4Packet(payload, &h)
-	// Set the checksum field in the UDP header to zero.
-	u := header.UDP(buf[header.IPv4MinimumSize:])
-	u.SetChecksum(0)
-	c.linkEP.InjectInbound(ipv4.ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
-		Data: buf.ToVectorisedView(),
-	}))
-
-	const want = 0
-	if got := c.s.Stats().UDP.ChecksumErrors.Value(); got != want {
-		t.Errorf("got stats.UDP.ChecksumErrors.Value() = %d, want = %d", got, want)
-	}
-	if got := c.ep.Stats().(*tcpip.TransportEndpointStats).ReceiveErrors.ChecksumErrors.Value(); got != want {
-		t.Errorf("got EP Stats.ReceiveErrors.ChecksumErrors stats = %d, want = %d", got, want)
-	}
-}
-
-// TestChecksumZeroV6 verifies if the checksum value is zero, global and
-// endpoint states are incremented (UDP checksum is *not* optional on IPv6).
-func TestChecksumZeroV6(t *testing.T) {
-	c := newDualTestContext(t, defaultMTU)
-	defer c.cleanup()
-
-	c.createEndpoint(ipv6.ProtocolNumber)
-	// Bind to wildcard.
-	if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}); err != nil {
-		c.t.Fatalf("Bind failed: %s", err)
-	}
-
-	payload := newPayload()
-	h := unicastV6.header4Tuple(incoming)
-	buf := c.buildV6Packet(payload, &h)
-	// Set the checksum field in the UDP header to zero.
-	u := header.UDP(buf[header.IPv6MinimumSize:])
-	u.SetChecksum(0)
-	c.linkEP.InjectInbound(ipv6.ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
-		Data: buf.ToVectorisedView(),
-	}))
-
-	const want = 1
-	if got := c.s.Stats().UDP.ChecksumErrors.Value(); got != want {
-		t.Errorf("got stats.UDP.ChecksumErrors.Value() = %d, want = %d", got, want)
-	}
-	if got := c.ep.Stats().(*tcpip.TransportEndpointStats).ReceiveErrors.ChecksumErrors.Value(); got != want {
-		t.Errorf("got EP Stats.ReceiveErrors.ChecksumErrors stats = %d, want = %d", got, want)
-	}
-}
-
-// TestShutdownRead verifies endpoint read shutdown and error
-// stats increment on packet receive.
-func TestShutdownRead(t *testing.T) {
-	c := newDualTestContext(t, defaultMTU)
-	defer c.cleanup()
-
-	c.createEndpoint(ipv6.ProtocolNumber)
-
-	// Bind to wildcard.
-	if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}); err != nil {
-		c.t.Fatalf("Bind failed: %s", err)
-	}
-
-	if err := c.ep.Connect(tcpip.FullAddress{Addr: testV6Addr, Port: testPort}); err != nil {
-		c.t.Fatalf("Connect failed: %s", err)
-	}
-
-	if err := c.ep.Shutdown(tcpip.ShutdownRead); err != nil {
-		t.Fatalf("Shutdown failed: %s", err)
-	}
-
-	testFailingRead(c, unicastV6, true /* expectReadError */)
-
-	var want uint64 = 1
-	if got := c.s.Stats().UDP.ReceiveBufferErrors.Value(); got != want {
-		t.Errorf("got stats.UDP.ReceiveBufferErrors.Value() = %v, want = %v", got, want)
-	}
-	if got := c.ep.Stats().(*tcpip.TransportEndpointStats).ReceiveErrors.ClosedReceiver.Value(); got != want {
-		t.Errorf("got EP Stats.ReceiveErrors.ClosedReceiver stats = %v, want = %v", got, want)
-	}
-}
-
-// TestShutdownWrite verifies endpoint write shutdown and error
-// stats increment on packet write.
-func TestShutdownWrite(t *testing.T) {
-	c := newDualTestContext(t, defaultMTU)
-	defer c.cleanup()
-
-	c.createEndpoint(ipv6.ProtocolNumber)
-
-	if err := c.ep.Connect(tcpip.FullAddress{Addr: testV6Addr, Port: testPort}); err != nil {
-		c.t.Fatalf("Connect failed: %s", err)
-	}
-
-	if err := c.ep.Shutdown(tcpip.ShutdownWrite); err != nil {
-		t.Fatalf("Shutdown failed: %s", err)
-	}
-
-	testFailingWrite(c, unicastV6, &tcpip.ErrClosedForSend{})
-}
-
-func (c *testContext) checkEndpointWriteStats(incr uint64, want tcpip.TransportEndpointStats, err tcpip.Error) {
-	got := c.ep.Stats().(*tcpip.TransportEndpointStats).Clone()
-	switch err.(type) {
-	case nil:
-		want.PacketsSent.IncrementBy(incr)
-	case *tcpip.ErrMessageTooLong, *tcpip.ErrInvalidOptionValue:
-		want.WriteErrors.InvalidArgs.IncrementBy(incr)
-	case *tcpip.ErrClosedForSend:
-		want.WriteErrors.WriteClosed.IncrementBy(incr)
-	case *tcpip.ErrInvalidEndpointState:
-		want.WriteErrors.InvalidEndpointState.IncrementBy(incr)
-	case *tcpip.ErrNoRoute, *tcpip.ErrBroadcastDisabled, *tcpip.ErrNetworkUnreachable:
-		want.SendErrors.NoRoute.IncrementBy(incr)
-	default:
-		want.SendErrors.SendToNetworkFailed.IncrementBy(incr)
-	}
-	if got != want {
-		c.t.Errorf("Endpoint stats not matching for error %s got %+v want %+v", err, got, want)
-	}
-}
-
-func (c *testContext) checkEndpointReadStats(incr uint64, want tcpip.TransportEndpointStats, err tcpip.Error) {
-	got := c.ep.Stats().(*tcpip.TransportEndpointStats).Clone()
-	switch err.(type) {
-	case nil, *tcpip.ErrWouldBlock:
-	case *tcpip.ErrClosedForReceive:
-		want.ReadErrors.ReadClosed.IncrementBy(incr)
-	default:
-		c.t.Errorf("Endpoint error missing stats update err %v", err)
-	}
-	if got != want {
-		c.t.Errorf("Endpoint stats not matching for error %s got %+v want %+v", err, got, want)
-	}
-}
-
-func TestOutgoingSubnetBroadcast(t *testing.T) {
-	const nicID1 = 1
-
-	ipv4Addr := tcpip.AddressWithPrefix{
-		Address:   "\xc0\xa8\x01\x3a",
-		PrefixLen: 24,
-	}
-	ipv4Subnet := ipv4Addr.Subnet()
-	ipv4SubnetBcast := ipv4Subnet.Broadcast()
-	ipv4Gateway := tcpip.Address("\xc0\xa8\x01\x01")
-	ipv4AddrPrefix31 := tcpip.AddressWithPrefix{
-		Address:   "\xc0\xa8\x01\x3a",
-		PrefixLen: 31,
-	}
-	ipv4Subnet31 := ipv4AddrPrefix31.Subnet()
-	ipv4Subnet31Bcast := ipv4Subnet31.Broadcast()
-	ipv4AddrPrefix32 := tcpip.AddressWithPrefix{
-		Address:   "\xc0\xa8\x01\x3a",
-		PrefixLen: 32,
-	}
-	ipv4Subnet32 := ipv4AddrPrefix32.Subnet()
-	ipv4Subnet32Bcast := ipv4Subnet32.Broadcast()
-	ipv6Addr := tcpip.AddressWithPrefix{
-		Address:   "\x20\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01",
-		PrefixLen: 64,
-	}
-	ipv6Subnet := ipv6Addr.Subnet()
-	ipv6SubnetBcast := ipv6Subnet.Broadcast()
-	remNetAddr := tcpip.AddressWithPrefix{
-		Address:   "\x64\x0a\x7b\x18",
-		PrefixLen: 24,
-	}
-	remNetSubnet := remNetAddr.Subnet()
-	remNetSubnetBcast := remNetSubnet.Broadcast()
-
-	tests := []struct {
-		name                 string
-		nicAddr              tcpip.ProtocolAddress
-		routes               []tcpip.Route
-		remoteAddr           tcpip.Address
-		requiresBroadcastOpt bool
-	}{
-		{
-			name: "IPv4 Broadcast to local subnet",
-			nicAddr: tcpip.ProtocolAddress{
-				Protocol:          header.IPv4ProtocolNumber,
-				AddressWithPrefix: ipv4Addr,
-			},
-			routes: []tcpip.Route{
-				{
-					Destination: ipv4Subnet,
-					NIC:         nicID1,
-				},
-			},
-			remoteAddr:           ipv4SubnetBcast,
-			requiresBroadcastOpt: true,
-		},
-		{
-			name: "IPv4 Broadcast to local /31 subnet",
-			nicAddr: tcpip.ProtocolAddress{
-				Protocol:          header.IPv4ProtocolNumber,
-				AddressWithPrefix: ipv4AddrPrefix31,
-			},
-			routes: []tcpip.Route{
-				{
-					Destination: ipv4Subnet31,
-					NIC:         nicID1,
-				},
-			},
-			remoteAddr:           ipv4Subnet31Bcast,
-			requiresBroadcastOpt: false,
-		},
-		{
-			name: "IPv4 Broadcast to local /32 subnet",
-			nicAddr: tcpip.ProtocolAddress{
-				Protocol:          header.IPv4ProtocolNumber,
-				AddressWithPrefix: ipv4AddrPrefix32,
-			},
-			routes: []tcpip.Route{
-				{
-					Destination: ipv4Subnet32,
-					NIC:         nicID1,
-				},
-			},
-			remoteAddr:           ipv4Subnet32Bcast,
-			requiresBroadcastOpt: false,
-		},
-		// IPv6 has no notion of a broadcast.
-		{
-			name: "IPv6 'Broadcast' to local subnet",
-			nicAddr: tcpip.ProtocolAddress{
-				Protocol:          header.IPv6ProtocolNumber,
-				AddressWithPrefix: ipv6Addr,
-			},
-			routes: []tcpip.Route{
-				{
-					Destination: ipv6Subnet,
-					NIC:         nicID1,
-				},
-			},
-			remoteAddr:           ipv6SubnetBcast,
-			requiresBroadcastOpt: false,
-		},
-		{
-			name: "IPv4 Broadcast to remote subnet",
-			nicAddr: tcpip.ProtocolAddress{
-				Protocol:          header.IPv4ProtocolNumber,
-				AddressWithPrefix: ipv4Addr,
-			},
-			routes: []tcpip.Route{
-				{
-					Destination: remNetSubnet,
-					Gateway:     ipv4Gateway,
-					NIC:         nicID1,
-				},
-			},
-			remoteAddr: remNetSubnetBcast,
-			// TODO(gvisor.dev/issue/3938): Once we support marking a route as
-			// broadcast, this test should require the broadcast option to be set.
-			requiresBroadcastOpt: false,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			s := stack.New(stack.Options{
-				NetworkProtocols:   []stack.NetworkProtocolFactory{ipv4.NewProtocol, ipv6.NewProtocol},
-				TransportProtocols: []stack.TransportProtocolFactory{udp.NewProtocol},
-			})
-			e := channel.New(0, defaultMTU, "")
-			if err := s.CreateNIC(nicID1, e); err != nil {
-				t.Fatalf("CreateNIC(%d, _): %s", nicID1, err)
-			}
-			if err := s.AddProtocolAddress(nicID1, test.nicAddr); err != nil {
-				t.Fatalf("AddProtocolAddress(%d, %+v): %s", nicID1, test.nicAddr, err)
-			}
-
-			s.SetRouteTable(test.routes)
-
-			var netProto tcpip.NetworkProtocolNumber
-			switch l := len(test.remoteAddr); l {
-			case header.IPv4AddressSize:
-				netProto = header.IPv4ProtocolNumber
-			case header.IPv6AddressSize:
-				netProto = header.IPv6ProtocolNumber
-			default:
-				t.Fatalf("got unexpected address length = %d bytes", l)
-			}
-
-			wq := waiter.Queue{}
-			ep, err := s.NewEndpoint(udp.ProtocolNumber, netProto, &wq)
-			if err != nil {
-				t.Fatalf("NewEndpoint(%d, %d, _): %s", udp.ProtocolNumber, netProto, err)
-			}
-			defer ep.Close()
-
-			var r bytes.Reader
-			data := []byte{1, 2, 3, 4}
-			to := tcpip.FullAddress{
-				Addr: test.remoteAddr,
-				Port: 80,
-			}
-			opts := tcpip.WriteOptions{To: &to}
-			expectedErrWithoutBcastOpt := func(err tcpip.Error) tcpip.Error {
-				if _, ok := err.(*tcpip.ErrBroadcastDisabled); ok {
-					return nil
-				}
-				return &tcpip.ErrBroadcastDisabled{}
-			}
-			if !test.requiresBroadcastOpt {
-				expectedErrWithoutBcastOpt = nil
-			}
-
-			r.Reset(data)
-			{
-				n, err := ep.Write(&r, opts)
-				if expectedErrWithoutBcastOpt != nil {
-					if want := expectedErrWithoutBcastOpt(err); want != nil {
-						t.Fatalf("got ep.Write(_, %#v) = (%d, %s), want = (_, %s)", opts, n, err, want)
-					}
-				} else if err != nil {
-					t.Fatalf("got ep.Write(_, %#v) = (%d, %s), want = (_, nil)", opts, n, err)
-				}
-			}
-
-			ep.SocketOptions().SetBroadcast(true)
-
-			r.Reset(data)
-			if n, err := ep.Write(&r, opts); err != nil {
-				t.Fatalf("got ep.Write(_, %#v) = (%d, %s), want = (_, nil)", opts, n, err)
-			}
-
-			ep.SocketOptions().SetBroadcast(false)
-
-			r.Reset(data)
-			{
-				n, err := ep.Write(&r, opts)
-				if expectedErrWithoutBcastOpt != nil {
-					if want := expectedErrWithoutBcastOpt(err); want != nil {
-						t.Fatalf("got ep.Write(_, %#v) = (%d, %s), want = (_, %s)", opts, n, err, want)
-					}
-				} else if err != nil {
-					t.Fatalf("got ep.Write(_, %#v) = (%d, %s), want = (_, nil)", opts, n, err)
-				}
-			}
-		})
-	}
-}
diff --git a/pkg/waiter/waiter_list.go b/pkg/waiter/waiter_list.go
new file mode 100644
index 0000000..f83aeb4
--- /dev/null
+++ b/pkg/waiter/waiter_list.go
@@ -0,0 +1,221 @@
+package waiter
+
+// ElementMapper provides an identity mapping by default.
+//
+// This can be replaced to provide a struct that maps elements to linker
+// objects, if they are not the same. An ElementMapper is not typically
+// required if: Linker is left as is, Element is left as is, or Linker and
+// Element are the same type.
+type waiterElementMapper struct{}
+
+// linkerFor maps an Element to a Linker.
+//
+// This default implementation should be inlined.
+//
+//go:nosplit
+func (waiterElementMapper) linkerFor(elem *Entry) *Entry { return elem }
+
+// List is an intrusive list. Entries can be added to or removed from the list
+// in O(1) time and with no additional memory allocations.
+//
+// The zero value for List is an empty list ready to use.
+//
+// To iterate over a list (where l is a List):
+//      for e := l.Front(); e != nil; e = e.Next() {
+// 		// do something with e.
+//      }
+//
+// +stateify savable
+type waiterList struct {
+	head *Entry
+	tail *Entry
+}
+
+// Reset resets list l to the empty state.
+func (l *waiterList) Reset() {
+	l.head = nil
+	l.tail = nil
+}
+
+// Empty returns true iff the list is empty.
+//
+//go:nosplit
+func (l *waiterList) Empty() bool {
+	return l.head == nil
+}
+
+// Front returns the first element of list l or nil.
+//
+//go:nosplit
+func (l *waiterList) Front() *Entry {
+	return l.head
+}
+
+// Back returns the last element of list l or nil.
+//
+//go:nosplit
+func (l *waiterList) Back() *Entry {
+	return l.tail
+}
+
+// Len returns the number of elements in the list.
+//
+// NOTE: This is an O(n) operation.
+//
+//go:nosplit
+func (l *waiterList) Len() (count int) {
+	for e := l.Front(); e != nil; e = (waiterElementMapper{}.linkerFor(e)).Next() {
+		count++
+	}
+	return count
+}
+
+// PushFront inserts the element e at the front of list l.
+//
+//go:nosplit
+func (l *waiterList) PushFront(e *Entry) {
+	linker := waiterElementMapper{}.linkerFor(e)
+	linker.SetNext(l.head)
+	linker.SetPrev(nil)
+	if l.head != nil {
+		waiterElementMapper{}.linkerFor(l.head).SetPrev(e)
+	} else {
+		l.tail = e
+	}
+
+	l.head = e
+}
+
+// PushBack inserts the element e at the back of list l.
+//
+//go:nosplit
+func (l *waiterList) PushBack(e *Entry) {
+	linker := waiterElementMapper{}.linkerFor(e)
+	linker.SetNext(nil)
+	linker.SetPrev(l.tail)
+	if l.tail != nil {
+		waiterElementMapper{}.linkerFor(l.tail).SetNext(e)
+	} else {
+		l.head = e
+	}
+
+	l.tail = e
+}
+
+// PushBackList inserts list m at the end of list l, emptying m.
+//
+//go:nosplit
+func (l *waiterList) PushBackList(m *waiterList) {
+	if l.head == nil {
+		l.head = m.head
+		l.tail = m.tail
+	} else if m.head != nil {
+		waiterElementMapper{}.linkerFor(l.tail).SetNext(m.head)
+		waiterElementMapper{}.linkerFor(m.head).SetPrev(l.tail)
+
+		l.tail = m.tail
+	}
+	m.head = nil
+	m.tail = nil
+}
+
+// InsertAfter inserts e after b.
+//
+//go:nosplit
+func (l *waiterList) InsertAfter(b, e *Entry) {
+	bLinker := waiterElementMapper{}.linkerFor(b)
+	eLinker := waiterElementMapper{}.linkerFor(e)
+
+	a := bLinker.Next()
+
+	eLinker.SetNext(a)
+	eLinker.SetPrev(b)
+	bLinker.SetNext(e)
+
+	if a != nil {
+		waiterElementMapper{}.linkerFor(a).SetPrev(e)
+	} else {
+		l.tail = e
+	}
+}
+
+// InsertBefore inserts e before a.
+//
+//go:nosplit
+func (l *waiterList) InsertBefore(a, e *Entry) {
+	aLinker := waiterElementMapper{}.linkerFor(a)
+	eLinker := waiterElementMapper{}.linkerFor(e)
+
+	b := aLinker.Prev()
+	eLinker.SetNext(a)
+	eLinker.SetPrev(b)
+	aLinker.SetPrev(e)
+
+	if b != nil {
+		waiterElementMapper{}.linkerFor(b).SetNext(e)
+	} else {
+		l.head = e
+	}
+}
+
+// Remove removes e from l.
+//
+//go:nosplit
+func (l *waiterList) Remove(e *Entry) {
+	linker := waiterElementMapper{}.linkerFor(e)
+	prev := linker.Prev()
+	next := linker.Next()
+
+	if prev != nil {
+		waiterElementMapper{}.linkerFor(prev).SetNext(next)
+	} else if l.head == e {
+		l.head = next
+	}
+
+	if next != nil {
+		waiterElementMapper{}.linkerFor(next).SetPrev(prev)
+	} else if l.tail == e {
+		l.tail = prev
+	}
+
+	linker.SetNext(nil)
+	linker.SetPrev(nil)
+}
+
+// Entry is a default implementation of Linker. Users can add anonymous fields
+// of this type to their structs to make them automatically implement the
+// methods needed by List.
+//
+// +stateify savable
+type waiterEntry struct {
+	next *Entry
+	prev *Entry
+}
+
+// Next returns the entry that follows e in the list.
+//
+//go:nosplit
+func (e *waiterEntry) Next() *Entry {
+	return e.next
+}
+
+// Prev returns the entry that precedes e in the list.
+//
+//go:nosplit
+func (e *waiterEntry) Prev() *Entry {
+	return e.prev
+}
+
+// SetNext assigns 'entry' as the entry that follows e in the list.
+//
+//go:nosplit
+func (e *waiterEntry) SetNext(elem *Entry) {
+	e.next = elem
+}
+
+// SetPrev assigns 'entry' as the entry that precedes e in the list.
+//
+//go:nosplit
+func (e *waiterEntry) SetPrev(elem *Entry) {
+	e.prev = elem
+}
diff --git a/pkg/waiter/waiter_state_autogen.go b/pkg/waiter/waiter_state_autogen.go
new file mode 100644
index 0000000..498b7e7
--- /dev/null
+++ b/pkg/waiter/waiter_state_autogen.go
@@ -0,0 +1,126 @@
+// automatically generated by stateify.
+
+package waiter
+
+import (
+	"gvisor.dev/gvisor/pkg/state"
+)
+
+func (e *Entry) StateTypeName() string {
+	return "pkg/waiter.Entry"
+}
+
+func (e *Entry) StateFields() []string {
+	return []string{
+		"Callback",
+		"mask",
+		"waiterEntry",
+	}
+}
+
+func (e *Entry) beforeSave() {}
+
+// +checklocksignore
+func (e *Entry) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+	stateSinkObject.Save(0, &e.Callback)
+	stateSinkObject.Save(1, &e.mask)
+	stateSinkObject.Save(2, &e.waiterEntry)
+}
+
+func (e *Entry) afterLoad() {}
+
+// +checklocksignore
+func (e *Entry) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &e.Callback)
+	stateSourceObject.Load(1, &e.mask)
+	stateSourceObject.Load(2, &e.waiterEntry)
+}
+
+func (q *Queue) StateTypeName() string {
+	return "pkg/waiter.Queue"
+}
+
+func (q *Queue) StateFields() []string {
+	return []string{
+		"list",
+	}
+}
+
+func (q *Queue) beforeSave() {}
+
+// +checklocksignore
+func (q *Queue) StateSave(stateSinkObject state.Sink) {
+	q.beforeSave()
+	stateSinkObject.Save(0, &q.list)
+}
+
+func (q *Queue) afterLoad() {}
+
+// +checklocksignore
+func (q *Queue) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &q.list)
+}
+
+func (l *waiterList) StateTypeName() string {
+	return "pkg/waiter.waiterList"
+}
+
+func (l *waiterList) StateFields() []string {
+	return []string{
+		"head",
+		"tail",
+	}
+}
+
+func (l *waiterList) beforeSave() {}
+
+// +checklocksignore
+func (l *waiterList) StateSave(stateSinkObject state.Sink) {
+	l.beforeSave()
+	stateSinkObject.Save(0, &l.head)
+	stateSinkObject.Save(1, &l.tail)
+}
+
+func (l *waiterList) afterLoad() {}
+
+// +checklocksignore
+func (l *waiterList) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &l.head)
+	stateSourceObject.Load(1, &l.tail)
+}
+
+func (e *waiterEntry) StateTypeName() string {
+	return "pkg/waiter.waiterEntry"
+}
+
+func (e *waiterEntry) StateFields() []string {
+	return []string{
+		"next",
+		"prev",
+	}
+}
+
+func (e *waiterEntry) beforeSave() {}
+
+// +checklocksignore
+func (e *waiterEntry) StateSave(stateSinkObject state.Sink) {
+	e.beforeSave()
+	stateSinkObject.Save(0, &e.next)
+	stateSinkObject.Save(1, &e.prev)
+}
+
+func (e *waiterEntry) afterLoad() {}
+
+// +checklocksignore
+func (e *waiterEntry) StateLoad(stateSourceObject state.Source) {
+	stateSourceObject.Load(0, &e.next)
+	stateSourceObject.Load(1, &e.prev)
+}
+
+func init() {
+	state.Register((*Entry)(nil))
+	state.Register((*Queue)(nil))
+	state.Register((*waiterList)(nil))
+	state.Register((*waiterEntry)(nil))
+}
diff --git a/pkg/waiter/waiter_test.go b/pkg/waiter/waiter_test.go
deleted file mode 100644
index 6928f28..0000000
--- a/pkg/waiter/waiter_test.go
+++ /dev/null
@@ -1,198 +0,0 @@
-// 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 waiter
-
-import (
-	"sync/atomic"
-	"testing"
-)
-
-type callbackStub struct {
-	f func(e *Entry, m EventMask)
-}
-
-// Callback implements EntryCallback.Callback.
-func (c *callbackStub) Callback(e *Entry, m EventMask) {
-	c.f(e, m)
-}
-
-func TestEmptyQueue(t *testing.T) {
-	var q Queue
-
-	// Notify the zero-value of a queue.
-	q.Notify(EventIn)
-
-	// Register then unregister a waiter, then notify the queue.
-	cnt := 0
-	e := Entry{Callback: &callbackStub{func(*Entry, EventMask) { cnt++ }}}
-	q.EventRegister(&e, EventIn)
-	q.EventUnregister(&e)
-	q.Notify(EventIn)
-	if cnt != 0 {
-		t.Errorf("Callback was called when it shouldn't have been")
-	}
-}
-
-func TestMask(t *testing.T) {
-	// Register a waiter.
-	var q Queue
-	var cnt int
-	e := Entry{Callback: &callbackStub{func(*Entry, EventMask) { cnt++ }}}
-	q.EventRegister(&e, EventIn|EventErr)
-
-	// Notify with an overlapping mask.
-	cnt = 0
-	q.Notify(EventIn | EventOut)
-	if cnt != 1 {
-		t.Errorf("Callback wasn't called when it should have been")
-	}
-
-	// Notify with a subset mask.
-	cnt = 0
-	q.Notify(EventIn)
-	if cnt != 1 {
-		t.Errorf("Callback wasn't called when it should have been")
-	}
-
-	// Notify with a superset mask.
-	cnt = 0
-	q.Notify(EventIn | EventErr | EventOut)
-	if cnt != 1 {
-		t.Errorf("Callback wasn't called when it should have been")
-	}
-
-	// Notify with the exact same mask.
-	cnt = 0
-	q.Notify(EventIn | EventErr)
-	if cnt != 1 {
-		t.Errorf("Callback wasn't called when it should have been")
-	}
-
-	// Notify with a disjoint mask.
-	cnt = 0
-	q.Notify(EventOut | EventHUp)
-	if cnt != 0 {
-		t.Errorf("Callback was called when it shouldn't have been")
-	}
-}
-
-func TestConcurrentRegistration(t *testing.T) {
-	var q Queue
-	var cnt int
-	const concurrency = 1000
-
-	ch1 := make(chan struct{})
-	ch2 := make(chan struct{})
-	ch3 := make(chan struct{})
-
-	// Create goroutines that will all register/unregister concurrently.
-	for i := 0; i < concurrency; i++ {
-		go func() {
-			var e Entry
-			e.Callback = &callbackStub{func(entry *Entry, mask EventMask) {
-				cnt++
-				if entry != &e {
-					t.Errorf("entry = %p, want %p", entry, &e)
-				}
-				if mask != EventIn {
-					t.Errorf("mask = %#x want %#x", mask, EventIn)
-				}
-			}}
-
-			// Wait for notification, then register.
-			<-ch1
-			q.EventRegister(&e, EventIn|EventErr)
-
-			// Tell main goroutine that we're done registering.
-			ch2 <- struct{}{}
-
-			// Wait for notification, then unregister.
-			<-ch3
-			q.EventUnregister(&e)
-
-			// Tell main goroutine that we're done unregistering.
-			ch2 <- struct{}{}
-		}()
-	}
-
-	// Let the goroutines register.
-	close(ch1)
-	for i := 0; i < concurrency; i++ {
-		<-ch2
-	}
-
-	// Issue a notification.
-	q.Notify(EventIn)
-	if cnt != concurrency {
-		t.Errorf("cnt = %d, want %d", cnt, concurrency)
-	}
-
-	// Let the goroutine unregister.
-	close(ch3)
-	for i := 0; i < concurrency; i++ {
-		<-ch2
-	}
-
-	// Issue a notification.
-	q.Notify(EventIn)
-	if cnt != concurrency {
-		t.Errorf("cnt = %d, want %d", cnt, concurrency)
-	}
-}
-
-func TestConcurrentNotification(t *testing.T) {
-	var q Queue
-	var cnt int32
-	const concurrency = 1000
-	const waiterCount = 1000
-
-	// Register waiters.
-	for i := 0; i < waiterCount; i++ {
-		var e Entry
-		e.Callback = &callbackStub{func(entry *Entry, mask EventMask) {
-			atomic.AddInt32(&cnt, 1)
-			if entry != &e {
-				t.Errorf("entry = %p, want %p", entry, &e)
-			}
-			if mask != EventIn {
-				t.Errorf("mask = %#x want %#x", mask, EventIn)
-			}
-		}}
-
-		q.EventRegister(&e, EventIn|EventErr)
-	}
-
-	// Launch notifiers.
-	ch1 := make(chan struct{})
-	ch2 := make(chan struct{})
-	for i := 0; i < concurrency; i++ {
-		go func() {
-			<-ch1
-			q.Notify(EventIn)
-			ch2 <- struct{}{}
-		}()
-	}
-
-	// Let notifiers go.
-	close(ch1)
-	for i := 0; i < concurrency; i++ {
-		<-ch2
-	}
-
-	// Check the count.
-	if cnt != concurrency*waiterCount {
-		t.Errorf("cnt = %d, want %d", cnt, concurrency*waiterCount)
-	}
-}
