diff --git a/pkg/linewriter/linewriter_state_autogen.go b/pkg/linewriter/linewriter_state_autogen.go
new file mode 100755
index 0000000..1cd1df9
--- /dev/null
+++ b/pkg/linewriter/linewriter_state_autogen.go
@@ -0,0 +1,3 @@
+// automatically generated by stateify.
+
+package linewriter
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_state_autogen.go b/pkg/log/log_state_autogen.go
new file mode 100755
index 0000000..4e243c2
--- /dev/null
+++ b/pkg/log/log_state_autogen.go
@@ -0,0 +1,3 @@
+// automatically generated by stateify.
+
+package log
diff --git a/pkg/log/log_test.go b/pkg/log/log_test.go
deleted file mode 100644
index 402cc29..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 100755
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 100755
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/commit_arm64.s b/pkg/sleep/commit_arm64.s
old mode 100644
new mode 100755
diff --git a/pkg/sleep/empty.s b/pkg/sleep/empty.s
deleted file mode 100644
index fb37360..0000000
--- a/pkg/sleep/empty.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/sleep/sleep_state_autogen.go b/pkg/sleep/sleep_state_autogen.go
new file mode 100755
index 0000000..e8727e1
--- /dev/null
+++ b/pkg/sleep/sleep_state_autogen.go
@@ -0,0 +1,9 @@
+// automatically generated by stateify.
+
+// +build amd64 arm64
+// +build !race
+// +build !amd64,!arm64
+// +build go1.11
+// +build !go1.15
+
+package sleep
diff --git a/pkg/sleep/sleep_test.go b/pkg/sleep/sleep_test.go
deleted file mode 100644
index af47e2b..0000000
--- a/pkg/sleep/sleep_test.go
+++ /dev/null
@@ -1,573 +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) {
-	const wakers = 100
-	const wakeRequests = 10000
-
-	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() {
-		n := 0
-		for n < wakeRequests {
-			wk := w[n%len(w)]
-			wk.Assert()
-			n++
-		}
-	}()
-
-	// Wait for all wake up notifications from all wakers.
-	for i := 0; i < wakeRequests; i++ {
-		v, _ := s.Fetch(true)
-		if got, want := v, i%wakers; 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/state/addr_range.go b/pkg/state/addr_range.go
new file mode 100755
index 0000000..45720c6
--- /dev/null
+++ b/pkg/state/addr_range.go
@@ -0,0 +1,62 @@
+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.
+func (r addrRange) WellFormed() bool {
+	return r.Start <= r.End
+}
+
+// Length returns the length of the range.
+func (r addrRange) Length() uintptr {
+	return r.End - r.Start
+}
+
+// Contains returns true if r contains x.
+func (r addrRange) Contains(x uintptr) bool {
+	return r.Start <= x && x < r.End
+}
+
+// Overlaps returns true if r and r2 overlap.
+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.
+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.
+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.
+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 100755
index 0000000..5261aa4
--- /dev/null
+++ b/pkg/state/addr_set.go
@@ -0,0 +1,1274 @@
+package state
+
+import (
+	__generics_imported0 "reflect"
+)
+
+import (
+	"bytes"
+	"fmt"
+)
+
+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 __generics_imported0.Value) 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 __generics_imported0.Value) 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 __generics_imported0.Value) 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 {
+			prev.SetEndUnchecked(r.End)
+			prev.SetValue(mval)
+			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 {
+			next.SetStartUnchecked(r.Start)
+			next.SetValue(mval)
+			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 __generics_imported0.Value) 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 __generics_imported0.Value) addrIterator {
+	gap = gap.node.rebalanceBeforeInsert(gap)
+	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++
+	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())
+		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--
+	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
+
+	// 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]__generics_imported0.Value
+	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.parent != nil {
+		gap = n.parent.rebalanceBeforeInsert(gap)
+	}
+	if n.nrSegments < addrmaxDegree-1 {
+		return 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 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 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 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 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--
+
+		n = p
+	}
+}
+
+// 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() __generics_imported0.Value {
+	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() *__generics_imported0.Value {
+	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 __generics_imported0.Value) {
+	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()
+}
+
+// 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 []__generics_imported0.Value) {
+
+	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)
+		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 []__generics_imported0.Value
+}
+
+// ExportSortedSlice 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
+}
+
+// ImportSortedSlice 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
+}
+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/object_go_proto/object.pb.go b/pkg/state/object_go_proto/object.pb.go
new file mode 100755
index 0000000..dc51271
--- /dev/null
+++ b/pkg/state/object_go_proto/object.pb.go
@@ -0,0 +1,1195 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: pkg/state/object.proto
+
+package gvisor_state_statefile
+
+import (
+	fmt "fmt"
+	proto "github.com/golang/protobuf/proto"
+	math "math"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
+
+type Slice struct {
+	Length               uint32   `protobuf:"varint,1,opt,name=length,proto3" json:"length,omitempty"`
+	Capacity             uint32   `protobuf:"varint,2,opt,name=capacity,proto3" json:"capacity,omitempty"`
+	RefValue             uint64   `protobuf:"varint,3,opt,name=ref_value,json=refValue,proto3" json:"ref_value,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *Slice) Reset()         { *m = Slice{} }
+func (m *Slice) String() string { return proto.CompactTextString(m) }
+func (*Slice) ProtoMessage()    {}
+func (*Slice) Descriptor() ([]byte, []int) {
+	return fileDescriptor_3dee2c1912d4d62d, []int{0}
+}
+
+func (m *Slice) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Slice.Unmarshal(m, b)
+}
+func (m *Slice) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Slice.Marshal(b, m, deterministic)
+}
+func (m *Slice) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Slice.Merge(m, src)
+}
+func (m *Slice) XXX_Size() int {
+	return xxx_messageInfo_Slice.Size(m)
+}
+func (m *Slice) XXX_DiscardUnknown() {
+	xxx_messageInfo_Slice.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Slice proto.InternalMessageInfo
+
+func (m *Slice) GetLength() uint32 {
+	if m != nil {
+		return m.Length
+	}
+	return 0
+}
+
+func (m *Slice) GetCapacity() uint32 {
+	if m != nil {
+		return m.Capacity
+	}
+	return 0
+}
+
+func (m *Slice) GetRefValue() uint64 {
+	if m != nil {
+		return m.RefValue
+	}
+	return 0
+}
+
+type Array struct {
+	Contents             []*Object `protobuf:"bytes,1,rep,name=contents,proto3" json:"contents,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}  `json:"-"`
+	XXX_unrecognized     []byte    `json:"-"`
+	XXX_sizecache        int32     `json:"-"`
+}
+
+func (m *Array) Reset()         { *m = Array{} }
+func (m *Array) String() string { return proto.CompactTextString(m) }
+func (*Array) ProtoMessage()    {}
+func (*Array) Descriptor() ([]byte, []int) {
+	return fileDescriptor_3dee2c1912d4d62d, []int{1}
+}
+
+func (m *Array) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Array.Unmarshal(m, b)
+}
+func (m *Array) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Array.Marshal(b, m, deterministic)
+}
+func (m *Array) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Array.Merge(m, src)
+}
+func (m *Array) XXX_Size() int {
+	return xxx_messageInfo_Array.Size(m)
+}
+func (m *Array) XXX_DiscardUnknown() {
+	xxx_messageInfo_Array.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Array proto.InternalMessageInfo
+
+func (m *Array) GetContents() []*Object {
+	if m != nil {
+		return m.Contents
+	}
+	return nil
+}
+
+type Map struct {
+	Keys                 []*Object `protobuf:"bytes,1,rep,name=keys,proto3" json:"keys,omitempty"`
+	Values               []*Object `protobuf:"bytes,2,rep,name=values,proto3" json:"values,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}  `json:"-"`
+	XXX_unrecognized     []byte    `json:"-"`
+	XXX_sizecache        int32     `json:"-"`
+}
+
+func (m *Map) Reset()         { *m = Map{} }
+func (m *Map) String() string { return proto.CompactTextString(m) }
+func (*Map) ProtoMessage()    {}
+func (*Map) Descriptor() ([]byte, []int) {
+	return fileDescriptor_3dee2c1912d4d62d, []int{2}
+}
+
+func (m *Map) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Map.Unmarshal(m, b)
+}
+func (m *Map) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Map.Marshal(b, m, deterministic)
+}
+func (m *Map) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Map.Merge(m, src)
+}
+func (m *Map) XXX_Size() int {
+	return xxx_messageInfo_Map.Size(m)
+}
+func (m *Map) XXX_DiscardUnknown() {
+	xxx_messageInfo_Map.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Map proto.InternalMessageInfo
+
+func (m *Map) GetKeys() []*Object {
+	if m != nil {
+		return m.Keys
+	}
+	return nil
+}
+
+func (m *Map) GetValues() []*Object {
+	if m != nil {
+		return m.Values
+	}
+	return nil
+}
+
+type Interface struct {
+	Type                 string   `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"`
+	Value                *Object  `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *Interface) Reset()         { *m = Interface{} }
+func (m *Interface) String() string { return proto.CompactTextString(m) }
+func (*Interface) ProtoMessage()    {}
+func (*Interface) Descriptor() ([]byte, []int) {
+	return fileDescriptor_3dee2c1912d4d62d, []int{3}
+}
+
+func (m *Interface) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Interface.Unmarshal(m, b)
+}
+func (m *Interface) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Interface.Marshal(b, m, deterministic)
+}
+func (m *Interface) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Interface.Merge(m, src)
+}
+func (m *Interface) XXX_Size() int {
+	return xxx_messageInfo_Interface.Size(m)
+}
+func (m *Interface) XXX_DiscardUnknown() {
+	xxx_messageInfo_Interface.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Interface proto.InternalMessageInfo
+
+func (m *Interface) GetType() string {
+	if m != nil {
+		return m.Type
+	}
+	return ""
+}
+
+func (m *Interface) GetValue() *Object {
+	if m != nil {
+		return m.Value
+	}
+	return nil
+}
+
+type Struct struct {
+	Fields               []*Field `protobuf:"bytes,1,rep,name=fields,proto3" json:"fields,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *Struct) Reset()         { *m = Struct{} }
+func (m *Struct) String() string { return proto.CompactTextString(m) }
+func (*Struct) ProtoMessage()    {}
+func (*Struct) Descriptor() ([]byte, []int) {
+	return fileDescriptor_3dee2c1912d4d62d, []int{4}
+}
+
+func (m *Struct) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Struct.Unmarshal(m, b)
+}
+func (m *Struct) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Struct.Marshal(b, m, deterministic)
+}
+func (m *Struct) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Struct.Merge(m, src)
+}
+func (m *Struct) XXX_Size() int {
+	return xxx_messageInfo_Struct.Size(m)
+}
+func (m *Struct) XXX_DiscardUnknown() {
+	xxx_messageInfo_Struct.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Struct proto.InternalMessageInfo
+
+func (m *Struct) GetFields() []*Field {
+	if m != nil {
+		return m.Fields
+	}
+	return nil
+}
+
+type Field struct {
+	Name                 string   `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+	Value                *Object  `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *Field) Reset()         { *m = Field{} }
+func (m *Field) String() string { return proto.CompactTextString(m) }
+func (*Field) ProtoMessage()    {}
+func (*Field) Descriptor() ([]byte, []int) {
+	return fileDescriptor_3dee2c1912d4d62d, []int{5}
+}
+
+func (m *Field) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Field.Unmarshal(m, b)
+}
+func (m *Field) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Field.Marshal(b, m, deterministic)
+}
+func (m *Field) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Field.Merge(m, src)
+}
+func (m *Field) XXX_Size() int {
+	return xxx_messageInfo_Field.Size(m)
+}
+func (m *Field) XXX_DiscardUnknown() {
+	xxx_messageInfo_Field.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Field proto.InternalMessageInfo
+
+func (m *Field) GetName() string {
+	if m != nil {
+		return m.Name
+	}
+	return ""
+}
+
+func (m *Field) GetValue() *Object {
+	if m != nil {
+		return m.Value
+	}
+	return nil
+}
+
+type Uint16S struct {
+	Values               []uint32 `protobuf:"varint,1,rep,packed,name=values,proto3" json:"values,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *Uint16S) Reset()         { *m = Uint16S{} }
+func (m *Uint16S) String() string { return proto.CompactTextString(m) }
+func (*Uint16S) ProtoMessage()    {}
+func (*Uint16S) Descriptor() ([]byte, []int) {
+	return fileDescriptor_3dee2c1912d4d62d, []int{6}
+}
+
+func (m *Uint16S) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Uint16S.Unmarshal(m, b)
+}
+func (m *Uint16S) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Uint16S.Marshal(b, m, deterministic)
+}
+func (m *Uint16S) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Uint16S.Merge(m, src)
+}
+func (m *Uint16S) XXX_Size() int {
+	return xxx_messageInfo_Uint16S.Size(m)
+}
+func (m *Uint16S) XXX_DiscardUnknown() {
+	xxx_messageInfo_Uint16S.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Uint16S proto.InternalMessageInfo
+
+func (m *Uint16S) GetValues() []uint32 {
+	if m != nil {
+		return m.Values
+	}
+	return nil
+}
+
+type Uint32S struct {
+	Values               []uint32 `protobuf:"fixed32,1,rep,packed,name=values,proto3" json:"values,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *Uint32S) Reset()         { *m = Uint32S{} }
+func (m *Uint32S) String() string { return proto.CompactTextString(m) }
+func (*Uint32S) ProtoMessage()    {}
+func (*Uint32S) Descriptor() ([]byte, []int) {
+	return fileDescriptor_3dee2c1912d4d62d, []int{7}
+}
+
+func (m *Uint32S) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Uint32S.Unmarshal(m, b)
+}
+func (m *Uint32S) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Uint32S.Marshal(b, m, deterministic)
+}
+func (m *Uint32S) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Uint32S.Merge(m, src)
+}
+func (m *Uint32S) XXX_Size() int {
+	return xxx_messageInfo_Uint32S.Size(m)
+}
+func (m *Uint32S) XXX_DiscardUnknown() {
+	xxx_messageInfo_Uint32S.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Uint32S proto.InternalMessageInfo
+
+func (m *Uint32S) GetValues() []uint32 {
+	if m != nil {
+		return m.Values
+	}
+	return nil
+}
+
+type Uint64S struct {
+	Values               []uint64 `protobuf:"fixed64,1,rep,packed,name=values,proto3" json:"values,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *Uint64S) Reset()         { *m = Uint64S{} }
+func (m *Uint64S) String() string { return proto.CompactTextString(m) }
+func (*Uint64S) ProtoMessage()    {}
+func (*Uint64S) Descriptor() ([]byte, []int) {
+	return fileDescriptor_3dee2c1912d4d62d, []int{8}
+}
+
+func (m *Uint64S) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Uint64S.Unmarshal(m, b)
+}
+func (m *Uint64S) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Uint64S.Marshal(b, m, deterministic)
+}
+func (m *Uint64S) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Uint64S.Merge(m, src)
+}
+func (m *Uint64S) XXX_Size() int {
+	return xxx_messageInfo_Uint64S.Size(m)
+}
+func (m *Uint64S) XXX_DiscardUnknown() {
+	xxx_messageInfo_Uint64S.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Uint64S proto.InternalMessageInfo
+
+func (m *Uint64S) GetValues() []uint64 {
+	if m != nil {
+		return m.Values
+	}
+	return nil
+}
+
+type Uintptrs struct {
+	Values               []uint64 `protobuf:"fixed64,1,rep,packed,name=values,proto3" json:"values,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *Uintptrs) Reset()         { *m = Uintptrs{} }
+func (m *Uintptrs) String() string { return proto.CompactTextString(m) }
+func (*Uintptrs) ProtoMessage()    {}
+func (*Uintptrs) Descriptor() ([]byte, []int) {
+	return fileDescriptor_3dee2c1912d4d62d, []int{9}
+}
+
+func (m *Uintptrs) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Uintptrs.Unmarshal(m, b)
+}
+func (m *Uintptrs) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Uintptrs.Marshal(b, m, deterministic)
+}
+func (m *Uintptrs) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Uintptrs.Merge(m, src)
+}
+func (m *Uintptrs) XXX_Size() int {
+	return xxx_messageInfo_Uintptrs.Size(m)
+}
+func (m *Uintptrs) XXX_DiscardUnknown() {
+	xxx_messageInfo_Uintptrs.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Uintptrs proto.InternalMessageInfo
+
+func (m *Uintptrs) GetValues() []uint64 {
+	if m != nil {
+		return m.Values
+	}
+	return nil
+}
+
+type Int8S struct {
+	Values               []byte   `protobuf:"bytes,1,opt,name=values,proto3" json:"values,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *Int8S) Reset()         { *m = Int8S{} }
+func (m *Int8S) String() string { return proto.CompactTextString(m) }
+func (*Int8S) ProtoMessage()    {}
+func (*Int8S) Descriptor() ([]byte, []int) {
+	return fileDescriptor_3dee2c1912d4d62d, []int{10}
+}
+
+func (m *Int8S) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Int8S.Unmarshal(m, b)
+}
+func (m *Int8S) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Int8S.Marshal(b, m, deterministic)
+}
+func (m *Int8S) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Int8S.Merge(m, src)
+}
+func (m *Int8S) XXX_Size() int {
+	return xxx_messageInfo_Int8S.Size(m)
+}
+func (m *Int8S) XXX_DiscardUnknown() {
+	xxx_messageInfo_Int8S.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Int8S proto.InternalMessageInfo
+
+func (m *Int8S) GetValues() []byte {
+	if m != nil {
+		return m.Values
+	}
+	return nil
+}
+
+type Int16S struct {
+	Values               []int32  `protobuf:"varint,1,rep,packed,name=values,proto3" json:"values,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *Int16S) Reset()         { *m = Int16S{} }
+func (m *Int16S) String() string { return proto.CompactTextString(m) }
+func (*Int16S) ProtoMessage()    {}
+func (*Int16S) Descriptor() ([]byte, []int) {
+	return fileDescriptor_3dee2c1912d4d62d, []int{11}
+}
+
+func (m *Int16S) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Int16S.Unmarshal(m, b)
+}
+func (m *Int16S) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Int16S.Marshal(b, m, deterministic)
+}
+func (m *Int16S) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Int16S.Merge(m, src)
+}
+func (m *Int16S) XXX_Size() int {
+	return xxx_messageInfo_Int16S.Size(m)
+}
+func (m *Int16S) XXX_DiscardUnknown() {
+	xxx_messageInfo_Int16S.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Int16S proto.InternalMessageInfo
+
+func (m *Int16S) GetValues() []int32 {
+	if m != nil {
+		return m.Values
+	}
+	return nil
+}
+
+type Int32S struct {
+	Values               []int32  `protobuf:"fixed32,1,rep,packed,name=values,proto3" json:"values,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *Int32S) Reset()         { *m = Int32S{} }
+func (m *Int32S) String() string { return proto.CompactTextString(m) }
+func (*Int32S) ProtoMessage()    {}
+func (*Int32S) Descriptor() ([]byte, []int) {
+	return fileDescriptor_3dee2c1912d4d62d, []int{12}
+}
+
+func (m *Int32S) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Int32S.Unmarshal(m, b)
+}
+func (m *Int32S) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Int32S.Marshal(b, m, deterministic)
+}
+func (m *Int32S) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Int32S.Merge(m, src)
+}
+func (m *Int32S) XXX_Size() int {
+	return xxx_messageInfo_Int32S.Size(m)
+}
+func (m *Int32S) XXX_DiscardUnknown() {
+	xxx_messageInfo_Int32S.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Int32S proto.InternalMessageInfo
+
+func (m *Int32S) GetValues() []int32 {
+	if m != nil {
+		return m.Values
+	}
+	return nil
+}
+
+type Int64S struct {
+	Values               []int64  `protobuf:"fixed64,1,rep,packed,name=values,proto3" json:"values,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *Int64S) Reset()         { *m = Int64S{} }
+func (m *Int64S) String() string { return proto.CompactTextString(m) }
+func (*Int64S) ProtoMessage()    {}
+func (*Int64S) Descriptor() ([]byte, []int) {
+	return fileDescriptor_3dee2c1912d4d62d, []int{13}
+}
+
+func (m *Int64S) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Int64S.Unmarshal(m, b)
+}
+func (m *Int64S) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Int64S.Marshal(b, m, deterministic)
+}
+func (m *Int64S) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Int64S.Merge(m, src)
+}
+func (m *Int64S) XXX_Size() int {
+	return xxx_messageInfo_Int64S.Size(m)
+}
+func (m *Int64S) XXX_DiscardUnknown() {
+	xxx_messageInfo_Int64S.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Int64S proto.InternalMessageInfo
+
+func (m *Int64S) GetValues() []int64 {
+	if m != nil {
+		return m.Values
+	}
+	return nil
+}
+
+type Bools struct {
+	Values               []bool   `protobuf:"varint,1,rep,packed,name=values,proto3" json:"values,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *Bools) Reset()         { *m = Bools{} }
+func (m *Bools) String() string { return proto.CompactTextString(m) }
+func (*Bools) ProtoMessage()    {}
+func (*Bools) Descriptor() ([]byte, []int) {
+	return fileDescriptor_3dee2c1912d4d62d, []int{14}
+}
+
+func (m *Bools) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Bools.Unmarshal(m, b)
+}
+func (m *Bools) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Bools.Marshal(b, m, deterministic)
+}
+func (m *Bools) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Bools.Merge(m, src)
+}
+func (m *Bools) XXX_Size() int {
+	return xxx_messageInfo_Bools.Size(m)
+}
+func (m *Bools) XXX_DiscardUnknown() {
+	xxx_messageInfo_Bools.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Bools proto.InternalMessageInfo
+
+func (m *Bools) GetValues() []bool {
+	if m != nil {
+		return m.Values
+	}
+	return nil
+}
+
+type Float64S struct {
+	Values               []float64 `protobuf:"fixed64,1,rep,packed,name=values,proto3" json:"values,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}  `json:"-"`
+	XXX_unrecognized     []byte    `json:"-"`
+	XXX_sizecache        int32     `json:"-"`
+}
+
+func (m *Float64S) Reset()         { *m = Float64S{} }
+func (m *Float64S) String() string { return proto.CompactTextString(m) }
+func (*Float64S) ProtoMessage()    {}
+func (*Float64S) Descriptor() ([]byte, []int) {
+	return fileDescriptor_3dee2c1912d4d62d, []int{15}
+}
+
+func (m *Float64S) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Float64S.Unmarshal(m, b)
+}
+func (m *Float64S) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Float64S.Marshal(b, m, deterministic)
+}
+func (m *Float64S) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Float64S.Merge(m, src)
+}
+func (m *Float64S) XXX_Size() int {
+	return xxx_messageInfo_Float64S.Size(m)
+}
+func (m *Float64S) XXX_DiscardUnknown() {
+	xxx_messageInfo_Float64S.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Float64S proto.InternalMessageInfo
+
+func (m *Float64S) GetValues() []float64 {
+	if m != nil {
+		return m.Values
+	}
+	return nil
+}
+
+type Float32S struct {
+	Values               []float32 `protobuf:"fixed32,1,rep,packed,name=values,proto3" json:"values,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}  `json:"-"`
+	XXX_unrecognized     []byte    `json:"-"`
+	XXX_sizecache        int32     `json:"-"`
+}
+
+func (m *Float32S) Reset()         { *m = Float32S{} }
+func (m *Float32S) String() string { return proto.CompactTextString(m) }
+func (*Float32S) ProtoMessage()    {}
+func (*Float32S) Descriptor() ([]byte, []int) {
+	return fileDescriptor_3dee2c1912d4d62d, []int{16}
+}
+
+func (m *Float32S) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Float32S.Unmarshal(m, b)
+}
+func (m *Float32S) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Float32S.Marshal(b, m, deterministic)
+}
+func (m *Float32S) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Float32S.Merge(m, src)
+}
+func (m *Float32S) XXX_Size() int {
+	return xxx_messageInfo_Float32S.Size(m)
+}
+func (m *Float32S) XXX_DiscardUnknown() {
+	xxx_messageInfo_Float32S.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Float32S proto.InternalMessageInfo
+
+func (m *Float32S) GetValues() []float32 {
+	if m != nil {
+		return m.Values
+	}
+	return nil
+}
+
+type Object struct {
+	// Types that are valid to be assigned to Value:
+	//	*Object_BoolValue
+	//	*Object_StringValue
+	//	*Object_Int64Value
+	//	*Object_Uint64Value
+	//	*Object_DoubleValue
+	//	*Object_RefValue
+	//	*Object_SliceValue
+	//	*Object_ArrayValue
+	//	*Object_InterfaceValue
+	//	*Object_StructValue
+	//	*Object_MapValue
+	//	*Object_ByteArrayValue
+	//	*Object_Uint16ArrayValue
+	//	*Object_Uint32ArrayValue
+	//	*Object_Uint64ArrayValue
+	//	*Object_UintptrArrayValue
+	//	*Object_Int8ArrayValue
+	//	*Object_Int16ArrayValue
+	//	*Object_Int32ArrayValue
+	//	*Object_Int64ArrayValue
+	//	*Object_BoolArrayValue
+	//	*Object_Float64ArrayValue
+	//	*Object_Float32ArrayValue
+	Value                isObject_Value `protobuf_oneof:"value"`
+	XXX_NoUnkeyedLiteral struct{}       `json:"-"`
+	XXX_unrecognized     []byte         `json:"-"`
+	XXX_sizecache        int32          `json:"-"`
+}
+
+func (m *Object) Reset()         { *m = Object{} }
+func (m *Object) String() string { return proto.CompactTextString(m) }
+func (*Object) ProtoMessage()    {}
+func (*Object) Descriptor() ([]byte, []int) {
+	return fileDescriptor_3dee2c1912d4d62d, []int{17}
+}
+
+func (m *Object) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Object.Unmarshal(m, b)
+}
+func (m *Object) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Object.Marshal(b, m, deterministic)
+}
+func (m *Object) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Object.Merge(m, src)
+}
+func (m *Object) XXX_Size() int {
+	return xxx_messageInfo_Object.Size(m)
+}
+func (m *Object) XXX_DiscardUnknown() {
+	xxx_messageInfo_Object.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Object proto.InternalMessageInfo
+
+type isObject_Value interface {
+	isObject_Value()
+}
+
+type Object_BoolValue struct {
+	BoolValue bool `protobuf:"varint,1,opt,name=bool_value,json=boolValue,proto3,oneof"`
+}
+
+type Object_StringValue struct {
+	StringValue []byte `protobuf:"bytes,2,opt,name=string_value,json=stringValue,proto3,oneof"`
+}
+
+type Object_Int64Value struct {
+	Int64Value int64 `protobuf:"varint,3,opt,name=int64_value,json=int64Value,proto3,oneof"`
+}
+
+type Object_Uint64Value struct {
+	Uint64Value uint64 `protobuf:"varint,4,opt,name=uint64_value,json=uint64Value,proto3,oneof"`
+}
+
+type Object_DoubleValue struct {
+	DoubleValue float64 `protobuf:"fixed64,5,opt,name=double_value,json=doubleValue,proto3,oneof"`
+}
+
+type Object_RefValue struct {
+	RefValue uint64 `protobuf:"varint,6,opt,name=ref_value,json=refValue,proto3,oneof"`
+}
+
+type Object_SliceValue struct {
+	SliceValue *Slice `protobuf:"bytes,7,opt,name=slice_value,json=sliceValue,proto3,oneof"`
+}
+
+type Object_ArrayValue struct {
+	ArrayValue *Array `protobuf:"bytes,8,opt,name=array_value,json=arrayValue,proto3,oneof"`
+}
+
+type Object_InterfaceValue struct {
+	InterfaceValue *Interface `protobuf:"bytes,9,opt,name=interface_value,json=interfaceValue,proto3,oneof"`
+}
+
+type Object_StructValue struct {
+	StructValue *Struct `protobuf:"bytes,10,opt,name=struct_value,json=structValue,proto3,oneof"`
+}
+
+type Object_MapValue struct {
+	MapValue *Map `protobuf:"bytes,11,opt,name=map_value,json=mapValue,proto3,oneof"`
+}
+
+type Object_ByteArrayValue struct {
+	ByteArrayValue []byte `protobuf:"bytes,12,opt,name=byte_array_value,json=byteArrayValue,proto3,oneof"`
+}
+
+type Object_Uint16ArrayValue struct {
+	Uint16ArrayValue *Uint16S `protobuf:"bytes,13,opt,name=uint16_array_value,json=uint16ArrayValue,proto3,oneof"`
+}
+
+type Object_Uint32ArrayValue struct {
+	Uint32ArrayValue *Uint32S `protobuf:"bytes,14,opt,name=uint32_array_value,json=uint32ArrayValue,proto3,oneof"`
+}
+
+type Object_Uint64ArrayValue struct {
+	Uint64ArrayValue *Uint64S `protobuf:"bytes,15,opt,name=uint64_array_value,json=uint64ArrayValue,proto3,oneof"`
+}
+
+type Object_UintptrArrayValue struct {
+	UintptrArrayValue *Uintptrs `protobuf:"bytes,16,opt,name=uintptr_array_value,json=uintptrArrayValue,proto3,oneof"`
+}
+
+type Object_Int8ArrayValue struct {
+	Int8ArrayValue *Int8S `protobuf:"bytes,17,opt,name=int8_array_value,json=int8ArrayValue,proto3,oneof"`
+}
+
+type Object_Int16ArrayValue struct {
+	Int16ArrayValue *Int16S `protobuf:"bytes,18,opt,name=int16_array_value,json=int16ArrayValue,proto3,oneof"`
+}
+
+type Object_Int32ArrayValue struct {
+	Int32ArrayValue *Int32S `protobuf:"bytes,19,opt,name=int32_array_value,json=int32ArrayValue,proto3,oneof"`
+}
+
+type Object_Int64ArrayValue struct {
+	Int64ArrayValue *Int64S `protobuf:"bytes,20,opt,name=int64_array_value,json=int64ArrayValue,proto3,oneof"`
+}
+
+type Object_BoolArrayValue struct {
+	BoolArrayValue *Bools `protobuf:"bytes,21,opt,name=bool_array_value,json=boolArrayValue,proto3,oneof"`
+}
+
+type Object_Float64ArrayValue struct {
+	Float64ArrayValue *Float64S `protobuf:"bytes,22,opt,name=float64_array_value,json=float64ArrayValue,proto3,oneof"`
+}
+
+type Object_Float32ArrayValue struct {
+	Float32ArrayValue *Float32S `protobuf:"bytes,23,opt,name=float32_array_value,json=float32ArrayValue,proto3,oneof"`
+}
+
+func (*Object_BoolValue) isObject_Value() {}
+
+func (*Object_StringValue) isObject_Value() {}
+
+func (*Object_Int64Value) isObject_Value() {}
+
+func (*Object_Uint64Value) isObject_Value() {}
+
+func (*Object_DoubleValue) isObject_Value() {}
+
+func (*Object_RefValue) isObject_Value() {}
+
+func (*Object_SliceValue) isObject_Value() {}
+
+func (*Object_ArrayValue) isObject_Value() {}
+
+func (*Object_InterfaceValue) isObject_Value() {}
+
+func (*Object_StructValue) isObject_Value() {}
+
+func (*Object_MapValue) isObject_Value() {}
+
+func (*Object_ByteArrayValue) isObject_Value() {}
+
+func (*Object_Uint16ArrayValue) isObject_Value() {}
+
+func (*Object_Uint32ArrayValue) isObject_Value() {}
+
+func (*Object_Uint64ArrayValue) isObject_Value() {}
+
+func (*Object_UintptrArrayValue) isObject_Value() {}
+
+func (*Object_Int8ArrayValue) isObject_Value() {}
+
+func (*Object_Int16ArrayValue) isObject_Value() {}
+
+func (*Object_Int32ArrayValue) isObject_Value() {}
+
+func (*Object_Int64ArrayValue) isObject_Value() {}
+
+func (*Object_BoolArrayValue) isObject_Value() {}
+
+func (*Object_Float64ArrayValue) isObject_Value() {}
+
+func (*Object_Float32ArrayValue) isObject_Value() {}
+
+func (m *Object) GetValue() isObject_Value {
+	if m != nil {
+		return m.Value
+	}
+	return nil
+}
+
+func (m *Object) GetBoolValue() bool {
+	if x, ok := m.GetValue().(*Object_BoolValue); ok {
+		return x.BoolValue
+	}
+	return false
+}
+
+func (m *Object) GetStringValue() []byte {
+	if x, ok := m.GetValue().(*Object_StringValue); ok {
+		return x.StringValue
+	}
+	return nil
+}
+
+func (m *Object) GetInt64Value() int64 {
+	if x, ok := m.GetValue().(*Object_Int64Value); ok {
+		return x.Int64Value
+	}
+	return 0
+}
+
+func (m *Object) GetUint64Value() uint64 {
+	if x, ok := m.GetValue().(*Object_Uint64Value); ok {
+		return x.Uint64Value
+	}
+	return 0
+}
+
+func (m *Object) GetDoubleValue() float64 {
+	if x, ok := m.GetValue().(*Object_DoubleValue); ok {
+		return x.DoubleValue
+	}
+	return 0
+}
+
+func (m *Object) GetRefValue() uint64 {
+	if x, ok := m.GetValue().(*Object_RefValue); ok {
+		return x.RefValue
+	}
+	return 0
+}
+
+func (m *Object) GetSliceValue() *Slice {
+	if x, ok := m.GetValue().(*Object_SliceValue); ok {
+		return x.SliceValue
+	}
+	return nil
+}
+
+func (m *Object) GetArrayValue() *Array {
+	if x, ok := m.GetValue().(*Object_ArrayValue); ok {
+		return x.ArrayValue
+	}
+	return nil
+}
+
+func (m *Object) GetInterfaceValue() *Interface {
+	if x, ok := m.GetValue().(*Object_InterfaceValue); ok {
+		return x.InterfaceValue
+	}
+	return nil
+}
+
+func (m *Object) GetStructValue() *Struct {
+	if x, ok := m.GetValue().(*Object_StructValue); ok {
+		return x.StructValue
+	}
+	return nil
+}
+
+func (m *Object) GetMapValue() *Map {
+	if x, ok := m.GetValue().(*Object_MapValue); ok {
+		return x.MapValue
+	}
+	return nil
+}
+
+func (m *Object) GetByteArrayValue() []byte {
+	if x, ok := m.GetValue().(*Object_ByteArrayValue); ok {
+		return x.ByteArrayValue
+	}
+	return nil
+}
+
+func (m *Object) GetUint16ArrayValue() *Uint16S {
+	if x, ok := m.GetValue().(*Object_Uint16ArrayValue); ok {
+		return x.Uint16ArrayValue
+	}
+	return nil
+}
+
+func (m *Object) GetUint32ArrayValue() *Uint32S {
+	if x, ok := m.GetValue().(*Object_Uint32ArrayValue); ok {
+		return x.Uint32ArrayValue
+	}
+	return nil
+}
+
+func (m *Object) GetUint64ArrayValue() *Uint64S {
+	if x, ok := m.GetValue().(*Object_Uint64ArrayValue); ok {
+		return x.Uint64ArrayValue
+	}
+	return nil
+}
+
+func (m *Object) GetUintptrArrayValue() *Uintptrs {
+	if x, ok := m.GetValue().(*Object_UintptrArrayValue); ok {
+		return x.UintptrArrayValue
+	}
+	return nil
+}
+
+func (m *Object) GetInt8ArrayValue() *Int8S {
+	if x, ok := m.GetValue().(*Object_Int8ArrayValue); ok {
+		return x.Int8ArrayValue
+	}
+	return nil
+}
+
+func (m *Object) GetInt16ArrayValue() *Int16S {
+	if x, ok := m.GetValue().(*Object_Int16ArrayValue); ok {
+		return x.Int16ArrayValue
+	}
+	return nil
+}
+
+func (m *Object) GetInt32ArrayValue() *Int32S {
+	if x, ok := m.GetValue().(*Object_Int32ArrayValue); ok {
+		return x.Int32ArrayValue
+	}
+	return nil
+}
+
+func (m *Object) GetInt64ArrayValue() *Int64S {
+	if x, ok := m.GetValue().(*Object_Int64ArrayValue); ok {
+		return x.Int64ArrayValue
+	}
+	return nil
+}
+
+func (m *Object) GetBoolArrayValue() *Bools {
+	if x, ok := m.GetValue().(*Object_BoolArrayValue); ok {
+		return x.BoolArrayValue
+	}
+	return nil
+}
+
+func (m *Object) GetFloat64ArrayValue() *Float64S {
+	if x, ok := m.GetValue().(*Object_Float64ArrayValue); ok {
+		return x.Float64ArrayValue
+	}
+	return nil
+}
+
+func (m *Object) GetFloat32ArrayValue() *Float32S {
+	if x, ok := m.GetValue().(*Object_Float32ArrayValue); ok {
+		return x.Float32ArrayValue
+	}
+	return nil
+}
+
+// XXX_OneofWrappers is for the internal use of the proto package.
+func (*Object) XXX_OneofWrappers() []interface{} {
+	return []interface{}{
+		(*Object_BoolValue)(nil),
+		(*Object_StringValue)(nil),
+		(*Object_Int64Value)(nil),
+		(*Object_Uint64Value)(nil),
+		(*Object_DoubleValue)(nil),
+		(*Object_RefValue)(nil),
+		(*Object_SliceValue)(nil),
+		(*Object_ArrayValue)(nil),
+		(*Object_InterfaceValue)(nil),
+		(*Object_StructValue)(nil),
+		(*Object_MapValue)(nil),
+		(*Object_ByteArrayValue)(nil),
+		(*Object_Uint16ArrayValue)(nil),
+		(*Object_Uint32ArrayValue)(nil),
+		(*Object_Uint64ArrayValue)(nil),
+		(*Object_UintptrArrayValue)(nil),
+		(*Object_Int8ArrayValue)(nil),
+		(*Object_Int16ArrayValue)(nil),
+		(*Object_Int32ArrayValue)(nil),
+		(*Object_Int64ArrayValue)(nil),
+		(*Object_BoolArrayValue)(nil),
+		(*Object_Float64ArrayValue)(nil),
+		(*Object_Float32ArrayValue)(nil),
+	}
+}
+
+func init() {
+	proto.RegisterType((*Slice)(nil), "gvisor.state.statefile.Slice")
+	proto.RegisterType((*Array)(nil), "gvisor.state.statefile.Array")
+	proto.RegisterType((*Map)(nil), "gvisor.state.statefile.Map")
+	proto.RegisterType((*Interface)(nil), "gvisor.state.statefile.Interface")
+	proto.RegisterType((*Struct)(nil), "gvisor.state.statefile.Struct")
+	proto.RegisterType((*Field)(nil), "gvisor.state.statefile.Field")
+	proto.RegisterType((*Uint16S)(nil), "gvisor.state.statefile.Uint16s")
+	proto.RegisterType((*Uint32S)(nil), "gvisor.state.statefile.Uint32s")
+	proto.RegisterType((*Uint64S)(nil), "gvisor.state.statefile.Uint64s")
+	proto.RegisterType((*Uintptrs)(nil), "gvisor.state.statefile.Uintptrs")
+	proto.RegisterType((*Int8S)(nil), "gvisor.state.statefile.Int8s")
+	proto.RegisterType((*Int16S)(nil), "gvisor.state.statefile.Int16s")
+	proto.RegisterType((*Int32S)(nil), "gvisor.state.statefile.Int32s")
+	proto.RegisterType((*Int64S)(nil), "gvisor.state.statefile.Int64s")
+	proto.RegisterType((*Bools)(nil), "gvisor.state.statefile.Bools")
+	proto.RegisterType((*Float64S)(nil), "gvisor.state.statefile.Float64s")
+	proto.RegisterType((*Float32S)(nil), "gvisor.state.statefile.Float32s")
+	proto.RegisterType((*Object)(nil), "gvisor.state.statefile.Object")
+}
+
+func init() { proto.RegisterFile("pkg/state/object.proto", fileDescriptor_3dee2c1912d4d62d) }
+
+var fileDescriptor_3dee2c1912d4d62d = []byte{
+	// 781 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x96, 0x6f, 0x4f, 0xda, 0x5e,
+	0x14, 0xc7, 0xa9, 0x40, 0x29, 0x07, 0x14, 0xb8, 0xfe, 0x7e, 0x8c, 0xcc, 0x38, 0xb1, 0x7b, 0x42,
+	0xf6, 0x00, 0x33, 0x60, 0xc4, 0xf8, 0x64, 0x53, 0x13, 0x03, 0xc9, 0x8c, 0x59, 0x8d, 0xcb, 0x9e,
+	0x99, 0x52, 0x2f, 0xac, 0xb3, 0xb6, 0x5d, 0x7b, 0x6b, 0xc2, 0xcb, 0xdc, 0x3b, 0x5a, 0xee, 0x1f,
+	0xae, 0xfd, 0x03, 0xc5, 0xec, 0x89, 0xa1, 0xb7, 0xdf, 0xf3, 0xe1, 0xdc, 0xf3, 0x3d, 0xe7, 0x08,
+	0xb4, 0xfd, 0xc7, 0xc5, 0x49, 0x48, 0x4c, 0x82, 0x4f, 0xbc, 0xd9, 0x2f, 0x6c, 0x91, 0xbe, 0x1f,
+	0x78, 0xc4, 0x43, 0xed, 0xc5, 0xb3, 0x1d, 0x7a, 0x41, 0x9f, 0xbd, 0xe2, 0x7f, 0xe7, 0xb6, 0x83,
+	0xf5, 0x1f, 0x50, 0xbe, 0x75, 0x6c, 0x0b, 0xa3, 0x36, 0xa8, 0x0e, 0x76, 0x17, 0xe4, 0x67, 0x47,
+	0xe9, 0x2a, 0xbd, 0x5d, 0x43, 0x3c, 0xa1, 0xb7, 0xa0, 0x59, 0xa6, 0x6f, 0x5a, 0x36, 0x59, 0x76,
+	0x76, 0xd8, 0x1b, 0xf9, 0x8c, 0x0e, 0xa0, 0x1a, 0xe0, 0xf9, 0xfd, 0xb3, 0xe9, 0x44, 0xb8, 0x53,
+	0xec, 0x2a, 0xbd, 0x92, 0xa1, 0x05, 0x78, 0xfe, 0x9d, 0x3e, 0xeb, 0x97, 0x50, 0x3e, 0x0f, 0x02,
+	0x73, 0x89, 0xce, 0x40, 0xb3, 0x3c, 0x97, 0x60, 0x97, 0x84, 0x1d, 0xa5, 0x5b, 0xec, 0xd5, 0x06,
+	0xef, 0xfa, 0xeb, 0xb3, 0xe9, 0xdf, 0xb0, 0x94, 0x0d, 0xa9, 0xd7, 0x7f, 0x43, 0xf1, 0xda, 0xf4,
+	0xd1, 0x00, 0x4a, 0x8f, 0x78, 0xf9, 0xda, 0x70, 0xa6, 0x45, 0x63, 0x50, 0x59, 0x62, 0x61, 0x67,
+	0xe7, 0x55, 0x51, 0x42, 0xad, 0xdf, 0x41, 0x75, 0xea, 0x12, 0x1c, 0xcc, 0x4d, 0x0b, 0x23, 0x04,
+	0x25, 0xb2, 0xf4, 0x31, 0xab, 0x49, 0xd5, 0x60, 0x9f, 0xd1, 0x08, 0xca, 0xfc, 0xc6, 0xb4, 0x1c,
+	0xdb, 0xb9, 0x5c, 0xac, 0x7f, 0x06, 0xf5, 0x96, 0x04, 0x91, 0x45, 0xd0, 0x27, 0x50, 0xe7, 0x36,
+	0x76, 0x1e, 0x56, 0xd7, 0x39, 0xdc, 0x04, 0xb8, 0xa2, 0x2a, 0x43, 0x88, 0xf5, 0x6f, 0x50, 0x66,
+	0x07, 0x34, 0x27, 0xd7, 0x7c, 0x92, 0x39, 0xd1, 0xcf, 0xff, 0x98, 0xd3, 0x31, 0x54, 0xee, 0x6c,
+	0x97, 0x7c, 0x1c, 0x87, 0xd4, 0x7e, 0x51, 0x2d, 0x9a, 0xd4, 0xae, 0xac, 0x86, 0x90, 0x0c, 0x07,
+	0x69, 0x49, 0x25, 0x2d, 0x19, 0x8f, 0xd2, 0x12, 0x55, 0x4a, 0x74, 0xd0, 0xa8, 0xc4, 0x27, 0xc1,
+	0x66, 0xcd, 0x11, 0x94, 0xa7, 0x2e, 0x39, 0x4d, 0x0a, 0x94, 0x5e, 0x5d, 0x0a, 0xba, 0xa0, 0x4e,
+	0xd7, 0x25, 0x5b, 0x4e, 0x29, 0xb2, 0xb9, 0x36, 0x52, 0x8a, 0x6c, 0xaa, 0xcd, 0x78, 0x1a, 0x17,
+	0x9e, 0xe7, 0xa4, 0x05, 0x5a, 0xfc, 0x2e, 0x57, 0x8e, 0x67, 0xae, 0x81, 0x28, 0x19, 0x4d, 0x36,
+	0x95, 0x1d, 0xa9, 0xf9, 0x53, 0x03, 0x95, 0xdb, 0x81, 0x8e, 0x00, 0x66, 0x9e, 0xe7, 0x88, 0x41,
+	0xa2, 0xb7, 0xd6, 0x26, 0x05, 0xa3, 0x4a, 0xcf, 0xd8, 0x2c, 0xa1, 0xf7, 0x50, 0x0f, 0x49, 0x60,
+	0xbb, 0x8b, 0xfb, 0x17, 0x97, 0xeb, 0x93, 0x82, 0x51, 0xe3, 0xa7, 0x5c, 0x74, 0x0c, 0x35, 0x66,
+	0x43, 0x6c, 0x1e, 0x8b, 0x93, 0x82, 0x01, 0xec, 0x50, 0x72, 0xa2, 0xb8, 0xa6, 0x44, 0x67, 0x96,
+	0x72, 0xa2, 0xa4, 0xe8, 0xc1, 0x8b, 0x66, 0x0e, 0x16, 0xa2, 0x72, 0x57, 0xe9, 0x29, 0x54, 0xc4,
+	0x4f, 0xb9, 0xe8, 0x30, 0x3e, 0xfa, 0xaa, 0xc0, 0xc8, 0xe1, 0x47, 0x5f, 0xa0, 0x16, 0xd2, 0xb5,
+	0x22, 0x04, 0x15, 0xd6, 0x95, 0x1b, 0x1b, 0x9d, 0x6d, 0x20, 0x9a, 0x2a, 0x8b, 0x91, 0x04, 0x93,
+	0xae, 0x0f, 0x41, 0xd0, 0xf2, 0x09, 0x6c, 0xd3, 0x50, 0x02, 0x8b, 0xe1, 0x84, 0xaf, 0xd0, 0xb0,
+	0x57, 0x83, 0x2c, 0x28, 0x55, 0x46, 0x39, 0xde, 0x44, 0x91, 0x73, 0x3f, 0x29, 0x18, 0x7b, 0x32,
+	0x96, 0xd3, 0x2e, 0x99, 0x05, 0x91, 0x45, 0x04, 0x0a, 0xf2, 0x07, 0x8d, 0xcf, 0xba, 0xb0, 0x28,
+	0xb2, 0x08, 0x87, 0x9c, 0x41, 0xf5, 0xc9, 0xf4, 0x05, 0xa1, 0xc6, 0x08, 0x07, 0x9b, 0x08, 0xd7,
+	0xa6, 0x4f, 0x4b, 0xfa, 0x64, 0xfa, 0x3c, 0xf6, 0x03, 0x34, 0x67, 0x4b, 0x82, 0xef, 0xe3, 0x55,
+	0xa9, 0x8b, 0x3e, 0xd8, 0xa3, 0x6f, 0xce, 0x5f, 0xae, 0x7e, 0x03, 0x28, 0x62, 0x83, 0x9d, 0x50,
+	0xef, 0xb2, 0x2f, 0x3c, 0xda, 0xf4, 0x85, 0x62, 0x15, 0x4c, 0x0a, 0x46, 0x93, 0x07, 0x67, 0x81,
+	0xc3, 0x41, 0x02, 0xb8, 0xb7, 0x1d, 0x38, 0x1c, 0x48, 0xe0, 0x70, 0x90, 0x05, 0x8e, 0x47, 0x09,
+	0x60, 0x63, 0x3b, 0x70, 0x3c, 0x92, 0xc0, 0xf1, 0x28, 0x06, 0x34, 0x60, 0x3f, 0xe2, 0x2b, 0x26,
+	0x41, 0x6c, 0x32, 0x62, 0x37, 0x8f, 0x48, 0xb7, 0xd2, 0xa4, 0x60, 0xb4, 0x44, 0x78, 0x8c, 0x39,
+	0x85, 0xa6, 0xed, 0x92, 0xd3, 0x04, 0xb0, 0x95, 0xdf, 0x88, 0x6c, 0x85, 0x89, 0xf6, 0x39, 0x3d,
+	0x8f, 0x37, 0x63, 0x2b, 0x6b, 0x08, 0xca, 0xef, 0xa1, 0xe9, 0xca, 0x8f, 0x46, 0xda, 0x0e, 0x4e,
+	0x4b, 0xb9, 0xb1, 0xbf, 0x95, 0xc6, 0xcd, 0x68, 0xa4, 0xbd, 0xe0, 0xb4, 0x94, 0x15, 0xff, 0x6d,
+	0xa5, 0x71, 0x27, 0x1a, 0x69, 0x23, 0xa6, 0xd0, 0x64, 0xcb, 0x2c, 0x0e, 0xfb, 0x3f, 0xbf, 0x68,
+	0x6c, 0xe1, 0xb2, 0x36, 0xf6, 0x3c, 0x27, 0xe9, 0xe9, 0x9c, 0xaf, 0xda, 0x04, 0xad, 0x9d, 0xef,
+	0xe9, 0x6a, 0x3b, 0x53, 0x4f, 0x45, 0xf8, 0x1a, 0x66, 0xaa, 0x78, 0x6f, 0x5e, 0xc1, 0xe4, 0xe5,
+	0x6b, 0x89, 0xf0, 0x17, 0xe6, 0x45, 0x45, 0xfc, 0xf7, 0x9d, 0xa9, 0xec, 0xc7, 0xd6, 0xf0, 0x6f,
+	0x00, 0x00, 0x00, 0xff, 0xff, 0x84, 0x69, 0xc9, 0x45, 0x86, 0x09, 0x00, 0x00,
+}
diff --git a/pkg/state/state_test.go b/pkg/state/state_test.go
deleted file mode 100644
index d7221e9..0000000
--- a/pkg/state/state_test.go
+++ /dev/null
@@ -1,721 +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 state
-
-import (
-	"bytes"
-	"context"
-	"io/ioutil"
-	"math"
-	"reflect"
-	"testing"
-)
-
-// TestCase is used to define a single success/failure testcase of
-// serialization of a set of objects.
-type TestCase struct {
-	// Name is the name of the test case.
-	Name string
-
-	// Objects is the list of values to serialize.
-	Objects []interface{}
-
-	// Fail is whether the test case is supposed to fail or not.
-	Fail bool
-}
-
-// runTest runs all testcases.
-func runTest(t *testing.T, tests []TestCase) {
-	for _, test := range tests {
-		t.Logf("TEST %s:", test.Name)
-		for i, root := range test.Objects {
-			t.Logf("  case#%d: %#v", i, root)
-
-			// Save the passed object.
-			saveBuffer := &bytes.Buffer{}
-			saveObjectPtr := reflect.New(reflect.TypeOf(root))
-			saveObjectPtr.Elem().Set(reflect.ValueOf(root))
-			if err := Save(context.Background(), saveBuffer, saveObjectPtr.Interface(), nil); err != nil && !test.Fail {
-				t.Errorf("    FAIL: Save failed unexpectedly: %v", err)
-				continue
-			} else if err != nil {
-				t.Logf("    PASS: Save failed as expected: %v", err)
-				continue
-			}
-
-			// Load a new copy of the object.
-			loadObjectPtr := reflect.New(reflect.TypeOf(root))
-			if err := Load(context.Background(), bytes.NewReader(saveBuffer.Bytes()), loadObjectPtr.Interface(), nil); err != nil && !test.Fail {
-				t.Errorf("    FAIL: Load failed unexpectedly: %v", err)
-				continue
-			} else if err != nil {
-				t.Logf("    PASS: Load failed as expected: %v", err)
-				continue
-			}
-
-			// Compare the values.
-			loadedValue := loadObjectPtr.Elem().Interface()
-			if eq := reflect.DeepEqual(root, loadedValue); !eq && !test.Fail {
-				t.Errorf("    FAIL: Objects differs; got %#v", loadedValue)
-				continue
-			} else if !eq {
-				t.Logf("    PASS: Object different as expected.")
-				continue
-			}
-
-			// Everything went okay. Is that good?
-			if test.Fail {
-				t.Errorf("    FAIL: Unexpected success.")
-			} else {
-				t.Logf("    PASS: Success.")
-			}
-		}
-	}
-}
-
-// dumbStruct is a struct which does not implement the loader/saver interface.
-// We expect that serialization of this struct will fail.
-type dumbStruct struct {
-	A int
-	B int
-}
-
-// smartStruct is a struct which does implement the loader/saver interface.
-// We expect that serialization of this struct will succeed.
-type smartStruct struct {
-	A int
-	B int
-}
-
-func (s *smartStruct) save(m Map) {
-	m.Save("A", &s.A)
-	m.Save("B", &s.B)
-}
-
-func (s *smartStruct) load(m Map) {
-	m.Load("A", &s.A)
-	m.Load("B", &s.B)
-}
-
-// valueLoadStruct uses a value load.
-type valueLoadStruct struct {
-	v int
-}
-
-func (v *valueLoadStruct) save(m Map) {
-	m.SaveValue("v", v.v)
-}
-
-func (v *valueLoadStruct) load(m Map) {
-	m.LoadValue("v", new(int), func(value interface{}) {
-		v.v = value.(int)
-	})
-}
-
-// afterLoadStruct has an AfterLoad function.
-type afterLoadStruct struct {
-	v int
-}
-
-func (a *afterLoadStruct) save(m Map) {
-}
-
-func (a *afterLoadStruct) load(m Map) {
-	m.AfterLoad(func() {
-		a.v++
-	})
-}
-
-// genericContainer is a generic dispatcher.
-type genericContainer struct {
-	v interface{}
-}
-
-func (g *genericContainer) save(m Map) {
-	m.Save("v", &g.v)
-}
-
-func (g *genericContainer) load(m Map) {
-	m.Load("v", &g.v)
-}
-
-// sliceContainer is a generic slice.
-type sliceContainer struct {
-	v []interface{}
-}
-
-func (s *sliceContainer) save(m Map) {
-	m.Save("v", &s.v)
-}
-
-func (s *sliceContainer) load(m Map) {
-	m.Load("v", &s.v)
-}
-
-// mapContainer is a generic map.
-type mapContainer struct {
-	v map[int]interface{}
-}
-
-func (mc *mapContainer) save(m Map) {
-	m.Save("v", &mc.v)
-}
-
-func (mc *mapContainer) load(m Map) {
-	// Some of the test cases below assume legacy behavior wherein maps
-	// will automatically inherit dependencies.
-	m.LoadWait("v", &mc.v)
-}
-
-// dumbMap is a map which does not implement the loader/saver interface.
-// Serialization of this map will default to the standard encode/decode logic.
-type dumbMap map[string]int
-
-// pointerStruct contains various pointers, shared and non-shared, and pointers
-// to pointers. We expect that serialization will respect the structure.
-type pointerStruct struct {
-	A *int
-	B *int
-	C *int
-	D *int
-
-	AA **int
-	BB **int
-}
-
-func (p *pointerStruct) save(m Map) {
-	m.Save("A", &p.A)
-	m.Save("B", &p.B)
-	m.Save("C", &p.C)
-	m.Save("D", &p.D)
-	m.Save("AA", &p.AA)
-	m.Save("BB", &p.BB)
-}
-
-func (p *pointerStruct) load(m Map) {
-	m.Load("A", &p.A)
-	m.Load("B", &p.B)
-	m.Load("C", &p.C)
-	m.Load("D", &p.D)
-	m.Load("AA", &p.AA)
-	m.Load("BB", &p.BB)
-}
-
-// testInterface is a trivial interface example.
-type testInterface interface {
-	Foo()
-}
-
-// testImpl is a trivial implementation of testInterface.
-type testImpl struct {
-}
-
-// Foo satisfies testInterface.
-func (t *testImpl) Foo() {
-}
-
-// testImpl is trivially serializable.
-func (t *testImpl) save(m Map) {
-}
-
-// testImpl is trivially serializable.
-func (t *testImpl) load(m Map) {
-}
-
-// testI demonstrates interface dispatching.
-type testI struct {
-	I testInterface
-}
-
-func (t *testI) save(m Map) {
-	m.Save("I", &t.I)
-}
-
-func (t *testI) load(m Map) {
-	m.Load("I", &t.I)
-}
-
-// cycleStruct is used to implement basic cycles.
-type cycleStruct struct {
-	c *cycleStruct
-}
-
-func (c *cycleStruct) save(m Map) {
-	m.Save("c", &c.c)
-}
-
-func (c *cycleStruct) load(m Map) {
-	m.Load("c", &c.c)
-}
-
-// badCycleStruct actually has deadlocking dependencies.
-//
-// This should pass if b.b = {nil|b} and fail otherwise.
-type badCycleStruct struct {
-	b *badCycleStruct
-}
-
-func (b *badCycleStruct) save(m Map) {
-	m.Save("b", &b.b)
-}
-
-func (b *badCycleStruct) load(m Map) {
-	m.LoadWait("b", &b.b)
-	m.AfterLoad(func() {
-		// This is not executable, since AfterLoad requires that the
-		// object and all dependencies are complete. This should cause
-		// a deadlock error during load.
-	})
-}
-
-// emptyStructPointer points to an empty struct.
-type emptyStructPointer struct {
-	nothing *struct{}
-}
-
-func (e *emptyStructPointer) save(m Map) {
-	m.Save("nothing", &e.nothing)
-}
-
-func (e *emptyStructPointer) load(m Map) {
-	m.Load("nothing", &e.nothing)
-}
-
-// truncateInteger truncates an integer.
-type truncateInteger struct {
-	v  int64
-	v2 int32
-}
-
-func (t *truncateInteger) save(m Map) {
-	t.v2 = int32(t.v)
-	m.Save("v", &t.v)
-}
-
-func (t *truncateInteger) load(m Map) {
-	m.Load("v", &t.v2)
-	t.v = int64(t.v2)
-}
-
-// truncateUnsignedInteger truncates an unsigned integer.
-type truncateUnsignedInteger struct {
-	v  uint64
-	v2 uint32
-}
-
-func (t *truncateUnsignedInteger) save(m Map) {
-	t.v2 = uint32(t.v)
-	m.Save("v", &t.v)
-}
-
-func (t *truncateUnsignedInteger) load(m Map) {
-	m.Load("v", &t.v2)
-	t.v = uint64(t.v2)
-}
-
-// truncateFloat truncates a floating point number.
-type truncateFloat struct {
-	v  float64
-	v2 float32
-}
-
-func (t *truncateFloat) save(m Map) {
-	t.v2 = float32(t.v)
-	m.Save("v", &t.v)
-}
-
-func (t *truncateFloat) load(m Map) {
-	m.Load("v", &t.v2)
-	t.v = float64(t.v2)
-}
-
-func TestTypes(t *testing.T) {
-	// x and y are basic integers, while xp points to x.
-	x := 1
-	y := 2
-	xp := &x
-
-	// cs is a single object cycle.
-	cs := cycleStruct{nil}
-	cs.c = &cs
-
-	// cs1 and cs2 are in a two object cycle.
-	cs1 := cycleStruct{nil}
-	cs2 := cycleStruct{nil}
-	cs1.c = &cs2
-	cs2.c = &cs1
-
-	// bs is a single object cycle.
-	bs := badCycleStruct{nil}
-	bs.b = &bs
-
-	// bs2 and bs2 are in a deadlocking cycle.
-	bs1 := badCycleStruct{nil}
-	bs2 := badCycleStruct{nil}
-	bs1.b = &bs2
-	bs2.b = &bs1
-
-	// regular nils.
-	var (
-		nilmap   dumbMap
-		nilslice []byte
-	)
-
-	// embed points to embedded fields.
-	embed1 := pointerStruct{}
-	embed1.AA = &embed1.A
-	embed2 := pointerStruct{}
-	embed2.BB = &embed2.B
-
-	// es1 contains two structs pointing to the same empty struct.
-	es := emptyStructPointer{new(struct{})}
-	es1 := []emptyStructPointer{es, es}
-
-	tests := []TestCase{
-		{
-			Name: "bool",
-			Objects: []interface{}{
-				true,
-				false,
-			},
-		},
-		{
-			Name: "integers",
-			Objects: []interface{}{
-				int(0),
-				int(1),
-				int(-1),
-				int8(0),
-				int8(1),
-				int8(-1),
-				int16(0),
-				int16(1),
-				int16(-1),
-				int32(0),
-				int32(1),
-				int32(-1),
-				int64(0),
-				int64(1),
-				int64(-1),
-			},
-		},
-		{
-			Name: "unsigned integers",
-			Objects: []interface{}{
-				uint(0),
-				uint(1),
-				uint8(0),
-				uint8(1),
-				uint16(0),
-				uint16(1),
-				uint32(1),
-				uint64(0),
-				uint64(1),
-			},
-		},
-		{
-			Name: "strings",
-			Objects: []interface{}{
-				"",
-				"foo",
-				"bar",
-				"\xa0",
-			},
-		},
-		{
-			Name: "slices",
-			Objects: []interface{}{
-				[]int{-1, 0, 1},
-				[]*int{&x, &x, &x},
-				[]int{1, 2, 3}[0:1],
-				[]int{1, 2, 3}[1:2],
-				make([]byte, 32),
-				make([]byte, 32)[:16],
-				make([]byte, 32)[:16:20],
-				nilslice,
-			},
-		},
-		{
-			Name: "arrays",
-			Objects: []interface{}{
-				&[1048576]bool{false, true, false, true},
-				&[1048576]uint8{0, 1, 2, 3},
-				&[1048576]byte{0, 1, 2, 3},
-				&[1048576]uint16{0, 1, 2, 3},
-				&[1048576]uint{0, 1, 2, 3},
-				&[1048576]uint32{0, 1, 2, 3},
-				&[1048576]uint64{0, 1, 2, 3},
-				&[1048576]uintptr{0, 1, 2, 3},
-				&[1048576]int8{0, -1, -2, -3},
-				&[1048576]int16{0, -1, -2, -3},
-				&[1048576]int32{0, -1, -2, -3},
-				&[1048576]int64{0, -1, -2, -3},
-				&[1048576]float32{0, 1.1, 2.2, 3.3},
-				&[1048576]float64{0, 1.1, 2.2, 3.3},
-			},
-		},
-		{
-			Name: "pointers",
-			Objects: []interface{}{
-				&pointerStruct{A: &x, B: &x, C: &y, D: &y, AA: &xp, BB: &xp},
-				&pointerStruct{},
-			},
-		},
-		{
-			Name: "empty struct",
-			Objects: []interface{}{
-				struct{}{},
-			},
-		},
-		{
-			Name: "unenlightened structs",
-			Objects: []interface{}{
-				&dumbStruct{A: 1, B: 2},
-			},
-			Fail: true,
-		},
-		{
-			Name: "enlightened structs",
-			Objects: []interface{}{
-				&smartStruct{A: 1, B: 2},
-			},
-		},
-		{
-			Name: "load-hooks",
-			Objects: []interface{}{
-				&afterLoadStruct{v: 1},
-				&valueLoadStruct{v: 1},
-				&genericContainer{v: &afterLoadStruct{v: 1}},
-				&genericContainer{v: &valueLoadStruct{v: 1}},
-				&sliceContainer{v: []interface{}{&afterLoadStruct{v: 1}}},
-				&sliceContainer{v: []interface{}{&valueLoadStruct{v: 1}}},
-				&mapContainer{v: map[int]interface{}{0: &afterLoadStruct{v: 1}}},
-				&mapContainer{v: map[int]interface{}{0: &valueLoadStruct{v: 1}}},
-			},
-		},
-		{
-			Name: "maps",
-			Objects: []interface{}{
-				dumbMap{"a": -1, "b": 0, "c": 1},
-				map[smartStruct]int{{}: 0, {A: 1}: 1},
-				nilmap,
-				&mapContainer{v: map[int]interface{}{0: &smartStruct{A: 1}}},
-			},
-		},
-		{
-			Name: "interfaces",
-			Objects: []interface{}{
-				&testI{&testImpl{}},
-				&testI{nil},
-				&testI{(*testImpl)(nil)},
-			},
-		},
-		{
-			Name: "unregistered-interfaces",
-			Objects: []interface{}{
-				&genericContainer{v: afterLoadStruct{v: 1}},
-				&genericContainer{v: valueLoadStruct{v: 1}},
-				&sliceContainer{v: []interface{}{afterLoadStruct{v: 1}}},
-				&sliceContainer{v: []interface{}{valueLoadStruct{v: 1}}},
-				&mapContainer{v: map[int]interface{}{0: afterLoadStruct{v: 1}}},
-				&mapContainer{v: map[int]interface{}{0: valueLoadStruct{v: 1}}},
-			},
-			Fail: true,
-		},
-		{
-			Name: "cycles",
-			Objects: []interface{}{
-				&cs,
-				&cs1,
-				&cycleStruct{&cs1},
-				&cycleStruct{&cs},
-				&badCycleStruct{nil},
-				&bs,
-			},
-		},
-		{
-			Name: "deadlock",
-			Objects: []interface{}{
-				&bs1,
-			},
-			Fail: true,
-		},
-		{
-			Name: "embed",
-			Objects: []interface{}{
-				&embed1,
-				&embed2,
-			},
-			Fail: true,
-		},
-		{
-			Name: "empty structs",
-			Objects: []interface{}{
-				new(struct{}),
-				es,
-				es1,
-			},
-		},
-		{
-			Name: "truncated okay",
-			Objects: []interface{}{
-				&truncateInteger{v: 1},
-				&truncateUnsignedInteger{v: 1},
-				&truncateFloat{v: 1.0},
-			},
-		},
-		{
-			Name: "truncated bad",
-			Objects: []interface{}{
-				&truncateInteger{v: math.MaxInt32 + 1},
-				&truncateUnsignedInteger{v: math.MaxUint32 + 1},
-				&truncateFloat{v: math.MaxFloat32 * 2},
-			},
-			Fail: true,
-		},
-	}
-
-	runTest(t, tests)
-}
-
-// benchStruct is used for benchmarking.
-type benchStruct struct {
-	b *benchStruct
-
-	// Dummy data is included to ensure that these objects are large.
-	// This is to detect possible regression when registering objects.
-	_ [4096]byte
-}
-
-func (b *benchStruct) save(m Map) {
-	m.Save("b", &b.b)
-}
-
-func (b *benchStruct) load(m Map) {
-	m.LoadWait("b", &b.b)
-	m.AfterLoad(b.afterLoad)
-}
-
-func (b *benchStruct) afterLoad() {
-	// Do nothing, just force scheduling.
-}
-
-// buildObject builds a benchmark object.
-func buildObject(n int) (b *benchStruct) {
-	for i := 0; i < n; i++ {
-		b = &benchStruct{b: b}
-	}
-	return
-}
-
-func BenchmarkEncoding(b *testing.B) {
-	b.StopTimer()
-	bs := buildObject(b.N)
-	var stats Stats
-	b.StartTimer()
-	if err := Save(context.Background(), ioutil.Discard, bs, &stats); err != nil {
-		b.Errorf("save failed: %v", err)
-	}
-	b.StopTimer()
-	if b.N > 1000 {
-		b.Logf("breakdown (n=%d): %s", b.N, &stats)
-	}
-}
-
-func BenchmarkDecoding(b *testing.B) {
-	b.StopTimer()
-	bs := buildObject(b.N)
-	var newBS benchStruct
-	buf := &bytes.Buffer{}
-	if err := Save(context.Background(), buf, bs, nil); err != nil {
-		b.Errorf("save failed: %v", err)
-	}
-	var stats Stats
-	b.StartTimer()
-	if err := Load(context.Background(), buf, &newBS, &stats); err != nil {
-		b.Errorf("load failed: %v", err)
-	}
-	b.StopTimer()
-	if b.N > 1000 {
-		b.Logf("breakdown (n=%d): %s", b.N, &stats)
-	}
-}
-
-func init() {
-	Register("stateTest.smartStruct", (*smartStruct)(nil), Fns{
-		Save: (*smartStruct).save,
-		Load: (*smartStruct).load,
-	})
-	Register("stateTest.afterLoadStruct", (*afterLoadStruct)(nil), Fns{
-		Save: (*afterLoadStruct).save,
-		Load: (*afterLoadStruct).load,
-	})
-	Register("stateTest.valueLoadStruct", (*valueLoadStruct)(nil), Fns{
-		Save: (*valueLoadStruct).save,
-		Load: (*valueLoadStruct).load,
-	})
-	Register("stateTest.genericContainer", (*genericContainer)(nil), Fns{
-		Save: (*genericContainer).save,
-		Load: (*genericContainer).load,
-	})
-	Register("stateTest.sliceContainer", (*sliceContainer)(nil), Fns{
-		Save: (*sliceContainer).save,
-		Load: (*sliceContainer).load,
-	})
-	Register("stateTest.mapContainer", (*mapContainer)(nil), Fns{
-		Save: (*mapContainer).save,
-		Load: (*mapContainer).load,
-	})
-	Register("stateTest.pointerStruct", (*pointerStruct)(nil), Fns{
-		Save: (*pointerStruct).save,
-		Load: (*pointerStruct).load,
-	})
-	Register("stateTest.testImpl", (*testImpl)(nil), Fns{
-		Save: (*testImpl).save,
-		Load: (*testImpl).load,
-	})
-	Register("stateTest.testI", (*testI)(nil), Fns{
-		Save: (*testI).save,
-		Load: (*testI).load,
-	})
-	Register("stateTest.cycleStruct", (*cycleStruct)(nil), Fns{
-		Save: (*cycleStruct).save,
-		Load: (*cycleStruct).load,
-	})
-	Register("stateTest.badCycleStruct", (*badCycleStruct)(nil), Fns{
-		Save: (*badCycleStruct).save,
-		Load: (*badCycleStruct).load,
-	})
-	Register("stateTest.emptyStructPointer", (*emptyStructPointer)(nil), Fns{
-		Save: (*emptyStructPointer).save,
-		Load: (*emptyStructPointer).load,
-	})
-	Register("stateTest.truncateInteger", (*truncateInteger)(nil), Fns{
-		Save: (*truncateInteger).save,
-		Load: (*truncateInteger).load,
-	})
-	Register("stateTest.truncateUnsignedInteger", (*truncateUnsignedInteger)(nil), Fns{
-		Save: (*truncateUnsignedInteger).save,
-		Load: (*truncateUnsignedInteger).load,
-	})
-	Register("stateTest.truncateFloat", (*truncateFloat)(nil), Fns{
-		Save: (*truncateFloat).save,
-		Load: (*truncateFloat).load,
-	})
-	Register("stateTest.benchStruct", (*benchStruct)(nil), Fns{
-		Save: (*benchStruct).save,
-		Load: (*benchStruct).load,
-	})
-}
diff --git a/pkg/sync/aliases.go b/pkg/sync/aliases.go
old mode 100644
new mode 100755
diff --git a/pkg/sync/atomicptr_unsafe.go b/pkg/sync/atomicptr_unsafe.go
deleted file mode 100644
index 525c4be..0000000
--- a/pkg/sync/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 template doesn't exist. This file must be instantiated using the
-// go_template_instance rule in tools/go_generics/defs.bzl.
-package template
-
-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/memmove_unsafe.go b/pkg/sync/memmove_unsafe.go
old mode 100644
new mode 100755
diff --git a/pkg/sync/mutex_test.go b/pkg/sync/mutex_test.go
deleted file mode 100644
index 0838248..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.state(); got != mutexLocked {
-		t.Errorf("got locked sync.Mutex.state = %d, want = %d", got, mutexLocked)
-	}
-	m.Unlock()
-	if got := *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/mutex_unsafe.go b/pkg/sync/mutex_unsafe.go
old mode 100644
new mode 100755
diff --git a/pkg/sync/norace_unsafe.go b/pkg/sync/norace_unsafe.go
old mode 100644
new mode 100755
diff --git a/pkg/sync/race_unsafe.go b/pkg/sync/race_unsafe.go
old mode 100644
new mode 100755
diff --git a/pkg/sync/rwmutex_test.go b/pkg/sync/rwmutex_test.go
deleted file mode 100644
index ce667e8..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++ {
-		}
-		n = 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/rwmutex_unsafe.go b/pkg/sync/rwmutex_unsafe.go
old mode 100644
new mode 100755
diff --git a/pkg/sync/seqatomic_unsafe.go b/pkg/sync/seqatomic_unsafe.go
deleted file mode 100644
index eda6fb1..0000000
--- a/pkg/sync/seqatomic_unsafe.go
+++ /dev/null
@@ -1,72 +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 template doesn't exist. This file must be instantiated using the
-// go_template_instance rule in tools/go_generics/defs.bzl.
-package template
-
-import (
-	"fmt"
-	"reflect"
-	"strings"
-	"unsafe"
-
-	"gvisor.dev/gvisor/pkg/sync"
-)
-
-// Value is a required type parameter.
-//
-// Value must not contain any pointers, including interface objects, function
-// objects, slices, maps, channels, unsafe.Pointer, and arrays or structs
-// containing any of the above. An init() function will panic if this property
-// does not hold.
-type Value struct{}
-
-// SeqAtomicLoad returns a copy of *ptr, ensuring that the read does not race
-// with any writer critical sections in sc.
-func SeqAtomicLoad(sc *sync.SeqCount, ptr *Value) Value {
-	// This function doesn't use SeqAtomicTryLoad because doing so is
-	// measurably, significantly (~20%) slower; Go is awful at inlining.
-	var val Value
-	for {
-		epoch := sc.BeginRead()
-		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
-		}
-		if sc.ReadOk(epoch) {
-			break
-		}
-	}
-	return val
-}
-
-// SeqAtomicTryLoad returns a copy of *ptr while in a reader critical section
-// in sc initiated by a call to sc.BeginRead() that returned epoch. If the read
-// would race with a writer critical section, SeqAtomicTryLoad returns
-// (unspecified, false).
-func SeqAtomicTryLoad(sc *sync.SeqCount, epoch sync.SeqCountEpoch, ptr *Value) (Value, bool) {
-	var val Value
-	if sync.RaceEnabled {
-		sync.Memmove(unsafe.Pointer(&val), unsafe.Pointer(ptr), unsafe.Sizeof(val))
-	} else {
-		val = *ptr
-	}
-	return val, sc.ReadOk(epoch)
-}
-
-func init() {
-	var val Value
-	typ := reflect.TypeOf(val)
-	name := typ.Name()
-	if ptrs := sync.PointersInType(typ, name); len(ptrs) != 0 {
-		panic(fmt.Sprintf("SeqAtomicLoad<%s> is invalid since values %s of type %s contain pointers:\n%s", typ, name, typ, strings.Join(ptrs, "\n")))
-	}
-}
diff --git a/pkg/sync/seqcount.go b/pkg/sync/seqcount.go
old mode 100644
new mode 100755
diff --git a/pkg/sync/seqcount_test.go b/pkg/sync/seqcount_test.go
deleted file mode 100644
index 6eb7b4b..0000000
--- a/pkg/sync/seqcount_test.go
+++ /dev/null
@@ -1,153 +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 (
-	"reflect"
-	"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")
-			}
-		}
-	})
-}
-
-func TestPointersInType(t *testing.T) {
-	for _, test := range []struct {
-		name string // used for both test and value name
-		val  interface{}
-		ptrs []string
-	}{
-		{
-			name: "EmptyStruct",
-			val:  struct{}{},
-		},
-		{
-			name: "Int",
-			val:  int(0),
-		},
-		{
-			name: "MixedStruct",
-			val: struct {
-				b             bool
-				I             int
-				ExportedPtr   *struct{}
-				unexportedPtr *struct{}
-				arr           [2]int
-				ptrArr        [2]*int
-				nestedStruct  struct {
-					nestedNonptr int
-					nestedPtr    *int
-				}
-				structArr [1]struct {
-					nonptr int
-					ptr    *int
-				}
-			}{},
-			ptrs: []string{
-				"MixedStruct.ExportedPtr",
-				"MixedStruct.unexportedPtr",
-				"MixedStruct.ptrArr[]",
-				"MixedStruct.nestedStruct.nestedPtr",
-				"MixedStruct.structArr[].ptr",
-			},
-		},
-	} {
-		t.Run(test.name, func(t *testing.T) {
-			typ := reflect.TypeOf(test.val)
-			ptrs := PointersInType(typ, test.name)
-			t.Logf("Found pointers: %v", ptrs)
-			if (len(ptrs) != 0 || len(test.ptrs) != 0) && !reflect.DeepEqual(ptrs, test.ptrs) {
-				t.Errorf("Got %v, wanted %v", ptrs, test.ptrs)
-			}
-		})
-	}
-}
diff --git a/pkg/sync/sync.go b/pkg/sync/sync.go
old mode 100644
new mode 100755
diff --git a/pkg/sync/sync_state_autogen.go b/pkg/sync/sync_state_autogen.go
new file mode 100755
index 0000000..6876ee8
--- /dev/null
+++ b/pkg/sync/sync_state_autogen.go
@@ -0,0 +1,12 @@
+// automatically generated by stateify.
+
+// +build go1.12
+// +build !go1.15
+// +build go1.13
+// +build !go1.15
+// +build !race
+// +build race
+// +build go1.13
+// +build !go1.15
+
+package sync
diff --git a/pkg/tcpip/buffer/buffer_state_autogen.go b/pkg/tcpip/buffer/buffer_state_autogen.go
new file mode 100755
index 0000000..9544877
--- /dev/null
+++ b/pkg/tcpip/buffer/buffer_state_autogen.go
@@ -0,0 +1,24 @@
+// automatically generated by stateify.
+
+package buffer
+
+import (
+	"gvisor.dev/gvisor/pkg/state"
+)
+
+func (x *VectorisedView) beforeSave() {}
+func (x *VectorisedView) save(m state.Map) {
+	x.beforeSave()
+	m.Save("views", &x.views)
+	m.Save("size", &x.size)
+}
+
+func (x *VectorisedView) afterLoad() {}
+func (x *VectorisedView) load(m state.Map) {
+	m.Load("views", &x.views)
+	m.Load("size", &x.size)
+}
+
+func init() {
+	state.Register("pkg/tcpip/buffer.VectorisedView", (*VectorisedView)(nil), state.Fns{Save: (*VectorisedView).save, Load: (*VectorisedView).load})
+}
diff --git a/pkg/tcpip/buffer/view_test.go b/pkg/tcpip/buffer/view_test.go
deleted file mode 100644
index ebc3a17..0000000
--- a/pkg/tcpip/buffer/view_test.go
+++ /dev/null
@@ -1,235 +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 VectorisedView type.
-package buffer
-
-import (
-	"reflect"
-	"testing"
-)
-
-// copy returns a deep-copy of the vectorised view.
-func (vv VectorisedView) copy() VectorisedView {
-	uu := VectorisedView{
-		views: make([]View, 0, len(vv.views)),
-		size:  vv.size,
-	}
-	for _, v := range vv.views {
-		uu.views = append(uu.views, append(View(nil), v...))
-	}
-	return uu
-}
-
-// vv is an helper to build VectorisedView from different strings.
-func vv(size int, pieces ...string) VectorisedView {
-	views := make([]View, len(pieces))
-	for i, p := range pieces {
-		views[i] = []byte(p)
-	}
-
-	return NewVectorisedView(size, views)
-}
-
-var capLengthTestCases = []struct {
-	comment string
-	in      VectorisedView
-	length  int
-	want    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 := c.in.copy()
-		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      VectorisedView
-	count   int
-	want    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: "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 := c.in.copy()
-		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      VectorisedView
-	want    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   VectorisedView
-	inBuffer []View
-}{
-	{
-		comment:  "Simple case",
-		inView:   vv(1, "1"),
-		inBuffer: make([]View, 1),
-	},
-	{
-		comment:  "Case with multiple views",
-		inView:   vv(2, "1", "2"),
-		inBuffer: make([]View, 2),
-	},
-	{
-		comment:  "Case with buffer too small",
-		inView:   vv(2, "1", "2"),
-		inBuffer: make([]View, 1),
-	},
-	{
-		comment:  "Case with buffer larger than needed",
-		inView:   vv(1, "1"),
-		inBuffer: make([]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)
-			}
-		})
-	}
-}
diff --git a/pkg/tcpip/hash/jenkins/jenkins_state_autogen.go b/pkg/tcpip/hash/jenkins/jenkins_state_autogen.go
new file mode 100755
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 3094034..0000000
--- a/pkg/tcpip/header/checksum_test.go
+++ /dev/null
@@ -1,171 +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 (
-	"fmt"
-	"math/rand"
-	"testing"
-
-	"gvisor.dev/gvisor/pkg/tcpip/buffer"
-	"gvisor.dev/gvisor/pkg/tcpip/header"
-)
-
-func TestChecksumVVWithOffset(t *testing.T) {
-	testCases := []struct {
-		name      string
-		vv        buffer.VectorisedView
-		off, size int
-		initial   uint16
-		want      uint16
-	}{
-		{
-			name: "empty",
-			vv: buffer.NewVectorisedView(0, []buffer.View{
-				buffer.NewViewFromBytes([]byte{1, 9, 0, 5, 4}),
-			}),
-			off:  0,
-			size: 0,
-			want: 0,
-		},
-		{
-			name: "OneView",
-			vv: buffer.NewVectorisedView(0, []buffer.View{
-				buffer.NewViewFromBytes([]byte{1, 9, 0, 5, 4}),
-			}),
-			off:  0,
-			size: 5,
-			want: 1294,
-		},
-		{
-			name: "TwoViews",
-			vv: buffer.NewVectorisedView(0, []buffer.View{
-				buffer.NewViewFromBytes([]byte{1, 9, 0, 5, 4}),
-				buffer.NewViewFromBytes([]byte{4, 3, 7, 1, 2, 123}),
-			}),
-			off:  0,
-			size: 11,
-			want: 33819,
-		},
-		{
-			name: "TwoViewsWithOffset",
-			vv: buffer.NewVectorisedView(0, []buffer.View{
-				buffer.NewViewFromBytes([]byte{98, 1, 9, 0, 5, 4}),
-				buffer.NewViewFromBytes([]byte{4, 3, 7, 1, 2, 123}),
-			}),
-			off:  1,
-			size: 11,
-			want: 33819,
-		},
-		{
-			name: "ThreeViewsWithOffset",
-			vv: buffer.NewVectorisedView(0, []buffer.View{
-				buffer.NewViewFromBytes([]byte{98, 1, 9, 0, 5, 4}),
-				buffer.NewViewFromBytes([]byte{98, 1, 9, 0, 5, 4}),
-				buffer.NewViewFromBytes([]byte{4, 3, 7, 1, 2, 123}),
-			}),
-			off:  7,
-			size: 11,
-			want: 33819,
-		},
-		{
-			name: "ThreeViewsWithInitial",
-			vv: buffer.NewVectorisedView(0, []buffer.View{
-				buffer.NewViewFromBytes([]byte{77, 11, 33, 0, 55, 44}),
-				buffer.NewViewFromBytes([]byte{98, 1, 9, 0, 5, 4}),
-				buffer.NewViewFromBytes([]byte{4, 3, 7, 1, 2, 123, 99}),
-			}),
-			initial: 77,
-			off:     7,
-			size:    11,
-			want:    33896,
-		},
-	}
-	for _, tc := range testCases {
-		t.Run(tc.name, func(t *testing.T) {
-			if got, want := header.ChecksumVVWithOffset(tc.vv, tc.initial, tc.off, tc.size), tc.want; got != want {
-				t.Errorf("header.ChecksumVVWithOffset(%v) = %v, want: %v", tc, got, tc.want)
-			}
-			v := tc.vv.ToView()
-			v.TrimFront(tc.off)
-			v.CapLength(tc.size)
-			if got, want := header.Checksum(v, tc.initial), tc.want; got != want {
-				t.Errorf("header.Checksum(%v) = %v, want: %v", tc, got, tc.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)
-				}
-			})
-		}
-	}
-}
diff --git a/pkg/tcpip/header/eth_test.go b/pkg/tcpip/header/eth_test.go
deleted file mode 100644
index 7a0014a..0000000
--- a/pkg/tcpip/header/eth_test.go
+++ /dev/null
@@ -1,102 +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 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", 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 100755
index 0000000..015d7e1
--- /dev/null
+++ b/pkg/tcpip/header/header_state_autogen.go
@@ -0,0 +1,42 @@
+// automatically generated by stateify.
+
+package header
+
+import (
+	"gvisor.dev/gvisor/pkg/state"
+)
+
+func (x *SACKBlock) beforeSave() {}
+func (x *SACKBlock) save(m state.Map) {
+	x.beforeSave()
+	m.Save("Start", &x.Start)
+	m.Save("End", &x.End)
+}
+
+func (x *SACKBlock) afterLoad() {}
+func (x *SACKBlock) load(m state.Map) {
+	m.Load("Start", &x.Start)
+	m.Load("End", &x.End)
+}
+
+func (x *TCPOptions) beforeSave() {}
+func (x *TCPOptions) save(m state.Map) {
+	x.beforeSave()
+	m.Save("TS", &x.TS)
+	m.Save("TSVal", &x.TSVal)
+	m.Save("TSEcr", &x.TSEcr)
+	m.Save("SACKBlocks", &x.SACKBlocks)
+}
+
+func (x *TCPOptions) afterLoad() {}
+func (x *TCPOptions) load(m state.Map) {
+	m.Load("TS", &x.TS)
+	m.Load("TSVal", &x.TSVal)
+	m.Load("TSEcr", &x.TSEcr)
+	m.Load("SACKBlocks", &x.SACKBlocks)
+}
+
+func init() {
+	state.Register("pkg/tcpip/header.SACKBlock", (*SACKBlock)(nil), state.Fns{Save: (*SACKBlock).save, Load: (*SACKBlock).load})
+	state.Register("pkg/tcpip/header.TCPOptions", (*TCPOptions)(nil), state.Fns{Save: (*TCPOptions).save, Load: (*TCPOptions).load})
+}
diff --git a/pkg/tcpip/header/ipv6_extension_headers.go b/pkg/tcpip/header/ipv6_extension_headers.go
old mode 100644
new mode 100755
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 133ccc8..0000000
--- a/pkg/tcpip/header/ipv6_extension_headers_test.go
+++ /dev/null
@@ -1,957 +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/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            IPv6ExtHdrOptionIndentifier
-		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,
-		},
-	}
-
-	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, the payload after the fragment will not be
-		// parsed because the payload may not be complete.
-		{
-			name:         "hopbyhop - fragment - routing - upper",
-			firstNextHdr: IPv6HopByHopOptionsExtHdrIdentifier,
-			payload: makeVectorisedViewFromByteBuffers([]byte{
-				// Hop By Hop extension header.
-				uint8(IPv6FragmentExtHdrIdentifier), 0, 1, 4, 1, 2, 3, 4,
-
-				// Fragment extension header.
-				uint8(IPv6RoutingExtHdrIdentifier), 0, 68, 9, 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{68, 9, 128, 4, 2, 1}),
-				IPv6RawPayloadHeader{
-					Identifier: IPv6RoutingExtHdrIdentifier,
-					Buf:        routingExtHdrWithUpperLayerData.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)
-			}
-		})
-	}
-}
diff --git a/pkg/tcpip/header/ipv6_test.go b/pkg/tcpip/header/ipv6_test.go
deleted file mode 100644
index 426a873..0000000
--- a/pkg/tcpip/header/ipv6_test.go
+++ /dev/null
@@ -1,417 +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 TestIsV6UniqueLocalAddress(t *testing.T) {
-	tests := []struct {
-		name     string
-		addr     tcpip.Address
-		expected bool
-	}{
-		{
-			name:     "Valid Unique 1",
-			addr:     uniqueLocalAddr1,
-			expected: true,
-		},
-		{
-			name:     "Valid Unique 2",
-			addr:     uniqueLocalAddr1,
-			expected: true,
-		},
-		{
-			name:     "Link Local",
-			addr:     linkLocalAddr,
-			expected: false,
-		},
-		{
-			name:     "Global",
-			addr:     globalAddr,
-			expected: false,
-		},
-		{
-			name:     "IPv4",
-			addr:     "\x01\x02\x03\x04",
-			expected: false,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			if got := header.IsV6UniqueLocalAddress(test.addr); got != test.expected {
-				t.Errorf("got header.IsV6UniqueLocalAddress(%s) = %t, want = %t", test.addr, got, test.expected)
-			}
-		})
-	}
-}
-
-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.UniqueLocalScope,
-			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 err != test.err {
-				t.Errorf("got header.IsV6UniqueLocalAddress(%s) = (_, %v), want = (_, %v)", test.addr, err, test.err)
-			}
-			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/ndp_neighbor_advert.go b/pkg/tcpip/header/ndp_neighbor_advert.go
old mode 100644
new mode 100755
diff --git a/pkg/tcpip/header/ndp_neighbor_solicit.go b/pkg/tcpip/header/ndp_neighbor_solicit.go
old mode 100644
new mode 100755
diff --git a/pkg/tcpip/header/ndp_options.go b/pkg/tcpip/header/ndp_options.go
old mode 100644
new mode 100755
diff --git a/pkg/tcpip/header/ndp_router_advert.go b/pkg/tcpip/header/ndp_router_advert.go
old mode 100644
new mode 100755
diff --git a/pkg/tcpip/header/ndp_router_solicit.go b/pkg/tcpip/header/ndp_router_solicit.go
old mode 100644
new mode 100755
diff --git a/pkg/tcpip/header/ndp_test.go b/pkg/tcpip/header/ndp_test.go
deleted file mode 100644
index 1cb9f5d..0000000
--- a/pkg/tcpip/header/ndp_test.go
+++ /dev/null
@@ -1,937 +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"
-	"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")
-	}
-}
-
-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)
-			}
-		})
-	}
-}
-
-// TestNDPSourceLinkLayerAddressOptionSerialize tests serializing a
-// NDPSourceLinkLayerAddressOption.
-func TestNDPSourceLinkLayerAddressOptionSerialize(t *testing.T) {
-	tests := []struct {
-		name        string
-		buf         []byte
-		expectedBuf []byte
-		addr        tcpip.LinkAddress
-	}{
-		{
-			"Ethernet",
-			make([]byte, 8),
-			[]byte{1, 1, 1, 2, 3, 4, 5, 6},
-			"\x01\x02\x03\x04\x05\x06",
-		},
-		{
-			"Padding",
-			[]byte{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
-			[]byte{1, 2, 1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0},
-			"\x01\x02\x03\x04\x05\x06\x07\x08",
-		},
-		{
-			"Empty",
-			nil,
-			nil,
-			"",
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			opts := NDPOptions(test.buf)
-			serializer := NDPOptionsSerializer{
-				NDPSourceLinkLayerAddressOption(test.addr),
-			}
-			if got, want := int(serializer.Length()), len(test.expectedBuf); got != want {
-				t.Fatalf("got Length = %d, want = %d", got, want)
-			}
-			opts.Serialize(serializer)
-			if !bytes.Equal(test.buf, test.expectedBuf) {
-				t.Fatalf("got b = %d, want = %d", test.buf, test.expectedBuf)
-			}
-
-			it, err := opts.Iter(true)
-			if err != nil {
-				t.Fatalf("got Iter = (_, %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, _)")
-				}
-				if got := next.Type(); got != NDPSourceLinkLayerAddressOptionType {
-					t.Fatalf("got Type = %d, want = %d", got, NDPSourceLinkLayerAddressOptionType)
-				}
-				sll := next.(NDPSourceLinkLayerAddressOption)
-				if got, want := []byte(sll), test.expectedBuf[2:]; !bytes.Equal(got, want) {
-					t.Fatalf("got Next = (%x, _, _), want = (%x, _, _)", got, want)
-				}
-
-				if got, want := sll.EthernetAddress(), tcpip.LinkAddress(test.expectedBuf[2:][:EthernetAddressSize]); got != want {
-					t.Errorf("got sll.EthernetAddress = %s, want = %s", got, want)
-				}
-			}
-
-			// 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)
-			}
-		})
-	}
-}
-
-// 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)
-			}
-		})
-	}
-}
-
-// TestNDPTargetLinkLayerAddressOptionSerialize tests serializing a
-// NDPTargetLinkLayerAddressOption.
-func TestNDPTargetLinkLayerAddressOptionSerialize(t *testing.T) {
-	tests := []struct {
-		name        string
-		buf         []byte
-		expectedBuf []byte
-		addr        tcpip.LinkAddress
-	}{
-		{
-			"Ethernet",
-			make([]byte, 8),
-			[]byte{2, 1, 1, 2, 3, 4, 5, 6},
-			"\x01\x02\x03\x04\x05\x06",
-		},
-		{
-			"Padding",
-			[]byte{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
-			[]byte{2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0},
-			"\x01\x02\x03\x04\x05\x06\x07\x08",
-		},
-		{
-			"Empty",
-			nil,
-			nil,
-			"",
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			opts := NDPOptions(test.buf)
-			serializer := NDPOptionsSerializer{
-				NDPTargetLinkLayerAddressOption(test.addr),
-			}
-			if got, want := int(serializer.Length()), len(test.expectedBuf); got != want {
-				t.Fatalf("got Length = %d, want = %d", got, want)
-			}
-			opts.Serialize(serializer)
-			if !bytes.Equal(test.buf, test.expectedBuf) {
-				t.Fatalf("got b = %d, want = %d", test.buf, test.expectedBuf)
-			}
-
-			it, err := opts.Iter(true)
-			if err != nil {
-				t.Fatalf("got Iter = (_, %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, _)")
-				}
-				if got := next.Type(); got != NDPTargetLinkLayerAddressOptionType {
-					t.Fatalf("got Type = %d, want = %d", got, NDPTargetLinkLayerAddressOptionType)
-				}
-				tll := next.(NDPTargetLinkLayerAddressOption)
-				if got, want := []byte(tll), test.expectedBuf[2:]; !bytes.Equal(got, want) {
-					t.Fatalf("got Next = (%x, _, _), want = (%x, _, _)", got, want)
-				}
-
-				if got, want := tll.EthernetAddress(), tcpip.LinkAddress(test.expectedBuf[2:][:EthernetAddressSize]); got != want {
-					t.Errorf("got tll.EthernetAddress = %s, want = %s", got, want)
-				}
-			}
-
-			// 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)
-			}
-		})
-	}
-}
-
-// TestNDPPrefixInformationOption tests the field getters and serialization of a
-// NDPPrefixInformation.
-func TestNDPPrefixInformationOption(t *testing.T) {
-	b := []byte{
-		43, 127,
-		1, 2, 3, 4,
-		5, 6, 7, 8,
-		5, 5, 5, 5,
-		9, 10, 11, 12,
-		13, 14, 15, 16,
-		17, 18, 19, 20,
-		21, 22, 23, 24,
-	}
-
-	targetBuf := []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}
-	opts := NDPOptions(targetBuf)
-	serializer := NDPOptionsSerializer{
-		NDPPrefixInformation(b),
-	}
-	opts.Serialize(serializer)
-	expectedBuf := []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,
-	}
-	if !bytes.Equal(targetBuf, expectedBuf) {
-		t.Fatalf("got targetBuf = %x, want = %x", targetBuf, expectedBuf)
-	}
-
-	it, err := opts.Iter(true)
-	if err != nil {
-		t.Fatalf("got Iter = (_, %s), want = (_, nil)", err)
-	}
-
-	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.Type(); got != NDPPrefixInformationType {
-		t.Errorf("got Type = %d, want = %d", got, NDPPrefixInformationType)
-	}
-
-	pi := next.(NDPPrefixInformation)
-
-	if got := pi.Type(); got != 3 {
-		t.Errorf("got Type = %d, want = 3", got)
-	}
-
-	if got := pi.Length(); got != 30 {
-		t.Errorf("got Length = %d, want = 30", got)
-	}
-
-	if got := pi.PrefixLength(); got != 43 {
-		t.Errorf("got PrefixLength = %d, want = 43", got)
-	}
-
-	if pi.OnLinkFlag() {
-		t.Error("got OnLinkFlag = true, want = false")
-	}
-
-	if !pi.AutonomousAddressConfigurationFlag() {
-		t.Error("got AutonomousAddressConfigurationFlag = false, want = true")
-	}
-
-	if got, want := pi.ValidLifetime(), 16909060*time.Second; got != want {
-		t.Errorf("got ValidLifetime = %d, want = %d", got, want)
-	}
-
-	if got, want := pi.PreferredLifetime(), 84281096*time.Second; got != want {
-		t.Errorf("got PreferredLifetime = %d, want = %d", got, want)
-	}
-
-	if got, want := pi.Prefix(), tcpip.Address("\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18"); got != want {
-		t.Errorf("got Prefix = %s, want = %s", got, want)
-	}
-
-	// 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 TestNDPRecursiveDNSServerOptionSerialize(t *testing.T) {
-	b := []byte{
-		9, 8,
-		1, 2, 4, 8,
-		0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
-	}
-	targetBuf := []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}
-	expected := []byte{
-		25, 3, 0, 0,
-		1, 2, 4, 8,
-		0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
-	}
-	opts := NDPOptions(targetBuf)
-	serializer := NDPOptionsSerializer{
-		NDPRecursiveDNSServer(b),
-	}
-	if got, want := opts.Serialize(serializer), len(expected); got != want {
-		t.Errorf("got Serialize = %d, want = %d", got, want)
-	}
-	if !bytes.Equal(targetBuf, expected) {
-		t.Fatalf("got targetBuf = %x, want = %x", targetBuf, expected)
-	}
-
-	it, err := opts.Iter(true)
-	if err != nil {
-		t.Fatalf("got Iter = (_, %s), want = (_, nil)", err)
-	}
-
-	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.Type(); got != NDPRecursiveDNSServerOptionType {
-		t.Errorf("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.Type(); got != 25 {
-		t.Errorf("got Type = %d, want = 31", got)
-	}
-	if got := opt.Length(); got != 22 {
-		t.Errorf("got Length = %d, want = 22", got)
-	}
-	if got, want := opt.Lifetime(), 16909320*time.Second; got != want {
-		t.Errorf("got Lifetime = %s, want = %s", got, want)
-	}
-	want := []tcpip.Address{
-		"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
-	}
-	if got := opt.Addresses(); !cmp.Equal(got, want) {
-		t.Errorf("got Addresses = %v, want = %v", got, want)
-	}
-
-	// 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.Type(); 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)
-			}
-			if got := opt.Addresses(); !cmp.Equal(got, test.addrs) {
-				t.Errorf("got Addresses = %v, want = %v", got, test.addrs)
-			}
-
-			// 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)
-			}
-		})
-	}
-}
-
-// 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
-		expected error
-	}{
-		{
-			"ZeroLengthField",
-			[]byte{0, 0, 0, 0, 0, 0, 0, 0},
-			ErrNDPOptZeroLength,
-		},
-		{
-			"ValidSourceLinkLayerAddressOption",
-			[]byte{1, 1, 1, 2, 3, 4, 5, 6},
-			nil,
-		},
-		{
-			"TooSmallSourceLinkLayerAddressOption",
-			[]byte{1, 1, 1, 2, 3, 4, 5},
-			ErrNDPOptBufExhausted,
-		},
-		{
-			"ValidTargetLinkLayerAddressOption",
-			[]byte{2, 1, 1, 2, 3, 4, 5, 6},
-			nil,
-		},
-		{
-			"TooSmallTargetLinkLayerAddressOption",
-			[]byte{2, 1, 1, 2, 3, 4, 5},
-			ErrNDPOptBufExhausted,
-		},
-		{
-			"ValidPrefixInformation",
-			[]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,
-			},
-			nil,
-		},
-		{
-			"TooSmallPrefixInformation",
-			[]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,
-			},
-			ErrNDPOptBufExhausted,
-		},
-		{
-			"InvalidPrefixInformationLength",
-			[]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,
-			},
-			ErrNDPOptMalformedBody,
-		},
-		{
-			"ValidSourceAndTargetLinkLayerAddressWithPrefixInformation",
-			[]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,
-			},
-			nil,
-		},
-		{
-			"ValidSourceAndTargetLinkLayerAddressWithPrefixInformationWithUnrecognized",
-			[]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,
-			},
-			nil,
-		},
-		{
-			"InvalidRecursiveDNSServerCutsOffAddress",
-			[]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,
-			},
-			ErrNDPOptMalformedBody,
-		},
-		{
-			"InvalidRecursiveDNSServerInvalidLengthField",
-			[]byte{
-				25, 2, 0, 0,
-				0, 0, 0, 0,
-				0, 1, 2, 3, 4, 5, 6, 7, 8,
-			},
-			ErrNDPInvalidLength,
-		},
-		{
-			"RecursiveDNSServerTooSmall",
-			[]byte{
-				25, 1, 0, 0,
-				0, 0, 0,
-			},
-			ErrNDPOptBufExhausted,
-		},
-		{
-			"RecursiveDNSServerMulticast",
-			[]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,
-			},
-			ErrNDPOptMalformedBody,
-		},
-		{
-			"RecursiveDNSServerUnspecified",
-			[]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,
-			},
-			ErrNDPOptMalformedBody,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			opts := NDPOptions(test.buf)
-
-			if _, err := opts.Iter(true); err != test.expected {
-				t.Fatalf("got Iter(true) = (_, %v), want = (_, %v)", err, test.expected)
-			}
-
-			// 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.Type(); 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.Type(); 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.Type(); 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/tcp_test.go b/pkg/tcpip/header/tcp_test.go
deleted file mode 100644
index 7256383..0000000
--- a/pkg/tcpip/header/tcp_test.go
+++ /dev/null
@@ -1,148 +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)
-		}
-	}
-}
diff --git a/pkg/tcpip/link/loopback/loopback_state_autogen.go b/pkg/tcpip/link/loopback/loopback_state_autogen.go
new file mode 100755
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/sniffer/sniffer_state_autogen.go b/pkg/tcpip/link/sniffer/sniffer_state_autogen.go
new file mode 100755
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 100755
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 b3e239a..0000000
--- a/pkg/tcpip/network/arp/arp_test.go
+++ /dev/null
@@ -1,145 +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"
-	"strconv"
-	"testing"
-	"time"
-
-	"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 (
-	stackLinkAddr = tcpip.LinkAddress("\x0a\x0a\x0b\x0b\x0c\x0c")
-	stackAddr1    = tcpip.Address("\x0a\x00\x00\x01")
-	stackAddr2    = tcpip.Address("\x0a\x00\x00\x02")
-	stackAddrBad  = tcpip.Address("\x0a\x00\x00\x03")
-)
-
-type testContext struct {
-	t      *testing.T
-	linkEP *channel.Endpoint
-	s      *stack.Stack
-}
-
-func newTestContext(t *testing.T) *testContext {
-	s := stack.New(stack.Options{
-		NetworkProtocols:   []stack.NetworkProtocol{ipv4.NewProtocol(), arp.NewProtocol()},
-		TransportProtocols: []stack.TransportProtocol{icmp.NewProtocol4()},
-	})
-
-	const defaultMTU = 65536
-	ep := channel.New(256, defaultMTU, stackLinkAddr)
-	wep := stack.LinkEndpoint(ep)
-
-	if testing.Verbose() {
-		wep = sniffer.New(ep)
-	}
-	if err := s.CreateNIC(1, wep); err != nil {
-		t.Fatalf("CreateNIC failed: %v", err)
-	}
-
-	if err := s.AddAddress(1, ipv4.ProtocolNumber, stackAddr1); err != nil {
-		t.Fatalf("AddAddress for ipv4 failed: %v", err)
-	}
-	if err := s.AddAddress(1, ipv4.ProtocolNumber, stackAddr2); err != nil {
-		t.Fatalf("AddAddress for ipv4 failed: %v", err)
-	}
-	if err := s.AddAddress(1, arp.ProtocolNumber, arp.ProtocolAddress); err != nil {
-		t.Fatalf("AddAddress for arp failed: %v", err)
-	}
-
-	s.SetRouteTable([]tcpip.Route{{
-		Destination: header.IPv4EmptySubnet,
-		NIC:         1,
-	}})
-
-	return &testContext{
-		t:      t,
-		s:      s,
-		linkEP: ep,
-	}
-}
-
-func (c *testContext) cleanup() {
-	c.linkEP.Close()
-}
-
-func TestDirectRequest(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.ARPRequest)
-	copy(h.HardwareAddressSender(), senderMAC)
-	copy(h.ProtocolAddressSender(), senderIPv4)
-
-	inject := func(addr tcpip.Address) {
-		copy(h.ProtocolAddressTarget(), addr)
-		c.linkEP.InjectInbound(arp.ProtocolNumber, stack.PacketBuffer{
-			Data: v.ToVectorisedView(),
-		})
-	}
-
-	for i, address := range []tcpip.Address{stackAddr1, stackAddr2} {
-		t.Run(strconv.Itoa(i), func(t *testing.T) {
-			inject(address)
-			pi, _ := c.linkEP.ReadContext(context.Background())
-			if pi.Proto != arp.ProtocolNumber {
-				t.Fatalf("expected ARP response, got network protocol number %d", pi.Proto)
-			}
-			rep := header.ARP(pi.Pkt.Header.View())
-			if !rep.IsValid() {
-				t.Fatalf("invalid ARP response pi.Pkt.Header.UsedLength()=%d", pi.Pkt.Header.UsedLength())
-			}
-			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)
-			}
-		})
-	}
-
-	inject(stackAddrBad)
-	// Sleep tests are gross, but this will only potentially flake
-	// if there's a bug. If there is no bug this will reliably
-	// succeed.
-	ctx, _ := context.WithTimeout(context.Background(), 100*time.Millisecond)
-	if pkt, ok := c.linkEP.ReadContext(ctx); ok {
-		t.Errorf("stackAddrBad: unexpected packet sent, Proto=%v", pkt.Proto)
-	}
-}
diff --git a/pkg/tcpip/network/fragmentation/frag_heap_test.go b/pkg/tcpip/network/fragmentation/frag_heap_test.go
deleted file mode 100644
index 9ececcb..0000000
--- a/pkg/tcpip/network/fragmentation/frag_heap_test.go
+++ /dev/null
@@ -1,126 +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 (
-	"container/heap"
-	"reflect"
-	"testing"
-
-	"gvisor.dev/gvisor/pkg/tcpip/buffer"
-)
-
-var reassambleTestCases = []struct {
-	comment string
-	in      []fragment
-	want    buffer.VectorisedView
-}{
-	{
-		comment: "Non-overlapping in-order",
-		in: []fragment{
-			{offset: 0, vv: vv(1, "0")},
-			{offset: 1, vv: vv(1, "1")},
-		},
-		want: vv(2, "0", "1"),
-	},
-	{
-		comment: "Non-overlapping out-of-order",
-		in: []fragment{
-			{offset: 1, vv: vv(1, "1")},
-			{offset: 0, vv: vv(1, "0")},
-		},
-		want: vv(2, "0", "1"),
-	},
-	{
-		comment: "Duplicated packets",
-		in: []fragment{
-			{offset: 0, vv: vv(1, "0")},
-			{offset: 0, vv: vv(1, "0")},
-		},
-		want: vv(1, "0"),
-	},
-	{
-		comment: "Overlapping in-order",
-		in: []fragment{
-			{offset: 0, vv: vv(2, "01")},
-			{offset: 1, vv: vv(2, "12")},
-		},
-		want: vv(3, "01", "2"),
-	},
-	{
-		comment: "Overlapping out-of-order",
-		in: []fragment{
-			{offset: 1, vv: vv(2, "12")},
-			{offset: 0, vv: vv(2, "01")},
-		},
-		want: vv(3, "01", "2"),
-	},
-	{
-		comment: "Overlapping subset in-order",
-		in: []fragment{
-			{offset: 0, vv: vv(3, "012")},
-			{offset: 1, vv: vv(1, "1")},
-		},
-		want: vv(3, "012"),
-	},
-	{
-		comment: "Overlapping subset out-of-order",
-		in: []fragment{
-			{offset: 1, vv: vv(1, "1")},
-			{offset: 0, vv: vv(3, "012")},
-		},
-		want: vv(3, "012"),
-	},
-}
-
-func TestReassamble(t *testing.T) {
-	for _, c := range reassambleTestCases {
-		t.Run(c.comment, func(t *testing.T) {
-			h := make(fragHeap, 0, 8)
-			heap.Init(&h)
-			for _, f := range c.in {
-				heap.Push(&h, f)
-			}
-			got, err := h.reassemble()
-			if err != nil {
-				t.Fatal(err)
-			}
-			if !reflect.DeepEqual(got, c.want) {
-				t.Errorf("got reassemble(%+v) = %v, want = %v", c.in, got, c.want)
-			}
-		})
-	}
-}
-
-func TestReassambleFailsForNonZeroOffset(t *testing.T) {
-	h := make(fragHeap, 0, 8)
-	heap.Init(&h)
-	heap.Push(&h, fragment{offset: 1, vv: vv(1, "0")})
-	_, err := h.reassemble()
-	if err == nil {
-		t.Errorf("reassemble() did not fail when the first packet had offset != 0")
-	}
-}
-
-func TestReassambleFailsForHoles(t *testing.T) {
-	h := make(fragHeap, 0, 8)
-	heap.Init(&h)
-	heap.Push(&h, fragment{offset: 0, vv: vv(1, "0")})
-	heap.Push(&h, fragment{offset: 2, vv: vv(1, "1")})
-	_, err := h.reassemble()
-	if err == nil {
-		t.Errorf("reassemble() did not fail when there was a hole in the packet")
-	}
-}
diff --git a/pkg/tcpip/network/fragmentation/fragmentation_state_autogen.go b/pkg/tcpip/network/fragmentation/fragmentation_state_autogen.go
new file mode 100755
index 0000000..cbaecda
--- /dev/null
+++ b/pkg/tcpip/network/fragmentation/fragmentation_state_autogen.go
@@ -0,0 +1,38 @@
+// automatically generated by stateify.
+
+package fragmentation
+
+import (
+	"gvisor.dev/gvisor/pkg/state"
+)
+
+func (x *reassemblerList) beforeSave() {}
+func (x *reassemblerList) save(m state.Map) {
+	x.beforeSave()
+	m.Save("head", &x.head)
+	m.Save("tail", &x.tail)
+}
+
+func (x *reassemblerList) afterLoad() {}
+func (x *reassemblerList) load(m state.Map) {
+	m.Load("head", &x.head)
+	m.Load("tail", &x.tail)
+}
+
+func (x *reassemblerEntry) beforeSave() {}
+func (x *reassemblerEntry) save(m state.Map) {
+	x.beforeSave()
+	m.Save("next", &x.next)
+	m.Save("prev", &x.prev)
+}
+
+func (x *reassemblerEntry) afterLoad() {}
+func (x *reassemblerEntry) load(m state.Map) {
+	m.Load("next", &x.next)
+	m.Load("prev", &x.prev)
+}
+
+func init() {
+	state.Register("pkg/tcpip/network/fragmentation.reassemblerList", (*reassemblerList)(nil), state.Fns{Save: (*reassemblerList).save, Load: (*reassemblerList).load})
+	state.Register("pkg/tcpip/network/fragmentation.reassemblerEntry", (*reassemblerEntry)(nil), state.Fns{Save: (*reassemblerEntry).save, Load: (*reassemblerEntry).load})
+}
diff --git a/pkg/tcpip/network/fragmentation/fragmentation_test.go b/pkg/tcpip/network/fragmentation/fragmentation_test.go
deleted file mode 100644
index 72c0f53..0000000
--- a/pkg/tcpip/network/fragmentation/fragmentation_test.go
+++ /dev/null
@@ -1,165 +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 (
-	"reflect"
-	"testing"
-	"time"
-
-	"gvisor.dev/gvisor/pkg/tcpip/buffer"
-)
-
-// 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)
-}
-
-type processInput struct {
-	id    uint32
-	first uint16
-	last  uint16
-	more  bool
-	vv    buffer.VectorisedView
-}
-
-type processOutput struct {
-	vv   buffer.VectorisedView
-	done bool
-}
-
-var processTestCases = []struct {
-	comment string
-	in      []processInput
-	out     []processOutput
-}{
-	{
-		comment: "One ID",
-		in: []processInput{
-			{id: 0, first: 0, last: 1, more: true, vv: vv(2, "01")},
-			{id: 0, first: 2, last: 3, more: false, vv: vv(2, "23")},
-		},
-		out: []processOutput{
-			{vv: buffer.VectorisedView{}, done: false},
-			{vv: vv(4, "01", "23"), done: true},
-		},
-	},
-	{
-		comment: "Two IDs",
-		in: []processInput{
-			{id: 0, first: 0, last: 1, more: true, vv: vv(2, "01")},
-			{id: 1, first: 0, last: 1, more: true, vv: vv(2, "ab")},
-			{id: 1, first: 2, last: 3, more: false, vv: vv(2, "cd")},
-			{id: 0, first: 2, last: 3, more: false, vv: vv(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(1024, 512, DefaultReassembleTimeout)
-			for i, in := range c.in {
-				vv, done, err := f.Process(in.id, in.first, in.last, in.more, in.vv)
-				if err != nil {
-					t.Fatalf("f.Process(%+v, %+d, %+d, %t, %+v) failed: %v", in.id, in.first, in.last, in.more, in.vv, err)
-				}
-				if !reflect.DeepEqual(vv, c.out[i].vv) {
-					t.Errorf("got Process(%d) = %+v, want = %+v", i, vv, c.out[i].vv)
-				}
-				if done != c.out[i].done {
-					t.Errorf("got Process(%d) = %+v, want = %+v", i, done, c.out[i].done)
-				}
-				if c.out[i].done {
-					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) {
-	timeout := time.Millisecond
-	f := NewFragmentation(1024, 512, timeout)
-	// Send first fragment with id = 0, first = 0, last = 0, and more = true.
-	f.Process(0, 0, 0, true, vv(1, "0"))
-	// Sleep more than the timeout.
-	time.Sleep(2 * timeout)
-	// Send another fragment that completes a packet.
-	// However, no packet should be reassembled because the fragment arrived after the timeout.
-	_, done, err := f.Process(0, 1, 1, false, vv(1, "1"))
-	if err != nil {
-		t.Fatalf("f.Process(0, 1, 1, false, vv(1, \"1\")) failed: %v", err)
-	}
-	if done {
-		t.Errorf("Fragmentation does not respect the reassembling timeout.")
-	}
-}
-
-func TestMemoryLimits(t *testing.T) {
-	f := NewFragmentation(3, 1, DefaultReassembleTimeout)
-	// Send first fragment with id = 0.
-	f.Process(0, 0, 0, true, vv(1, "0"))
-	// Send first fragment with id = 1.
-	f.Process(1, 0, 0, true, vv(1, "1"))
-	// Send first fragment with id = 2.
-	f.Process(2, 0, 0, true, vv(1, "2"))
-
-	// Send first fragment with id = 3. This should caused id = 0 and id = 1 to be
-	// evicted.
-	f.Process(3, 0, 0, true, vv(1, "3"))
-
-	if _, ok := f.reassemblers[0]; ok {
-		t.Errorf("Memory limits are not respected: id=0 has not been evicted.")
-	}
-	if _, ok := f.reassemblers[1]; ok {
-		t.Errorf("Memory limits are not respected: id=1 has not been evicted.")
-	}
-	if _, ok := f.reassemblers[3]; !ok {
-		t.Errorf("Implementation of memory limits is wrong: id=3 is not present.")
-	}
-}
-
-func TestMemoryLimitsIgnoresDuplicates(t *testing.T) {
-	f := NewFragmentation(1, 0, DefaultReassembleTimeout)
-	// Send first fragment with id = 0.
-	f.Process(0, 0, 0, true, vv(1, "0"))
-	// Send the same packet again.
-	f.Process(0, 0, 0, true, vv(1, "0"))
-
-	got := f.size
-	want := 1
-	if got != want {
-		t.Errorf("Wrong size, duplicates are not handled correctly: got=%d, want=%d.", got, want)
-	}
-}
diff --git a/pkg/tcpip/network/fragmentation/reassembler_list.go b/pkg/tcpip/network/fragmentation/reassembler_list.go
new file mode 100755
index 0000000..a48422c
--- /dev/null
+++ b/pkg/tcpip/network/fragmentation/reassembler_list.go
@@ -0,0 +1,186 @@
+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.
+func (l *reassemblerList) Empty() bool {
+	return l.head == nil
+}
+
+// Front returns the first element of list l or nil.
+func (l *reassemblerList) Front() *reassembler {
+	return l.head
+}
+
+// Back returns the last element of list l or nil.
+func (l *reassemblerList) Back() *reassembler {
+	return l.tail
+}
+
+// PushFront inserts the element e at the front of list l.
+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.
+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.
+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.
+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.
+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.
+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 {
+		l.head = next
+	}
+
+	if next != nil {
+		reassemblerElementMapper{}.linkerFor(next).SetPrev(prev)
+	} else {
+		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.
+func (e *reassemblerEntry) Next() *reassembler {
+	return e.next
+}
+
+// Prev returns the entry that precedes e in the list.
+func (e *reassemblerEntry) Prev() *reassembler {
+	return e.prev
+}
+
+// SetNext assigns 'entry' as the entry that follows e in the list.
+func (e *reassemblerEntry) SetNext(elem *reassembler) {
+	e.next = elem
+}
+
+// SetPrev assigns 'entry' as the entry that precedes e in the list.
+func (e *reassemblerEntry) SetPrev(elem *reassembler) {
+	e.prev = elem
+}
diff --git a/pkg/tcpip/network/fragmentation/reassembler_test.go b/pkg/tcpip/network/fragmentation/reassembler_test.go
deleted file mode 100644
index 7eee071..0000000
--- a/pkg/tcpip/network/fragmentation/reassembler_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 fragmentation
-
-import (
-	"math"
-	"reflect"
-	"testing"
-)
-
-type updateHolesInput struct {
-	first uint16
-	last  uint16
-	more  bool
-}
-
-var holesTestCases = []struct {
-	comment string
-	in      []updateHolesInput
-	want    []hole
-}{
-	{
-		comment: "No fragments. Expected holes: {[0 -> inf]}.",
-		in:      []updateHolesInput{},
-		want:    []hole{{first: 0, last: math.MaxUint16, deleted: false}},
-	},
-	{
-		comment: "One fragment at beginning. Expected holes: {[2, inf]}.",
-		in:      []updateHolesInput{{first: 0, last: 1, more: true}},
-		want: []hole{
-			{first: 0, last: math.MaxUint16, deleted: true},
-			{first: 2, last: math.MaxUint16, deleted: false},
-		},
-	},
-	{
-		comment: "One fragment in the middle. Expected holes: {[0, 0], [3, inf]}.",
-		in:      []updateHolesInput{{first: 1, last: 2, more: true}},
-		want: []hole{
-			{first: 0, last: math.MaxUint16, deleted: true},
-			{first: 0, last: 0, deleted: false},
-			{first: 3, last: math.MaxUint16, deleted: false},
-		},
-	},
-	{
-		comment: "One fragment at the end. Expected holes: {[0, 0]}.",
-		in:      []updateHolesInput{{first: 1, last: 2, more: false}},
-		want: []hole{
-			{first: 0, last: math.MaxUint16, deleted: true},
-			{first: 0, last: 0, deleted: false},
-		},
-	},
-	{
-		comment: "One fragment completing a packet. Expected holes: {}.",
-		in:      []updateHolesInput{{first: 0, last: 1, more: false}},
-		want: []hole{
-			{first: 0, last: math.MaxUint16, deleted: true},
-		},
-	},
-	{
-		comment: "Two non-overlapping fragments completing a packet. Expected holes: {}.",
-		in: []updateHolesInput{
-			{first: 0, last: 1, more: true},
-			{first: 2, last: 3, more: false},
-		},
-		want: []hole{
-			{first: 0, last: math.MaxUint16, deleted: true},
-			{first: 2, last: math.MaxUint16, deleted: true},
-		},
-	},
-	{
-		comment: "Two overlapping fragments completing a packet. Expected holes: {}.",
-		in: []updateHolesInput{
-			{first: 0, last: 2, more: true},
-			{first: 2, last: 3, more: false},
-		},
-		want: []hole{
-			{first: 0, last: math.MaxUint16, deleted: true},
-			{first: 3, last: math.MaxUint16, deleted: true},
-		},
-	},
-}
-
-func TestUpdateHoles(t *testing.T) {
-	for _, c := range holesTestCases {
-		r := newReassembler(0)
-		for _, i := range c.in {
-			r.updateHoles(i.first, i.last, i.more)
-		}
-		if !reflect.DeepEqual(r.holes, c.want) {
-			t.Errorf("Test \"%s\" produced unexepetced holes. Got %v. Want %v", c.comment, r.holes, c.want)
-		}
-	}
-}
diff --git a/pkg/tcpip/network/hash/hash_state_autogen.go b/pkg/tcpip/network/hash/hash_state_autogen.go
new file mode 100755
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/ipv4/ipv4_state_autogen.go b/pkg/tcpip/network/ipv4/ipv4_state_autogen.go
new file mode 100755
index 0000000..250b212
--- /dev/null
+++ b/pkg/tcpip/network/ipv4/ipv4_state_autogen.go
@@ -0,0 +1,3 @@
+// automatically generated by stateify.
+
+package ipv4
diff --git a/pkg/tcpip/network/ipv4/ipv4_test.go b/pkg/tcpip/network/ipv4/ipv4_test.go
deleted file mode 100644
index 5a864d8..0000000
--- a/pkg/tcpip/network/ipv4/ipv4_test.go
+++ /dev/null
@@ -1,475 +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 ipv4_test
-
-import (
-	"bytes"
-	"encoding/hex"
-	"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/link/sniffer"
-	"gvisor.dev/gvisor/pkg/tcpip/network/ipv4"
-	"gvisor.dev/gvisor/pkg/tcpip/stack"
-	"gvisor.dev/gvisor/pkg/tcpip/transport/tcp"
-	"gvisor.dev/gvisor/pkg/tcpip/transport/udp"
-	"gvisor.dev/gvisor/pkg/waiter"
-)
-
-func TestExcludeBroadcast(t *testing.T) {
-	s := stack.New(stack.Options{
-		NetworkProtocols:   []stack.NetworkProtocol{ipv4.NewProtocol()},
-		TransportProtocols: []stack.TransportProtocol{udp.NewProtocol()},
-	})
-
-	const defaultMTU = 65536
-	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.
-		if err := ep.Connect(randomAddr); err != tcpip.ErrNoRoute {
-			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)
-		}
-	})
-}
-
-// makeHdrAndPayload generates a randomize packet. hdrLength indicates how much
-// data should already be in the header before WritePacket. extraLength
-// indicates how much extra space should be in the header. The payload is made
-// from many Views of the sizes listed in viewSizes.
-func makeHdrAndPayload(hdrLength int, extraLength int, viewSizes []int) (buffer.Prependable, buffer.VectorisedView) {
-	hdr := buffer.NewPrependable(hdrLength + extraLength)
-	hdr.Prepend(hdrLength)
-	rand.Read(hdr.View())
-
-	var views []buffer.View
-	totalLength := 0
-	for _, s := range viewSizes {
-		newView := buffer.NewView(s)
-		rand.Read(newView)
-		views = append(views, newView)
-		totalLength += s
-	}
-	payload := buffer.NewVectorisedView(totalLength, views)
-	return hdr, payload
-}
-
-// comparePayloads compared the contents of all the packets against the contents
-// of the source packet.
-func compareFragments(t *testing.T, packets []stack.PacketBuffer, sourcePacketInfo stack.PacketBuffer, mtu uint32) {
-	t.Helper()
-	// Make a complete array of the sourcePacketInfo packet.
-	source := header.IPv4(packets[0].Header.View()[:header.IPv4MinimumSize])
-	source = append(source, sourcePacketInfo.Header.View()...)
-	source = append(source, sourcePacketInfo.Data.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)
-	var offset uint16
-	// Build up an array of the bytes sent.
-	var reassembledPayload []byte
-	for i, packet := range packets {
-		// Confirm that the packet is valid.
-		allBytes := packet.Header.View().ToVectorisedView()
-		allBytes.Append(packet.Data)
-		ip := header.IPv4(allBytes.ToView())
-		if !ip.IsValid(len(ip)) {
-			t.Errorf("IP packet is invalid:\n%s", hex.Dump(ip))
-		}
-		if got, want := ip.CalculateChecksum(), uint16(0xffff); got != want {
-			t.Errorf("ip.CalculateChecksum() got %#x, want %#x", got, want)
-		}
-		if got, want := len(ip), int(mtu); got > want {
-			t.Errorf("fragment is too large, got %d want %d", got, want)
-		}
-		if got, want := packet.Header.UsedLength(), sourcePacketInfo.Header.UsedLength()+header.IPv4MinimumSize; i == 0 && want < int(mtu) && got != want {
-			t.Errorf("first fragment hdr parts should have unmodified length if possible: got %d, want %d", got, want)
-		}
-		if got, want := packet.Header.AvailableLength(), sourcePacketInfo.Header.AvailableLength()-header.IPv4MinimumSize; got != want {
-			t.Errorf("fragment #%d should have the same available space for prepending as source: got %d, want %d", i, got, want)
-		}
-		if i < len(packets)-1 {
-			sourceCopy.SetFlagsFragmentOffset(sourceCopy.Flags()|header.IPv4FlagMoreFragments, offset)
-		} else {
-			sourceCopy.SetFlagsFragmentOffset(sourceCopy.Flags()&^header.IPv4FlagMoreFragments, offset)
-		}
-		reassembledPayload = append(reassembledPayload, ip.Payload()...)
-		offset += ip.TotalLength() - uint16(ip.HeaderLength())
-		// Clear out the checksum and length from the ip because we can't compare
-		// it.
-		sourceCopy.SetTotalLength(uint16(len(ip)))
-		sourceCopy.SetChecksum(0)
-		sourceCopy.SetChecksum(^sourceCopy.CalculateChecksum())
-		if !bytes.Equal(ip[:ip.HeaderLength()], sourceCopy[:sourceCopy.HeaderLength()]) {
-			t.Errorf("ip[:ip.HeaderLength()] got:\n%s\nwant:\n%s", hex.Dump(ip[:ip.HeaderLength()]), hex.Dump(sourceCopy[:sourceCopy.HeaderLength()]))
-		}
-	}
-	expected := source[source.HeaderLength():]
-	if !bytes.Equal(reassembledPayload, expected) {
-		t.Errorf("reassembledPayload got:\n%s\nwant:\n%s", hex.Dump(reassembledPayload), hex.Dump(expected))
-	}
-}
-
-type errorChannel struct {
-	*channel.Endpoint
-	Ch                    chan stack.PacketBuffer
-	packetCollectorErrors []*tcpip.Error
-}
-
-// newErrorChannel creates a new errorChannel endpoint. Each call to WritePacket
-// will return successive errors from packetCollectorErrors until the list is
-// empty and then return nil each time.
-func newErrorChannel(size int, mtu uint32, linkAddr tcpip.LinkAddress, packetCollectorErrors []*tcpip.Error) *errorChannel {
-	return &errorChannel{
-		Endpoint:              channel.New(size, mtu, linkAddr),
-		Ch:                    make(chan stack.PacketBuffer, size),
-		packetCollectorErrors: packetCollectorErrors,
-	}
-}
-
-// Drain removes all outbound packets from the channel and counts them.
-func (e *errorChannel) Drain() int {
-	c := 0
-	for {
-		select {
-		case <-e.Ch:
-			c++
-		default:
-			return c
-		}
-	}
-}
-
-// WritePacket stores outbound packets into the channel.
-func (e *errorChannel) WritePacket(r *stack.Route, gso *stack.GSO, protocol tcpip.NetworkProtocolNumber, pkt stack.PacketBuffer) *tcpip.Error {
-	select {
-	case e.Ch <- pkt:
-	default:
-	}
-
-	nextError := (*tcpip.Error)(nil)
-	if len(e.packetCollectorErrors) > 0 {
-		nextError = e.packetCollectorErrors[0]
-		e.packetCollectorErrors = e.packetCollectorErrors[1:]
-	}
-	return nextError
-}
-
-type context struct {
-	stack.Route
-	linkEP *errorChannel
-}
-
-func buildContext(t *testing.T, packetCollectorErrors []*tcpip.Error, mtu uint32) context {
-	// Make the packet and write it.
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocol{ipv4.NewProtocol()},
-	})
-	ep := newErrorChannel(100 /* Enough for all tests. */, mtu, "", packetCollectorErrors)
-	s.CreateNIC(1, ep)
-	const (
-		src = "\x10\x00\x00\x01"
-		dst = "\x10\x00\x00\x02"
-	)
-	s.AddAddress(1, ipv4.ProtocolNumber, src)
-	{
-		subnet, err := tcpip.NewSubnet(dst, tcpip.AddressMask(header.IPv4Broadcast))
-		if err != nil {
-			t.Fatal(err)
-		}
-		s.SetRouteTable([]tcpip.Route{{
-			Destination: subnet,
-			NIC:         1,
-		}})
-	}
-	r, err := s.FindRoute(0, src, dst, ipv4.ProtocolNumber, false /* multicastLoop */)
-	if err != nil {
-		t.Fatalf("s.FindRoute got %v, want %v", err, nil)
-	}
-	return context{
-		Route:  r,
-		linkEP: ep,
-	}
-}
-
-func TestFragmentation(t *testing.T) {
-	var manyPayloadViewsSizes [1000]int
-	for i := range manyPayloadViewsSizes {
-		manyPayloadViewsSizes[i] = 7
-	}
-	fragTests := []struct {
-		description       string
-		mtu               uint32
-		gso               *stack.GSO
-		hdrLength         int
-		extraLength       int
-		payloadViewsSizes []int
-		expectedFrags     int
-	}{
-		{"NoFragmentation", 2000, &stack.GSO{}, 0, header.IPv4MinimumSize, []int{1000}, 1},
-		{"NoFragmentationWithBigHeader", 2000, &stack.GSO{}, 16, header.IPv4MinimumSize, []int{1000}, 1},
-		{"Fragmented", 800, &stack.GSO{}, 0, header.IPv4MinimumSize, []int{1000}, 2},
-		{"FragmentedWithGsoNil", 800, nil, 0, header.IPv4MinimumSize, []int{1000}, 2},
-		{"FragmentedWithManyViews", 300, &stack.GSO{}, 0, header.IPv4MinimumSize, manyPayloadViewsSizes[:], 25},
-		{"FragmentedWithManyViewsAndPrependableBytes", 300, &stack.GSO{}, 0, header.IPv4MinimumSize + 55, manyPayloadViewsSizes[:], 25},
-		{"FragmentedWithBigHeader", 800, &stack.GSO{}, 20, header.IPv4MinimumSize, []int{1000}, 2},
-		{"FragmentedWithBigHeaderAndPrependableBytes", 800, &stack.GSO{}, 20, header.IPv4MinimumSize + 66, []int{1000}, 2},
-		{"FragmentedWithMTUSmallerThanHeaderAndPrependableBytes", 300, &stack.GSO{}, 1000, header.IPv4MinimumSize + 77, []int{500}, 6},
-	}
-
-	for _, ft := range fragTests {
-		t.Run(ft.description, func(t *testing.T) {
-			hdr, payload := makeHdrAndPayload(ft.hdrLength, ft.extraLength, ft.payloadViewsSizes)
-			source := stack.PacketBuffer{
-				Header: hdr,
-				// Save the source payload because WritePacket will modify it.
-				Data: payload.Clone(nil),
-			}
-			c := buildContext(t, nil, ft.mtu)
-			err := c.Route.WritePacket(ft.gso, stack.NetworkHeaderParams{Protocol: tcp.ProtocolNumber, TTL: 42, TOS: stack.DefaultTOS}, stack.PacketBuffer{
-				Header: hdr,
-				Data:   payload,
-			})
-			if err != nil {
-				t.Errorf("err got %v, want %v", err, nil)
-			}
-
-			var results []stack.PacketBuffer
-		L:
-			for {
-				select {
-				case pi := <-c.linkEP.Ch:
-					results = append(results, pi)
-				default:
-					break L
-				}
-			}
-
-			if got, want := len(results), ft.expectedFrags; got != want {
-				t.Errorf("len(result) got %d, want %d", got, want)
-			}
-			if got, want := len(results), int(c.Route.Stats().IP.PacketsSent.Value()); got != want {
-				t.Errorf("no errors yet len(result) got %d, want %d", got, want)
-			}
-			compareFragments(t, results, source, ft.mtu)
-		})
-	}
-}
-
-// TestFragmentationErrors checks that errors are returned from write packet
-// correctly.
-func TestFragmentationErrors(t *testing.T) {
-	fragTests := []struct {
-		description           string
-		mtu                   uint32
-		hdrLength             int
-		payloadViewsSizes     []int
-		packetCollectorErrors []*tcpip.Error
-	}{
-		{"NoFrag", 2000, 0, []int{1000}, []*tcpip.Error{tcpip.ErrAborted}},
-		{"ErrorOnFirstFrag", 500, 0, []int{1000}, []*tcpip.Error{tcpip.ErrAborted}},
-		{"ErrorOnSecondFrag", 500, 0, []int{1000}, []*tcpip.Error{nil, tcpip.ErrAborted}},
-		{"ErrorOnFirstFragMTUSmallerThanHdr", 500, 1000, []int{500}, []*tcpip.Error{tcpip.ErrAborted}},
-	}
-
-	for _, ft := range fragTests {
-		t.Run(ft.description, func(t *testing.T) {
-			hdr, payload := makeHdrAndPayload(ft.hdrLength, header.IPv4MinimumSize, ft.payloadViewsSizes)
-			c := buildContext(t, ft.packetCollectorErrors, ft.mtu)
-			err := c.Route.WritePacket(&stack.GSO{}, stack.NetworkHeaderParams{Protocol: tcp.ProtocolNumber, TTL: 42, TOS: stack.DefaultTOS}, stack.PacketBuffer{
-				Header: hdr,
-				Data:   payload,
-			})
-			for i := 0; i < len(ft.packetCollectorErrors)-1; i++ {
-				if got, want := ft.packetCollectorErrors[i], (*tcpip.Error)(nil); got != want {
-					t.Errorf("ft.packetCollectorErrors[%d] got %v, want %v", i, got, want)
-				}
-			}
-			// We only need to check that last error because all the ones before are
-			// nil.
-			if got, want := err, ft.packetCollectorErrors[len(ft.packetCollectorErrors)-1]; got != want {
-				t.Errorf("err got %v, want %v", got, want)
-			}
-			if got, want := c.linkEP.Drain(), int(c.Route.Stats().IP.PacketsSent.Value())+1; err != nil && got != want {
-				t.Errorf("after linkEP error len(result) got %d, want %d", got, want)
-			}
-		})
-	}
-}
-
-func TestInvalidFragments(t *testing.T) {
-	// These packets have both IHL and TotalLength set to 0.
-	testCases := []struct {
-		name                   string
-		packets                [][]byte
-		wantMalformedIPPackets uint64
-		wantMalformedFragments uint64
-	}{
-		{
-			"ihl_totallen_zero_valid_frag_offset",
-			[][]byte{
-				{0x40, 0x30, 0x00, 0x00, 0x6c, 0x74, 0x7d, 0x30, 0x30, 0x30, 0x30, 0x30, 0x39, 0x32, 0x39, 0x33, 0xff, 0xff, 0xff, 0xff, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30},
-			},
-			1,
-			0,
-		},
-		{
-			"ihl_totallen_zero_invalid_frag_offset",
-			[][]byte{
-				{0x40, 0x30, 0x00, 0x00, 0x6c, 0x74, 0x20, 0x00, 0x30, 0x30, 0x30, 0x30, 0x39, 0x32, 0x39, 0x33, 0xff, 0xff, 0xff, 0xff, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30},
-			},
-			1,
-			0,
-		},
-		{
-			// Total Length of 37(20 bytes IP header + 17 bytes of
-			// payload)
-			// Frag Offset of 0x1ffe = 8190*8 = 65520
-			// Leading to the fragment end to be past 65535.
-			"ihl_totallen_valid_invalid_frag_offset_1",
-			[][]byte{
-				{0x45, 0x30, 0x00, 0x25, 0x6c, 0x74, 0x1f, 0xfe, 0x30, 0x30, 0x30, 0x30, 0x39, 0x32, 0x39, 0x33, 0xff, 0xff, 0xff, 0xff, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30},
-			},
-			1,
-			1,
-		},
-		// The following 3 tests were found by running a fuzzer and were
-		// triggering a panic in the IPv4 reassembler code.
-		{
-			"ihl_less_than_ipv4_minimum_size_1",
-			[][]byte{
-				{0x42, 0x30, 0x0, 0x30, 0x30, 0x40, 0x0, 0xf3, 0x30, 0x1, 0x30, 0x30, 0x73, 0x73, 0x69, 0x6e, 0xff, 0xff, 0xff, 0xff, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30},
-				{0x42, 0x30, 0x0, 0x8, 0x30, 0x40, 0x20, 0x0, 0x30, 0x1, 0x30, 0x30, 0x73, 0x73, 0x69, 0x6e, 0xff, 0xff, 0xff, 0xff, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30},
-			},
-			2,
-			0,
-		},
-		{
-			"ihl_less_than_ipv4_minimum_size_2",
-			[][]byte{
-				{0x42, 0x30, 0x0, 0x30, 0x30, 0x40, 0xb3, 0x12, 0x30, 0x6, 0x30, 0x30, 0x73, 0x73, 0x69, 0x6e, 0xff, 0xff, 0xff, 0xff, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30},
-				{0x42, 0x30, 0x0, 0x8, 0x30, 0x40, 0x20, 0x0, 0x30, 0x6, 0x30, 0x30, 0x73, 0x73, 0x69, 0x6e, 0xff, 0xff, 0xff, 0xff, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30},
-			},
-			2,
-			0,
-		},
-		{
-			"ihl_less_than_ipv4_minimum_size_3",
-			[][]byte{
-				{0x42, 0x30, 0x0, 0x30, 0x30, 0x40, 0xb3, 0x30, 0x30, 0x6, 0x30, 0x30, 0x73, 0x73, 0x69, 0x6e, 0xff, 0xff, 0xff, 0xff, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30},
-				{0x42, 0x30, 0x0, 0x8, 0x30, 0x40, 0x20, 0x0, 0x30, 0x6, 0x30, 0x30, 0x73, 0x73, 0x69, 0x6e, 0xff, 0xff, 0xff, 0xff, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30},
-			},
-			2,
-			0,
-		},
-		{
-			"fragment_with_short_total_len_extra_payload",
-			[][]byte{
-				{0x46, 0x30, 0x00, 0x30, 0x30, 0x40, 0x0e, 0x12, 0x30, 0x06, 0x30, 0x30, 0x73, 0x73, 0x69, 0x6e, 0xff, 0xff, 0xff, 0xff, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30},
-				{0x46, 0x30, 0x00, 0x18, 0x30, 0x40, 0x20, 0x00, 0x30, 0x06, 0x30, 0x30, 0x73, 0x73, 0x69, 0x6e, 0xff, 0xff, 0xff, 0xff, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30},
-			},
-			1,
-			1,
-		},
-		{
-			"multiple_fragments_with_more_fragments_set_to_false",
-			[][]byte{
-				{0x45, 0x00, 0x00, 0x1c, 0x30, 0x40, 0x00, 0x10, 0x00, 0x06, 0x34, 0x69, 0x73, 0x73, 0x69, 0x6e, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
-				{0x45, 0x00, 0x00, 0x1c, 0x30, 0x40, 0x00, 0x01, 0x61, 0x06, 0x34, 0x69, 0x73, 0x73, 0x69, 0x6e, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
-				{0x45, 0x00, 0x00, 0x1c, 0x30, 0x40, 0x20, 0x00, 0x00, 0x06, 0x34, 0x1e, 0x73, 0x73, 0x69, 0x6e, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
-			},
-			1,
-			1,
-		},
-	}
-
-	for _, tc := range testCases {
-		t.Run(tc.name, func(t *testing.T) {
-			const nicID tcpip.NICID = 42
-			s := stack.New(stack.Options{
-				NetworkProtocols: []stack.NetworkProtocol{
-					ipv4.NewProtocol(),
-				},
-			})
-
-			var linkAddr = tcpip.LinkAddress([]byte{0x30, 0x30, 0x30, 0x30, 0x30, 0x30})
-			var remoteLinkAddr = tcpip.LinkAddress([]byte{0x30, 0x30, 0x30, 0x30, 0x30, 0x31})
-			ep := channel.New(10, 1500, linkAddr)
-			s.CreateNIC(nicID, sniffer.New(ep))
-
-			for _, pkt := range tc.packets {
-				ep.InjectLinkAddr(header.IPv4ProtocolNumber, remoteLinkAddr, stack.PacketBuffer{
-					Data: buffer.NewVectorisedView(len(pkt), []buffer.View{pkt}),
-				})
-			}
-
-			if got, want := s.Stats().IP.MalformedPacketsReceived.Value(), tc.wantMalformedIPPackets; got != want {
-				t.Errorf("incorrect Stats.IP.MalformedPacketsReceived, got: %d, want: %d", got, want)
-			}
-			if got, want := s.Stats().IP.MalformedFragmentsReceived.Value(), tc.wantMalformedFragments; got != want {
-				t.Errorf("incorrect Stats.IP.MalformedFragmentsReceived, got: %d, want: %d", got, want)
-			}
-		})
-	}
-}
diff --git a/pkg/tcpip/network/ipv6/icmp_test.go b/pkg/tcpip/network/ipv6/icmp_test.go
deleted file mode 100644
index bae09ed..0000000
--- a/pkg/tcpip/network/ipv6/icmp_test.go
+++ /dev/null
@@ -1,958 +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 (
-	"context"
-	"reflect"
-	"strings"
-	"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/sniffer"
-	"gvisor.dev/gvisor/pkg/tcpip/stack"
-	"gvisor.dev/gvisor/pkg/tcpip/transport/icmp"
-	"gvisor.dev/gvisor/pkg/waiter"
-)
-
-const (
-	linkAddr0 = tcpip.LinkAddress("\x02\x02\x03\x04\x05\x06")
-	linkAddr1 = tcpip.LinkAddress("\x0a\x0b\x0c\x0d\x0e\x0f")
-)
-
-var (
-	lladdr0 = header.LinkLocalAddr(linkAddr0)
-	lladdr1 = header.LinkLocalAddr(linkAddr1)
-)
-
-type stubLinkEndpoint struct {
-	stack.LinkEndpoint
-}
-
-func (*stubLinkEndpoint) Capabilities() stack.LinkEndpointCapabilities {
-	return 0
-}
-
-func (*stubLinkEndpoint) MaxHeaderLength() uint16 {
-	return 0
-}
-
-func (*stubLinkEndpoint) LinkAddress() tcpip.LinkAddress {
-	return ""
-}
-
-func (*stubLinkEndpoint) WritePacket(*stack.Route, *stack.GSO, tcpip.NetworkProtocolNumber, stack.PacketBuffer) *tcpip.Error {
-	return nil
-}
-
-func (*stubLinkEndpoint) Attach(stack.NetworkDispatcher) {}
-
-type stubDispatcher struct {
-	stack.TransportDispatcher
-}
-
-func (*stubDispatcher) DeliverTransportPacket(*stack.Route, tcpip.TransportProtocolNumber, stack.PacketBuffer) {
-}
-
-type stubLinkAddressCache struct {
-	stack.LinkAddressCache
-}
-
-func (*stubLinkAddressCache) CheckLocalAddress(tcpip.NICID, tcpip.NetworkProtocolNumber, tcpip.Address) tcpip.NICID {
-	return 0
-}
-
-func (*stubLinkAddressCache) AddLinkAddress(tcpip.NICID, tcpip.Address, tcpip.LinkAddress) {
-}
-
-func TestICMPCounts(t *testing.T) {
-	s := stack.New(stack.Options{
-		NetworkProtocols:   []stack.NetworkProtocol{NewProtocol()},
-		TransportProtocols: []stack.TransportProtocol{icmp.NewProtocol6()},
-	})
-	{
-		if err := s.CreateNIC(1, &stubLinkEndpoint{}); err != nil {
-			t.Fatalf("CreateNIC(_) = %s", err)
-		}
-		if err := s.AddAddress(1, 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:         1,
-			}},
-		)
-	}
-
-	netProto := s.NetworkProtocolInstance(ProtocolNumber)
-	if netProto == nil {
-		t.Fatalf("cannot find protocol instance for network protocol %d", ProtocolNumber)
-	}
-	ep, err := netProto.NewEndpoint(0, tcpip.AddressWithPrefix{lladdr1, netProto.DefaultPrefixLen()}, &stubLinkAddressCache{}, &stubDispatcher{}, nil, s)
-	if err != nil {
-		t.Fatalf("NewEndpoint(_) = _, %s, want = _, nil", err)
-	}
-
-	r, err := s.FindRoute(1, lladdr0, lladdr1, ProtocolNumber, false /* multicastLoop */)
-	if err != nil {
-		t.Fatalf("FindRoute(_) = _, %s, want = _, nil", err)
-	}
-	defer r.Release()
-
-	var tllData [header.NDPLinkLayerAddressSize]byte
-	header.NDPOptions(tllData[:]).Serialize(header.NDPOptionsSerializer{
-		header.NDPTargetLinkLayerAddressOption(linkAddr1),
-	})
-
-	types := []struct {
-		typ       header.ICMPv6Type
-		size      int
-		extraData []byte
-	}{
-		{
-			typ:  header.ICMPv6DstUnreachable,
-			size: header.ICMPv6DstUnreachableMinimumSize,
-		},
-		{
-			typ:  header.ICMPv6PacketTooBig,
-			size: header.ICMPv6PacketTooBigMinimumSize,
-		},
-		{
-			typ:  header.ICMPv6TimeExceeded,
-			size: header.ICMPv6MinimumSize,
-		},
-		{
-			typ:  header.ICMPv6ParamProblem,
-			size: header.ICMPv6MinimumSize,
-		},
-		{
-			typ:  header.ICMPv6EchoRequest,
-			size: header.ICMPv6EchoMinimumSize,
-		},
-		{
-			typ:  header.ICMPv6EchoReply,
-			size: header.ICMPv6EchoMinimumSize,
-		},
-		{
-			typ:  header.ICMPv6RouterSolicit,
-			size: header.ICMPv6MinimumSize,
-		},
-		{
-			typ:  header.ICMPv6RouterAdvert,
-			size: header.ICMPv6HeaderSize + header.NDPRAMinimumSize,
-		},
-		{
-			typ:  header.ICMPv6NeighborSolicit,
-			size: header.ICMPv6NeighborSolicitMinimumSize},
-		{
-			typ:       header.ICMPv6NeighborAdvert,
-			size:      header.ICMPv6NeighborAdvertMinimumSize,
-			extraData: tllData[:],
-		},
-		{
-			typ:  header.ICMPv6RedirectMsg,
-			size: header.ICMPv6MinimumSize,
-		},
-	}
-
-	handleIPv6Payload := func(hdr buffer.Prependable) {
-		payloadLength := hdr.UsedLength()
-		ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize))
-		ip.Encode(&header.IPv6Fields{
-			PayloadLength: uint16(payloadLength),
-			NextHeader:    uint8(header.ICMPv6ProtocolNumber),
-			HopLimit:      header.NDPHopLimit,
-			SrcAddr:       r.LocalAddress,
-			DstAddr:       r.RemoteAddress,
-		})
-		ep.HandlePacket(&r, stack.PacketBuffer{
-			Data: hdr.View().ToVectorisedView(),
-		})
-	}
-
-	for _, typ := range types {
-		extraDataLen := len(typ.extraData)
-		hdr := buffer.NewPrependable(header.IPv6MinimumSize + typ.size + extraDataLen)
-		extraData := buffer.View(hdr.Prepend(extraDataLen))
-		copy(extraData, typ.extraData)
-		pkt := header.ICMPv6(hdr.Prepend(typ.size))
-		pkt.SetType(typ.typ)
-		pkt.SetChecksum(header.ICMPv6Checksum(pkt, r.LocalAddress, r.RemoteAddress, extraData.ToVectorisedView()))
-
-		handleIPv6Payload(hdr)
-	}
-
-	// Construct an empty ICMP packet so that
-	// Stats().ICMP.ICMPv6ReceivedPacketStats.Invalid is incremented.
-	handleIPv6Payload(buffer.NewPrependable(header.IPv6MinimumSize))
-
-	icmpv6Stats := s.Stats().ICMP.V6PacketsReceived
-	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.NetworkProtocol{NewProtocol()},
-			TransportProtocols: []stack.TransportProtocol{icmp.NewProtocol6()},
-		}),
-		s1: stack.New(stack.Options{
-			NetworkProtocols:   []stack.NetworkProtocol{NewProtocol()},
-			TransportProtocols: []stack.TransportProtocol{icmp.NewProtocol6()},
-		}),
-	}
-
-	const defaultMTU = 65536
-	c.linkEP0 = channel.New(256, defaultMTU, linkAddr0)
-
-	wrappedEP0 := stack.LinkEndpoint(endpointWithResolutionCapability{LinkEndpoint: c.linkEP0})
-	if testing.Verbose() {
-		wrappedEP0 = sniffer.New(wrappedEP0)
-	}
-	if err := c.s0.CreateNIC(1, wrappedEP0); err != nil {
-		t.Fatalf("CreateNIC s0: %v", err)
-	}
-	if err := c.s0.AddAddress(1, ProtocolNumber, lladdr0); err != nil {
-		t.Fatalf("AddAddress lladdr0: %v", err)
-	}
-
-	c.linkEP1 = channel.New(256, defaultMTU, linkAddr1)
-	wrappedEP1 := stack.LinkEndpoint(endpointWithResolutionCapability{LinkEndpoint: c.linkEP1})
-	if err := c.s1.CreateNIC(1, wrappedEP1); err != nil {
-		t.Fatalf("CreateNIC failed: %v", err)
-	}
-	if err := c.s1.AddAddress(1, 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:         1,
-		}},
-	)
-	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:         1,
-		}},
-	)
-
-	return c
-}
-
-func (c *testContext) cleanup() {
-	c.linkEP0.Close()
-	c.linkEP1.Close()
-}
-
-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())
-
-	{
-		views := []buffer.View{pi.Pkt.Header.View(), pi.Pkt.Data.ToView()}
-		size := pi.Pkt.Header.UsedLength() + pi.Pkt.Data.Size()
-		vv := buffer.NewVectorisedView(size, views)
-		args.dst.InjectLinkAddr(pi.Proto, args.dst.LinkAddress(), stack.PacketBuffer{
-			Data: vv,
-		})
-	}
-
-	if pi.Proto != ProtocolNumber {
-		t.Errorf("unexpected protocol number %d", pi.Proto)
-		return
-	}
-
-	if len(args.remoteLinkAddr) != 0 && args.remoteLinkAddr != pi.Route.RemoteLinkAddress {
-		t.Errorf("got remote link address = %s, want = %s", pi.Route.RemoteLinkAddress, args.remoteLinkAddr)
-	}
-
-	ipv6 := header.IPv6(pi.Pkt.Header.View())
-	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)
-	defer c.cleanup()
-
-	r, err := c.s0.FindRoute(1, lladdr0, lladdr1, ProtocolNumber, false /* multicastLoop */)
-	if err != nil {
-		t.Fatalf("FindRoute(_) = _, %s, want = _, nil", 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(pkt, r.LocalAddress, r.RemoteAddress, buffer.VectorisedView{}))
-	payload := tcpip.SlicePayload(hdr.View())
-
-	// 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)
-	}
-
-	for {
-		_, resCh, err := ep.Write(payload, tcpip.WriteOptions{To: &tcpip.FullAddress{NIC: 1, Addr: lladdr1}})
-		if resCh != nil {
-			if err != tcpip.ErrNoLinkAddress {
-				t.Fatalf("ep.Write(_) = _, <non-nil>, %s, want = _, <non-nil>, tcpip.ErrNoLinkAddress", 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)
-					}
-				})
-			}
-			<-resCh
-			continue
-		}
-		if err != nil {
-			t.Fatalf("ep.Write(_) = _, _, %s", err)
-		}
-		break
-	}
-
-	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
-	}{
-		{
-			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
-			},
-		},
-		{
-			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 {
-		t.Run(typ.name, func(t *testing.T) {
-			e := channel.New(10, 1280, linkAddr0)
-			s := stack.New(stack.Options{
-				NetworkProtocols: []stack.NetworkProtocol{NewProtocol()},
-			})
-			if err := s.CreateNIC(1, e); err != nil {
-				t.Fatalf("CreateNIC(_) = %s", err)
-			}
-
-			if err := s.AddAddress(1, 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:         1,
-					}},
-				)
-			}
-
-			handleIPv6Payload := func(checksum bool) {
-				extraDataLen := len(typ.extraData)
-				hdr := buffer.NewPrependable(header.IPv6MinimumSize + typ.size + extraDataLen)
-				extraData := buffer.View(hdr.Prepend(extraDataLen))
-				copy(extraData, typ.extraData)
-				pkt := header.ICMPv6(hdr.Prepend(typ.size))
-				pkt.SetType(typ.typ)
-				if checksum {
-					pkt.SetChecksum(header.ICMPv6Checksum(pkt, lladdr1, lladdr0, extraData.ToVectorisedView()))
-				}
-				ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize))
-				ip.Encode(&header.IPv6Fields{
-					PayloadLength: uint16(typ.size + extraDataLen),
-					NextHeader:    uint8(header.ICMPv6ProtocolNumber),
-					HopLimit:      header.NDPHopLimit,
-					SrcAddr:       lladdr1,
-					DstAddr:       lladdr0,
-				})
-				e.InjectInbound(ProtocolNumber, stack.PacketBuffer{
-					Data: hdr.View().ToVectorisedView(),
-				})
-			}
-
-			stats := s.Stats().ICMP.V6PacketsReceived
-			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 %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)
-			}
-			// 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)
-			}
-		})
-	}
-}
-
-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,
-			NextHeader:    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.NetworkProtocol{NewProtocol()},
-			})
-			if err := s.CreateNIC(1, e); err != nil {
-				t.Fatalf("CreateNIC(_) = %s", err)
-			}
-
-			if err := s.AddAddress(1, 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:         1,
-					}},
-				)
-			}
-
-			handleIPv6Payload := func(typ header.ICMPv6Type, size, payloadSize int, payloadFn func(buffer.View), checksum bool) {
-				icmpSize := size + payloadSize
-				hdr := buffer.NewPrependable(header.IPv6MinimumSize + icmpSize)
-				pkt := header.ICMPv6(hdr.Prepend(icmpSize))
-				pkt.SetType(typ)
-				payloadFn(pkt.Payload())
-
-				if checksum {
-					pkt.SetChecksum(header.ICMPv6Checksum(pkt, lladdr1, lladdr0, buffer.VectorisedView{}))
-				}
-
-				ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize))
-				ip.Encode(&header.IPv6Fields{
-					PayloadLength: uint16(icmpSize),
-					NextHeader:    uint8(header.ICMPv6ProtocolNumber),
-					HopLimit:      header.NDPHopLimit,
-					SrcAddr:       lladdr1,
-					DstAddr:       lladdr0,
-				})
-				e.InjectInbound(ProtocolNumber, stack.PacketBuffer{
-					Data: hdr.View().ToVectorisedView(),
-				})
-			}
-
-			stats := s.Stats().ICMP.V6PacketsReceived
-			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 %s = %d, want = 0", typ.name, 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 %s = %d, want = 0", typ.name, 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 %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)
-			}
-		})
-	}
-}
-
-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,
-			NextHeader:    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.NetworkProtocol{NewProtocol()},
-			})
-			if err := s.CreateNIC(1, e); err != nil {
-				t.Fatalf("CreateNIC(_) = %s", err)
-			}
-
-			if err := s.AddAddress(1, 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:         1,
-					}},
-				)
-			}
-
-			handleIPv6Payload := func(typ header.ICMPv6Type, size, payloadSize int, payloadFn func(buffer.View), checksum bool) {
-				hdr := buffer.NewPrependable(header.IPv6MinimumSize + size)
-				pkt := header.ICMPv6(hdr.Prepend(size))
-				pkt.SetType(typ)
-
-				payload := buffer.NewView(payloadSize)
-				payloadFn(payload)
-
-				if checksum {
-					pkt.SetChecksum(header.ICMPv6Checksum(pkt, lladdr1, lladdr0, payload.ToVectorisedView()))
-				}
-
-				ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize))
-				ip.Encode(&header.IPv6Fields{
-					PayloadLength: uint16(size + payloadSize),
-					NextHeader:    uint8(header.ICMPv6ProtocolNumber),
-					HopLimit:      header.NDPHopLimit,
-					SrcAddr:       lladdr1,
-					DstAddr:       lladdr0,
-				})
-				e.InjectInbound(ProtocolNumber, stack.PacketBuffer{
-					Data: buffer.NewVectorisedView(header.IPv6MinimumSize+size+payloadSize, []buffer.View{hdr.View(), payload}),
-				})
-			}
-
-			stats := s.Stats().ICMP.V6PacketsReceived
-			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 %s = %d, want = 0", typ.name, 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 %s = %d, want = 0", typ.name, 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 %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)
-			}
-		})
-	}
-}
diff --git a/pkg/tcpip/network/ipv6/ipv6_state_autogen.go b/pkg/tcpip/network/ipv6/ipv6_state_autogen.go
new file mode 100755
index 0000000..40c67d4
--- /dev/null
+++ b/pkg/tcpip/network/ipv6/ipv6_state_autogen.go
@@ -0,0 +1,3 @@
+// automatically generated by stateify.
+
+package ipv6
diff --git a/pkg/tcpip/network/ipv6/ipv6_test.go b/pkg/tcpip/network/ipv6/ipv6_test.go
deleted file mode 100644
index 37f7e53..0000000
--- a/pkg/tcpip/network/ipv6/ipv6_test.go
+++ /dev/null
@@ -1,1251 +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 (
-	"testing"
-
-	"github.com/google/go-cmp/cmp"
-	"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/stack"
-	"gvisor.dev/gvisor/pkg/tcpip/transport/icmp"
-	"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"
-
-	// 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)
-)
-
-// 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.ICMPv6NeighborAdvertSize)
-	pkt := header.ICMPv6(hdr.Prepend(header.ICMPv6NeighborAdvertSize))
-	pkt.SetType(header.ICMPv6NeighborAdvert)
-	pkt.SetChecksum(header.ICMPv6Checksum(pkt, src, dst, buffer.VectorisedView{}))
-	payloadLength := hdr.UsedLength()
-	ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize))
-	ip.Encode(&header.IPv6Fields{
-		PayloadLength: uint16(payloadLength),
-		NextHeader:    uint8(header.ICMPv6ProtocolNumber),
-		HopLimit:      255,
-		SrcAddr:       src,
-		DstAddr:       dst,
-	})
-
-	e.InjectInbound(ProtocolNumber, stack.PacketBuffer{
-		Data: hdr.View().ToVectorisedView(),
-	})
-
-	stats := s.Stats().ICMP.V6PacketsReceived
-
-	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),
-		NextHeader:    uint8(udp.ProtocolNumber),
-		HopLimit:      255,
-		SrcAddr:       src,
-		DstAddr:       dst,
-	})
-
-	e.InjectInbound(ProtocolNumber, stack.PacketBuffer{
-		Data: hdr.View().ToVectorisedView(),
-	})
-
-	stat := s.Stats().UDP.PacketsReceived
-
-	if got := stat.Value(); got != want {
-		t.Fatalf("got UDPPacketsReceived = %d, want = %d", got, want)
-	}
-}
-
-// 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.TransportProtocol
-		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.NetworkProtocol{NewProtocol()},
-				TransportProtocols: []stack.TransportProtocol{test.protocolFactory},
-			})
-			e := channel.New(10, 1280, 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.TransportProtocol
-		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.NetworkProtocol{NewProtocol()},
-				TransportProtocols: []stack.TransportProtocol{test.protocolFactory},
-			})
-			e := channel.New(10, 1280, linkAddr1)
-			if err := s.CreateNIC(1, e); err != nil {
-				t.Fatalf("CreateNIC(_) = %s", err)
-			}
-
-			// 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(1, ProtocolNumber, addr2); err != nil {
-				t.Fatalf("AddAddress(_, %d, %s) = %s", 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(1, ProtocolNumber, addr3); err != nil {
-				t.Fatalf("AddAddress(_, %d, %s) = %s", 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(1, addr2); err != nil {
-				t.Fatalf("RemoveAddress(_, %s) = %s", 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)
-
-			if err := s.RemoveAddress(1, addr3); err != nil {
-				t.Fatalf("RemoveAddress(_, %s) = %s", addr3, err)
-			}
-
-			// Should not receive a packet destined to the solicited
-			// node address of addr2/addr3 yet as both of them got
-			// removed.
-			test.rxf(t, s, e, addr1, snmc, 3)
-		})
-	}
-}
-
-// TestAddIpv6Address tests adding IPv6 addresses.
-func TestAddIpv6Address(t *testing.T) {
-	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.NetworkProtocol{NewProtocol()},
-			})
-			if err := s.CreateNIC(1, &stubLinkEndpoint{}); err != nil {
-				t.Fatalf("CreateNIC(_) = %s", err)
-			}
-
-			if err := s.AddAddress(1, ProtocolNumber, test.addr); err != nil {
-				t.Fatalf("AddAddress(_, %d, nil) = %s", ProtocolNumber, err)
-			}
-
-			addr, err := s.GetMainNICAddress(1, header.IPv6ProtocolNumber)
-			if err != nil {
-				t.Fatalf("stack.GetMainNICAddress(_, _) err = %s", err)
-			}
-			if addr.Address != test.addr {
-				t.Fatalf("got stack.GetMainNICAddress(_, _) = %s, want = %s", addr.Address, test.addr)
-			}
-		})
-	}
-}
-
-func TestReceiveIPv6ExtHdrs(t *testing.T) {
-	const nicID = 1
-
-	tests := []struct {
-		name         string
-		extHdr       func(nextHdr uint8) ([]byte, uint8)
-		shouldAccept bool
-	}{
-		{
-			name:         "None",
-			extHdr:       func(nextHdr uint8) ([]byte, uint8) { return []byte{}, nextHdr },
-			shouldAccept: true,
-		},
-		{
-			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,
-		},
-		{
-			name: "hopbyhop with unknown option discard and send icmp action",
-			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,
-				}, hopByHopExtHdrID
-			},
-			shouldAccept: false,
-		},
-		{
-			name: "hopbyhop with unknown option discard and send icmp action unless multicast dest",
-			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,
-				}, hopByHopExtHdrID
-			},
-			shouldAccept: 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,
-		},
-		{
-			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,
-		},
-		{
-			name:         "fragment",
-			extHdr:       func(nextHdr uint8) ([]byte, uint8) { return []byte{nextHdr, 0, 1, 0, 1, 2, 3, 4}, fragmentExtHdrID },
-			shouldAccept: false,
-		},
-		{
-			name:         "No next header",
-			extHdr:       func(nextHdr uint8) ([]byte, uint8) { return []byte{}, noNextHdrID },
-			shouldAccept: false,
-		},
-		{
-			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,
-		},
-		{
-			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,
-		},
-		{
-			name: "destination with unknown option discard and send icmp action",
-			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,
-				}, destinationExtHdrID
-			},
-			shouldAccept: false,
-		},
-		{
-			name: "destination with unknown option discard and send icmp action unless multicast dest",
-			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,
-				}, destinationExtHdrID
-			},
-			shouldAccept: false,
-		},
-		{
-			name: "routing - atomic fragment",
-			extHdr: func(nextHdr uint8) ([]byte, uint8) {
-				return []byte{
-					// Routing extension header.
-					fragmentExtHdrID, 0, 1, 0, 2, 3, 4, 5,
-
-					// Fragment extension header.
-					nextHdr, 0, 0, 0, 1, 2, 3, 4,
-				}, routingExtHdrID
-			},
-			shouldAccept: 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,
-
-					// Hop By Hop extension header with skippable unknown option.
-					nextHdr, 0, 62, 4, 1, 2, 3, 4,
-				}, routingExtHdrID
-			},
-			shouldAccept: false,
-		},
-		{
-			name:         "No next header",
-			extHdr:       func(nextHdr uint8) ([]byte, uint8) { return []byte{}, noNextHdrID },
-			shouldAccept: false,
-		},
-		{
-			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,
-		},
-		{
-			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,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			s := stack.New(stack.Options{
-				NetworkProtocols:   []stack.NetworkProtocol{NewProtocol()},
-				TransportProtocols: []stack.TransportProtocol{udp.NewProtocol()},
-			})
-			e := channel.New(0, 1280, 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)
-			}
-
-			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)
-			sum := header.PseudoHeaderChecksum(udp.ProtocolNumber, addr1, addr2, 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),
-				NextHeader:    ipv6NextHdr,
-				HopLimit:      255,
-				SrcAddr:       addr1,
-				DstAddr:       addr2,
-			})
-
-			e.InjectInbound(ProtocolNumber, stack.PacketBuffer{
-				Data: hdr.View().ToVectorisedView(),
-			})
-
-			stats := s.Stats().UDP.PacketsReceived
-
-			if !test.shouldAccept {
-				if got := stats.Value(); got != 0 {
-					t.Errorf("got UDP Rx Packets = %d, want = 0", got)
-				}
-
-				return
-			}
-
-			// Expect a UDP packet.
-			if got := stats.Value(); got != 1 {
-				t.Errorf("got UDP Rx Packets = %d, want = 1", got)
-			}
-			gotPayload, _, err := ep.Read(nil)
-			if err != nil {
-				t.Fatalf("Read(nil): %s", err)
-			}
-			if diff := cmp.Diff(buffer.View(udpPayload), gotPayload); diff != "" {
-				t.Errorf("got UDP payload mismatch (-want +got):\n%s", diff)
-			}
-
-			// Should not have any more UDP packets.
-			if gotPayload, _, err := ep.Read(nil); err != tcpip.ErrWouldBlock {
-				t.Fatalf("got Read(nil) = (%x, _, %v), want = (_, _, %s)", gotPayload, err, tcpip.ErrWouldBlock)
-			}
-		})
-	}
-}
-
-// fragmentData holds the IPv6 payload for a fragmented IPv6 packet.
-type fragmentData struct {
-	nextHdr uint8
-	data    buffer.VectorisedView
-}
-
-func TestReceiveIPv6Fragments(t *testing.T) {
-	const nicID = 1
-	const udpPayload1Length = 256
-	const udpPayload2Length = 128
-	const 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.
-	const routingExtHdrLen = 8
-
-	udpGen := func(payload []byte, multiplier uint8) 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, addr1, addr2, uint16(udpLength))
-		sum = header.Checksum(payload, sum)
-		u.SetChecksum(^u.CalculateChecksum(sum))
-		return hdr.View()
-	}
-
-	var udpPayload1Buf [udpPayload1Length]byte
-	udpPayload1 := udpPayload1Buf[:]
-	ipv6Payload1 := udpGen(udpPayload1, 1)
-
-	var udpPayload2Buf [udpPayload2Length]byte
-	udpPayload2 := udpPayload2Buf[:]
-	ipv6Payload2 := udpGen(udpPayload2, 2)
-
-	tests := []struct {
-		name             string
-		expectedPayload  []byte
-		fragments        []fragmentData
-		expectedPayloads [][]byte
-	}{
-		{
-			name: "No fragmentation",
-			fragments: []fragmentData{
-				{
-					nextHdr: uint8(header.UDPProtocolNumber),
-					data:    ipv6Payload1.ToVectorisedView(),
-				},
-			},
-			expectedPayloads: [][]byte{udpPayload1},
-		},
-		{
-			name: "Atomic fragment",
-			fragments: []fragmentData{
-				{
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						fragmentExtHdrLen+len(ipv6Payload1),
-						[]buffer.View{
-							// Fragment extension header.
-							buffer.View([]byte{uint8(header.UDPProtocolNumber), 0, 0, 0, 0, 0, 0, 0}),
-
-							ipv6Payload1,
-						},
-					),
-				},
-			},
-			expectedPayloads: [][]byte{udpPayload1},
-		},
-		{
-			name: "Two fragments",
-			fragments: []fragmentData{
-				{
-					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}),
-
-							ipv6Payload1[:64],
-						},
-					),
-				},
-				{
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						fragmentExtHdrLen+len(ipv6Payload1)-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}),
-
-							ipv6Payload1[64:],
-						},
-					),
-				},
-			},
-			expectedPayloads: [][]byte{udpPayload1},
-		},
-		{
-			name: "Two fragments with different IDs",
-			fragments: []fragmentData{
-				{
-					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}),
-
-							ipv6Payload1[:64],
-						},
-					),
-				},
-				{
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						fragmentExtHdrLen+len(ipv6Payload1)-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}),
-
-							ipv6Payload1[64:],
-						},
-					),
-				},
-			},
-			expectedPayloads: nil,
-		},
-		{
-			name: "Two fragments with per-fragment routing header with zero segments left",
-			fragments: []fragmentData{
-				{
-					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}),
-
-							ipv6Payload1[:64],
-						},
-					),
-				},
-				{
-					nextHdr: routingExtHdrID,
-					data: buffer.NewVectorisedView(
-						routingExtHdrLen+fragmentExtHdrLen+len(ipv6Payload1)-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}),
-
-							ipv6Payload1[64:],
-						},
-					),
-				},
-			},
-			expectedPayloads: [][]byte{udpPayload1},
-		},
-		{
-			name: "Two fragments with per-fragment routing header with non-zero segments left",
-			fragments: []fragmentData{
-				{
-					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}),
-
-							ipv6Payload1[:64],
-						},
-					),
-				},
-				{
-					nextHdr: routingExtHdrID,
-					data: buffer.NewVectorisedView(
-						routingExtHdrLen+fragmentExtHdrLen+len(ipv6Payload1)-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}),
-
-							ipv6Payload1[64:],
-						},
-					),
-				},
-			},
-			expectedPayloads: nil,
-		},
-		{
-			name: "Two fragments with routing header with zero segments left",
-			fragments: []fragmentData{
-				{
-					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}),
-
-							ipv6Payload1[:64],
-						},
-					),
-				},
-				{
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						fragmentExtHdrLen+len(ipv6Payload1)-64,
-						[]buffer.View{
-							// Fragment extension header.
-							//
-							// Fragment offset = 9, More = false, ID = 1
-							buffer.View([]byte{routingExtHdrID, 0, 0, 72, 0, 0, 0, 1}),
-
-							ipv6Payload1[64:],
-						},
-					),
-				},
-			},
-			expectedPayloads: [][]byte{udpPayload1},
-		},
-		{
-			name: "Two fragments with routing header with non-zero segments left",
-			fragments: []fragmentData{
-				{
-					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}),
-
-							ipv6Payload1[:64],
-						},
-					),
-				},
-				{
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						fragmentExtHdrLen+len(ipv6Payload1)-64,
-						[]buffer.View{
-							// Fragment extension header.
-							//
-							// Fragment offset = 9, More = false, ID = 1
-							buffer.View([]byte{routingExtHdrID, 0, 0, 72, 0, 0, 0, 1}),
-
-							ipv6Payload1[64:],
-						},
-					),
-				},
-			},
-			expectedPayloads: nil,
-		},
-		{
-			name: "Two fragments with routing header with zero segments left across fragments",
-			fragments: []fragmentData{
-				{
-					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}),
-						},
-					),
-				},
-				{
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						// The length of this payload is
-						// fragmentExtHdrLen+8+len(ipv6Payload1) because the last 8 bytes of
-						// the 16 byte routing extension header is in this fagment.
-						fragmentExtHdrLen+8+len(ipv6Payload1),
-						[]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}),
-
-							ipv6Payload1,
-						},
-					),
-				},
-			},
-			expectedPayloads: [][]byte{udpPayload1},
-		},
-		{
-			name: "Two fragments with routing header with non-zero segments left across fragments",
-			fragments: []fragmentData{
-				{
-					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}),
-						},
-					),
-				},
-				{
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						// The length of this payload is
-						// fragmentExtHdrLen+8+len(ipv6Payload1) because the last 8 bytes of
-						// the 16 byte routing extension header is in this fagment.
-						fragmentExtHdrLen+8+len(ipv6Payload1),
-						[]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}),
-
-							ipv6Payload1,
-						},
-					),
-				},
-			},
-			expectedPayloads: nil,
-		},
-		// As per RFC 6946, IPv6 atomic fragments MUST NOT interfere with "normal"
-		// fragmented traffic.
-		{
-			name: "Two fragments with atomic",
-			fragments: []fragmentData{
-				{
-					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}),
-
-							ipv6Payload1[:64],
-						},
-					),
-				},
-				// This fragment has the same ID as the other fragments but is an atomic
-				// fragment. It should not interfere with the other fragments.
-				{
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						fragmentExtHdrLen+len(ipv6Payload2),
-						[]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}),
-
-							ipv6Payload2,
-						},
-					),
-				},
-				{
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						fragmentExtHdrLen+len(ipv6Payload1)-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}),
-
-							ipv6Payload1[64:],
-						},
-					),
-				},
-			},
-			expectedPayloads: [][]byte{udpPayload2, udpPayload1},
-		},
-		{
-			name: "Two interleaved fragmented packets",
-			fragments: []fragmentData{
-				{
-					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}),
-
-							ipv6Payload1[:64],
-						},
-					),
-				},
-				{
-					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}),
-
-							ipv6Payload2[:32],
-						},
-					),
-				},
-				{
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						fragmentExtHdrLen+len(ipv6Payload1)-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}),
-
-							ipv6Payload1[64:],
-						},
-					),
-				},
-				{
-					nextHdr: fragmentExtHdrID,
-					data: buffer.NewVectorisedView(
-						fragmentExtHdrLen+len(ipv6Payload2)-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}),
-
-							ipv6Payload2[32:],
-						},
-					),
-				},
-			},
-			expectedPayloads: [][]byte{udpPayload1, udpPayload2},
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			s := stack.New(stack.Options{
-				NetworkProtocols:   []stack.NetworkProtocol{NewProtocol()},
-				TransportProtocols: []stack.TransportProtocol{udp.NewProtocol()},
-			})
-			e := channel.New(0, 1280, 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()),
-					NextHeader:    f.nextHdr,
-					HopLimit:      255,
-					SrcAddr:       addr1,
-					DstAddr:       addr2,
-				})
-
-				vv := hdr.View().ToVectorisedView()
-				vv.Append(f.data)
-
-				e.InjectInbound(ProtocolNumber, stack.PacketBuffer{
-					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 {
-				gotPayload, _, err := ep.Read(nil)
-				if err != nil {
-					t.Fatalf("(i=%d) Read(nil): %s", i, err)
-				}
-				if diff := cmp.Diff(buffer.View(p), gotPayload); diff != "" {
-					t.Errorf("(i=%d) got UDP payload mismatch (-want +got):\n%s", i, diff)
-				}
-			}
-
-			if gotPayload, _, err := ep.Read(nil); err != tcpip.ErrWouldBlock {
-				t.Fatalf("(last) got Read(nil) = (%x, _, %v), want = (_, _, %s)", gotPayload, err, tcpip.ErrWouldBlock)
-			}
-		})
-	}
-}
diff --git a/pkg/tcpip/network/ipv6/ndp_test.go b/pkg/tcpip/network/ipv6/ndp_test.go
deleted file mode 100644
index b113aaa..0000000
--- a/pkg/tcpip/network/ipv6/ndp_test.go
+++ /dev/null
@@ -1,647 +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 (
-	"strings"
-	"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/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.NetworkProtocol{NewProtocol()},
-		TransportProtocols: []stack.TransportProtocol{icmp.NewProtocol6()},
-	})
-
-	if err := s.CreateNIC(1, &stubLinkEndpoint{}); err != nil {
-		t.Fatalf("CreateNIC(_) = %s", err)
-	}
-	if err := s.AddAddress(1, ProtocolNumber, llladdr); err != nil {
-		t.Fatalf("AddAddress(_, %d, %s) = %s", ProtocolNumber, llladdr, 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, err := netProto.NewEndpoint(0, tcpip.AddressWithPrefix{rlladdr, netProto.DefaultPrefixLen()}, &stubLinkAddressCache{}, &stubDispatcher{}, nil, s)
-	if err != nil {
-		t.Fatalf("NewEndpoint(_) = _, %s, want = _, nil", err)
-	}
-
-	return s, ep
-}
-
-// TestNeighorSolicitationWithSourceLinkLayerOption 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 TestNeighorSolicitationWithSourceLinkLayerOption(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.NetworkProtocol{NewProtocol()},
-			})
-			e := channel.New(0, 1280, linkAddr0)
-			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.NDPPayload())
-			ns.SetTargetAddress(lladdr0)
-			opts := ns.Options()
-			copy(opts, test.optsBuf)
-			pkt.SetChecksum(header.ICMPv6Checksum(pkt, lladdr1, lladdr0, buffer.VectorisedView{}))
-			payloadLength := hdr.UsedLength()
-			ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize))
-			ip.Encode(&header.IPv6Fields{
-				PayloadLength: uint16(payloadLength),
-				NextHeader:    uint8(header.ICMPv6ProtocolNumber),
-				HopLimit:      255,
-				SrcAddr:       lladdr1,
-				DstAddr:       lladdr0,
-			})
-
-			invalid := s.Stats().ICMP.V6PacketsReceived.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.PacketBuffer{
-				Data: hdr.View().ToVectorisedView(),
-			})
-
-			linkAddr, c, err := s.GetLinkAddress(nicID, lladdr1, lladdr0, ProtocolNumber, nil)
-			if linkAddr != test.expectedLinkAddr {
-				t.Errorf("got link address = %s, want = %s", linkAddr, test.expectedLinkAddr)
-			}
-
-			if test.expectedLinkAddr != "" {
-				if err != nil {
-					t.Errorf("s.GetLinkAddress(%d, %s, %s, %d, nil): %s", nicID, lladdr1, lladdr0, ProtocolNumber, err)
-				}
-				if c != nil {
-					t.Errorf("got unexpected channel")
-				}
-
-				// Invalid count should not have increased.
-				if got := invalid.Value(); got != 0 {
-					t.Errorf("got invalid = %d, want = 0", got)
-				}
-			} else {
-				if err != tcpip.ErrWouldBlock {
-					t.Errorf("got s.GetLinkAddress(%d, %s, %s, %d, nil) = (_, _, %v), want = (_, _, %s)", nicID, lladdr1, lladdr0, ProtocolNumber, err, tcpip.ErrWouldBlock)
-				}
-				if c == nil {
-					t.Errorf("expected channel from call to s.GetLinkAddress(%d, %s, %s, %d, nil)", nicID, lladdr1, lladdr0, ProtocolNumber)
-				}
-
-				// Invalid count should have increased.
-				if got := invalid.Value(); got != 1 {
-					t.Errorf("got invalid = %d, want = 1", got)
-				}
-			}
-		})
-	}
-}
-
-// TestNeighorAdvertisementWithTargetLinkLayerOption tests that receiving a
-// valid NDP NA message with the Target Link Layer Address option results in a
-// new entry in the link address cache for the target of the message.
-func TestNeighorAdvertisementWithTargetLinkLayerOption(t *testing.T) {
-	const nicID = 1
-
-	tests := []struct {
-		name             string
-		optsBuf          []byte
-		expectedLinkAddr tcpip.LinkAddress
-	}{
-		{
-			name:             "Valid",
-			optsBuf:          []byte{2, 1, 2, 3, 4, 5, 6, 7},
-			expectedLinkAddr: "\x02\x03\x04\x05\x06\x07",
-		},
-		{
-			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},
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			s := stack.New(stack.Options{
-				NetworkProtocols: []stack.NetworkProtocol{NewProtocol()},
-			})
-			e := channel.New(0, 1280, linkAddr0)
-			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.NDPPayload())
-			ns.SetTargetAddress(lladdr1)
-			opts := ns.Options()
-			copy(opts, test.optsBuf)
-			pkt.SetChecksum(header.ICMPv6Checksum(pkt, lladdr1, lladdr0, buffer.VectorisedView{}))
-			payloadLength := hdr.UsedLength()
-			ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize))
-			ip.Encode(&header.IPv6Fields{
-				PayloadLength: uint16(payloadLength),
-				NextHeader:    uint8(header.ICMPv6ProtocolNumber),
-				HopLimit:      255,
-				SrcAddr:       lladdr1,
-				DstAddr:       lladdr0,
-			})
-
-			invalid := s.Stats().ICMP.V6PacketsReceived.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.PacketBuffer{
-				Data: hdr.View().ToVectorisedView(),
-			})
-
-			linkAddr, c, err := s.GetLinkAddress(nicID, lladdr1, lladdr0, ProtocolNumber, nil)
-			if linkAddr != test.expectedLinkAddr {
-				t.Errorf("got link address = %s, want = %s", linkAddr, test.expectedLinkAddr)
-			}
-
-			if test.expectedLinkAddr != "" {
-				if err != nil {
-					t.Errorf("s.GetLinkAddress(%d, %s, %s, %d, nil): %s", nicID, lladdr1, lladdr0, ProtocolNumber, err)
-				}
-				if c != nil {
-					t.Errorf("got unexpected channel")
-				}
-
-				// Invalid count should not have increased.
-				if got := invalid.Value(); got != 0 {
-					t.Errorf("got invalid = %d, want = 0", got)
-				}
-			} else {
-				if err != tcpip.ErrWouldBlock {
-					t.Errorf("got s.GetLinkAddress(%d, %s, %s, %d, nil) = (_, _, %v), want = (_, _, %s)", nicID, lladdr1, lladdr0, ProtocolNumber, err, tcpip.ErrWouldBlock)
-				}
-				if c == nil {
-					t.Errorf("expected channel from call to s.GetLinkAddress(%d, %s, %s, %d, nil)", nicID, lladdr1, lladdr0, ProtocolNumber)
-				}
-
-				// 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, stack.Route) {
-		t.Helper()
-
-		// Create a stack with the assigned link-local address lladdr0
-		// and an endpoint to lladdr1.
-		s, ep := setupStackAndEndpoint(t, lladdr0, lladdr1)
-
-		r, err := s.FindRoute(1, lladdr0, lladdr1, ProtocolNumber, false /* multicastLoop */)
-		if err != nil {
-			t.Fatalf("FindRoute(_) = _, %s, want = _, nil", err)
-		}
-
-		return s, ep, r
-	}
-
-	handleIPv6Payload := func(hdr buffer.Prependable, hopLimit uint8, atomicFragment bool, ep stack.NetworkEndpoint, r *stack.Route) {
-		nextHdr := uint8(header.ICMPv6ProtocolNumber)
-		if atomicFragment {
-			bytes := hdr.Prepend(header.IPv6FragmentExtHdrLength)
-			bytes[0] = nextHdr
-			nextHdr = uint8(header.IPv6FragmentExtHdrIdentifier)
-		}
-
-		payloadLength := hdr.UsedLength()
-		ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize))
-		ip.Encode(&header.IPv6Fields{
-			PayloadLength: uint16(payloadLength),
-			NextHeader:    nextHdr,
-			HopLimit:      hopLimit,
-			SrcAddr:       r.LocalAddress,
-			DstAddr:       r.RemoteAddress,
-		})
-		ep.HandlePacket(r, stack.PacketBuffer{
-			Data: hdr.View().ToVectorisedView(),
-		})
-	}
-
-	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
-	}{
-		{
-			name: "RouterSolicit",
-			typ:  header.ICMPv6RouterSolicit,
-			size: header.ICMPv6MinimumSize,
-			statCounter: func(stats tcpip.ICMPv6ReceivedPacketStats) *tcpip.StatCounter {
-				return stats.RouterSolicit
-			},
-		},
-		{
-			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
-			},
-		},
-	}
-
-	subTests := []struct {
-		name           string
-		atomicFragment bool
-		hopLimit       uint8
-		code           uint8
-		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 {
-		t.Run(typ.name, func(t *testing.T) {
-			for _, test := range subTests {
-				t.Run(test.name, func(t *testing.T) {
-					s, ep, r := setup(t)
-					defer r.Release()
-
-					stats := s.Stats().ICMP.V6PacketsReceived
-					invalid := stats.Invalid
-					typStat := typ.statCounter(stats)
-
-					extraDataLen := len(typ.extraData)
-					hdr := buffer.NewPrependable(header.IPv6MinimumSize + typ.size + extraDataLen + header.IPv6FragmentExtHdrLength)
-					extraData := buffer.View(hdr.Prepend(extraDataLen))
-					copy(extraData, typ.extraData)
-					pkt := header.ICMPv6(hdr.Prepend(typ.size))
-					pkt.SetType(typ.typ)
-					pkt.SetCode(test.code)
-					pkt.SetChecksum(header.ICMPv6Checksum(pkt, r.LocalAddress, r.RemoteAddress, extraData.ToVectorisedView()))
-
-					// 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)
-					}
-
-					if t.Failed() {
-						t.FailNow()
-					}
-
-					handleIPv6Payload(hdr, test.hopLimit, test.atomicFragment, ep, &r)
-
-					// 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)
-					}
-				})
-			}
-		})
-	}
-}
-
-// 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            uint8
-		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)
-			s := stack.New(stack.Options{
-				NetworkProtocols: []stack.NetworkProtocol{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.NDPPayload(), test.ndpPayload)
-			payloadLength := hdr.UsedLength()
-			pkt.SetChecksum(header.ICMPv6Checksum(pkt, test.src, header.IPv6AllNodesMulticastAddress, buffer.VectorisedView{}))
-			ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize))
-			ip.Encode(&header.IPv6Fields{
-				PayloadLength: uint16(payloadLength),
-				NextHeader:    uint8(icmp.ProtocolNumber6),
-				HopLimit:      test.hopLimit,
-				SrcAddr:       test.src,
-				DstAddr:       header.IPv6AllNodesMulticastAddress,
-			})
-
-			stats := s.Stats().ICMP.V6PacketsReceived
-			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.PacketBuffer{
-				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)
-				}
-			}
-		})
-	}
-}
diff --git a/pkg/tcpip/ports/ports_state_autogen.go b/pkg/tcpip/ports/ports_state_autogen.go
new file mode 100755
index 0000000..f0ee1bb
--- /dev/null
+++ b/pkg/tcpip/ports/ports_state_autogen.go
@@ -0,0 +1,24 @@
+// automatically generated by stateify.
+
+package ports
+
+import (
+	"gvisor.dev/gvisor/pkg/state"
+)
+
+func (x *Flags) beforeSave() {}
+func (x *Flags) save(m state.Map) {
+	x.beforeSave()
+	m.Save("MostRecent", &x.MostRecent)
+	m.Save("LoadBalanced", &x.LoadBalanced)
+}
+
+func (x *Flags) afterLoad() {}
+func (x *Flags) load(m state.Map) {
+	m.Load("MostRecent", &x.MostRecent)
+	m.Load("LoadBalanced", &x.LoadBalanced)
+}
+
+func init() {
+	state.Register("pkg/tcpip/ports.Flags", (*Flags)(nil), state.Fns{Save: (*Flags).save, Load: (*Flags).load})
+}
diff --git a/pkg/tcpip/ports/ports_test.go b/pkg/tcpip/ports/ports_test.go
deleted file mode 100644
index d6969d0..0000000
--- a/pkg/tcpip/ports/ports_test.go
+++ /dev/null
@@ -1,402 +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"
-
-	"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
-}
-
-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},
-			},
-		},
-	} {
-		t.Run(test.tname, func(t *testing.T) {
-			pm := NewPortManager()
-			net := []tcpip.NetworkProtocolNumber{fakeNetworkNumber}
-
-			for _, test := range test.actions {
-				if test.release {
-					pm.ReleasePort(net, fakeTransNumber, test.ip, test.port, test.flags, test.device)
-					continue
-				}
-				gotPort, err := pm.ReservePort(net, fakeTransNumber, test.ip, test.port, test.flags, test.device)
-				if err != test.want {
-					t.Fatalf("ReservePort(.., .., %s, %d, %+v, %d) = %v, want %v", test.ip, test.port, test.flags, test.device, err, test.want)
-				}
-				if test.port == 0 && (gotPort == 0 || gotPort < FirstEphemeral) {
-					t.Fatalf("ReservePort(.., .., .., 0) = %d, want port number >= %d to be picked", gotPort, FirstEphemeral)
-				}
-			}
-		})
-
-	}
-}
-
-func TestPickEphemeralPort(t *testing.T) {
-	customErr := &tcpip.Error{}
-	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, customErr
-			},
-			wantErr: customErr,
-		},
-		{
-			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 port, err := pm.PickEphemeralPort(test.f); port != test.wantPort || err != test.wantErr {
-				t.Errorf("PickEphemeralPort(..) = (port %d, err %v); want (port %d, err %v)", port, err, test.wantPort, test.wantErr)
-			}
-		})
-	}
-}
-
-func TestPickEphemeralPortStable(t *testing.T) {
-	customErr := &tcpip.Error{}
-	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, customErr
-			},
-			wantErr: customErr,
-		},
-		{
-			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()
-			portOffset := uint32(rand.Int31n(int32(numEphemeralPorts)))
-			if port, err := pm.PickEphemeralPortStable(portOffset, test.f); port != test.wantPort || err != test.wantErr {
-				t.Errorf("PickEphemeralPort(..) = (port %d, err %v); want (port %d, err %v)", port, err, test.wantPort, test.wantErr)
-			}
-		})
-	}
-}
diff --git a/pkg/tcpip/seqnum/seqnum_state_autogen.go b/pkg/tcpip/seqnum/seqnum_state_autogen.go
new file mode 100755
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/stack/dhcpv6configurationfromndpra_string.go b/pkg/tcpip/stack/dhcpv6configurationfromndpra_string.go
old mode 100644
new mode 100755
diff --git a/pkg/tcpip/stack/forwarder.go b/pkg/tcpip/stack/forwarder.go
old mode 100644
new mode 100755
diff --git a/pkg/tcpip/stack/forwarder_test.go b/pkg/tcpip/stack/forwarder_test.go
deleted file mode 100644
index c45c43d..0000000
--- a/pkg/tcpip/stack/forwarder_test.go
+++ /dev/null
@@ -1,635 +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/tcpip"
-	"gvisor.dev/gvisor/pkg/tcpip/buffer"
-)
-
-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
-)
-
-// 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 {
-	nicID      tcpip.NICID
-	id         NetworkEndpointID
-	prefixLen  int
-	proto      *fwdTestNetworkProtocol
-	dispatcher TransportDispatcher
-	ep         LinkEndpoint
-}
-
-func (f *fwdTestNetworkEndpoint) MTU() uint32 {
-	return f.ep.MTU() - uint32(f.MaxHeaderLength())
-}
-
-func (f *fwdTestNetworkEndpoint) NICID() tcpip.NICID {
-	return f.nicID
-}
-
-func (f *fwdTestNetworkEndpoint) PrefixLen() int {
-	return f.prefixLen
-}
-
-func (*fwdTestNetworkEndpoint) DefaultTTL() uint8 {
-	return 123
-}
-
-func (f *fwdTestNetworkEndpoint) ID() *NetworkEndpointID {
-	return &f.id
-}
-
-func (f *fwdTestNetworkEndpoint) HandlePacket(r *Route, pkt PacketBuffer) {
-	// Consume the network header.
-	b := pkt.Data.First()
-	pkt.Data.TrimFront(fwdTestNetHeaderLen)
-
-	// Dispatch the packet to the transport protocol.
-	f.dispatcher.DeliverTransportPacket(r, tcpip.TransportProtocolNumber(b[2]), pkt)
-}
-
-func (f *fwdTestNetworkEndpoint) MaxHeaderLength() uint16 {
-	return f.ep.MaxHeaderLength() + fwdTestNetHeaderLen
-}
-
-func (f *fwdTestNetworkEndpoint) PseudoHeaderChecksum(protocol tcpip.TransportProtocolNumber, dstAddr tcpip.Address) uint16 {
-	return 0
-}
-
-func (f *fwdTestNetworkEndpoint) Capabilities() LinkEndpointCapabilities {
-	return f.ep.Capabilities()
-}
-
-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.Header.Prepend(fwdTestNetHeaderLen)
-	b[0] = r.RemoteAddress[0]
-	b[1] = f.id.LocalAddress[0]
-	b[2] = byte(params.Protocol)
-
-	return f.ep.WritePacket(r, gso, fwdTestNetNumber, pkt)
-}
-
-// WritePackets implements LinkEndpoint.WritePackets.
-func (f *fwdTestNetworkEndpoint) WritePackets(r *Route, gso *GSO, pkts []PacketBuffer, params NetworkHeaderParams) (int, *tcpip.Error) {
-	panic("not implemented")
-}
-
-func (*fwdTestNetworkEndpoint) WriteHeaderIncludedPacket(r *Route, pkt PacketBuffer) *tcpip.Error {
-	return tcpip.ErrNotSupported
-}
-
-func (*fwdTestNetworkEndpoint) Close() {}
-
-// fwdTestNetworkProtocol is a network-layer protocol that implements Address
-// resolution.
-type fwdTestNetworkProtocol struct {
-	addrCache              *linkAddrCache
-	addrResolveDelay       time.Duration
-	onLinkAddressResolved  func(cache *linkAddrCache, addr tcpip.Address)
-	onResolveStaticAddress func(tcpip.Address) (tcpip.LinkAddress, bool)
-}
-
-func (f *fwdTestNetworkProtocol) Number() tcpip.NetworkProtocolNumber {
-	return fwdTestNetNumber
-}
-
-func (f *fwdTestNetworkProtocol) MinimumPacketSize() int {
-	return fwdTestNetHeaderLen
-}
-
-func (f *fwdTestNetworkProtocol) DefaultPrefixLen() int {
-	return fwdTestNetDefaultPrefixLen
-}
-
-func (*fwdTestNetworkProtocol) ParseAddresses(v buffer.View) (src, dst tcpip.Address) {
-	return tcpip.Address(v[1:2]), tcpip.Address(v[0:1])
-}
-
-func (f *fwdTestNetworkProtocol) NewEndpoint(nicID tcpip.NICID, addrWithPrefix tcpip.AddressWithPrefix, linkAddrCache LinkAddressCache, dispatcher TransportDispatcher, ep LinkEndpoint, _ *Stack) (NetworkEndpoint, *tcpip.Error) {
-	return &fwdTestNetworkEndpoint{
-		nicID:      nicID,
-		id:         NetworkEndpointID{LocalAddress: addrWithPrefix.Address},
-		prefixLen:  addrWithPrefix.PrefixLen,
-		proto:      f,
-		dispatcher: dispatcher,
-		ep:         ep,
-	}, nil
-}
-
-func (f *fwdTestNetworkProtocol) SetOption(option interface{}) *tcpip.Error {
-	return tcpip.ErrUnknownProtocolOption
-}
-
-func (f *fwdTestNetworkProtocol) Option(option interface{}) *tcpip.Error {
-	return tcpip.ErrUnknownProtocolOption
-}
-
-func (f *fwdTestNetworkProtocol) Close() {}
-
-func (f *fwdTestNetworkProtocol) Wait() {}
-
-func (f *fwdTestNetworkProtocol) LinkAddressRequest(addr, localAddr tcpip.Address, linkEP LinkEndpoint) *tcpip.Error {
-	if f.addrCache != nil && f.onLinkAddressResolved != nil {
-		time.AfterFunc(f.addrResolveDelay, func() {
-			f.onLinkAddressResolved(f.addrCache, addr)
-		})
-	}
-	return nil
-}
-
-func (f *fwdTestNetworkProtocol) ResolveStaticAddress(addr tcpip.Address) (tcpip.LinkAddress, bool) {
-	if f.onResolveStaticAddress != nil {
-		return f.onResolveStaticAddress(addr)
-	}
-	return "", false
-}
-
-func (f *fwdTestNetworkProtocol) LinkAddressProtocol() tcpip.NetworkProtocolNumber {
-	return fwdTestNetNumber
-}
-
-// 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(e, 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 *Route, 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 *Route, gso *GSO, pkts []PacketBuffer, protocol tcpip.NetworkProtocolNumber) (int, *tcpip.Error) {
-	n := 0
-	for _, pkt := range pkts {
-		e.WritePacket(r, gso, protocol, pkt)
-		n++
-	}
-
-	return n, nil
-}
-
-// WriteRawPacket implements stack.LinkEndpoint.WriteRawPacket.
-func (e *fwdTestLinkEndpoint) WriteRawPacket(vv buffer.VectorisedView) *tcpip.Error {
-	p := fwdTestPacketInfo{
-		Pkt: PacketBuffer{Data: vv},
-	}
-
-	select {
-	case e.C <- p:
-	default:
-	}
-
-	return nil
-}
-
-// Wait implements stack.LinkEndpoint.Wait.
-func (*fwdTestLinkEndpoint) Wait() {}
-
-func fwdTestNetFactory(t *testing.T, proto *fwdTestNetworkProtocol) (ep1, ep2 *fwdTestLinkEndpoint) {
-	// Create a stack with the network protocol and two NICs.
-	s := New(Options{
-		NetworkProtocols: []NetworkProtocol{proto},
-	})
-
-	proto.addrCache = s.linkAddrCache
-
-	// Enable forwarding.
-	s.SetForwarding(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)
-	}
-
-	// 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[0] = 3
-	ep1.InjectInbound(fwdTestNetNumber, PacketBuffer{
-		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) {
-	// Create a network protocol with a fake resolver.
-	proto := &fwdTestNetworkProtocol{
-		addrResolveDelay: 500 * time.Millisecond,
-		onLinkAddressResolved: func(cache *linkAddrCache, addr tcpip.Address) {
-			// Any address will be resolved to the link address "c".
-			cache.add(tcpip.FullAddress{NIC: 2, Addr: addr}, "c")
-		},
-	}
-
-	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[0] = 3
-	ep1.InjectInbound(fwdTestNetNumber, PacketBuffer{
-		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{}
-
-	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[0] = 3
-	ep1.InjectInbound(fwdTestNetNumber, PacketBuffer{
-		Data: buf.ToVectorisedView(),
-	})
-
-	select {
-	case <-ep2.C:
-		t.Fatal("Packet should not be forwarded")
-	case <-time.After(time.Second):
-	}
-}
-
-func TestForwardingWithFakeResolverPartialTimeout(t *testing.T) {
-	// Create a network protocol with a fake resolver.
-	proto := &fwdTestNetworkProtocol{
-		addrResolveDelay: 500 * time.Millisecond,
-		onLinkAddressResolved: func(cache *linkAddrCache, addr tcpip.Address) {
-			// Only packets to address 3 will be resolved to the
-			// link address "c".
-			if addr == "\x03" {
-				cache.add(tcpip.FullAddress{NIC: 2, Addr: addr}, "c")
-			}
-		},
-	}
-
-	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[0] = 4
-	ep1.InjectInbound(fwdTestNetNumber, PacketBuffer{
-		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[0] = 3
-	ep1.InjectInbound(fwdTestNetNumber, PacketBuffer{
-		Data: buf.ToVectorisedView(),
-	})
-
-	var p fwdTestPacketInfo
-
-	select {
-	case p = <-ep2.C:
-	case <-time.After(time.Second):
-		t.Fatal("packet not forwarded")
-	}
-
-	b := p.Pkt.Header.View()
-	if b[0] != 3 {
-		t.Fatalf("got b[0] = %d, want = 3", b[0])
-	}
-
-	// 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) {
-	// Create a network protocol with a fake resolver.
-	proto := &fwdTestNetworkProtocol{
-		addrResolveDelay: 500 * time.Millisecond,
-		onLinkAddressResolved: func(cache *linkAddrCache, addr tcpip.Address) {
-			// Any packets will be resolved to the link address "c".
-			cache.add(tcpip.FullAddress{NIC: 2, Addr: addr}, "c")
-		},
-	}
-
-	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[0] = 3
-		ep1.InjectInbound(fwdTestNetNumber, PacketBuffer{
-			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")
-		}
-
-		b := p.Pkt.Header.View()
-		if b[0] != 3 {
-			t.Fatalf("got b[0] = %d, want = 3", b[0])
-		}
-
-		// 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) {
-	// Create a network protocol with a fake resolver.
-	proto := &fwdTestNetworkProtocol{
-		addrResolveDelay: 500 * time.Millisecond,
-		onLinkAddressResolved: func(cache *linkAddrCache, addr tcpip.Address) {
-			// Any packets will be resolved to the link address "c".
-			cache.add(tcpip.FullAddress{NIC: 2, Addr: addr}, "c")
-		},
-	}
-
-	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[0] = 3
-		// Set the packet sequence number.
-		binary.BigEndian.PutUint16(buf[fwdTestNetHeaderLen:], uint16(i))
-		ep1.InjectInbound(fwdTestNetNumber, PacketBuffer{
-			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 := p.Pkt.Header.View()
-		if b[0] != 3 {
-			t.Fatalf("got b[0] = %d, want = 3", b[0])
-		}
-		// The first 5 packets should not be forwarded so the the
-		// sequemnce number should start with 5.
-		want := uint16(i + 5)
-		if n := binary.BigEndian.Uint16(b[fwdTestNetHeaderLen:]); 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) {
-	// Create a network protocol with a fake resolver.
-	proto := &fwdTestNetworkProtocol{
-		addrResolveDelay: 500 * time.Millisecond,
-		onLinkAddressResolved: func(cache *linkAddrCache, addr tcpip.Address) {
-			// Any packets will be resolved to the link address "c".
-			cache.add(tcpip.FullAddress{NIC: 2, Addr: addr}, "c")
-		},
-	}
-
-	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[0] = byte(3 + i)
-		ep1.InjectInbound(fwdTestNetNumber, PacketBuffer{
-			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.
-		b := p.Pkt.Header.View()
-		if b[0] < 8 {
-			t.Fatalf("got b[0] = %d, want b[0] >= 8", b[0])
-		}
-
-		// 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/iptables.go b/pkg/tcpip/stack/iptables.go
old mode 100644
new mode 100755
diff --git a/pkg/tcpip/stack/iptables_targets.go b/pkg/tcpip/stack/iptables_targets.go
old mode 100644
new mode 100755
diff --git a/pkg/tcpip/stack/iptables_types.go b/pkg/tcpip/stack/iptables_types.go
old mode 100644
new mode 100755
diff --git a/pkg/tcpip/stack/linkaddrcache_test.go b/pkg/tcpip/stack/linkaddrcache_test.go
deleted file mode 100644
index 1baa498..0000000
--- a/pkg/tcpip/stack/linkaddrcache_test.go
+++ /dev/null
@@ -1,277 +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
-
-import (
-	"fmt"
-	"sync/atomic"
-	"testing"
-	"time"
-
-	"gvisor.dev/gvisor/pkg/sleep"
-	"gvisor.dev/gvisor/pkg/sync"
-	"gvisor.dev/gvisor/pkg/tcpip"
-)
-
-type testaddr struct {
-	addr     tcpip.FullAddress
-	linkAddr tcpip.LinkAddress
-}
-
-var testAddrs = func() []testaddr {
-	var addrs []testaddr
-	for i := 0; i < 4*linkAddrCacheSize; i++ {
-		addr := fmt.Sprintf("Addr%06d", i)
-		addrs = append(addrs, testaddr{
-			addr:     tcpip.FullAddress{NIC: 1, Addr: tcpip.Address(addr)},
-			linkAddr: tcpip.LinkAddress("Link" + addr),
-		})
-	}
-	return addrs
-}()
-
-type testLinkAddressResolver struct {
-	cache                *linkAddrCache
-	delay                time.Duration
-	onLinkAddressRequest func()
-}
-
-func (r *testLinkAddressResolver) LinkAddressRequest(addr, _ tcpip.Address, _ LinkEndpoint) *tcpip.Error {
-	time.AfterFunc(r.delay, func() { r.fakeRequest(addr) })
-	if f := r.onLinkAddressRequest; f != nil {
-		f()
-	}
-	return nil
-}
-
-func (r *testLinkAddressResolver) fakeRequest(addr tcpip.Address) {
-	for _, ta := range testAddrs {
-		if ta.addr.Addr == addr {
-			r.cache.add(ta.addr, ta.linkAddr)
-			break
-		}
-	}
-}
-
-func (*testLinkAddressResolver) ResolveStaticAddress(addr tcpip.Address) (tcpip.LinkAddress, bool) {
-	if addr == "broadcast" {
-		return "mac_broadcast", true
-	}
-	return "", false
-}
-
-func (*testLinkAddressResolver) LinkAddressProtocol() tcpip.NetworkProtocolNumber {
-	return 1
-}
-
-func getBlocking(c *linkAddrCache, addr tcpip.FullAddress, linkRes LinkAddressResolver) (tcpip.LinkAddress, *tcpip.Error) {
-	w := sleep.Waker{}
-	s := sleep.Sleeper{}
-	s.AddWaker(&w, 123)
-	defer s.Done()
-
-	for {
-		if got, _, err := c.get(addr, linkRes, "", nil, &w); err != tcpip.ErrWouldBlock {
-			return got, err
-		}
-		s.Fetch(true)
-	}
-}
-
-func TestCacheOverflow(t *testing.T) {
-	c := newLinkAddrCache(1<<63-1, 1*time.Second, 3)
-	for i := len(testAddrs) - 1; i >= 0; i-- {
-		e := testAddrs[i]
-		c.add(e.addr, e.linkAddr)
-		got, _, err := c.get(e.addr, nil, "", nil, nil)
-		if err != nil {
-			t.Errorf("insert %d, c.get(%q)=%q, got error: %v", i, string(e.addr.Addr), got, err)
-		}
-		if got != e.linkAddr {
-			t.Errorf("insert %d, c.get(%q)=%q, want %q", i, string(e.addr.Addr), got, e.linkAddr)
-		}
-	}
-	// Expect to find at least half of the most recent entries.
-	for i := 0; i < linkAddrCacheSize/2; i++ {
-		e := testAddrs[i]
-		got, _, err := c.get(e.addr, nil, "", nil, nil)
-		if err != nil {
-			t.Errorf("check %d, c.get(%q)=%q, got error: %v", i, string(e.addr.Addr), got, err)
-		}
-		if got != e.linkAddr {
-			t.Errorf("check %d, c.get(%q)=%q, want %q", i, string(e.addr.Addr), got, e.linkAddr)
-		}
-	}
-	// The earliest entries should no longer be in the cache.
-	for i := len(testAddrs) - 1; i >= len(testAddrs)-linkAddrCacheSize; i-- {
-		e := testAddrs[i]
-		if _, _, err := c.get(e.addr, nil, "", nil, nil); err != tcpip.ErrNoLinkAddress {
-			t.Errorf("check %d, c.get(%q), got error: %v, want: error ErrNoLinkAddress", i, string(e.addr.Addr), err)
-		}
-	}
-}
-
-func TestCacheConcurrent(t *testing.T) {
-	c := newLinkAddrCache(1<<63-1, 1*time.Second, 3)
-
-	var wg sync.WaitGroup
-	for r := 0; r < 16; r++ {
-		wg.Add(1)
-		go func() {
-			for _, e := range testAddrs {
-				c.add(e.addr, e.linkAddr)
-				c.get(e.addr, nil, "", nil, nil) // make work for gotsan
-			}
-			wg.Done()
-		}()
-	}
-	wg.Wait()
-
-	// All goroutines add in the same order and add more values than
-	// can fit in the cache, so our eviction strategy requires that
-	// the last entry be present and the first be missing.
-	e := testAddrs[len(testAddrs)-1]
-	got, _, err := c.get(e.addr, nil, "", nil, nil)
-	if err != nil {
-		t.Errorf("c.get(%q)=%q, got error: %v", string(e.addr.Addr), got, err)
-	}
-	if got != e.linkAddr {
-		t.Errorf("c.get(%q)=%q, want %q", string(e.addr.Addr), got, e.linkAddr)
-	}
-
-	e = testAddrs[0]
-	if _, _, err := c.get(e.addr, nil, "", nil, nil); err != tcpip.ErrNoLinkAddress {
-		t.Errorf("c.get(%q), got error: %v, want: error ErrNoLinkAddress", string(e.addr.Addr), err)
-	}
-}
-
-func TestCacheAgeLimit(t *testing.T) {
-	c := newLinkAddrCache(1*time.Millisecond, 1*time.Second, 3)
-	e := testAddrs[0]
-	c.add(e.addr, e.linkAddr)
-	time.Sleep(50 * time.Millisecond)
-	if _, _, err := c.get(e.addr, nil, "", nil, nil); err != tcpip.ErrNoLinkAddress {
-		t.Errorf("c.get(%q), got error: %v, want: error ErrNoLinkAddress", string(e.addr.Addr), err)
-	}
-}
-
-func TestCacheReplace(t *testing.T) {
-	c := newLinkAddrCache(1<<63-1, 1*time.Second, 3)
-	e := testAddrs[0]
-	l2 := e.linkAddr + "2"
-	c.add(e.addr, e.linkAddr)
-	got, _, err := c.get(e.addr, nil, "", nil, nil)
-	if err != nil {
-		t.Errorf("c.get(%q)=%q, got error: %v", string(e.addr.Addr), got, err)
-	}
-	if got != e.linkAddr {
-		t.Errorf("c.get(%q)=%q, want %q", string(e.addr.Addr), got, e.linkAddr)
-	}
-
-	c.add(e.addr, l2)
-	got, _, err = c.get(e.addr, nil, "", nil, nil)
-	if err != nil {
-		t.Errorf("c.get(%q)=%q, got error: %v", string(e.addr.Addr), got, err)
-	}
-	if got != l2 {
-		t.Errorf("c.get(%q)=%q, want %q", string(e.addr.Addr), got, l2)
-	}
-}
-
-func TestCacheResolution(t *testing.T) {
-	c := newLinkAddrCache(1<<63-1, 250*time.Millisecond, 1)
-	linkRes := &testLinkAddressResolver{cache: c}
-	for i, ta := range testAddrs {
-		got, err := getBlocking(c, ta.addr, linkRes)
-		if err != nil {
-			t.Errorf("check %d, c.get(%q)=%q, got error: %v", i, string(ta.addr.Addr), got, err)
-		}
-		if got != ta.linkAddr {
-			t.Errorf("check %d, c.get(%q)=%q, want %q", i, string(ta.addr.Addr), got, ta.linkAddr)
-		}
-	}
-
-	// Check that after resolved, address stays in the cache and never returns WouldBlock.
-	for i := 0; i < 10; i++ {
-		e := testAddrs[len(testAddrs)-1]
-		got, _, err := c.get(e.addr, linkRes, "", nil, nil)
-		if err != nil {
-			t.Errorf("c.get(%q)=%q, got error: %v", string(e.addr.Addr), got, err)
-		}
-		if got != e.linkAddr {
-			t.Errorf("c.get(%q)=%q, want %q", string(e.addr.Addr), got, e.linkAddr)
-		}
-	}
-}
-
-func TestCacheResolutionFailed(t *testing.T) {
-	c := newLinkAddrCache(1<<63-1, 10*time.Millisecond, 5)
-	linkRes := &testLinkAddressResolver{cache: c}
-
-	var requestCount uint32
-	linkRes.onLinkAddressRequest = func() {
-		atomic.AddUint32(&requestCount, 1)
-	}
-
-	// First, sanity check that resolution is working...
-	e := testAddrs[0]
-	got, err := getBlocking(c, e.addr, linkRes)
-	if err != nil {
-		t.Errorf("c.get(%q)=%q, got error: %v", string(e.addr.Addr), got, err)
-	}
-	if got != e.linkAddr {
-		t.Errorf("c.get(%q)=%q, want %q", string(e.addr.Addr), got, e.linkAddr)
-	}
-
-	before := atomic.LoadUint32(&requestCount)
-
-	e.addr.Addr += "2"
-	if _, err := getBlocking(c, e.addr, linkRes); err != tcpip.ErrNoLinkAddress {
-		t.Errorf("c.get(%q), got error: %v, want: error ErrNoLinkAddress", string(e.addr.Addr), err)
-	}
-
-	if got, want := int(atomic.LoadUint32(&requestCount)-before), c.resolutionAttempts; got != want {
-		t.Errorf("got link address request count = %d, want = %d", got, want)
-	}
-}
-
-func TestCacheResolutionTimeout(t *testing.T) {
-	resolverDelay := 500 * time.Millisecond
-	expiration := resolverDelay / 10
-	c := newLinkAddrCache(expiration, 1*time.Millisecond, 3)
-	linkRes := &testLinkAddressResolver{cache: c, delay: resolverDelay}
-
-	e := testAddrs[0]
-	if _, err := getBlocking(c, e.addr, linkRes); err != tcpip.ErrNoLinkAddress {
-		t.Errorf("c.get(%q), got error: %v, want: error ErrNoLinkAddress", string(e.addr.Addr), err)
-	}
-}
-
-// TestStaticResolution checks that static link addresses are resolved immediately and don't
-// send resolution requests.
-func TestStaticResolution(t *testing.T) {
-	c := newLinkAddrCache(1<<63-1, time.Millisecond, 1)
-	linkRes := &testLinkAddressResolver{cache: c, delay: time.Minute}
-
-	addr := tcpip.Address("broadcast")
-	want := tcpip.LinkAddress("mac_broadcast")
-	got, _, err := c.get(tcpip.FullAddress{Addr: addr}, linkRes, "", nil, nil)
-	if err != nil {
-		t.Errorf("c.get(%q)=%q, got error: %v", string(addr), string(got), err)
-	}
-	if got != want {
-		t.Errorf("c.get(%q)=%q, want %q", string(addr), string(got), string(want))
-	}
-}
diff --git a/pkg/tcpip/stack/linkaddrentry_list.go b/pkg/tcpip/stack/linkaddrentry_list.go
new file mode 100755
index 0000000..6697281
--- /dev/null
+++ b/pkg/tcpip/stack/linkaddrentry_list.go
@@ -0,0 +1,186 @@
+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 linkAddrEntryElementMapper struct{}
+
+// linkerFor maps an Element to a Linker.
+//
+// This default implementation should be inlined.
+//
+//go:nosplit
+func (linkAddrEntryElementMapper) linkerFor(elem *linkAddrEntry) *linkAddrEntry { 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 linkAddrEntryList struct {
+	head *linkAddrEntry
+	tail *linkAddrEntry
+}
+
+// Reset resets list l to the empty state.
+func (l *linkAddrEntryList) Reset() {
+	l.head = nil
+	l.tail = nil
+}
+
+// Empty returns true iff the list is empty.
+func (l *linkAddrEntryList) Empty() bool {
+	return l.head == nil
+}
+
+// Front returns the first element of list l or nil.
+func (l *linkAddrEntryList) Front() *linkAddrEntry {
+	return l.head
+}
+
+// Back returns the last element of list l or nil.
+func (l *linkAddrEntryList) Back() *linkAddrEntry {
+	return l.tail
+}
+
+// PushFront inserts the element e at the front of list l.
+func (l *linkAddrEntryList) PushFront(e *linkAddrEntry) {
+	linker := linkAddrEntryElementMapper{}.linkerFor(e)
+	linker.SetNext(l.head)
+	linker.SetPrev(nil)
+
+	if l.head != nil {
+		linkAddrEntryElementMapper{}.linkerFor(l.head).SetPrev(e)
+	} else {
+		l.tail = e
+	}
+
+	l.head = e
+}
+
+// PushBack inserts the element e at the back of list l.
+func (l *linkAddrEntryList) PushBack(e *linkAddrEntry) {
+	linker := linkAddrEntryElementMapper{}.linkerFor(e)
+	linker.SetNext(nil)
+	linker.SetPrev(l.tail)
+
+	if l.tail != nil {
+		linkAddrEntryElementMapper{}.linkerFor(l.tail).SetNext(e)
+	} else {
+		l.head = e
+	}
+
+	l.tail = e
+}
+
+// PushBackList inserts list m at the end of list l, emptying m.
+func (l *linkAddrEntryList) PushBackList(m *linkAddrEntryList) {
+	if l.head == nil {
+		l.head = m.head
+		l.tail = m.tail
+	} else if m.head != nil {
+		linkAddrEntryElementMapper{}.linkerFor(l.tail).SetNext(m.head)
+		linkAddrEntryElementMapper{}.linkerFor(m.head).SetPrev(l.tail)
+
+		l.tail = m.tail
+	}
+
+	m.head = nil
+	m.tail = nil
+}
+
+// InsertAfter inserts e after b.
+func (l *linkAddrEntryList) InsertAfter(b, e *linkAddrEntry) {
+	bLinker := linkAddrEntryElementMapper{}.linkerFor(b)
+	eLinker := linkAddrEntryElementMapper{}.linkerFor(e)
+
+	a := bLinker.Next()
+
+	eLinker.SetNext(a)
+	eLinker.SetPrev(b)
+	bLinker.SetNext(e)
+
+	if a != nil {
+		linkAddrEntryElementMapper{}.linkerFor(a).SetPrev(e)
+	} else {
+		l.tail = e
+	}
+}
+
+// InsertBefore inserts e before a.
+func (l *linkAddrEntryList) InsertBefore(a, e *linkAddrEntry) {
+	aLinker := linkAddrEntryElementMapper{}.linkerFor(a)
+	eLinker := linkAddrEntryElementMapper{}.linkerFor(e)
+
+	b := aLinker.Prev()
+	eLinker.SetNext(a)
+	eLinker.SetPrev(b)
+	aLinker.SetPrev(e)
+
+	if b != nil {
+		linkAddrEntryElementMapper{}.linkerFor(b).SetNext(e)
+	} else {
+		l.head = e
+	}
+}
+
+// Remove removes e from l.
+func (l *linkAddrEntryList) Remove(e *linkAddrEntry) {
+	linker := linkAddrEntryElementMapper{}.linkerFor(e)
+	prev := linker.Prev()
+	next := linker.Next()
+
+	if prev != nil {
+		linkAddrEntryElementMapper{}.linkerFor(prev).SetNext(next)
+	} else {
+		l.head = next
+	}
+
+	if next != nil {
+		linkAddrEntryElementMapper{}.linkerFor(next).SetPrev(prev)
+	} else {
+		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 linkAddrEntryEntry struct {
+	next *linkAddrEntry
+	prev *linkAddrEntry
+}
+
+// Next returns the entry that follows e in the list.
+func (e *linkAddrEntryEntry) Next() *linkAddrEntry {
+	return e.next
+}
+
+// Prev returns the entry that precedes e in the list.
+func (e *linkAddrEntryEntry) Prev() *linkAddrEntry {
+	return e.prev
+}
+
+// SetNext assigns 'entry' as the entry that follows e in the list.
+func (e *linkAddrEntryEntry) SetNext(elem *linkAddrEntry) {
+	e.next = elem
+}
+
+// SetPrev assigns 'entry' as the entry that precedes e in the list.
+func (e *linkAddrEntryEntry) SetPrev(elem *linkAddrEntry) {
+	e.prev = elem
+}
diff --git a/pkg/tcpip/stack/ndp.go b/pkg/tcpip/stack/ndp.go
old mode 100644
new mode 100755
diff --git a/pkg/tcpip/stack/ndp_test.go b/pkg/tcpip/stack/ndp_test.go
deleted file mode 100644
index 598468b..0000000
--- a/pkg/tcpip/stack/ndp_test.go
+++ /dev/null
@@ -1,3721 +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 (
-	"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/header"
-	"gvisor.dev/gvisor/pkg/tcpip/link/channel"
-	"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")
-	defaultTimeout           = 100 * time.Millisecond
-	defaultAsyncEventTimeout = 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.OnDuplicateAddressDetectionStatus.
-type ndpDADEvent struct {
-	nicID    tcpip.NICID
-	addr     tcpip.Address
-	resolved bool
-	err      *tcpip.Error
-}
-
-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 ndpDHCPv6Event struct {
-	nicID         tcpip.NICID
-	configuration stack.DHCPv6ConfigurationFromNDPRA
-}
-
-var _ stack.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
-	dhcpv6ConfigurationC chan ndpDHCPv6Event
-}
-
-// Implements stack.NDPDispatcher.OnDuplicateAddressDetectionStatus.
-func (n *ndpDispatcher) OnDuplicateAddressDetectionStatus(nicID tcpip.NICID, addr tcpip.Address, resolved bool, err *tcpip.Error) {
-	if n.dadC != nil {
-		n.dadC <- ndpDADEvent{
-			nicID,
-			addr,
-			resolved,
-			err,
-		}
-	}
-}
-
-// Implements stack.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 stack.NDPDispatcher.OnDefaultRouterInvalidated.
-func (n *ndpDispatcher) OnDefaultRouterInvalidated(nicID tcpip.NICID, addr tcpip.Address) {
-	if c := n.routerC; c != nil {
-		c <- ndpRouterEvent{
-			nicID,
-			addr,
-			false,
-		}
-	}
-}
-
-// Implements stack.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 stack.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 stack.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 stack.NDPDispatcher.OnDHCPv6Configuration.
-func (n *ndpDispatcher) OnDHCPv6Configuration(nicID tcpip.NICID, configuration stack.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, resolved bool, err *tcpip.Error) string {
-	return cmp.Diff(ndpDADEvent{nicID: nicID, addr: addr, resolved: resolved, err: err}, 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),
-	}
-	opts := stack.Options{
-		NetworkProtocols: []stack.NetworkProtocol{ipv6.NewProtocol()},
-		NDPDisp:          &ndpDisp,
-	}
-
-	e := channel.New(0, 1280, linkAddr1)
-	s := stack.New(opts)
-	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)
-	}
-
-	// 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, true, nil); diff != "" {
-			t.Errorf("dad event mismatch (-want +got):\n%s", diff)
-		}
-	default:
-		t.Fatal("expected DAD event")
-	}
-	addr, err := s.GetMainNICAddress(nicID, header.IPv6ProtocolNumber)
-	if err != nil {
-		t.Fatalf("stack.GetMainNICAddress(%d, %d) err = %s", nicID, header.IPv6ProtocolNumber, err)
-	}
-	if addr.Address != addr1 {
-		t.Fatalf("got stack.GetMainNICAddress(%d, %d) = %s, want = %s", nicID, header.IPv6ProtocolNumber, addr, addr1)
-	}
-
-	// We should not have sent any NDP NS messages.
-	if got := s.Stats().ICMP.V6PacketsSent.NeighborSolicit.Value(); got != 0 {
-		t.Fatalf("got NeighborSolicit = %d, want = 0", got)
-	}
-}
-
-// 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,
-		},
-	}
-
-	for _, test := range tests {
-		test := test
-
-		t.Run(test.name, func(t *testing.T) {
-			t.Parallel()
-
-			ndpDisp := ndpDispatcher{
-				dadC: make(chan ndpDADEvent),
-			}
-			opts := stack.Options{
-				NetworkProtocols: []stack.NetworkProtocol{ipv6.NewProtocol()},
-				NDPDisp:          &ndpDisp,
-			}
-			opts.NDPConfigs.RetransmitTimer = test.retransTimer
-			opts.NDPConfigs.DupAddrDetectTransmits = test.dupAddrDetectTransmits
-
-			e := channelLinkWithHeaderLength{
-				Endpoint:     channel.New(int(test.dupAddrDetectTransmits), 1280, linkAddr1),
-				headerLength: test.linkHeaderLen,
-			}
-			e.Endpoint.LinkEPCapabilities |= stack.CapabilityResolutionRequired
-			s := stack.New(opts)
-			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).
-			addr, err := s.GetMainNICAddress(nicID, header.IPv6ProtocolNumber)
-			if err != nil {
-				t.Fatalf("got stack.GetMainNICAddress(%d, %d) = (_, %v), want = (_, nil)", nicID, header.IPv6ProtocolNumber, err)
-			}
-			if want := (tcpip.AddressWithPrefix{}); addr != want {
-				t.Fatalf("got stack.GetMainNICAddress(%d, %d) = (%s, nil), want = (%s, nil)", nicID, header.IPv6ProtocolNumber, addr, want)
-			}
-
-			// Make sure the address does not resolve before the resolution time has
-			// passed.
-			time.Sleep(test.expectedRetransmitTimer*time.Duration(test.dupAddrDetectTransmits) - defaultAsyncEventTimeout)
-			addr, err = s.GetMainNICAddress(nicID, header.IPv6ProtocolNumber)
-			if err != nil {
-				t.Fatalf("got stack.GetMainNICAddress(%d, %d) = (_, %v), want = (_, nil)", nicID, header.IPv6ProtocolNumber, err)
-			}
-			if want := (tcpip.AddressWithPrefix{}); addr != want {
-				t.Fatalf("got stack.GetMainNICAddress(%d, %d) = (%s, nil), want = (%s, nil)", nicID, header.IPv6ProtocolNumber, addr, want)
-			}
-
-			// Wait for DAD to resolve.
-			select {
-			case <-time.After(2 * defaultAsyncEventTimeout):
-				t.Fatal("timed out waiting for DAD resolution")
-			case e := <-ndpDisp.dadC:
-				if diff := checkDADEvent(e, nicID, addr1, true, nil); diff != "" {
-					t.Errorf("dad event mismatch (-want +got):\n%s", diff)
-				}
-			}
-			addr, err = s.GetMainNICAddress(nicID, header.IPv6ProtocolNumber)
-			if err != nil {
-				t.Fatalf("got stack.GetMainNICAddress(%d, %d) = (_, %v), want = (_, nil)", nicID, header.IPv6ProtocolNumber, err)
-			}
-			if addr.Address != addr1 {
-				t.Fatalf("got stack.GetMainNICAddress(%d, %d) = %s, want = %s", nicID, header.IPv6ProtocolNumber, addr, addr1)
-			}
-
-			// Should not have sent any more NS messages.
-			if got := s.Stats().ICMP.V6PacketsSent.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, p.Pkt.Header.View().ToVectorisedView().First(),
-					checker.SrcAddr(header.IPv6Any),
-					checker.DstAddr(snmc),
-					checker.TTL(header.NDPHopLimit),
-					checker.NDPNS(
-						checker.NDPNSTargetAddress(addr1),
-						checker.NDPNSOptions(nil),
-					))
-
-				if l, want := p.Pkt.Header.AvailableLength(), int(test.linkHeaderLen); l != want {
-					t.Errorf("got p.Pkt.Header.AvailableLength() = %d; want = %d", l, want)
-				}
-			}
-		})
-	}
-}
-
-// 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
-		makeBuf func(tgt tcpip.Address) buffer.Prependable
-		getStat func(s tcpip.ICMPv6ReceivedPacketStats) *tcpip.StatCounter
-	}{
-		{
-			"RxSolicit",
-			func(tgt tcpip.Address) buffer.Prependable {
-				hdr := buffer.NewPrependable(header.IPv6MinimumSize + header.ICMPv6NeighborSolicitMinimumSize)
-				pkt := header.ICMPv6(hdr.Prepend(header.ICMPv6NeighborSolicitMinimumSize))
-				pkt.SetType(header.ICMPv6NeighborSolicit)
-				ns := header.NDPNeighborSolicit(pkt.NDPPayload())
-				ns.SetTargetAddress(tgt)
-				snmc := header.SolicitedNodeAddr(tgt)
-				pkt.SetChecksum(header.ICMPv6Checksum(pkt, header.IPv6Any, snmc, buffer.VectorisedView{}))
-				payloadLength := hdr.UsedLength()
-				ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize))
-				ip.Encode(&header.IPv6Fields{
-					PayloadLength: uint16(payloadLength),
-					NextHeader:    uint8(icmp.ProtocolNumber6),
-					HopLimit:      255,
-					SrcAddr:       header.IPv6Any,
-					DstAddr:       snmc,
-				})
-
-				return hdr
-
-			},
-			func(s tcpip.ICMPv6ReceivedPacketStats) *tcpip.StatCounter {
-				return s.NeighborSolicit
-			},
-		},
-		{
-			"RxAdvert",
-			func(tgt tcpip.Address) buffer.Prependable {
-				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.NDPPayload())
-				na.SetSolicitedFlag(true)
-				na.SetOverrideFlag(true)
-				na.SetTargetAddress(tgt)
-				na.Options().Serialize(header.NDPOptionsSerializer{
-					header.NDPTargetLinkLayerAddressOption(linkAddr1),
-				})
-				pkt.SetChecksum(header.ICMPv6Checksum(pkt, tgt, header.IPv6AllNodesMulticastAddress, buffer.VectorisedView{}))
-				payloadLength := hdr.UsedLength()
-				ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize))
-				ip.Encode(&header.IPv6Fields{
-					PayloadLength: uint16(payloadLength),
-					NextHeader:    uint8(icmp.ProtocolNumber6),
-					HopLimit:      255,
-					SrcAddr:       tgt,
-					DstAddr:       header.IPv6AllNodesMulticastAddress,
-				})
-
-				return hdr
-
-			},
-			func(s tcpip.ICMPv6ReceivedPacketStats) *tcpip.StatCounter {
-				return s.NeighborAdvert
-			},
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			ndpDisp := ndpDispatcher{
-				dadC: make(chan ndpDADEvent, 1),
-			}
-			ndpConfigs := stack.DefaultNDPConfigurations()
-			opts := stack.Options{
-				NetworkProtocols: []stack.NetworkProtocol{ipv6.NewProtocol()},
-				NDPConfigs:       ndpConfigs,
-				NDPDisp:          &ndpDisp,
-			}
-			opts.NDPConfigs.RetransmitTimer = time.Second * 2
-
-			e := channel.New(0, 1280, linkAddr1)
-			s := stack.New(opts)
-			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).
-			addr, err := s.GetMainNICAddress(nicID, header.IPv6ProtocolNumber)
-			if err != nil {
-				t.Fatalf("got stack.GetMainNICAddress(%d, %d) = (_, %v), want = (_, nil)", nicID, header.IPv6ProtocolNumber, err)
-			}
-			if want := (tcpip.AddressWithPrefix{}); addr != want {
-				t.Fatalf("got stack.GetMainNICAddress(%d, %d) = (%s, nil), want = (%s, nil)", nicID, header.IPv6ProtocolNumber, addr, want)
-			}
-
-			// Receive a packet to simulate multiple nodes owning or
-			// attempting to own the same address.
-			hdr := test.makeBuf(addr1)
-			e.InjectInbound(header.IPv6ProtocolNumber, stack.PacketBuffer{
-				Data: hdr.View().ToVectorisedView(),
-			})
-
-			stat := test.getStat(s.Stats().ICMP.V6PacketsReceived)
-			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(ndpConfigs.DupAddrDetectTransmits)*ndpConfigs.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, false, nil); diff != "" {
-					t.Errorf("dad event mismatch (-want +got):\n%s", diff)
-				}
-			}
-			addr, err = s.GetMainNICAddress(nicID, header.IPv6ProtocolNumber)
-			if err != nil {
-				t.Fatalf("got stack.GetMainNICAddress(%d, %d) = (_, %v), want = (_, nil)", nicID, header.IPv6ProtocolNumber, err)
-			}
-			if want := (tcpip.AddressWithPrefix{}); addr != want {
-				t.Fatalf("got stack.GetMainNICAddress(%d, %d) = (%s, nil), want = (%s, nil)", nicID, header.IPv6ProtocolNumber, addr, want)
-			}
-		})
-	}
-}
-
-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),
-			}
-			ndpConfigs := stack.NDPConfigurations{
-				RetransmitTimer:        time.Second,
-				DupAddrDetectTransmits: 2,
-			}
-			opts := stack.Options{
-				NetworkProtocols: []stack.NetworkProtocol{ipv6.NewProtocol()},
-				NDPDisp:          &ndpDisp,
-				NDPConfigs:       ndpConfigs,
-			}
-
-			e := channel.New(0, 1280, linkAddr1)
-			s := stack.New(opts)
-			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).
-			addr, err := s.GetMainNICAddress(nicID, header.IPv6ProtocolNumber)
-			if err != nil {
-				t.Fatalf("got stack.GetMainNICAddress(%d, %d) = (_, %v), want = (_, nil)", nicID, header.IPv6ProtocolNumber, err)
-			}
-			if want := (tcpip.AddressWithPrefix{}); addr != want {
-				t.Fatalf("got stack.GetMainNICAddress(%d, %d) = (%s, nil), want = (%s, nil)", nicID, header.IPv6ProtocolNumber, addr, want)
-			}
-
-			test.stopFn(t, s)
-
-			// Wait for DAD to fail (since the address was removed during DAD).
-			select {
-			case <-time.After(time.Duration(ndpConfigs.DupAddrDetectTransmits)*ndpConfigs.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, false, nil); diff != "" {
-					t.Errorf("dad event mismatch (-want +got):\n%s", diff)
-				}
-			}
-
-			if !test.skipFinalAddrCheck {
-				addr, err := s.GetMainNICAddress(nicID, header.IPv6ProtocolNumber)
-				if err != nil {
-					t.Fatalf("got stack.GetMainNICAddress(%d, %d) = (_, %v), want = (_, nil)", nicID, header.IPv6ProtocolNumber, err)
-				}
-				if want := (tcpip.AddressWithPrefix{}); addr != want {
-					t.Errorf("got stack.GetMainNICAddress(%d, %d) = (%s, nil), want = (%s, nil)", nicID, header.IPv6ProtocolNumber, addr, want)
-				}
-			}
-
-			// Should not have sent more than 1 NS message.
-			if got := s.Stats().ICMP.V6PacketsSent.NeighborSolicit.Value(); got > 1 {
-				t.Errorf("got NeighborSolicit = %d, want <= 1", got)
-			}
-		})
-	}
-}
-
-// TestSetNDPConfigurationFailsForBadNICID tests to make sure we get an error if
-// we attempt to update NDP configurations using an invalid NICID.
-func TestSetNDPConfigurationFailsForBadNICID(t *testing.T) {
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocol{ipv6.NewProtocol()},
-	})
-
-	// No NIC with ID 1 yet.
-	if got := s.SetNDPConfigurations(1, stack.NDPConfigurations{}); got != tcpip.ErrUnknownNICID {
-		t.Fatalf("got s.SetNDPConfigurations = %v, want = %s", got, tcpip.ErrUnknownNICID)
-	}
-}
-
-// 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.NetworkProtocol{ipv6.NewProtocol()},
-				NDPDisp:          &ndpDisp,
-			})
-
-			expectDADEvent := func(nicID tcpip.NICID, addr tcpip.Address) {
-				select {
-				case e := <-ndpDisp.dadC:
-					if diff := checkDADEvent(e, nicID, addr, true, nil); 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 NDP configurations on NIC(1) to use DAD.
-			configs := stack.NDPConfigurations{
-				DupAddrDetectTransmits: test.dupAddrDetectTransmits,
-				RetransmitTimer:        test.retransmitTimer,
-			}
-			if err := s.SetNDPConfigurations(nicID1, configs); err != nil {
-				t.Fatalf("got SetNDPConfigurations(%d, _) = %s", nicID1, err)
-			}
-
-			// 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.
-			if err := s.AddAddress(nicID1, header.IPv6ProtocolNumber, addr1); err != nil {
-				t.Fatalf("AddAddress(%d, %d, %s) = %s", nicID1, header.IPv6ProtocolNumber, addr1, err)
-			}
-			if err := s.AddAddress(nicID2, header.IPv6ProtocolNumber, addr2); err != nil {
-				t.Fatalf("AddAddress(%d, %d, %s) = %s", nicID2, header.IPv6ProtocolNumber, addr2, err)
-			}
-			expectDADEvent(nicID2, addr2)
-			if err := s.AddAddress(nicID3, header.IPv6ProtocolNumber, addr3); err != nil {
-				t.Fatalf("AddAddress(%d, %d, %s) = %s", nicID3, header.IPv6ProtocolNumber, addr3, err)
-			}
-			expectDADEvent(nicID3, addr3)
-
-			// Address should not be considered bound to NIC(1) yet
-			// (DAD ongoing).
-			addr, err := s.GetMainNICAddress(nicID1, header.IPv6ProtocolNumber)
-			if err != nil {
-				t.Fatalf("got stack.GetMainNICAddress(%d, %d) = (_, %v), want = (_, nil)", nicID1, header.IPv6ProtocolNumber, err)
-			}
-			if want := (tcpip.AddressWithPrefix{}); addr != want {
-				t.Fatalf("got stack.GetMainNICAddress(%d, %d) = (%s, nil), want = (%s, nil)", nicID1, header.IPv6ProtocolNumber, addr, want)
-			}
-
-			// 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).
-			addr, err = s.GetMainNICAddress(nicID2, header.IPv6ProtocolNumber)
-			if err != nil {
-				t.Fatalf("got stack.GetMainNICAddress(%d, %d) = (_, %v), want = (_, nil)", nicID2, header.IPv6ProtocolNumber, err)
-			}
-			if addr.Address != addr2 {
-				t.Fatalf("got stack.GetMainNICAddress(%d, %d) = %s, want = %s", nicID2, header.IPv6ProtocolNumber, addr, addr2)
-			}
-			addr, err = s.GetMainNICAddress(nicID3, header.IPv6ProtocolNumber)
-			if err != nil {
-				t.Fatalf("got stack.GetMainNICAddress(%d, %d) = (_, %v), want = (_, nil)", nicID3, header.IPv6ProtocolNumber, err)
-			}
-			if addr.Address != addr3 {
-				t.Fatalf("got stack.GetMainNICAddress(%d, %d) = %s, want = %s", nicID3, header.IPv6ProtocolNumber, addr, addr3)
-			}
-
-			// 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)
-			addr, err = s.GetMainNICAddress(nicID1, header.IPv6ProtocolNumber)
-			if err != nil {
-				t.Fatalf("got stack.GetMainNICAddress(%d, %d) = (_, %v), want = (_, nil)", nicID1, header.IPv6ProtocolNumber, err)
-			}
-			if want := (tcpip.AddressWithPrefix{}); addr != want {
-				t.Fatalf("got stack.GetMainNICAddress(%d, %d) = (%s, nil), want = (%s, nil)", nicID1, header.IPv6ProtocolNumber, addr, want)
-			}
-
-			// 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, true, nil); diff != "" {
-					t.Errorf("dad event mismatch (-want +got):\n%s", diff)
-				}
-			}
-			addr, err = s.GetMainNICAddress(nicID1, header.IPv6ProtocolNumber)
-			if err != nil {
-				t.Fatalf("got stack.GetMainNICAddress(%d, %d) = (_, %v), want = (_, nil)", nicID1, header.IPv6ProtocolNumber, err)
-			}
-			if addr.Address != addr1 {
-				t.Fatalf("got stack.GetMainNICAddress(%d, %d) = %s, want = %s", nicID1, header.IPv6ProtocolNumber, addr, addr1)
-			}
-		})
-	}
-}
-
-// 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.NDPPayload()
-	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(pkt, ip, header.IPv6AllNodesMulticastAddress, buffer.VectorisedView{}))
-	payloadLength := hdr.UsedLength()
-	iph := header.IPv6(hdr.Prepend(header.IPv6MinimumSize))
-	iph.Encode(&header.IPv6Fields{
-		PayloadLength: uint16(payloadLength),
-		NextHeader:    uint8(icmp.ProtocolNumber6),
-		HopLimit:      header.NDPHopLimit,
-		SrcAddr:       ip,
-		DstAddr:       header.IPv6AllNodesMulticastAddress,
-	})
-
-	return stack.PacketBuffer{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.NetworkProtocol{ipv6.NewProtocol()},
-				NDPConfigs: stack.NDPConfigurations{
-					HandleRAs:              handle,
-					DiscoverDefaultRouters: discover,
-				},
-				NDPDisp: &ndpDisp,
-			})
-			s.SetForwarding(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.NetworkProtocol{ipv6.NewProtocol()},
-		NDPConfigs: stack.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 + defaultTimeout):
-	}
-}
-
-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.NetworkProtocol{ipv6.NewProtocol()},
-		NDPConfigs: stack.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 timer to fire. 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+defaultAsyncEventTimeout)
-
-	// 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 timer to fire. 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+defaultAsyncEventTimeout)
-}
-
-// TestRouterDiscoveryMaxRouters tests that only
-// stack.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.NetworkProtocol{ipv6.NewProtocol()},
-		NDPConfigs: stack.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 <= stack.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 <= stack.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.NetworkProtocol{ipv6.NewProtocol()},
-				NDPConfigs: stack.NDPConfigurations{
-					HandleRAs:              handle,
-					DiscoverOnLinkPrefixes: discover,
-				},
-				NDPDisp: &ndpDisp,
-			})
-			s.SetForwarding(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.NetworkProtocol{ipv6.NewProtocol()},
-		NDPConfigs: stack.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 + defaultTimeout):
-	}
-}
-
-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.NetworkProtocol{ipv6.NewProtocol()},
-		NDPConfigs: stack.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 timer 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 + defaultAsyncEventTimeout):
-		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.NetworkProtocol{ipv6.NewProtocol()},
-		NDPConfigs: stack.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 + defaultTimeout):
-	}
-
-	// 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 + defaultTimeout):
-	}
-
-	// 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 + defaultTimeout):
-	}
-
-	// 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
-// stack.MaxDiscoveredOnLinkPrefixes discovered on-link prefixes are remembered.
-func TestPrefixDiscoveryMaxOnLinkPrefixes(t *testing.T) {
-	ndpDisp := ndpDispatcher{
-		prefixC:        make(chan ndpPrefixEvent, stack.MaxDiscoveredOnLinkPrefixes+3),
-		rememberPrefix: true,
-	}
-	e := channel.New(0, 1280, linkAddr1)
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocol{ipv6.NewProtocol()},
-		NDPConfigs: stack.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, stack.MaxDiscoveredOnLinkPrefixes+2)
-	prefixes := [stack.MaxDiscoveredOnLinkPrefixes + 2]tcpip.Subnet{}
-
-	// Receive an RA with 2 more than the max number of discovered on-link
-	// prefixes.
-	for i := 0; i < stack.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 < stack.MaxDiscoveredOnLinkPrefixes+2; i++ {
-		if i < stack.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,
-	}
-
-	for _, i := range list {
-		if i == protocolAddress {
-			return true
-		}
-	}
-
-	return false
-}
-
-// 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.NetworkProtocol{ipv6.NewProtocol()},
-				NDPConfigs: stack.NDPConfigurations{
-					HandleRAs:              handle,
-					AutoGenGlobalAddresses: autogen,
-				},
-				NDPDisp: &ndpDisp,
-			})
-			s.SetForwarding(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 TestAutoGenAddr(t *testing.T) {
-	const newMinVL = 2
-	newMinVLDuration := newMinVL * time.Second
-	saved := stack.MinPrefixInformationValidLifetimeForUpdate
-	defer func() {
-		stack.MinPrefixInformationValidLifetimeForUpdate = saved
-	}()
-	stack.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.NetworkProtocol{ipv6.NewProtocol()},
-		NDPConfigs: stack.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 + defaultAsyncEventTimeout):
-		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)
-	}
-}
-
-// 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)
-	s := stack.New(stack.Options{
-		NetworkProtocols:   []stack.NetworkProtocol{ipv6.NewProtocol()},
-		TransportProtocols: []stack.TransportProtocol{udp.NewProtocol()},
-		NDPConfigs: stack.NDPConfigurations{
-			HandleRAs:              true,
-			AutoGenGlobalAddresses: true,
-		},
-		NDPDisp: ndpDisp,
-	})
-	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,
-	}})
-	s.AddLinkAddress(nicID, llAddr3, linkAddr3)
-	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()
-	if err := ep.SetSockOptBool(tcpip.V6OnlyOption, true); err != nil {
-		t.Fatalf("SetSockOpt(tcpip.V6OnlyOption, true): %s", err)
-	}
-	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()
-	if err := ep.SetSockOptBool(tcpip.V6OnlyOption, true); err != nil {
-		t.Fatalf("SetSockOpt(tcpip.V6OnlyOption, true): %s", err)
-	}
-	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 got, err := s.GetMainNICAddress(nicID, header.IPv6ProtocolNumber); err != nil {
-			t.Fatalf("s.GetMainNICAddress(%d, %d): %s", nicID, header.IPv6ProtocolNumber, err)
-		} else if got != addr {
-			t.Errorf("got s.GetMainNICAddress(%d, %d) = %s, want = %s", nicID, header.IPv6ProtocolNumber, got, addr)
-		}
-
-		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", 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", 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)
-}
-
-// TestAutoGenAddrTimerDeprecation tests that an address is properly deprecated
-// when its preferred lifetime expires.
-func TestAutoGenAddrTimerDeprecation(t *testing.T) {
-	const nicID = 1
-	const newMinVL = 2
-	newMinVLDuration := newMinVL * time.Second
-	saved := stack.MinPrefixInformationValidLifetimeForUpdate
-	defer func() {
-		stack.MinPrefixInformationValidLifetimeForUpdate = saved
-	}()
-	stack.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 got, err := s.GetMainNICAddress(nicID, header.IPv6ProtocolNumber); err != nil {
-			t.Fatalf("s.GetMainNICAddress(%d, %d): %s", nicID, header.IPv6ProtocolNumber, err)
-		} else if got != addr {
-			t.Errorf("got s.GetMainNICAddress(%d, %d) = %s, want = %s", nicID, header.IPv6ProtocolNumber, got, addr)
-		}
-
-		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+defaultAsyncEventTimeout)
-	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", 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", 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+defaultAsyncEventTimeout)
-	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", got, addr1.Address)
-	}
-
-	// Wait for addr of prefix1 to be invalidated.
-	expectAutoGenAddrEventAfter(addr1, invalidatedAddr, time.Second+defaultAsyncEventTimeout)
-	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(defaultAsyncEventTimeout):
-				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(defaultTimeout):
-			}
-		} else {
-			t.Fatalf("got unexpected auto-generated event")
-		}
-
-	case <-time.After(newMinVLDuration + defaultAsyncEventTimeout):
-		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 got, err := s.GetMainNICAddress(nicID, header.IPv6ProtocolNumber); err != nil {
-		t.Fatalf("s.GetMainNICAddress(%d, %d): %s", nicID, header.IPv6ProtocolNumber, err)
-	} else if want := (tcpip.AddressWithPrefix{}); got != want {
-		t.Errorf("got s.GetMainNICAddress(%d, %d) = %s, want = %s", nicID, header.IPv6ProtocolNumber, got, want)
-	}
-	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()
-	if err := ep.SetSockOptBool(tcpip.V6OnlyOption, true); err != nil {
-		t.Fatalf("SetSockOpt(tcpip.V6OnlyOption, true): %s", err)
-	}
-
-	if err := ep.Connect(dstAddr); err != tcpip.ErrNoRoute {
-		t.Errorf("got ep.Connect(%+v) = %v, 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 := stack.MinPrefixInformationValidLifetimeForUpdate
-	defer func() {
-		stack.MinPrefixInformationValidLifetimeForUpdate = savedMinVL
-		header.NDPInfiniteLifetime = savedIL
-	}()
-	stack.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.NetworkProtocol{ipv6.NewProtocol()},
-					NDPConfigs: stack.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 + defaultAsyncEventTimeout):
-					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 := stack.MinPrefixInformationValidLifetimeForUpdate
-	defer func() {
-		stack.MinPrefixInformationValidLifetimeForUpdate = saved
-	}()
-	stack.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.NetworkProtocol{ipv6.NewProtocol()},
-					NDPConfigs: stack.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 - defaultAsyncEventTimeout):
-				}
-
-				// 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(2 * defaultAsyncEventTimeout):
-					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.NetworkProtocol{ipv6.NewProtocol()},
-		NDPConfigs: stack.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 timer
-	// got stopped/cleaned up.
-	select {
-	case <-ndpDisp.autoGenAddrC:
-		t.Fatal("unexpectedly received an auto gen addr event")
-	case <-time.After(lifetimeSeconds*time.Second + defaultTimeout):
-	}
-}
-
-// 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 got, err := s.GetMainNICAddress(nicID, header.IPv6ProtocolNumber); err != nil {
-			t.Fatalf("s.GetMainNICAddress(%d, %d): %s", nicID, header.IPv6ProtocolNumber, err)
-		} else if got != addr {
-			t.Errorf("got s.GetMainNICAddress(%d, %d) = %s, want = %s", nicID, header.IPv6ProtocolNumber, got, addr)
-		}
-
-		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) = %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.NetworkProtocol{ipv6.NewProtocol()},
-		NDPConfigs: stack.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 + defaultTimeout):
-	}
-	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.NetworkProtocol{ipv6.NewProtocol()},
-		NDPConfigs: stack.NDPConfigurations{
-			HandleRAs:              true,
-			AutoGenGlobalAddresses: true,
-		},
-		NDPDisp: &ndpDisp,
-		OpaqueIIDOpts: stack.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 + defaultAsyncEventTimeout):
-		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)
-	}
-}
-
-// 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.NetworkProtocol{ipv6.NewProtocol()},
-				NDPConfigs: stack.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:
-			}
-		})
-	}
-}
-
-// 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(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.NetworkProtocol{ipv6.NewProtocol()},
-				AutoGenIPv6LinkLocal: true,
-				NDPConfigs: stack.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 + defaultTimeout)
-			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.NetworkProtocol{ipv6.NewProtocol()},
-		NDPConfigs: stack.NDPConfigurations{
-			HandleRAs: true,
-		},
-		NDPDisp: &ndpDisp,
-	})
-
-	if err := s.CreateNIC(nicID, e); err != nil {
-		t.Fatalf("CreateNIC(%d, _) = %s", nicID, err)
-	}
-
-	expectDHCPv6Event := func(configuration stack.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:
-		}
-	}
-
-	// The initial DHCPv6 configuration should be stack.DHCPv6NoConfiguration.
-	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(stack.DHCPv6OtherConfigurations)
-	// Receiving the same update again should not result in an event to the
-	// NDPDispatcher.
-	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(stack.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(stack.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(stack.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(stack.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,
-		},
-	}
-
-	// 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()
-
-				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()
-					ctx, _ := context.WithTimeout(context.Background(), timeout)
-					p, ok := e.ReadContext(ctx)
-					if !ok {
-						t.Fatal("timed out waiting for packet")
-						return
-					}
-
-					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,
-						p.Pkt.Header.View(),
-						checker.SrcAddr(test.expectedSrcAddr),
-						checker.DstAddr(header.IPv6AllRoutersMulticastAddress),
-						checker.TTL(header.NDPHopLimit),
-						checker.NDPRS(checker.NDPRSOptions(test.expectedNDPOpts)),
-					)
-
-					if l, want := p.Pkt.Header.AvailableLength(), int(test.linkHeaderLen); l != want {
-						t.Errorf("got p.Pkt.Header.AvailableLength() = %d; want = %d", l, want)
-					}
-				}
-				waitForNothing := func(timeout time.Duration) {
-					t.Helper()
-					ctx, _ := context.WithTimeout(context.Background(), timeout)
-					if _, ok := e.ReadContext(ctx); ok {
-						t.Fatal("unexpectedly got a packet")
-					}
-				}
-				s := stack.New(stack.Options{
-					NetworkProtocols: []stack.NetworkProtocol{ipv6.NewProtocol()},
-					NDPConfigs: stack.NDPConfigurations{
-						MaxRtrSolicitations:     test.maxRtrSolicit,
-						RtrSolicitationInterval: test.rtrSolicitInt,
-						MaxRtrSolicitationDelay: test.maxRtrSolicitDelay,
-					},
-				})
-				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 + defaultAsyncEventTimeout)
-					remaining--
-				}
-
-				for ; remaining > 0; remaining-- {
-					if test.effectiveRtrSolicitInt > defaultAsyncEventTimeout {
-						waitForNothing(test.effectiveRtrSolicitInt - defaultAsyncEventTimeout)
-						waitForPkt(2 * defaultAsyncEventTimeout)
-					} else {
-						waitForPkt(test.effectiveRtrSolicitInt * defaultAsyncEventTimeout)
-					}
-				}
-
-				// Make sure no more RS.
-				if test.effectiveRtrSolicitInt > test.effectiveMaxRtrSolicitDelay {
-					waitForNothing(test.effectiveRtrSolicitInt + defaultAsyncEventTimeout)
-				} else {
-					waitForNothing(test.effectiveMaxRtrSolicitDelay + defaultAsyncEventTimeout)
-				}
-
-				// Make sure the counter got properly
-				// incremented.
-				if got, want := s.Stats().ICMP.V6PacketsSent.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(false)
-			},
-			stopFn: func(t *testing.T, s *stack.Stack, _ bool) {
-				t.Helper()
-				s.SetForwarding(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, p.Pkt.Header.View(),
-					checker.SrcAddr(header.IPv6Any),
-					checker.DstAddr(header.IPv6AllRoutersMulticastAddress),
-					checker.TTL(header.NDPHopLimit),
-					checker.NDPRS())
-			}
-			s := stack.New(stack.Options{
-				NetworkProtocols: []stack.NetworkProtocol{ipv6.NewProtocol()},
-				NDPConfigs: stack.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+defaultAsyncEventTimeout)
-			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+defaultAsyncEventTimeout)
-				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+defaultAsyncEventTimeout)
-			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 + defaultAsyncEventTimeout)
-			waitForPkt(interval + defaultAsyncEventTimeout)
-			waitForPkt(interval + defaultAsyncEventTimeout)
-			ctx, cancel = context.WithTimeout(context.Background(), interval+defaultAsyncEventTimeout)
-			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+defaultAsyncEventTimeout)
-			defer cancel()
-			if _, ok := e.ReadContext(ctx); ok {
-				t.Fatal("unexpectedly got a packet after finishing router solicitations")
-			}
-		})
-	}
-}
diff --git a/pkg/tcpip/stack/nic_test.go b/pkg/tcpip/stack/nic_test.go
deleted file mode 100644
index d672fc1..0000000
--- a/pkg/tcpip/stack/nic_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
-
-import (
-	"testing"
-
-	"gvisor.dev/gvisor/pkg/tcpip/buffer"
-)
-
-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(nil, "", "", 0, PacketBuffer{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/packet_buffer.go b/pkg/tcpip/stack/packet_buffer.go
old mode 100644
new mode 100755
diff --git a/pkg/tcpip/stack/packet_buffer_state.go b/pkg/tcpip/stack/packet_buffer_state.go
old mode 100644
new mode 100755
diff --git a/pkg/tcpip/stack/rand.go b/pkg/tcpip/stack/rand.go
old mode 100644
new mode 100755
diff --git a/pkg/tcpip/stack/stack_state_autogen.go b/pkg/tcpip/stack/stack_state_autogen.go
new file mode 100755
index 0000000..7f038a8
--- /dev/null
+++ b/pkg/tcpip/stack/stack_state_autogen.go
@@ -0,0 +1,156 @@
+// automatically generated by stateify.
+
+package stack
+
+import (
+	"gvisor.dev/gvisor/pkg/state"
+)
+
+func (x *linkAddrEntryList) beforeSave() {}
+func (x *linkAddrEntryList) save(m state.Map) {
+	x.beforeSave()
+	m.Save("head", &x.head)
+	m.Save("tail", &x.tail)
+}
+
+func (x *linkAddrEntryList) afterLoad() {}
+func (x *linkAddrEntryList) load(m state.Map) {
+	m.Load("head", &x.head)
+	m.Load("tail", &x.tail)
+}
+
+func (x *linkAddrEntryEntry) beforeSave() {}
+func (x *linkAddrEntryEntry) save(m state.Map) {
+	x.beforeSave()
+	m.Save("next", &x.next)
+	m.Save("prev", &x.prev)
+}
+
+func (x *linkAddrEntryEntry) afterLoad() {}
+func (x *linkAddrEntryEntry) load(m state.Map) {
+	m.Load("next", &x.next)
+	m.Load("prev", &x.prev)
+}
+
+func (x *PacketBuffer) save(m state.Map) {
+	x.beforeSave()
+	m.Save("Data", &x.Data)
+	m.Save("DataOffset", &x.DataOffset)
+	m.Save("DataSize", &x.DataSize)
+	m.Save("Header", &x.Header)
+	m.Save("LinkHeader", &x.LinkHeader)
+	m.Save("NetworkHeader", &x.NetworkHeader)
+	m.Save("TransportHeader", &x.TransportHeader)
+	m.Save("Hash", &x.Hash)
+	m.Save("Owner", &x.Owner)
+}
+
+func (x *PacketBuffer) afterLoad() {}
+func (x *PacketBuffer) load(m state.Map) {
+	m.Load("Data", &x.Data)
+	m.Load("DataOffset", &x.DataOffset)
+	m.Load("DataSize", &x.DataSize)
+	m.Load("Header", &x.Header)
+	m.Load("LinkHeader", &x.LinkHeader)
+	m.Load("NetworkHeader", &x.NetworkHeader)
+	m.Load("TransportHeader", &x.TransportHeader)
+	m.Load("Hash", &x.Hash)
+	m.Load("Owner", &x.Owner)
+}
+
+func (x *TransportEndpointID) beforeSave() {}
+func (x *TransportEndpointID) save(m state.Map) {
+	x.beforeSave()
+	m.Save("LocalPort", &x.LocalPort)
+	m.Save("LocalAddress", &x.LocalAddress)
+	m.Save("RemotePort", &x.RemotePort)
+	m.Save("RemoteAddress", &x.RemoteAddress)
+}
+
+func (x *TransportEndpointID) afterLoad() {}
+func (x *TransportEndpointID) load(m state.Map) {
+	m.Load("LocalPort", &x.LocalPort)
+	m.Load("LocalAddress", &x.LocalAddress)
+	m.Load("RemotePort", &x.RemotePort)
+	m.Load("RemoteAddress", &x.RemoteAddress)
+}
+
+func (x *GSOType) save(m state.Map) {
+	m.SaveValue("", (int)(*x))
+}
+
+func (x *GSOType) load(m state.Map) {
+	m.LoadValue("", new(int), func(y interface{}) { *x = (GSOType)(y.(int)) })
+}
+
+func (x *GSO) beforeSave() {}
+func (x *GSO) save(m state.Map) {
+	x.beforeSave()
+	m.Save("Type", &x.Type)
+	m.Save("NeedsCsum", &x.NeedsCsum)
+	m.Save("CsumOffset", &x.CsumOffset)
+	m.Save("MSS", &x.MSS)
+	m.Save("L3HdrLen", &x.L3HdrLen)
+	m.Save("MaxSize", &x.MaxSize)
+}
+
+func (x *GSO) afterLoad() {}
+func (x *GSO) load(m state.Map) {
+	m.Load("Type", &x.Type)
+	m.Load("NeedsCsum", &x.NeedsCsum)
+	m.Load("CsumOffset", &x.CsumOffset)
+	m.Load("MSS", &x.MSS)
+	m.Load("L3HdrLen", &x.L3HdrLen)
+	m.Load("MaxSize", &x.MaxSize)
+}
+
+func (x *TransportEndpointInfo) beforeSave() {}
+func (x *TransportEndpointInfo) save(m state.Map) {
+	x.beforeSave()
+	m.Save("NetProto", &x.NetProto)
+	m.Save("TransProto", &x.TransProto)
+	m.Save("ID", &x.ID)
+	m.Save("BindNICID", &x.BindNICID)
+	m.Save("BindAddr", &x.BindAddr)
+	m.Save("RegisterNICID", &x.RegisterNICID)
+}
+
+func (x *TransportEndpointInfo) afterLoad() {}
+func (x *TransportEndpointInfo) load(m state.Map) {
+	m.Load("NetProto", &x.NetProto)
+	m.Load("TransProto", &x.TransProto)
+	m.Load("ID", &x.ID)
+	m.Load("BindNICID", &x.BindNICID)
+	m.Load("BindAddr", &x.BindAddr)
+	m.Load("RegisterNICID", &x.RegisterNICID)
+}
+
+func (x *multiPortEndpoint) beforeSave() {}
+func (x *multiPortEndpoint) save(m state.Map) {
+	x.beforeSave()
+	m.Save("demux", &x.demux)
+	m.Save("netProto", &x.netProto)
+	m.Save("transProto", &x.transProto)
+	m.Save("endpoints", &x.endpoints)
+	m.Save("reuse", &x.reuse)
+}
+
+func (x *multiPortEndpoint) afterLoad() {}
+func (x *multiPortEndpoint) load(m state.Map) {
+	m.Load("demux", &x.demux)
+	m.Load("netProto", &x.netProto)
+	m.Load("transProto", &x.transProto)
+	m.Load("endpoints", &x.endpoints)
+	m.Load("reuse", &x.reuse)
+}
+
+func init() {
+	state.Register("pkg/tcpip/stack.linkAddrEntryList", (*linkAddrEntryList)(nil), state.Fns{Save: (*linkAddrEntryList).save, Load: (*linkAddrEntryList).load})
+	state.Register("pkg/tcpip/stack.linkAddrEntryEntry", (*linkAddrEntryEntry)(nil), state.Fns{Save: (*linkAddrEntryEntry).save, Load: (*linkAddrEntryEntry).load})
+	state.Register("pkg/tcpip/stack.PacketBuffer", (*PacketBuffer)(nil), state.Fns{Save: (*PacketBuffer).save, Load: (*PacketBuffer).load})
+	state.Register("pkg/tcpip/stack.TransportEndpointID", (*TransportEndpointID)(nil), state.Fns{Save: (*TransportEndpointID).save, Load: (*TransportEndpointID).load})
+	state.Register("pkg/tcpip/stack.GSOType", (*GSOType)(nil), state.Fns{Save: (*GSOType).save, Load: (*GSOType).load})
+	state.Register("pkg/tcpip/stack.GSO", (*GSO)(nil), state.Fns{Save: (*GSO).save, Load: (*GSO).load})
+	state.Register("pkg/tcpip/stack.TransportEndpointInfo", (*TransportEndpointInfo)(nil), state.Fns{Save: (*TransportEndpointInfo).save, Load: (*TransportEndpointInfo).load})
+	state.Register("pkg/tcpip/stack.multiPortEndpoint", (*multiPortEndpoint)(nil), state.Fns{Save: (*multiPortEndpoint).save, Load: (*multiPortEndpoint).load})
+}
diff --git a/pkg/tcpip/stack/stack_test.go b/pkg/tcpip/stack/stack_test.go
deleted file mode 100644
index b8543b7..0000000
--- a/pkg/tcpip/stack/stack_test.go
+++ /dev/null
@@ -1,3278 +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"
-	"sort"
-	"strings"
-	"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/header"
-	"gvisor.dev/gvisor/pkg/tcpip/link/channel"
-	"gvisor.dev/gvisor/pkg/tcpip/link/loopback"
-	"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
-)
-
-// 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 {
-	nicID      tcpip.NICID
-	id         stack.NetworkEndpointID
-	prefixLen  int
-	proto      *fakeNetworkProtocol
-	dispatcher stack.TransportDispatcher
-	ep         stack.LinkEndpoint
-}
-
-func (f *fakeNetworkEndpoint) MTU() uint32 {
-	return f.ep.MTU() - uint32(f.MaxHeaderLength())
-}
-
-func (f *fakeNetworkEndpoint) NICID() tcpip.NICID {
-	return f.nicID
-}
-
-func (f *fakeNetworkEndpoint) PrefixLen() int {
-	return f.prefixLen
-}
-
-func (*fakeNetworkEndpoint) DefaultTTL() uint8 {
-	return 123
-}
-
-func (f *fakeNetworkEndpoint) ID() *stack.NetworkEndpointID {
-	return &f.id
-}
-
-func (f *fakeNetworkEndpoint) HandlePacket(r *stack.Route, pkt stack.PacketBuffer) {
-	// Increment the received packet count in the protocol descriptor.
-	f.proto.packetCount[int(f.id.LocalAddress[0])%len(f.proto.packetCount)]++
-
-	// Consume the network header.
-	b := pkt.Data.First()
-	pkt.Data.TrimFront(fakeNetHeaderLen)
-
-	// Handle control packets.
-	if b[2] == uint8(fakeControlProtocol) {
-		nb := pkt.Data.First()
-		if len(nb) < fakeNetHeaderLen {
-			return
-		}
-
-		pkt.Data.TrimFront(fakeNetHeaderLen)
-		f.dispatcher.DeliverTransportControlPacket(tcpip.Address(nb[1:2]), tcpip.Address(nb[0:1]), fakeNetNumber, tcpip.TransportProtocolNumber(nb[2]), stack.ControlPortUnreachable, 0, pkt)
-		return
-	}
-
-	// Dispatch the packet to the transport protocol.
-	f.dispatcher.DeliverTransportPacket(r, tcpip.TransportProtocolNumber(b[2]), pkt)
-}
-
-func (f *fakeNetworkEndpoint) MaxHeaderLength() uint16 {
-	return f.ep.MaxHeaderLength() + fakeNetHeaderLen
-}
-
-func (f *fakeNetworkEndpoint) PseudoHeaderChecksum(protocol tcpip.TransportProtocolNumber, dstAddr tcpip.Address) uint16 {
-	return 0
-}
-
-func (f *fakeNetworkEndpoint) Capabilities() stack.LinkEndpointCapabilities {
-	return f.ep.Capabilities()
-}
-
-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.
-	b := pkt.Header.Prepend(fakeNetHeaderLen)
-	b[0] = r.RemoteAddress[0]
-	b[1] = f.id.LocalAddress[0]
-	b[2] = byte(params.Protocol)
-
-	if r.Loop&stack.PacketLoop != 0 {
-		views := make([]buffer.View, 1, 1+len(pkt.Data.Views()))
-		views[0] = pkt.Header.View()
-		views = append(views, pkt.Data.Views()...)
-		f.HandlePacket(r, stack.PacketBuffer{
-			Data: buffer.NewVectorisedView(len(views[0])+pkt.Data.Size(), views),
-		})
-	}
-	if r.Loop&stack.PacketOut == 0 {
-		return nil
-	}
-
-	return f.ep.WritePacket(r, gso, fakeNetNumber, pkt)
-}
-
-// WritePackets implements stack.LinkEndpoint.WritePackets.
-func (f *fakeNetworkEndpoint) WritePackets(r *stack.Route, gso *stack.GSO, pkts []stack.PacketBuffer, params stack.NetworkHeaderParams) (int, *tcpip.Error) {
-	panic("not implemented")
-}
-
-func (*fakeNetworkEndpoint) WriteHeaderIncludedPacket(r *stack.Route, pkt stack.PacketBuffer) *tcpip.Error {
-	return tcpip.ErrNotSupported
-}
-
-func (*fakeNetworkEndpoint) Close() {}
-
-type fakeNetGoodOption bool
-
-type fakeNetBadOption bool
-
-type fakeNetInvalidValueOption int
-
-type fakeNetOptions struct {
-	good bool
-}
-
-// 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
-	opts            fakeNetOptions
-}
-
-func (f *fakeNetworkProtocol) Number() tcpip.NetworkProtocolNumber {
-	return fakeNetNumber
-}
-
-func (f *fakeNetworkProtocol) MinimumPacketSize() int {
-	return fakeNetHeaderLen
-}
-
-func (f *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[1:2]), tcpip.Address(v[0:1])
-}
-
-func (f *fakeNetworkProtocol) NewEndpoint(nicID tcpip.NICID, addrWithPrefix tcpip.AddressWithPrefix, linkAddrCache stack.LinkAddressCache, dispatcher stack.TransportDispatcher, ep stack.LinkEndpoint, _ *stack.Stack) (stack.NetworkEndpoint, *tcpip.Error) {
-	return &fakeNetworkEndpoint{
-		nicID:      nicID,
-		id:         stack.NetworkEndpointID{LocalAddress: addrWithPrefix.Address},
-		prefixLen:  addrWithPrefix.PrefixLen,
-		proto:      f,
-		dispatcher: dispatcher,
-		ep:         ep,
-	}, nil
-}
-
-func (f *fakeNetworkProtocol) SetOption(option interface{}) *tcpip.Error {
-	switch v := option.(type) {
-	case fakeNetGoodOption:
-		f.opts.good = bool(v)
-		return nil
-	case fakeNetInvalidValueOption:
-		return tcpip.ErrInvalidOptionValue
-	default:
-		return tcpip.ErrUnknownProtocolOption
-	}
-}
-
-func (f *fakeNetworkProtocol) Option(option interface{}) *tcpip.Error {
-	switch v := option.(type) {
-	case *fakeNetGoodOption:
-		*v = fakeNetGoodOption(f.opts.good)
-		return nil
-	default:
-		return tcpip.ErrUnknownProtocolOption
-	}
-}
-
-// Close implements TransportProtocol.Close.
-func (*fakeNetworkProtocol) Close() {}
-
-// Wait implements TransportProtocol.Wait.
-func (*fakeNetworkProtocol) Wait() {}
-
-func fakeNetFactory() 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
-}
-
-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.NetworkProtocol{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[0] = 3
-	ep.InjectInbound(fakeNetNumber, stack.PacketBuffer{
-		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[0] = 1
-	ep.InjectInbound(fakeNetNumber, stack.PacketBuffer{
-		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[0] = 2
-	ep.InjectInbound(fakeNetNumber, stack.PacketBuffer{
-		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.PacketBuffer{
-		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.PacketBuffer{
-		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 {
-	hdr := buffer.NewPrependable(int(r.MaxHeaderLength()))
-	return r.WritePacket(nil /* gso */, stack.NetworkHeaderParams{Protocol: fakeTransNumber, TTL: 123, TOS: stack.DefaultTOS}, stack.PacketBuffer{
-		Header: hdr,
-		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.PacketBuffer{
-		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.NetworkProtocol{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.NetworkProtocol{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 err != tcpip.ErrNoRoute {
-		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.NetworkProtocol{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.NetworkProtocol{fakeNetFactory()},
-	})
-
-	if err := s.DisableNIC(1); err != tcpip.ErrUnknownNICID {
-		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.NetworkProtocol{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.NetworkProtocol{fakeNetFactory()},
-	})
-
-	if err := s.RemoveNIC(1); err != tcpip.ErrUnknownNICID {
-		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.NetworkProtocol{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.NetworkProtocol{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(b/147015577): 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.NetworkProtocol{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.NetworkProtocol{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[0] = 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.
-	if err := s.RemoveAddress(1, localAddr); err != tcpip.ErrBadLocalAddress {
-		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.NetworkProtocol{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[0] = 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.
-	if err := s.RemoveAddress(1, localAddr); err != tcpip.ErrBadLocalAddress {
-		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.NetworkProtocol{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[0] = 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.NetworkProtocol{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[0] = 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 err != tcpip.ErrNoRoute {
-		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)
-}
-
-func TestSpoofingWithAddress(t *testing.T) {
-	localAddr := tcpip.Address("\x01")
-	nonExistentLocalAddr := tcpip.Address("\x02")
-	dstAddr := tcpip.Address("\x03")
-
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocol{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.NetworkProtocol{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 gotRoute.RemoteLinkAddress != wantRoute.RemoteLinkAddress {
-		return fmt.Errorf("bad remote link address: got %s, want = %s", gotRoute.RemoteLinkAddress, wantRoute.RemoteLinkAddress)
-	}
-	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.NetworkProtocol{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.
-	if _, err := s.FindRoute(1, header.IPv4Any, header.IPv4Broadcast, fakeNetNumber, false /* multicastLoop */); err != tcpip.ErrNetworkUnreachable {
-		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, %s) failed: %s", protoAddr, err)
-	}
-	r, err := s.FindRoute(1, header.IPv4Any, header.IPv4Broadcast, fakeNetNumber, false /* multicastLoop */)
-	if err != nil {
-		t.Fatalf("FindRoute(1, %s, %s, %d) failed: %s", header.IPv4Any, header.IPv4Broadcast, fakeNetNumber, err)
-	}
-	if err := verifyRoute(r, stack.Route{LocalAddress: header.IPv4Any, RemoteAddress: header.IPv4Broadcast}); err != nil {
-		t.Errorf("FindRoute(1, %s, %s, %d) returned unexpected Route: %s)", header.IPv4Any, header.IPv4Broadcast, fakeNetNumber, err)
-	}
-
-	// If the NIC doesn't exist, it won't work.
-	if _, err := s.FindRoute(2, header.IPv4Any, header.IPv4Broadcast, fakeNetNumber, false /* multicastLoop */); err != tcpip.ErrNetworkUnreachable {
-		t.Fatalf("got FindRoute(2, %s, %s, %d) = %s want = %s", 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.NetworkProtocol{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, %s) failed: %s", nic1ProtoAddr, err)
-	}
-
-	nic2ProtoAddr := tcpip.ProtocolAddress{fakeNetNumber, nic2Addr}
-	if err := s.AddProtocolAddress(2, nic2ProtoAddr); err != nil {
-		t.Fatalf("AddAddress(2, %s) failed: %s", 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, %s, %s, %d) failed: %s", nic1Addr.Address, header.IPv4Broadcast, fakeNetNumber, err)
-	}
-	if err := verifyRoute(r, stack.Route{LocalAddress: nic1Addr.Address, RemoteAddress: header.IPv4Broadcast}); err != nil {
-		t.Errorf("FindRoute(1, %s, %s, %d) returned unexpected Route: %s)", 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)
-	}
-	if err := verifyRoute(r, stack.Route{LocalAddress: nic2Addr.Address, RemoteAddress: header.IPv4Broadcast}); 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)
-	}
-	if err := verifyRoute(r, stack.Route{LocalAddress: nic1Addr.Address, RemoteAddress: header.IPv4Broadcast}); 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.NetworkProtocol{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
-			}
-
-			want := 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 err != tcpip.ErrNoRoute {
-					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)
-			}
-		})
-	}
-}
-
-// Add a range of addresses, then check that a packet is delivered.
-func TestAddressRangeAcceptsMatchingPacket(t *testing.T) {
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocol{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)
-
-	const localAddrByte byte = 0x01
-	buf[0] = localAddrByte
-	subnet, err := tcpip.NewSubnet(tcpip.Address("\x00"), tcpip.AddressMask("\xF0"))
-	if err != nil {
-		t.Fatal("NewSubnet failed:", err)
-	}
-	if err := s.AddAddressRange(1, fakeNetNumber, subnet); err != nil {
-		t.Fatal("AddAddressRange failed:", err)
-	}
-
-	testRecv(t, fakeNet, localAddrByte, ep, buf)
-}
-
-func testNicForAddressRange(t *testing.T, nicID tcpip.NICID, s *stack.Stack, subnet tcpip.Subnet, rangeExists bool) {
-	t.Helper()
-
-	// Loop over all addresses and check them.
-	numOfAddresses := 1 << uint(8-subnet.Prefix())
-	if numOfAddresses < 1 || numOfAddresses > 255 {
-		t.Fatalf("got numOfAddresses = %d, want = [1 .. 255] (subnet=%s)", numOfAddresses, subnet)
-	}
-
-	addrBytes := []byte(subnet.ID())
-	for i := 0; i < numOfAddresses; i++ {
-		addr := tcpip.Address(addrBytes)
-		wantNicID := nicID
-		// The subnet and broadcast addresses are skipped.
-		if !rangeExists || addr == subnet.ID() || addr == subnet.Broadcast() {
-			wantNicID = 0
-		}
-		if gotNicID := s.CheckLocalAddress(0, fakeNetNumber, addr); gotNicID != wantNicID {
-			t.Errorf("got CheckLocalAddress(0, %d, %s) = %d, want = %d", fakeNetNumber, addr, gotNicID, wantNicID)
-		}
-		addrBytes[0]++
-	}
-
-	// Trying the next address should always fail since it is outside the range.
-	if gotNicID := s.CheckLocalAddress(0, fakeNetNumber, tcpip.Address(addrBytes)); gotNicID != 0 {
-		t.Errorf("got CheckLocalAddress(0, %d, %s) = %d, want = %d", fakeNetNumber, tcpip.Address(addrBytes), gotNicID, 0)
-	}
-}
-
-// Set a range of addresses, then remove it again, and check at each step that
-// CheckLocalAddress returns the correct NIC for each address or zero if not
-// existent.
-func TestCheckLocalAddressForSubnet(t *testing.T) {
-	const nicID tcpip.NICID = 1
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocol{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: nicID}})
-	}
-
-	subnet, err := tcpip.NewSubnet(tcpip.Address("\xa0"), tcpip.AddressMask("\xf0"))
-	if err != nil {
-		t.Fatal("NewSubnet failed:", err)
-	}
-
-	testNicForAddressRange(t, nicID, s, subnet, false /* rangeExists */)
-
-	if err := s.AddAddressRange(nicID, fakeNetNumber, subnet); err != nil {
-		t.Fatal("AddAddressRange failed:", err)
-	}
-
-	testNicForAddressRange(t, nicID, s, subnet, true /* rangeExists */)
-
-	if err := s.RemoveAddressRange(nicID, subnet); err != nil {
-		t.Fatal("RemoveAddressRange failed:", err)
-	}
-
-	testNicForAddressRange(t, nicID, s, subnet, false /* rangeExists */)
-}
-
-// Set a range of addresses, then send a packet to a destination outside the
-// range and then check it doesn't get delivered.
-func TestAddressRangeRejectsNonmatchingPacket(t *testing.T) {
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocol{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)
-
-	const localAddrByte byte = 0x01
-	buf[0] = localAddrByte
-	subnet, err := tcpip.NewSubnet(tcpip.Address("\x10"), tcpip.AddressMask("\xF0"))
-	if err != nil {
-		t.Fatal("NewSubnet failed:", err)
-	}
-	if err := s.AddAddressRange(1, fakeNetNumber, subnet); err != nil {
-		t.Fatal("AddAddressRange failed:", err)
-	}
-	testFailingRecv(t, fakeNet, localAddrByte, ep, buf)
-}
-
-func TestNetworkOptions(t *testing.T) {
-	s := stack.New(stack.Options{
-		NetworkProtocols:   []stack.NetworkProtocol{fakeNetFactory()},
-		TransportProtocols: []stack.TransportProtocol{},
-	})
-
-	// Try an unsupported network protocol.
-	if err := s.SetNetworkProtocolOption(tcpip.NetworkProtocolNumber(99999), fakeNetGoodOption(false)); err != tcpip.ErrUnknownProtocol {
-		t.Fatalf("SetNetworkProtocolOption(fakeNet2, blah, false) = %v, want = tcpip.ErrUnknownProtocol", err)
-	}
-
-	testCases := []struct {
-		option   interface{}
-		wantErr  *tcpip.Error
-		verifier func(t *testing.T, p stack.NetworkProtocol)
-	}{
-		{fakeNetGoodOption(true), nil, func(t *testing.T, p stack.NetworkProtocol) {
-			t.Helper()
-			fakeNet := p.(*fakeNetworkProtocol)
-			if fakeNet.opts.good != true {
-				t.Fatalf("fakeNet.opts.good = false, want = true")
-			}
-			var v fakeNetGoodOption
-			if err := s.NetworkProtocolOption(fakeNetNumber, &v); err != nil {
-				t.Fatalf("s.NetworkProtocolOption(fakeNetNumber, &v) = %v, want = nil, where v is option %T", v, err)
-			}
-			if v != true {
-				t.Fatalf("s.NetworkProtocolOption(fakeNetNumber, &v) returned v = %v, want = true", v)
-			}
-		}},
-		{fakeNetBadOption(true), tcpip.ErrUnknownProtocolOption, nil},
-		{fakeNetInvalidValueOption(1), tcpip.ErrInvalidOptionValue, nil},
-	}
-	for _, tc := range testCases {
-		if got := s.SetNetworkProtocolOption(fakeNetNumber, tc.option); got != tc.wantErr {
-			t.Errorf("s.SetNetworkProtocolOption(fakeNet, %v) = %v, want = %v", tc.option, got, tc.wantErr)
-		}
-		if tc.verifier != nil {
-			tc.verifier(t, s.NetworkProtocolInstance(fakeNetNumber))
-		}
-	}
-}
-
-func stackContainsAddressRange(s *stack.Stack, id tcpip.NICID, addrRange tcpip.Subnet) bool {
-	ranges, ok := s.NICAddressRanges()[id]
-	if !ok {
-		return false
-	}
-	for _, r := range ranges {
-		if r == addrRange {
-			return true
-		}
-	}
-	return false
-}
-
-func TestAddresRangeAddRemove(t *testing.T) {
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocol{fakeNetFactory()},
-	})
-	ep := channel.New(10, defaultMTU, "")
-	if err := s.CreateNIC(1, ep); err != nil {
-		t.Fatal("CreateNIC failed:", err)
-	}
-
-	addr := tcpip.Address("\x01\x01\x01\x01")
-	mask := tcpip.AddressMask(strings.Repeat("\xff", len(addr)))
-	addrRange, err := tcpip.NewSubnet(addr, mask)
-	if err != nil {
-		t.Fatal("NewSubnet failed:", err)
-	}
-
-	if got, want := stackContainsAddressRange(s, 1, addrRange), false; got != want {
-		t.Fatalf("got stackContainsAddressRange(...) = %t, want = %t", got, want)
-	}
-
-	if err := s.AddAddressRange(1, fakeNetNumber, addrRange); err != nil {
-		t.Fatal("AddAddressRange failed:", err)
-	}
-
-	if got, want := stackContainsAddressRange(s, 1, addrRange), true; got != want {
-		t.Fatalf("got stackContainsAddressRange(...) = %t, want = %t", got, want)
-	}
-
-	if err := s.RemoveAddressRange(1, addrRange); err != nil {
-		t.Fatal("RemoveAddressRange failed:", err)
-	}
-
-	if got, want := stackContainsAddressRange(s, 1, addrRange), false; got != want {
-		t.Fatalf("got stackContainsAddressRange(...) = %t, want = %t", got, want)
-	}
-}
-
-func TestGetMainNICAddressAddPrimaryNonPrimary(t *testing.T) {
-	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.NetworkProtocol{fakeNetFactory()},
-							})
-							ep := channel.New(10, defaultMTU, "")
-							if err := s.CreateNIC(1, ep); err != nil {
-								t.Fatal("CreateNIC failed:", 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(1, protocolAddress, behavior); err != nil {
-										t.Fatal("AddProtocolAddressWithOptions failed:", err)
-									}
-									// Remember the address/prefix.
-									primaryAddrAdded[protocolAddress.AddressWithPrefix] = struct{}{}
-								} else {
-									if err := s.AddAddressWithOptions(1, fakeNetNumber, address, behavior); err != nil {
-										t.Fatal("AddAddressWithOptions failed:", 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(1, fakeNetNumber)
-							if err != nil {
-								t.Fatal("GetMainNICAddress failed:", err)
-							}
-							if len(primaryAddrAdded) == 0 {
-								// No primary addresses present.
-								if wantAddr := (tcpip.AddressWithPrefix{}); gotAddr != wantAddr {
-									t.Fatalf("GetMainNICAddress: got addr = %s, want = %s", 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("GetMainNICAddress: got = %s, want any in {%v}", gotAddr, primaryAddrAdded)
-								}
-							}
-						})
-					}
-				})
-			}
-		})
-	}
-}
-
-func TestGetMainNICAddressAddRemove(t *testing.T) {
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocol{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.
-			gotAddr, err := s.GetMainNICAddress(1, fakeNetNumber)
-			if err != nil {
-				t.Fatal("GetMainNICAddress failed:", err)
-			}
-			if wantAddr := protocolAddress.AddressWithPrefix; gotAddr != wantAddr {
-				t.Fatalf("got s.GetMainNICAddress(...) = %s, want = %s", gotAddr, wantAddr)
-			}
-
-			if err := s.RemoveAddress(1, protocolAddress.AddressWithPrefix.Address); err != nil {
-				t.Fatal("RemoveAddress failed:", err)
-			}
-
-			// Check that we get no address after removal.
-			gotAddr, err = s.GetMainNICAddress(1, fakeNetNumber)
-			if err != nil {
-				t.Fatal("GetMainNICAddress failed:", err)
-			}
-			if wantAddr := (tcpip.AddressWithPrefix{}); gotAddr != wantAddr {
-				t.Fatalf("got GetMainNICAddress(...) = %s, want = %s", gotAddr, wantAddr)
-			}
-		})
-	}
-}
-
-// 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.NetworkProtocol{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.NetworkProtocol{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.NetworkProtocol{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.NetworkProtocol{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.NetworkProtocol{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.PacketBuffer{
-		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)); got != want {
-		t.Errorf("got Tx.Bytes.Value() = %d, want = %d", got, want)
-	}
-}
-
-func TestNICForwarding(t *testing.T) {
-	const nicID1 = 1
-	const nicID2 = 2
-	const dstAddr = tcpip.Address("\x03")
-
-	tests := []struct {
-		name      string
-		headerLen uint16
-	}{
-		{
-			name: "Zero header length",
-		},
-		{
-			name:      "Non-zero header length",
-			headerLen: 16,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			s := stack.New(stack.Options{
-				NetworkProtocols: []stack.NetworkProtocol{fakeNetFactory()},
-			})
-			s.SetForwarding(true)
-
-			ep1 := channel.New(10, defaultMTU, "")
-			if err := s.CreateNIC(nicID1, ep1); err != nil {
-				t.Fatalf("CreateNIC(%d, _): %s", nicID1, err)
-			}
-			if err := s.AddAddress(nicID1, fakeNetNumber, "\x01"); err != nil {
-				t.Fatalf("AddAddress(%d, %d, 0x01): %s", nicID1, fakeNetNumber, err)
-			}
-
-			ep2 := channelLinkWithHeaderLength{
-				Endpoint:     channel.New(10, defaultMTU, ""),
-				headerLength: test.headerLen,
-			}
-			if err := s.CreateNIC(nicID2, &ep2); err != nil {
-				t.Fatalf("CreateNIC(%d, _): %s", nicID2, err)
-			}
-			if err := s.AddAddress(nicID2, fakeNetNumber, "\x02"); err != nil {
-				t.Fatalf("AddAddress(%d, %d, 0x02): %s", nicID2, fakeNetNumber, err)
-			}
-
-			// Route all packets to dstAddr to NIC 2.
-			{
-				subnet, err := tcpip.NewSubnet(dstAddr, "\xff")
-				if err != nil {
-					t.Fatal(err)
-				}
-				s.SetRouteTable([]tcpip.Route{{Destination: subnet, Gateway: "\x00", NIC: nicID2}})
-			}
-
-			// Send a packet to dstAddr.
-			buf := buffer.NewView(30)
-			buf[0] = dstAddr[0]
-			ep1.InjectInbound(fakeNetNumber, stack.PacketBuffer{
-				Data: buf.ToVectorisedView(),
-			})
-
-			pkt, ok := ep2.Read()
-			if !ok {
-				t.Fatal("packet not forwarded")
-			}
-
-			// Test that the link's MaxHeaderLength is honoured.
-			if capacity, want := pkt.Pkt.Header.AvailableLength(), int(test.headerLen); capacity != want {
-				t.Errorf("got Header.AvailableLength() = %d, want = %d", capacity, want)
-			}
-
-			// Test that forwarding increments Tx stats correctly.
-			if got, want := s.NICInfo()[nicID2].Stats.Tx.Packets.Value(), uint64(1); got != want {
-				t.Errorf("got Tx.Packets.Value() = %d, want = %d", got, want)
-			}
-
-			if got, want := s.NICInfo()[nicID2].Stats.Tx.Bytes.Value(), uint64(len(buf)); 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.Fatal("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      stack.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: stack.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: stack.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: stack.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: stack.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: stack.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: stack.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.NetworkProtocol{ipv6.NewProtocol()},
-				AutoGenIPv6LinkLocal: 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:
-				}
-			}
-
-			gotMainAddr, err := s.GetMainNICAddress(1, header.IPv6ProtocolNumber)
-			if err != nil {
-				t.Fatalf("stack.GetMainNICAddress(_, _) err = %s", err)
-			}
-			if gotMainAddr != expectedMainAddr {
-				t.Fatalf("got stack.GetMainNICAddress(_, _) = %s, want = %s", gotMainAddr, expectedMainAddr)
-			}
-		})
-	}
-}
-
-// 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 stack.OpaqueInterfaceIdentifierOptions
-	}{
-		{
-			name:          "IID From MAC",
-			opaqueIIDOpts: stack.OpaqueInterfaceIdentifierOptions{},
-		},
-		{
-			name: "Opaque IID",
-			opaqueIIDOpts: stack.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.NetworkProtocol{ipv6.NewProtocol()},
-				AutoGenIPv6LinkLocal: 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)
-			}
-
-			addr, err := s.GetMainNICAddress(nicID, header.IPv6ProtocolNumber)
-			if err != nil {
-				t.Fatalf("stack.GetMainNICAddress(%d, _) err = %s", nicID, err)
-			}
-			if want := (tcpip.AddressWithPrefix{}); addr != want {
-				t.Errorf("got stack.GetMainNICAddress(%d, _) = %s, want = %s", nicID, addr, want)
-			}
-		})
-	}
-}
-
-// 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),
-	}
-	ndpConfigs := stack.DefaultNDPConfigurations()
-	opts := stack.Options{
-		NetworkProtocols:     []stack.NetworkProtocol{ipv6.NewProtocol()},
-		NDPConfigs:           ndpConfigs,
-		AutoGenIPv6LinkLocal: true,
-		NDPDisp:              &ndpDisp,
-	}
-
-	e := channel.New(int(ndpConfigs.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).
-	addr, err := s.GetMainNICAddress(nicID, header.IPv6ProtocolNumber)
-	if err != nil {
-		t.Fatalf("got stack.GetMainNICAddress(%d, %d) = (_, %v), want = (_, nil)", nicID, header.IPv6ProtocolNumber, err)
-	}
-	if want := (tcpip.AddressWithPrefix{}); addr != want {
-		t.Fatalf("got stack.GetMainNICAddress(%d, %d) = (%s, nil), want = (%s, nil)", nicID, header.IPv6ProtocolNumber, addr, want)
-	}
-
-	linkLocalAddr := header.LinkLocalAddr(linkAddr1)
-
-	// Wait for DAD to resolve.
-	select {
-	case <-time.After(time.Duration(ndpConfigs.DupAddrDetectTransmits)*ndpConfigs.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, true, nil); diff != "" {
-			t.Errorf("dad event mismatch (-want +got):\n%s", diff)
-		}
-	}
-	addr, err = s.GetMainNICAddress(nicID, header.IPv6ProtocolNumber)
-	if err != nil {
-		t.Fatalf("got stack.GetMainNICAddress(%d, %d) = (_, %v), want = (_, nil)", nicID, header.IPv6ProtocolNumber, err)
-	}
-	if want := (tcpip.AddressWithPrefix{Address: linkLocalAddr, PrefixLen: header.IPv6LinkLocalPrefix.PrefixLen}); addr != want {
-		t.Fatalf("got stack.GetMainNICAddress(%d, %d) = (%s, nil), want = (%s, nil)", nicID, header.IPv6ProtocolNumber, addr, want)
-	}
-}
-
-// 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) {
-	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.NetworkProtocol{fakeNetFactory()},
-				})
-				ep1 := channel.New(10, defaultMTU, "")
-				if err := s.CreateNIC(1, ep1); err != nil {
-					t.Fatal("CreateNIC failed:", 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.
-				if err := s.AddAddressWithOptions(1, fakeNetNumber, "\x01", pi); err != nil {
-					t.Fatal("AddAddressWithOptions failed:", err)
-				}
-				addr, err := s.GetMainNICAddress(1, fakeNetNumber)
-				if err != nil {
-					t.Fatal("s.GetMainNICAddress failed:", err)
-				}
-				if pi == stack.NeverPrimaryEndpoint {
-					if want := (tcpip.AddressWithPrefix{}); addr != want {
-						t.Fatalf("got GetMainNICAddress = %s, want = %s", addr, want)
-
-					}
-				} else if addr.Address != "\x01" {
-					t.Fatalf("got GetMainNICAddress = %s, want = 1", addr.Address)
-				}
-
-				{
-					subnet, err := tcpip.NewSubnet("\x00", "\x00")
-					if err != nil {
-						t.Fatalf("NewSubnet failed:", 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.
-				r, err := s.FindRoute(1, "\x01", "\x02", fakeNetNumber, false)
-				if err != nil {
-					t.Fatal("FindRoute failed:", err)
-				}
-				defer r.Release()
-				if err := s.RemoveAddress(1, "\x01"); err != nil {
-					t.Fatalf("RemoveAddress failed:", 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.
-				if err := s.AddAddressWithOptions(1, fakeNetNumber, "\x03", stack.FirstPrimaryEndpoint); err != nil {
-					t.Fatal("AddAddressWithOptions failed:", 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(1, fakeNetNumber, "\x01", ps); err != nil {
-					t.Fatal("AddAddressWithOptions failed:", err)
-				}
-				var primaryAddrs []tcpip.Address
-				for _, pa := range s.NICInfo()[1].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(1, "\x03"); err != nil {
-					t.Fatalf("RemoveAddress failed:", err)
-				}
-				addr, err = s.GetMainNICAddress(1, fakeNetNumber)
-				if err != nil {
-					t.Fatal("s.GetMainNICAddress failed:", err)
-				}
-				if ps == stack.NeverPrimaryEndpoint {
-					if want := (tcpip.AddressWithPrefix{}); addr != want {
-						t.Fatalf("got GetMainNICAddress = %s, want = %s", addr, want)
-
-					}
-				} else {
-					if addr.Address != "\x01" {
-						t.Fatalf("got GetMainNICAddress = %s, want = 1", addr.Address)
-					}
-				}
-			})
-		}
-	}
-}
-
-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")
-		nicID                  = 1
-	)
-
-	// Rule 3 is not tested here, and is instead tested by NDP's AutoGenAddr test.
-	tests := []struct {
-		name              string
-		nicAddrs          []tcpip.Address
-		connectAddr       tcpip.Address
-		expectedLocalAddr tcpip.Address
-	}{
-		// Test Rule 1 of RFC 6724 section 5.
-		{
-			name:              "Same Global most preferred (last address)",
-			nicAddrs:          []tcpip.Address{linkLocalAddr1, uniqueLocalAddr1, globalAddr1},
-			connectAddr:       globalAddr1,
-			expectedLocalAddr: globalAddr1,
-		},
-		{
-			name:              "Same Global most preferred (first address)",
-			nicAddrs:          []tcpip.Address{globalAddr1, linkLocalAddr1, uniqueLocalAddr1},
-			connectAddr:       globalAddr1,
-			expectedLocalAddr: globalAddr1,
-		},
-		{
-			name:              "Same Link Local most preferred (last address)",
-			nicAddrs:          []tcpip.Address{globalAddr1, uniqueLocalAddr1, linkLocalAddr1},
-			connectAddr:       linkLocalAddr1,
-			expectedLocalAddr: linkLocalAddr1,
-		},
-		{
-			name:              "Same Link Local most preferred (first address)",
-			nicAddrs:          []tcpip.Address{linkLocalAddr1, uniqueLocalAddr1, globalAddr1},
-			connectAddr:       linkLocalAddr1,
-			expectedLocalAddr: linkLocalAddr1,
-		},
-		{
-			name:              "Same Unique Local most preferred (last address)",
-			nicAddrs:          []tcpip.Address{uniqueLocalAddr1, globalAddr1, linkLocalAddr1},
-			connectAddr:       uniqueLocalAddr1,
-			expectedLocalAddr: uniqueLocalAddr1,
-		},
-		{
-			name:              "Same Unique Local most preferred (first address)",
-			nicAddrs:          []tcpip.Address{globalAddr1, linkLocalAddr1, uniqueLocalAddr1},
-			connectAddr:       uniqueLocalAddr1,
-			expectedLocalAddr: uniqueLocalAddr1,
-		},
-
-		// Test Rule 2 of RFC 6724 section 5.
-		{
-			name:              "Global most preferred (last address)",
-			nicAddrs:          []tcpip.Address{linkLocalAddr1, uniqueLocalAddr1, globalAddr1},
-			connectAddr:       globalAddr2,
-			expectedLocalAddr: globalAddr1,
-		},
-		{
-			name:              "Global most preferred (first address)",
-			nicAddrs:          []tcpip.Address{globalAddr1, linkLocalAddr1, uniqueLocalAddr1},
-			connectAddr:       globalAddr2,
-			expectedLocalAddr: globalAddr1,
-		},
-		{
-			name:              "Link Local most preferred (last address)",
-			nicAddrs:          []tcpip.Address{globalAddr1, uniqueLocalAddr1, linkLocalAddr1},
-			connectAddr:       linkLocalAddr2,
-			expectedLocalAddr: linkLocalAddr1,
-		},
-		{
-			name:              "Link Local most preferred (first address)",
-			nicAddrs:          []tcpip.Address{linkLocalAddr1, uniqueLocalAddr1, globalAddr1},
-			connectAddr:       linkLocalAddr2,
-			expectedLocalAddr: linkLocalAddr1,
-		},
-		{
-			name:              "Link Local most preferred for link local multicast (last address)",
-			nicAddrs:          []tcpip.Address{globalAddr1, uniqueLocalAddr1, linkLocalAddr1},
-			connectAddr:       linkLocalMulticastAddr,
-			expectedLocalAddr: linkLocalAddr1,
-		},
-		{
-			name:              "Link Local most preferred for link local multicast (first address)",
-			nicAddrs:          []tcpip.Address{linkLocalAddr1, uniqueLocalAddr1, globalAddr1},
-			connectAddr:       linkLocalMulticastAddr,
-			expectedLocalAddr: linkLocalAddr1,
-		},
-		{
-			name:              "Unique Local most preferred (last address)",
-			nicAddrs:          []tcpip.Address{uniqueLocalAddr1, globalAddr1, linkLocalAddr1},
-			connectAddr:       uniqueLocalAddr2,
-			expectedLocalAddr: uniqueLocalAddr1,
-		},
-		{
-			name:              "Unique Local most preferred (first address)",
-			nicAddrs:          []tcpip.Address{globalAddr1, linkLocalAddr1, uniqueLocalAddr1},
-			connectAddr:       uniqueLocalAddr2,
-			expectedLocalAddr: uniqueLocalAddr1,
-		},
-
-		// 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},
-			connectAddr:       globalAddr2,
-			expectedLocalAddr: uniqueLocalAddr1,
-		},
-		{
-			name:              "Link Local for Global",
-			nicAddrs:          []tcpip.Address{linkLocalAddr1, linkLocalAddr2},
-			connectAddr:       globalAddr2,
-			expectedLocalAddr: linkLocalAddr1,
-		},
-		{
-			name:              "Link Local for Unique Local",
-			nicAddrs:          []tcpip.Address{linkLocalAddr1, linkLocalAddr2},
-			connectAddr:       uniqueLocalAddr2,
-			expectedLocalAddr: linkLocalAddr1,
-		},
-	}
-
-	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.NetworkProtocol{ipv6.NewProtocol()},
-				TransportProtocols: []stack.TransportProtocol{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,
-			}})
-			s.AddLinkAddress(nicID, llAddr3, linkAddr3)
-
-			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 t.Failed() {
-				t.FailNow()
-			}
-
-			if got := addrForNewConnectionTo(t, s, tcpip.FullAddress{Addr: test.connectAddr, NIC: nicID, Port: 1234}); got != test.expectedLocalAddr {
-				t.Errorf("got local address = %s, want = %s", got, test.expectedLocalAddr)
-			}
-		})
-	}
-}
-
-func TestAddRemoveIPv4BroadcastAddressOnNICEnableDisable(t *testing.T) {
-	const nicID = 1
-
-	e := loopback.New()
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocol{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()
-	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 add the IPv4 broadcast address.
-	if err := s.EnableNIC(nicID); err != nil {
-		t.Fatalf("s.EnableNIC(%d): %s", nicID, err)
-	}
-	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 != 1 {
-		t.Fatalf("got len(allNICAddrs) = %d, want = 1", l)
-	}
-	want := tcpip.ProtocolAddress{
-		Protocol: header.IPv4ProtocolNumber,
-		AddressWithPrefix: tcpip.AddressWithPrefix{
-			Address:   header.IPv4Broadcast,
-			PrefixLen: 32,
-		},
-	}
-	if allNICAddrs[0] != want {
-		t.Fatalf("got allNICAddrs[0] = %+v, want = %+v", allNICAddrs[0], want)
-	}
-
-	// 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()
-	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)
-	}
-}
-
-// 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.NetworkProtocol{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 TestJoinLeaveAllNodesMulticastOnNICEnableDisable(t *testing.T) {
-	const nicID = 1
-
-	e := loopback.New()
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocol{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 IPv6 all-nodes multicast group yet because the NIC has
-	// not been enabled yet.
-	isInGroup, err := s.IsInGroup(nicID, header.IPv6AllNodesMulticastAddress)
-	if err != nil {
-		t.Fatalf("IsInGroup(%d, %s): %s", nicID, header.IPv6AllNodesMulticastAddress, err)
-	}
-	if isInGroup {
-		t.Fatalf("got IsInGroup(%d, %s) = true, want = false", nicID, header.IPv6AllNodesMulticastAddress)
-	}
-
-	// 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)
-	}
-	isInGroup, err = s.IsInGroup(nicID, header.IPv6AllNodesMulticastAddress)
-	if err != nil {
-		t.Fatalf("IsInGroup(%d, %s): %s", nicID, header.IPv6AllNodesMulticastAddress, err)
-	}
-	if !isInGroup {
-		t.Fatalf("got IsInGroup(%d, %s) = false, want = true", nicID, header.IPv6AllNodesMulticastAddress)
-	}
-
-	// The all-nodes 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)
-	}
-	isInGroup, err = s.IsInGroup(nicID, header.IPv6AllNodesMulticastAddress)
-	if err != nil {
-		t.Fatalf("IsInGroup(%d, %s): %s", nicID, header.IPv6AllNodesMulticastAddress, err)
-	}
-	if isInGroup {
-		t.Fatalf("got IsInGroup(%d, %s) = true, want = false", nicID, header.IPv6AllNodesMulticastAddress)
-	}
-}
-
-// 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.NetworkProtocol{ipv6.NewProtocol()},
-		NDPConfigs: stack.NDPConfigurations{
-			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.
-	got, err := s.GetMainNICAddress(nicID, header.IPv6ProtocolNumber)
-	if err != nil {
-		t.Fatalf("got stack.GetMainNICAddress(%d, %d) = (_, %v), want = (_, nil)", nicID, header.IPv6ProtocolNumber, err)
-	}
-	if want := (tcpip.AddressWithPrefix{}); got != want {
-		t.Fatalf("got stack.GetMainNICAddress(%d, %d) = (%s, nil), want = (%s, nil)", nicID, header.IPv6ProtocolNumber, got, want)
-	}
-
-	// 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).
-	got, err = s.GetMainNICAddress(nicID, header.IPv6ProtocolNumber)
-	if err != nil {
-		t.Fatalf("got stack.GetMainNICAddress(%d, %d) = (_, %v), want = (_, nil)", nicID, header.IPv6ProtocolNumber, err)
-	}
-	if want := (tcpip.AddressWithPrefix{}); got != want {
-		t.Fatalf("got stack.GetMainNICAddress(%d, %d) = (%s, nil), want = (%s, nil)", nicID, header.IPv6ProtocolNumber, got, want)
-	}
-
-	// Wait for DAD to resolve.
-	select {
-	case <-time.After(dadTransmits*retransmitTimer + defaultAsyncEventTimeout):
-		t.Fatal("timed out waiting for DAD resolution")
-	case e := <-ndpDisp.dadC:
-		if diff := checkDADEvent(e, nicID, addr.AddressWithPrefix.Address, true, nil); 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)
-	}
-	got, err = s.GetMainNICAddress(nicID, header.IPv6ProtocolNumber)
-	if err != nil {
-		t.Fatalf("got stack.GetMainNICAddress(%d, %d) = (_, %v), want = (_, nil)", nicID, header.IPv6ProtocolNumber, err)
-	}
-	if got != addr.AddressWithPrefix {
-		t.Fatalf("got stack.GetMainNICAddress(%d, %d) = %s, want = %s", nicID, header.IPv6ProtocolNumber, got, addr.AddressWithPrefix)
-	}
-
-	// 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)
-	}
-	got, err = s.GetMainNICAddress(nicID, header.IPv6ProtocolNumber)
-	if err != nil {
-		t.Fatalf("got stack.GetMainNICAddress(%d, %d) = (_, %v), want = (_, nil)", nicID, header.IPv6ProtocolNumber, err)
-	}
-	if got != addr.AddressWithPrefix {
-		t.Fatalf("got stack.GetMainNICAddress(%d, %d) = (%s, nil), want = (%s, nil)", nicID, header.IPv6ProtocolNumber, got, addr.AddressWithPrefix)
-	}
-}
diff --git a/pkg/tcpip/stack/transport_demuxer_test.go b/pkg/tcpip/stack/transport_demuxer_test.go
deleted file mode 100644
index c65b0c6..0000000
--- a/pkg/tcpip/stack/transport_demuxer_test.go
+++ /dev/null
@@ -1,390 +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 (
-	"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/stack"
-	"gvisor.dev/gvisor/pkg/tcpip/transport/udp"
-	"gvisor.dev/gvisor/pkg/waiter"
-)
-
-const (
-	testSrcAddrV6 = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"
-	testDstAddrV6 = "\x00\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.NetworkProtocol{ipv4.NewProtocol(), ipv6.NewProtocol()},
-		TransportProtocols: []stack.TransportProtocol{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{
-		IHL:         header.IPv4MinimumSize,
-		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.
-	c.linkEps[linkEpID].InjectInbound(ipv4.ProtocolNumber, stack.PacketBuffer{
-		Data:            buf.ToVectorisedView(),
-		NetworkHeader:   buffer.View(ip),
-		TransportHeader: buffer.View(u),
-	})
-}
-
-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)),
-		NextHeader:    uint8(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.
-	c.linkEps[linkEpID].InjectInbound(ipv6.ProtocolNumber, stack.PacketBuffer{
-		Data:            buf.ToVectorisedView(),
-		NetworkHeader:   buffer.View(ip),
-		TransportHeader: buffer.View(u),
-	})
-}
-
-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.NetworkProtocol{ipv4.NewProtocol()},
-				TransportProtocols: []stack.TransportProtocol{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(0, []tcpip.NetworkProtocolNumber{test.proto}, udp.ProtocolNumber, stack.TransportEndpointID{}, tEP, false, 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        int
-		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: 1, bindToDevice: 0},
-				{reuse: 1, bindToDevice: 0},
-				{reuse: 1, bindToDevice: 0},
-				{reuse: 1, bindToDevice: 0},
-				{reuse: 1, 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: 0, bindToDevice: 1},
-				{reuse: 0, bindToDevice: 2},
-				{reuse: 0, 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: 1, bindToDevice: 1},
-				{reuse: 1, bindToDevice: 1},
-				{reuse: 1, bindToDevice: 2},
-				{reuse: 1, bindToDevice: 2},
-				{reuse: 1, bindToDevice: 2},
-				{reuse: 1, 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()
-						reusePortOption := tcpip.ReusePortOption(endpoint.reuse)
-						if err := ep.SetSockOpt(reusePortOption); err != nil {
-							t.Fatalf("SetSockOpt(%#v) on endpoint %d failed: %s", reusePortOption, i, err)
-						}
-						bindToDeviceOption := tcpip.BindToDeviceOption(endpoint.bindToDevice)
-						if err := ep.SetSockOpt(bindToDeviceOption); err != nil {
-							t.Fatalf("SetSockOpt(%#v) on endpoint %d failed: %s", bindToDeviceOption, 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(nil); 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 3084e65..0000000
--- a/pkg/tcpip/stack/transport_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 stack_test
-
-import (
-	"testing"
-
-	"gvisor.dev/gvisor/pkg/tcpip"
-	"gvisor.dev/gvisor/pkg/tcpip/buffer"
-	"gvisor.dev/gvisor/pkg/tcpip/link/channel"
-	"gvisor.dev/gvisor/pkg/tcpip/link/loopback"
-	"gvisor.dev/gvisor/pkg/tcpip/stack"
-	"gvisor.dev/gvisor/pkg/waiter"
-)
-
-const (
-	fakeTransNumber    tcpip.TransportProtocolNumber = 1
-	fakeTransHeaderLen                               = 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
-	stack    *stack.Stack
-	proto    *fakeTransportProtocol
-	peerAddr tcpip.Address
-	route    stack.Route
-	uniqueID uint64
-
-	// acceptQueue is non-nil iff bound.
-	acceptQueue []fakeTransportEndpoint
-}
-
-func (f *fakeTransportEndpoint) Info() tcpip.EndpointInfo {
-	return &f.TransportEndpointInfo
-}
-
-func (f *fakeTransportEndpoint) Stats() tcpip.EndpointStats {
-	return nil
-}
-
-func (f *fakeTransportEndpoint) SetOwner(owner tcpip.PacketOwner) {}
-
-func newFakeTransportEndpoint(s *stack.Stack, proto *fakeTransportProtocol, netProto tcpip.NetworkProtocolNumber, uniqueID uint64) tcpip.Endpoint {
-	return &fakeTransportEndpoint{stack: s, TransportEndpointInfo: stack.TransportEndpointInfo{NetProto: netProto}, proto: proto, uniqueID: uniqueID}
-}
-
-func (f *fakeTransportEndpoint) Abort() {
-	f.Close()
-}
-
-func (f *fakeTransportEndpoint) Close() {
-	f.route.Release()
-}
-
-func (*fakeTransportEndpoint) Readiness(mask waiter.EventMask) waiter.EventMask {
-	return mask
-}
-
-func (*fakeTransportEndpoint) Read(*tcpip.FullAddress) (buffer.View, tcpip.ControlMessages, *tcpip.Error) {
-	return buffer.View{}, tcpip.ControlMessages{}, nil
-}
-
-func (f *fakeTransportEndpoint) Write(p tcpip.Payloader, opts tcpip.WriteOptions) (int64, <-chan struct{}, *tcpip.Error) {
-	if len(f.route.RemoteAddress) == 0 {
-		return 0, nil, tcpip.ErrNoRoute
-	}
-
-	hdr := buffer.NewPrependable(int(f.route.MaxHeaderLength()))
-	v, err := p.FullPayload()
-	if err != nil {
-		return 0, nil, err
-	}
-	if err := f.route.WritePacket(nil /* gso */, stack.NetworkHeaderParams{Protocol: fakeTransNumber, TTL: 123, TOS: stack.DefaultTOS}, stack.PacketBuffer{
-		Header: hdr,
-		Data:   buffer.View(v).ToVectorisedView(),
-	}); err != nil {
-		return 0, nil, err
-	}
-
-	return int64(len(v)), nil, nil
-}
-
-func (f *fakeTransportEndpoint) Peek([][]byte) (int64, tcpip.ControlMessages, *tcpip.Error) {
-	return 0, tcpip.ControlMessages{}, nil
-}
-
-// SetSockOpt sets a socket option. Currently not supported.
-func (*fakeTransportEndpoint) SetSockOpt(interface{}) *tcpip.Error {
-	return tcpip.ErrInvalidEndpointState
-}
-
-// SetSockOptBool sets a socket option. Currently not supported.
-func (*fakeTransportEndpoint) SetSockOptBool(tcpip.SockOptBool, bool) *tcpip.Error {
-	return tcpip.ErrInvalidEndpointState
-}
-
-// SetSockOptInt sets a socket option. Currently not supported.
-func (*fakeTransportEndpoint) SetSockOptInt(tcpip.SockOptInt, int) *tcpip.Error {
-	return tcpip.ErrInvalidEndpointState
-}
-
-// GetSockOptBool implements tcpip.Endpoint.GetSockOptBool.
-func (*fakeTransportEndpoint) GetSockOptBool(opt tcpip.SockOptBool) (bool, *tcpip.Error) {
-	return false, tcpip.ErrUnknownProtocolOption
-}
-
-// 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(opt interface{}) *tcpip.Error {
-	switch opt.(type) {
-	case tcpip.ErrorOption:
-		return nil
-	}
-	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.stack.FindRoute(addr.NIC, "", addr.Addr, fakeNetNumber, false /* multicastLoop */)
-	if err != nil {
-		return tcpip.ErrNoRoute
-	}
-	defer r.Release()
-
-	// Try to register so that we can start receiving packets.
-	f.ID.RemoteAddress = addr.Addr
-	err = f.stack.RegisterTransportEndpoint(0, []tcpip.NetworkProtocolNumber{fakeNetNumber}, fakeTransNumber, f.ID, f, false /* reuse */, 0 /* bindToDevice */)
-	if err != nil {
-		return err
-	}
-
-	f.route = r.Clone()
-
-	return nil
-}
-
-func (f *fakeTransportEndpoint) UniqueID() uint64 {
-	return f.uniqueID
-}
-
-func (f *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.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.stack.RegisterTransportEndpoint(
-		a.NIC,
-		[]tcpip.NetworkProtocolNumber{fakeNetNumber},
-		fakeTransNumber,
-		stack.TransportEndpointID{LocalAddress: a.Addr},
-		f,
-		false, /* reuse */
-		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(r *stack.Route, id stack.TransportEndpointID, _ stack.PacketBuffer) {
-	// Increment the number of received packets.
-	f.proto.packetCount++
-	if f.acceptQueue != nil {
-		f.acceptQueue = append(f.acceptQueue, fakeTransportEndpoint{
-			stack: f.stack,
-			TransportEndpointInfo: stack.TransportEndpointInfo{
-				ID:       f.ID,
-				NetProto: f.NetProto,
-			},
-			proto:    f.proto,
-			peerAddr: r.RemoteAddress,
-			route:    r.Clone(),
-		})
-	}
-}
-
-func (f *fakeTransportEndpoint) HandleControlPacket(stack.TransportEndpointID, stack.ControlType, uint32, stack.PacketBuffer) {
-	// Increment the number of received control packets.
-	f.proto.controlCount++
-}
-
-func (f *fakeTransportEndpoint) State() uint32 {
-	return 0
-}
-
-func (f *fakeTransportEndpoint) ModerateRecvBuf(copied int) {}
-
-func (f *fakeTransportEndpoint) IPTables() (stack.IPTables, error) {
-	return stack.IPTables{}, nil
-}
-
-func (f *fakeTransportEndpoint) Resume(*stack.Stack) {}
-
-func (f *fakeTransportEndpoint) Wait() {}
-
-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 {
-	packetCount  int
-	controlCount int
-	opts         fakeTransportProtocolOptions
-}
-
-func (*fakeTransportProtocol) Number() tcpip.TransportProtocolNumber {
-	return fakeTransNumber
-}
-
-func (f *fakeTransportProtocol) NewEndpoint(stack *stack.Stack, netProto tcpip.NetworkProtocolNumber, _ *waiter.Queue) (tcpip.Endpoint, *tcpip.Error) {
-	return newFakeTransportEndpoint(stack, f, netProto, stack.UniqueID()), nil
-}
-
-func (*fakeTransportProtocol) NewRawEndpoint(stack *stack.Stack, netProto 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.Route, stack.TransportEndpointID, stack.PacketBuffer) bool {
-	return true
-}
-
-func (f *fakeTransportProtocol) SetOption(option interface{}) *tcpip.Error {
-	switch v := option.(type) {
-	case fakeTransportGoodOption:
-		f.opts.good = bool(v)
-		return nil
-	case fakeTransportInvalidValueOption:
-		return tcpip.ErrInvalidOptionValue
-	default:
-		return tcpip.ErrUnknownProtocolOption
-	}
-}
-
-func (f *fakeTransportProtocol) Option(option interface{}) *tcpip.Error {
-	switch v := option.(type) {
-	case *fakeTransportGoodOption:
-		*v = fakeTransportGoodOption(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() {}
-
-func fakeTransFactory() stack.TransportProtocol {
-	return &fakeTransportProtocol{}
-}
-
-func TestTransportReceive(t *testing.T) {
-	linkEP := channel.New(10, defaultMTU, "")
-	s := stack.New(stack.Options{
-		NetworkProtocols:   []stack.NetworkProtocol{fakeNetFactory()},
-		TransportProtocols: []stack.TransportProtocol{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.PacketBuffer{
-		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.PacketBuffer{
-		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.PacketBuffer{
-		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.NetworkProtocol{fakeNetFactory()},
-		TransportProtocols: []stack.TransportProtocol{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.PacketBuffer{
-		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.PacketBuffer{
-		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.PacketBuffer{
-		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.NetworkProtocol{fakeNetFactory()},
-		TransportProtocols: []stack.TransportProtocol{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.
-	view := buffer.NewView(30)
-	_, _, err = ep.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{})
-	if 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.NetworkProtocol{fakeNetFactory()},
-		TransportProtocols: []stack.TransportProtocol{fakeTransFactory()},
-	})
-
-	// Try an unsupported transport protocol.
-	if err := s.SetTransportProtocolOption(tcpip.TransportProtocolNumber(99999), fakeTransportGoodOption(false)); err != tcpip.ErrUnknownProtocol {
-		t.Fatalf("SetTransportProtocolOption(fakeTrans2, blah, false) = %v, want = tcpip.ErrUnknownProtocol", err)
-	}
-
-	testCases := []struct {
-		option   interface{}
-		wantErr  *tcpip.Error
-		verifier func(t *testing.T, p stack.TransportProtocol)
-	}{
-		{fakeTransportGoodOption(true), nil, func(t *testing.T, p stack.TransportProtocol) {
-			t.Helper()
-			fakeTrans := p.(*fakeTransportProtocol)
-			if fakeTrans.opts.good != true {
-				t.Fatalf("fakeTrans.opts.good = false, want = true")
-			}
-			var v fakeTransportGoodOption
-			if err := s.TransportProtocolOption(fakeTransNumber, &v); err != nil {
-				t.Fatalf("s.TransportProtocolOption(fakeTransNumber, &v) = %v, want = nil, where v is option %T", v, err)
-			}
-			if v != true {
-				t.Fatalf("s.TransportProtocolOption(fakeTransNumber, &v) returned v = %v, want = true", v)
-			}
-
-		}},
-		{fakeTransportBadOption(true), tcpip.ErrUnknownProtocolOption, nil},
-		{fakeTransportInvalidValueOption(1), tcpip.ErrInvalidOptionValue, nil},
-	}
-	for _, tc := range testCases {
-		if got := s.SetTransportProtocolOption(fakeTransNumber, tc.option); got != tc.wantErr {
-			t.Errorf("s.SetTransportProtocolOption(fakeTrans, %v) = %v, want = %v", tc.option, got, tc.wantErr)
-		}
-		if tc.verifier != nil {
-			tc.verifier(t, s.TransportProtocolInstance(fakeTransNumber))
-		}
-	}
-}
-
-func TestTransportForwarding(t *testing.T) {
-	s := stack.New(stack.Options{
-		NetworkProtocols:   []stack.NetworkProtocol{fakeNetFactory()},
-		TransportProtocols: []stack.TransportProtocol{fakeTransFactory()},
-	})
-	s.SetForwarding(true)
-
-	// TODO(b/123449044): Change this to a channel NIC.
-	ep1 := loopback.New()
-	if err := s.CreateNIC(1, ep1); err != nil {
-		t.Fatalf("CreateNIC #1 failed: %v", err)
-	}
-	if err := s.AddAddress(1, fakeNetNumber, "\x01"); err != nil {
-		t.Fatalf("AddAddress #1 failed: %v", err)
-	}
-
-	ep2 := channel.New(10, defaultMTU, "")
-	if err := s.CreateNIC(2, ep2); err != nil {
-		t.Fatalf("CreateNIC #2 failed: %v", err)
-	}
-	if err := s.AddAddress(2, fakeNetNumber, "\x02"); err != nil {
-		t.Fatalf("AddAddress #2 failed: %v", err)
-	}
-
-	// Route all packets to address 3 to NIC 2 and all packets to address
-	// 1 to NIC 1.
-	{
-		subnet0, err := tcpip.NewSubnet("\x03", "\xff")
-		if err != nil {
-			t.Fatal(err)
-		}
-		subnet1, err := tcpip.NewSubnet("\x01", "\xff")
-		if err != nil {
-			t.Fatal(err)
-		}
-		s.SetRouteTable([]tcpip.Route{
-			{Destination: subnet0, Gateway: "\x00", NIC: 2},
-			{Destination: subnet1, Gateway: "\x00", NIC: 1},
-		})
-	}
-
-	wq := waiter.Queue{}
-	ep, err := s.NewEndpoint(fakeTransNumber, fakeNetNumber, &wq)
-	if err != nil {
-		t.Fatalf("NewEndpoint failed: %v", err)
-	}
-
-	if err := ep.Bind(tcpip.FullAddress{Addr: "\x01", NIC: 1}); err != nil {
-		t.Fatalf("Bind failed: %v", err)
-	}
-
-	// Send a packet to address 1 from address 3.
-	req := buffer.NewView(30)
-	req[0] = 1
-	req[1] = 3
-	req[2] = byte(fakeTransNumber)
-	ep2.InjectInbound(fakeNetNumber, stack.PacketBuffer{
-		Data: req.ToVectorisedView(),
-	})
-
-	aep, _, err := ep.Accept()
-	if err != nil || aep == nil {
-		t.Fatalf("Accept failed: %v, %v", aep, err)
-	}
-
-	resp := buffer.NewView(30)
-	if _, _, err := aep.Write(tcpip.SlicePayload(resp), tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %v", err)
-	}
-
-	p, ok := ep2.Read()
-	if !ok {
-		t.Fatal("Response packet not forwarded")
-	}
-
-	if dst := p.Pkt.Header.View()[0]; dst != 3 {
-		t.Errorf("Response packet has incorrect destination addresss: got = %d, want = 3", dst)
-	}
-	if src := p.Pkt.Header.View()[1]; src != 1 {
-		t.Errorf("Response packet has incorrect source addresss: got = %d, want = 3", src)
-	}
-}
diff --git a/pkg/tcpip/tcpip_state_autogen.go b/pkg/tcpip/tcpip_state_autogen.go
new file mode 100755
index 0000000..37b1170
--- /dev/null
+++ b/pkg/tcpip/tcpip_state_autogen.go
@@ -0,0 +1,85 @@
+// automatically generated by stateify.
+
+// +build go1.9
+// +build !go1.15
+
+package tcpip
+
+import (
+	"gvisor.dev/gvisor/pkg/state"
+)
+
+func (x *FullAddress) beforeSave() {}
+func (x *FullAddress) save(m state.Map) {
+	x.beforeSave()
+	m.Save("NIC", &x.NIC)
+	m.Save("Addr", &x.Addr)
+	m.Save("Port", &x.Port)
+}
+
+func (x *FullAddress) afterLoad() {}
+func (x *FullAddress) load(m state.Map) {
+	m.Load("NIC", &x.NIC)
+	m.Load("Addr", &x.Addr)
+	m.Load("Port", &x.Port)
+}
+
+func (x *ControlMessages) beforeSave() {}
+func (x *ControlMessages) save(m state.Map) {
+	x.beforeSave()
+	m.Save("HasTimestamp", &x.HasTimestamp)
+	m.Save("Timestamp", &x.Timestamp)
+	m.Save("HasInq", &x.HasInq)
+	m.Save("Inq", &x.Inq)
+	m.Save("HasTOS", &x.HasTOS)
+	m.Save("TOS", &x.TOS)
+	m.Save("HasTClass", &x.HasTClass)
+	m.Save("TClass", &x.TClass)
+	m.Save("HasIPPacketInfo", &x.HasIPPacketInfo)
+	m.Save("PacketInfo", &x.PacketInfo)
+}
+
+func (x *ControlMessages) afterLoad() {}
+func (x *ControlMessages) load(m state.Map) {
+	m.Load("HasTimestamp", &x.HasTimestamp)
+	m.Load("Timestamp", &x.Timestamp)
+	m.Load("HasInq", &x.HasInq)
+	m.Load("Inq", &x.Inq)
+	m.Load("HasTOS", &x.HasTOS)
+	m.Load("TOS", &x.TOS)
+	m.Load("HasTClass", &x.HasTClass)
+	m.Load("TClass", &x.TClass)
+	m.Load("HasIPPacketInfo", &x.HasIPPacketInfo)
+	m.Load("PacketInfo", &x.PacketInfo)
+}
+
+func (x *IPPacketInfo) beforeSave() {}
+func (x *IPPacketInfo) save(m state.Map) {
+	x.beforeSave()
+	m.Save("NIC", &x.NIC)
+	m.Save("LocalAddr", &x.LocalAddr)
+	m.Save("DestinationAddr", &x.DestinationAddr)
+}
+
+func (x *IPPacketInfo) afterLoad() {}
+func (x *IPPacketInfo) load(m state.Map) {
+	m.Load("NIC", &x.NIC)
+	m.Load("LocalAddr", &x.LocalAddr)
+	m.Load("DestinationAddr", &x.DestinationAddr)
+}
+
+func (x *StdClock) beforeSave() {}
+func (x *StdClock) save(m state.Map) {
+	x.beforeSave()
+}
+
+func (x *StdClock) afterLoad() {}
+func (x *StdClock) load(m state.Map) {
+}
+
+func init() {
+	state.Register("pkg/tcpip.FullAddress", (*FullAddress)(nil), state.Fns{Save: (*FullAddress).save, Load: (*FullAddress).load})
+	state.Register("pkg/tcpip.ControlMessages", (*ControlMessages)(nil), state.Fns{Save: (*ControlMessages).save, Load: (*ControlMessages).load})
+	state.Register("pkg/tcpip.IPPacketInfo", (*IPPacketInfo)(nil), state.Fns{Save: (*IPPacketInfo).save, Load: (*IPPacketInfo).load})
+	state.Register("pkg/tcpip.StdClock", (*StdClock)(nil), state.Fns{Save: (*StdClock).save, Load: (*StdClock).load})
+}
diff --git a/pkg/tcpip/tcpip_test.go b/pkg/tcpip/tcpip_test.go
deleted file mode 100644
index 8c0aacf..0000000
--- a/pkg/tcpip/tcpip_test.go
+++ /dev/null
@@ -1,228 +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 (
-	"fmt"
-	"net"
-	"strings"
-	"testing"
-)
-
-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.Error("NewSubnet(%q, %q) failed: %s", tt.subnetAddr, tt.subnetMask, err)
-			continue
-		}
-		if gotSubnet != wantSubnet {
-			t.Errorf("got subnet = %q, want = %q", gotSubnet, wantSubnet)
-		}
-	}
-}
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.go b/pkg/tcpip/timer.go
old mode 100644
new mode 100755
diff --git a/pkg/tcpip/timer_test.go b/pkg/tcpip/timer_test.go
deleted file mode 100644
index 2d20f7e..0000000
--- a/pkg/tcpip/timer_test.go
+++ /dev/null
@@ -1,236 +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 TestCancellableTimerFire(t *testing.T) {
-	t.Parallel()
-
-	ch := make(chan struct{})
-	var lock sync.Mutex
-
-	timer := tcpip.MakeCancellableTimer(&lock, func() {
-		ch <- struct{}{}
-	})
-	timer.Reset(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()
-
-	ch := make(chan struct{})
-	var lock sync.Mutex
-
-	timer := tcpip.MakeCancellableTimer(&lock, func() { ch <- struct{}{} })
-	timer.Reset(middleDuration)
-
-	lock.Lock()
-	timer.StopLocked()
-	lock.Unlock()
-
-	timer.Reset(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 TestCancellableTimerResetFromShortDuration(t *testing.T) {
-	t.Parallel()
-
-	ch := make(chan struct{})
-	var lock sync.Mutex
-
-	lock.Lock()
-	timer := tcpip.MakeCancellableTimer(&lock, func() { ch <- struct{}{} })
-	timer.Reset(shortDuration)
-	timer.StopLocked()
-	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):
-	}
-
-	timer.Reset(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 TestCancellableTimerImmediatelyStop(t *testing.T) {
-	t.Parallel()
-
-	ch := make(chan struct{})
-	var lock sync.Mutex
-
-	for i := 0; i < 1000; i++ {
-		lock.Lock()
-		timer := tcpip.MakeCancellableTimer(&lock, func() { ch <- struct{}{} })
-		timer.Reset(shortDuration)
-		timer.StopLocked()
-		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 TestCancellableTimerStoppedResetWithoutLock(t *testing.T) {
-	t.Parallel()
-
-	ch := make(chan struct{})
-	var lock sync.Mutex
-
-	lock.Lock()
-	timer := tcpip.MakeCancellableTimer(&lock, func() { ch <- struct{}{} })
-	timer.Reset(shortDuration)
-	timer.StopLocked()
-	lock.Unlock()
-
-	for i := 0; i < 10; i++ {
-		timer.Reset(middleDuration)
-
-		lock.Lock()
-		// Sleep until the timer fires and gets blocked trying to take the lock.
-		time.Sleep(middleDuration * 2)
-		timer.StopLocked()
-		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()
-
-	ch := make(chan struct{})
-	var lock sync.Mutex
-
-	lock.Lock()
-	timer := tcpip.MakeCancellableTimer(&lock, func() { ch <- struct{}{} })
-	timer.Reset(shortDuration)
-	for i := 0; i < 10; i++ {
-		// Sleep until the timer fires and gets blocked trying to take the lock.
-		time.Sleep(middleDuration)
-		timer.StopLocked()
-		timer.Reset(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 TestManyCancellableTimerResetUnderLock(t *testing.T) {
-	t.Parallel()
-
-	ch := make(chan struct{})
-	var lock sync.Mutex
-
-	lock.Lock()
-	timer := tcpip.MakeCancellableTimer(&lock, func() { ch <- struct{}{} })
-	timer.Reset(shortDuration)
-	for i := 0; i < 10; i++ {
-		timer.StopLocked()
-		timer.Reset(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 100755
index 0000000..ddee31a
--- /dev/null
+++ b/pkg/tcpip/transport/icmp/icmp_packet_list.go
@@ -0,0 +1,186 @@
+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.
+func (l *icmpPacketList) Empty() bool {
+	return l.head == nil
+}
+
+// Front returns the first element of list l or nil.
+func (l *icmpPacketList) Front() *icmpPacket {
+	return l.head
+}
+
+// Back returns the last element of list l or nil.
+func (l *icmpPacketList) Back() *icmpPacket {
+	return l.tail
+}
+
+// PushFront inserts the element e at the front of list l.
+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.
+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.
+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.
+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.
+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.
+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 {
+		l.head = next
+	}
+
+	if next != nil {
+		icmpPacketElementMapper{}.linkerFor(next).SetPrev(prev)
+	} else {
+		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.
+func (e *icmpPacketEntry) Next() *icmpPacket {
+	return e.next
+}
+
+// Prev returns the entry that precedes e in the list.
+func (e *icmpPacketEntry) Prev() *icmpPacket {
+	return e.prev
+}
+
+// SetNext assigns 'entry' as the entry that follows e in the list.
+func (e *icmpPacketEntry) SetNext(elem *icmpPacket) {
+	e.next = elem
+}
+
+// SetPrev assigns 'entry' as the entry that precedes e in the list.
+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 100755
index 0000000..c26460a
--- /dev/null
+++ b/pkg/tcpip/transport/icmp/icmp_state_autogen.go
@@ -0,0 +1,94 @@
+// automatically generated by stateify.
+
+package icmp
+
+import (
+	"gvisor.dev/gvisor/pkg/state"
+	"gvisor.dev/gvisor/pkg/tcpip/buffer"
+)
+
+func (x *icmpPacket) beforeSave() {}
+func (x *icmpPacket) save(m state.Map) {
+	x.beforeSave()
+	var data buffer.VectorisedView = x.saveData()
+	m.SaveValue("data", data)
+	m.Save("icmpPacketEntry", &x.icmpPacketEntry)
+	m.Save("senderAddress", &x.senderAddress)
+	m.Save("timestamp", &x.timestamp)
+}
+
+func (x *icmpPacket) afterLoad() {}
+func (x *icmpPacket) load(m state.Map) {
+	m.Load("icmpPacketEntry", &x.icmpPacketEntry)
+	m.Load("senderAddress", &x.senderAddress)
+	m.Load("timestamp", &x.timestamp)
+	m.LoadValue("data", new(buffer.VectorisedView), func(y interface{}) { x.loadData(y.(buffer.VectorisedView)) })
+}
+
+func (x *endpoint) save(m state.Map) {
+	x.beforeSave()
+	var rcvBufSizeMax int = x.saveRcvBufSizeMax()
+	m.SaveValue("rcvBufSizeMax", rcvBufSizeMax)
+	m.Save("TransportEndpointInfo", &x.TransportEndpointInfo)
+	m.Save("waiterQueue", &x.waiterQueue)
+	m.Save("uniqueID", &x.uniqueID)
+	m.Save("rcvReady", &x.rcvReady)
+	m.Save("rcvList", &x.rcvList)
+	m.Save("rcvBufSize", &x.rcvBufSize)
+	m.Save("rcvClosed", &x.rcvClosed)
+	m.Save("sndBufSize", &x.sndBufSize)
+	m.Save("shutdownFlags", &x.shutdownFlags)
+	m.Save("state", &x.state)
+	m.Save("ttl", &x.ttl)
+	m.Save("owner", &x.owner)
+}
+
+func (x *endpoint) load(m state.Map) {
+	m.Load("TransportEndpointInfo", &x.TransportEndpointInfo)
+	m.Load("waiterQueue", &x.waiterQueue)
+	m.Load("uniqueID", &x.uniqueID)
+	m.Load("rcvReady", &x.rcvReady)
+	m.Load("rcvList", &x.rcvList)
+	m.Load("rcvBufSize", &x.rcvBufSize)
+	m.Load("rcvClosed", &x.rcvClosed)
+	m.Load("sndBufSize", &x.sndBufSize)
+	m.Load("shutdownFlags", &x.shutdownFlags)
+	m.Load("state", &x.state)
+	m.Load("ttl", &x.ttl)
+	m.Load("owner", &x.owner)
+	m.LoadValue("rcvBufSizeMax", new(int), func(y interface{}) { x.loadRcvBufSizeMax(y.(int)) })
+	m.AfterLoad(x.afterLoad)
+}
+
+func (x *icmpPacketList) beforeSave() {}
+func (x *icmpPacketList) save(m state.Map) {
+	x.beforeSave()
+	m.Save("head", &x.head)
+	m.Save("tail", &x.tail)
+}
+
+func (x *icmpPacketList) afterLoad() {}
+func (x *icmpPacketList) load(m state.Map) {
+	m.Load("head", &x.head)
+	m.Load("tail", &x.tail)
+}
+
+func (x *icmpPacketEntry) beforeSave() {}
+func (x *icmpPacketEntry) save(m state.Map) {
+	x.beforeSave()
+	m.Save("next", &x.next)
+	m.Save("prev", &x.prev)
+}
+
+func (x *icmpPacketEntry) afterLoad() {}
+func (x *icmpPacketEntry) load(m state.Map) {
+	m.Load("next", &x.next)
+	m.Load("prev", &x.prev)
+}
+
+func init() {
+	state.Register("pkg/tcpip/transport/icmp.icmpPacket", (*icmpPacket)(nil), state.Fns{Save: (*icmpPacket).save, Load: (*icmpPacket).load})
+	state.Register("pkg/tcpip/transport/icmp.endpoint", (*endpoint)(nil), state.Fns{Save: (*endpoint).save, Load: (*endpoint).load})
+	state.Register("pkg/tcpip/transport/icmp.icmpPacketList", (*icmpPacketList)(nil), state.Fns{Save: (*icmpPacketList).save, Load: (*icmpPacketList).load})
+	state.Register("pkg/tcpip/transport/icmp.icmpPacketEntry", (*icmpPacketEntry)(nil), state.Fns{Save: (*icmpPacketEntry).save, Load: (*icmpPacketEntry).load})
+}
diff --git a/pkg/tcpip/transport/packet/endpoint.go b/pkg/tcpip/transport/packet/endpoint.go
old mode 100644
new mode 100755
diff --git a/pkg/tcpip/transport/packet/endpoint_state.go b/pkg/tcpip/transport/packet/endpoint_state.go
old mode 100644
new mode 100755
diff --git a/pkg/tcpip/transport/packet/packet_list.go b/pkg/tcpip/transport/packet/packet_list.go
new file mode 100755
index 0000000..ad27c7c
--- /dev/null
+++ b/pkg/tcpip/transport/packet/packet_list.go
@@ -0,0 +1,186 @@
+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.
+func (l *packetList) Empty() bool {
+	return l.head == nil
+}
+
+// Front returns the first element of list l or nil.
+func (l *packetList) Front() *packet {
+	return l.head
+}
+
+// Back returns the last element of list l or nil.
+func (l *packetList) Back() *packet {
+	return l.tail
+}
+
+// PushFront inserts the element e at the front of list l.
+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.
+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.
+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.
+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.
+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.
+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 {
+		l.head = next
+	}
+
+	if next != nil {
+		packetElementMapper{}.linkerFor(next).SetPrev(prev)
+	} else {
+		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.
+func (e *packetEntry) Next() *packet {
+	return e.next
+}
+
+// Prev returns the entry that precedes e in the list.
+func (e *packetEntry) Prev() *packet {
+	return e.prev
+}
+
+// SetNext assigns 'entry' as the entry that follows e in the list.
+func (e *packetEntry) SetNext(elem *packet) {
+	e.next = elem
+}
+
+// SetPrev assigns 'entry' as the entry that precedes e in the list.
+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 100755
index 0000000..8ff339e
--- /dev/null
+++ b/pkg/tcpip/transport/packet/packet_state_autogen.go
@@ -0,0 +1,90 @@
+// automatically generated by stateify.
+
+package packet
+
+import (
+	"gvisor.dev/gvisor/pkg/state"
+	"gvisor.dev/gvisor/pkg/tcpip/buffer"
+)
+
+func (x *packet) beforeSave() {}
+func (x *packet) save(m state.Map) {
+	x.beforeSave()
+	var data buffer.VectorisedView = x.saveData()
+	m.SaveValue("data", data)
+	m.Save("packetEntry", &x.packetEntry)
+	m.Save("timestampNS", &x.timestampNS)
+	m.Save("senderAddr", &x.senderAddr)
+}
+
+func (x *packet) afterLoad() {}
+func (x *packet) load(m state.Map) {
+	m.Load("packetEntry", &x.packetEntry)
+	m.Load("timestampNS", &x.timestampNS)
+	m.Load("senderAddr", &x.senderAddr)
+	m.LoadValue("data", new(buffer.VectorisedView), func(y interface{}) { x.loadData(y.(buffer.VectorisedView)) })
+}
+
+func (x *endpoint) save(m state.Map) {
+	x.beforeSave()
+	var rcvBufSizeMax int = x.saveRcvBufSizeMax()
+	m.SaveValue("rcvBufSizeMax", rcvBufSizeMax)
+	m.Save("TransportEndpointInfo", &x.TransportEndpointInfo)
+	m.Save("netProto", &x.netProto)
+	m.Save("waiterQueue", &x.waiterQueue)
+	m.Save("cooked", &x.cooked)
+	m.Save("rcvList", &x.rcvList)
+	m.Save("rcvBufSize", &x.rcvBufSize)
+	m.Save("rcvClosed", &x.rcvClosed)
+	m.Save("sndBufSize", &x.sndBufSize)
+	m.Save("closed", &x.closed)
+	m.Save("bound", &x.bound)
+}
+
+func (x *endpoint) load(m state.Map) {
+	m.Load("TransportEndpointInfo", &x.TransportEndpointInfo)
+	m.Load("netProto", &x.netProto)
+	m.Load("waiterQueue", &x.waiterQueue)
+	m.Load("cooked", &x.cooked)
+	m.Load("rcvList", &x.rcvList)
+	m.Load("rcvBufSize", &x.rcvBufSize)
+	m.Load("rcvClosed", &x.rcvClosed)
+	m.Load("sndBufSize", &x.sndBufSize)
+	m.Load("closed", &x.closed)
+	m.Load("bound", &x.bound)
+	m.LoadValue("rcvBufSizeMax", new(int), func(y interface{}) { x.loadRcvBufSizeMax(y.(int)) })
+	m.AfterLoad(x.afterLoad)
+}
+
+func (x *packetList) beforeSave() {}
+func (x *packetList) save(m state.Map) {
+	x.beforeSave()
+	m.Save("head", &x.head)
+	m.Save("tail", &x.tail)
+}
+
+func (x *packetList) afterLoad() {}
+func (x *packetList) load(m state.Map) {
+	m.Load("head", &x.head)
+	m.Load("tail", &x.tail)
+}
+
+func (x *packetEntry) beforeSave() {}
+func (x *packetEntry) save(m state.Map) {
+	x.beforeSave()
+	m.Save("next", &x.next)
+	m.Save("prev", &x.prev)
+}
+
+func (x *packetEntry) afterLoad() {}
+func (x *packetEntry) load(m state.Map) {
+	m.Load("next", &x.next)
+	m.Load("prev", &x.prev)
+}
+
+func init() {
+	state.Register("pkg/tcpip/transport/packet.packet", (*packet)(nil), state.Fns{Save: (*packet).save, Load: (*packet).load})
+	state.Register("pkg/tcpip/transport/packet.endpoint", (*endpoint)(nil), state.Fns{Save: (*endpoint).save, Load: (*endpoint).load})
+	state.Register("pkg/tcpip/transport/packet.packetList", (*packetList)(nil), state.Fns{Save: (*packetList).save, Load: (*packetList).load})
+	state.Register("pkg/tcpip/transport/packet.packetEntry", (*packetEntry)(nil), state.Fns{Save: (*packetEntry).save, Load: (*packetEntry).load})
+}
diff --git a/pkg/tcpip/transport/raw/raw_packet_list.go b/pkg/tcpip/transport/raw/raw_packet_list.go
new file mode 100755
index 0000000..e8c1bc9
--- /dev/null
+++ b/pkg/tcpip/transport/raw/raw_packet_list.go
@@ -0,0 +1,186 @@
+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.
+func (l *rawPacketList) Empty() bool {
+	return l.head == nil
+}
+
+// Front returns the first element of list l or nil.
+func (l *rawPacketList) Front() *rawPacket {
+	return l.head
+}
+
+// Back returns the last element of list l or nil.
+func (l *rawPacketList) Back() *rawPacket {
+	return l.tail
+}
+
+// PushFront inserts the element e at the front of list l.
+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.
+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.
+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.
+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.
+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.
+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 {
+		l.head = next
+	}
+
+	if next != nil {
+		rawPacketElementMapper{}.linkerFor(next).SetPrev(prev)
+	} else {
+		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.
+func (e *rawPacketEntry) Next() *rawPacket {
+	return e.next
+}
+
+// Prev returns the entry that precedes e in the list.
+func (e *rawPacketEntry) Prev() *rawPacket {
+	return e.prev
+}
+
+// SetNext assigns 'entry' as the entry that follows e in the list.
+func (e *rawPacketEntry) SetNext(elem *rawPacket) {
+	e.next = elem
+}
+
+// SetPrev assigns 'entry' as the entry that precedes e in the list.
+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 100755
index 0000000..c755fa8
--- /dev/null
+++ b/pkg/tcpip/transport/raw/raw_state_autogen.go
@@ -0,0 +1,92 @@
+// automatically generated by stateify.
+
+package raw
+
+import (
+	"gvisor.dev/gvisor/pkg/state"
+	"gvisor.dev/gvisor/pkg/tcpip/buffer"
+)
+
+func (x *rawPacket) beforeSave() {}
+func (x *rawPacket) save(m state.Map) {
+	x.beforeSave()
+	var data buffer.VectorisedView = x.saveData()
+	m.SaveValue("data", data)
+	m.Save("rawPacketEntry", &x.rawPacketEntry)
+	m.Save("timestampNS", &x.timestampNS)
+	m.Save("senderAddr", &x.senderAddr)
+}
+
+func (x *rawPacket) afterLoad() {}
+func (x *rawPacket) load(m state.Map) {
+	m.Load("rawPacketEntry", &x.rawPacketEntry)
+	m.Load("timestampNS", &x.timestampNS)
+	m.Load("senderAddr", &x.senderAddr)
+	m.LoadValue("data", new(buffer.VectorisedView), func(y interface{}) { x.loadData(y.(buffer.VectorisedView)) })
+}
+
+func (x *endpoint) save(m state.Map) {
+	x.beforeSave()
+	var rcvBufSizeMax int = x.saveRcvBufSizeMax()
+	m.SaveValue("rcvBufSizeMax", rcvBufSizeMax)
+	m.Save("TransportEndpointInfo", &x.TransportEndpointInfo)
+	m.Save("waiterQueue", &x.waiterQueue)
+	m.Save("associated", &x.associated)
+	m.Save("rcvList", &x.rcvList)
+	m.Save("rcvBufSize", &x.rcvBufSize)
+	m.Save("rcvClosed", &x.rcvClosed)
+	m.Save("sndBufSize", &x.sndBufSize)
+	m.Save("closed", &x.closed)
+	m.Save("connected", &x.connected)
+	m.Save("bound", &x.bound)
+	m.Save("owner", &x.owner)
+}
+
+func (x *endpoint) load(m state.Map) {
+	m.Load("TransportEndpointInfo", &x.TransportEndpointInfo)
+	m.Load("waiterQueue", &x.waiterQueue)
+	m.Load("associated", &x.associated)
+	m.Load("rcvList", &x.rcvList)
+	m.Load("rcvBufSize", &x.rcvBufSize)
+	m.Load("rcvClosed", &x.rcvClosed)
+	m.Load("sndBufSize", &x.sndBufSize)
+	m.Load("closed", &x.closed)
+	m.Load("connected", &x.connected)
+	m.Load("bound", &x.bound)
+	m.Load("owner", &x.owner)
+	m.LoadValue("rcvBufSizeMax", new(int), func(y interface{}) { x.loadRcvBufSizeMax(y.(int)) })
+	m.AfterLoad(x.afterLoad)
+}
+
+func (x *rawPacketList) beforeSave() {}
+func (x *rawPacketList) save(m state.Map) {
+	x.beforeSave()
+	m.Save("head", &x.head)
+	m.Save("tail", &x.tail)
+}
+
+func (x *rawPacketList) afterLoad() {}
+func (x *rawPacketList) load(m state.Map) {
+	m.Load("head", &x.head)
+	m.Load("tail", &x.tail)
+}
+
+func (x *rawPacketEntry) beforeSave() {}
+func (x *rawPacketEntry) save(m state.Map) {
+	x.beforeSave()
+	m.Save("next", &x.next)
+	m.Save("prev", &x.prev)
+}
+
+func (x *rawPacketEntry) afterLoad() {}
+func (x *rawPacketEntry) load(m state.Map) {
+	m.Load("next", &x.next)
+	m.Load("prev", &x.prev)
+}
+
+func init() {
+	state.Register("pkg/tcpip/transport/raw.rawPacket", (*rawPacket)(nil), state.Fns{Save: (*rawPacket).save, Load: (*rawPacket).load})
+	state.Register("pkg/tcpip/transport/raw.endpoint", (*endpoint)(nil), state.Fns{Save: (*endpoint).save, Load: (*endpoint).load})
+	state.Register("pkg/tcpip/transport/raw.rawPacketList", (*rawPacketList)(nil), state.Fns{Save: (*rawPacketList).save, Load: (*rawPacketList).load})
+	state.Register("pkg/tcpip/transport/raw.rawPacketEntry", (*rawPacketEntry)(nil), state.Fns{Save: (*rawPacketEntry).save, Load: (*rawPacketEntry).load})
+}
diff --git a/pkg/tcpip/transport/tcp/connect_unsafe.go b/pkg/tcpip/transport/tcp/connect_unsafe.go
old mode 100644
new mode 100755
diff --git a/pkg/tcpip/transport/tcp/dispatcher.go b/pkg/tcpip/transport/tcp/dispatcher.go
old mode 100644
new mode 100755
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 4f361b2..0000000
--- a/pkg/tcpip/transport/tcp/dual_stack_test.go
+++ /dev/null
@@ -1,652 +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"
-	"time"
-
-	"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/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 err != tcpip.ErrNoRoute {
-		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 err != tcpip.ErrConnectStarted {
-		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.SeqNum(uint32(c.IRS)+1),
-		checker.AckNum(uint32(iss)+1),
-	))
-	checker.IPv4(t, c.GetPacket(), ackCheckers...)
-
-	// Wait for connection to be established.
-	select {
-	case <-ch:
-		err = c.EP.GetSockOpt(tcpip.ErrorOption{})
-		if 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 err != tcpip.ErrConnectStarted {
-		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.SeqNum(uint32(c.IRS)+1),
-		checker.AckNum(uint32(iss)+1),
-	))
-	checker.IPv6(t, c.GetV6Packet(), ackCheckers...)
-
-	// Wait for connection to be established.
-	select {
-	case <-ch:
-		err = c.EP.GetSockOpt(tcpip.ErrorOption{})
-		if 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 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.AckNum(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.AckNum(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.AckNum(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()
-	if err == tcpip.ErrWouldBlock {
-		// Wait for connection to be established.
-		select {
-		case <-ch:
-			nep, _, err = c.EP.Accept()
-			if err != nil {
-				t.Fatalf("Accept failed: %v", err)
-			}
-
-		case <-time.After(1 * time.Second):
-			t.Fatalf("Timed out waiting for accept")
-		}
-	}
-
-	// Make sure we get the same error when calling the original ep and the
-	// new one. This validates that v4-mapped endpoints are still able to
-	// query the V6Only flag, whereas pure v4 endpoints are not.
-	_, expected := c.EP.GetSockOptBool(tcpip.V6OnlyOption)
-	if _, err := nep.GetSockOptBool(tcpip.V6OnlyOption); err != expected {
-		t.Fatalf("GetSockOpt returned unexpected value: got %v, want %v", err, expected)
-	}
-
-	// 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)
-	}
-
-	data := "Don't panic"
-	nep.Write(tcpip.SlicePayload(buffer.NewViewFromBytes([]byte(data))), 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.AckNum(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)
-
-	nep, _, err := c.EP.Accept()
-	if err == tcpip.ErrWouldBlock {
-		// Wait for connection to be established.
-		select {
-		case <-ch:
-			nep, _, err = c.EP.Accept()
-			if err != nil {
-				t.Fatalf("Accept failed: %v", err)
-			}
-
-		case <-time.After(1 * time.Second):
-			t.Fatalf("Timed out waiting for accept")
-		}
-	}
-
-	// Make sure we can still query the v6 only status of the new endpoint,
-	// that is, that it is in fact a v6 socket.
-	if _, err := nep.GetSockOptBool(tcpip.V6OnlyOption); err != nil {
-		t.Fatalf("GetSockOpt failed failed: %v", err)
-	}
-
-	// Check the peer address.
-	addr, err := nep.GetRemoteAddress()
-	if err != nil {
-		t.Fatalf("GetRemoteAddress failed failed: %v", err)
-	}
-
-	if addr.Addr != context.TestV6Addr {
-		t.Fatalf("Unexpected remote address: got %v, want %v", 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.
-	saved := tcp.SynRcvdCountThreshold
-	defer func() {
-		tcp.SynRcvdCountThreshold = saved
-	}()
-	tcp.SynRcvdCountThreshold = 0
-	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()
-	if err == tcpip.ErrWouldBlock {
-		// Wait for connection to be established.
-		select {
-		case <-ch:
-			nep, _, err = c.EP.Accept()
-			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_state.go b/pkg/tcpip/transport/tcp/rcv_state.go
old mode 100644
new mode 100755
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 100755
index 0000000..62c042a
--- /dev/null
+++ b/pkg/tcpip/transport/tcp/tcp_endpoint_list.go
@@ -0,0 +1,186 @@
+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.
+func (l *endpointList) Empty() bool {
+	return l.head == nil
+}
+
+// Front returns the first element of list l or nil.
+func (l *endpointList) Front() *endpoint {
+	return l.head
+}
+
+// Back returns the last element of list l or nil.
+func (l *endpointList) Back() *endpoint {
+	return l.tail
+}
+
+// PushFront inserts the element e at the front of list l.
+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.
+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.
+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.
+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.
+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.
+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 {
+		l.head = next
+	}
+
+	if next != nil {
+		endpointElementMapper{}.linkerFor(next).SetPrev(prev)
+	} else {
+		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.
+func (e *endpointEntry) Next() *endpoint {
+	return e.next
+}
+
+// Prev returns the entry that precedes e in the list.
+func (e *endpointEntry) Prev() *endpoint {
+	return e.prev
+}
+
+// SetNext assigns 'entry' as the entry that follows e in the list.
+func (e *endpointEntry) SetNext(elem *endpoint) {
+	e.next = elem
+}
+
+// SetPrev assigns 'entry' as the entry that precedes e in the list.
+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 782d7b4..0000000
--- a/pkg/tcpip/transport/tcp/tcp_noracedetector_test.go
+++ /dev/null
@@ -1,527 +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 (
-	"fmt"
-	"math"
-	"testing"
-	"time"
-
-	"gvisor.dev/gvisor/pkg/tcpip"
-	"gvisor.dev/gvisor/pkg/tcpip/buffer"
-	"gvisor.dev/gvisor/pkg/tcpip/header"
-	"gvisor.dev/gvisor/pkg/tcpip/transport/tcp"
-	"gvisor.dev/gvisor/pkg/tcpip/transport/tcp/testing/context"
-)
-
-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 = 7
-	data := buffer.NewView(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.
-	if _, _, err := c.EP.Write(tcpip.SlicePayload(data), tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %v", 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)
-
-	if got, want := c.Stack().Stats().TCP.FastRetransmit.Value(), uint64(1); got != want {
-		t.Errorf("got stats.TCP.FastRetransmit.Value = %v, want = %v", got, want)
-	}
-
-	if got, want := c.Stack().Stats().TCP.Retransmits.Value(), uint64(1); got != want {
-		t.Errorf("got stats.TCP.Retransmit.Value = %v, want = %v", got, want)
-	}
-
-	if got, want := c.Stack().Stats().TCP.FastRecovery.Value(), uint64(1); got != want {
-		t.Errorf("got stats.TCP.FastRecovery.Value = %v, want = %v", got, want)
-	}
-
-	// 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)
-
-	if got, want := c.Stack().Stats().TCP.FastRetransmit.Value(), uint64(2); got != want {
-		t.Errorf("got stats.TCP.FastRetransmit.Value = %v, want = %v", got, want)
-	}
-
-	if got, want := c.Stack().Stats().TCP.Retransmits.Value(), uint64(2); got != want {
-		t.Errorf("got stats.TCP.Retransmit.Value = %v, want = %v", got, want)
-	}
-
-	// 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 = 7
-	data := buffer.NewView(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.
-	if _, _, err := c.EP.Write(tcpip.SlicePayload(data), tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %v", 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 = 7
-	data := buffer.NewView(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.
-	if _, _, err := c.EP.Write(tcpip.SlicePayload(data), tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %v", 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 = 7
-	data := buffer.NewView(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.
-	if _, _, err := c.EP.Write(tcpip.SlicePayload(data), tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %v", 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 = 7
-	data := buffer.NewView(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.
-	half := data[:len(data)/2]
-	if _, _, err := c.EP.Write(tcpip.SlicePayload(half), tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %v", err)
-	}
-	half = data[len(data)/2:]
-	if _, _, err := c.EP.Write(tcpip.SlicePayload(half), tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %v", 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)
-
-	if got, want := c.Stack().Stats().TCP.Timeouts.Value(), uint64(1); got != want {
-		t.Errorf("got stats.TCP.Timeouts.Value = %v, want = %v", got, want)
-	}
-
-	if got, want := c.Stack().Stats().TCP.Retransmits.Value(), uint64(1); got != want {
-		t.Errorf("got stats.TCP.Retransmits.Value = %v, want = %v", got, want)
-	}
-
-	if got, want := c.EP.Stats().(*tcp.Stats).SendErrors.Timeouts.Value(), uint64(1); got != want {
-		t.Errorf("got EP SendErrors.Timeouts.Value = %v, want = %v", got, want)
-	}
-
-	if got, want := c.EP.Stats().(*tcp.Stats).SendErrors.Retransmits.Value(), uint64(1); got != want {
-		t.Errorf("got EP stats SendErrors.Retransmits.Value = %v, want = %v", got, want)
-	}
-
-	if got, want := c.Stack().Stats().TCP.SlowStartRetransmits.Value(), uint64(1); got != want {
-		t.Errorf("got stats.TCP.SlowStartRetransmits.Value = %v, want = %v", got, want)
-	}
-
-	// 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_sack_test.go b/pkg/tcpip/transport/tcp/tcp_sack_test.go
deleted file mode 100644
index afea124..0000000
--- a/pkg/tcpip/transport/tcp/tcp_sack_test.go
+++ /dev/null
@@ -1,572 +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 (
-	"fmt"
-	"log"
-	"reflect"
-	"testing"
-	"time"
-
-	"gvisor.dev/gvisor/pkg/tcpip"
-	"gvisor.dev/gvisor/pkg/tcpip/buffer"
-	"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"
-)
-
-// 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()
-	if err := c.Stack().SetTransportProtocolOption(tcp.ProtocolNumber, tcp.SACKEnabled(enable)); err != nil {
-		t.Fatalf("c.s.SetTransportProtocolOption(tcp.ProtocolNumber, SACKEnabled(%v) = %v", enable, 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).
-	}
-	savedSynCountThreshold := tcp.SynRcvdCountThreshold
-	defer func() {
-		tcp.SynRcvdCountThreshold = savedSynCountThreshold
-	}()
-	for _, tc := range testCases {
-		t.Run(fmt.Sprintf("test: %#v", tc), func(t *testing.T) {
-			if tc.cookieEnabled {
-				tcp.SynRcvdCountThreshold = 0
-			} else {
-				tcp.SynRcvdCountThreshold = savedSynCountThreshold
-			}
-			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()
-					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).
-	}
-	savedSynCountThreshold := tcp.SynRcvdCountThreshold
-	defer func() {
-		tcp.SynRcvdCountThreshold = savedSynCountThreshold
-	}()
-	for _, tc := range testCases {
-		t.Run(fmt.Sprintf("test: %#v", tc), func(t *testing.T) {
-			if tc.cookieEnabled {
-				tcp.SynRcvdCountThreshold = 0
-			} else {
-				tcp.SynRcvdCountThreshold = savedSynCountThreshold
-			}
-			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()
-					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 = 7
-	data := buffer.NewView(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.
-	if _, _, err := c.EP.Write(tcpip.SlicePayload(data), tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %v", 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.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(790, rtxOffset, []header.SACKBlock{{start, end}})
-		end = end.Add(10)
-	}
-
-	// Receive the retransmitted packet.
-	c.ReceiveAndCheckPacketWithOptions(data, rtxOffset, maxPayload, tsOptionSize)
-
-	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 {
-			t.Errorf("got %s.Value() = %v, want = %v", s.name, got, want)
-		}
-	}
-
-	// 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(790, 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(790, 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
-	}
-
-	// 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 {
-		t.Errorf("got stats.TCP.FastRetransmit.Value = %v, want = %v", got, want)
-	}
-
-	if got, want := c.EP.Stats().(*tcp.Stats).SendErrors.FastRetransmit.Value(), uint64(1); got != want {
-		t.Errorf("got EP stats SendErrors.FastRetransmit = %v, want = %v", got, want)
-	}
-
-	if got, want := c.Stack().Stats().TCP.Retransmits.Value(), uint64(4); got != want {
-		t.Errorf("got stats.TCP.Retransmits.Value = %v, want = %v", got, want)
-	}
-
-	if got, want := c.EP.Stats().(*tcp.Stats).SendErrors.Retransmits.Value(), uint64(4); got != want {
-		t.Errorf("got EP stats Stats.SendErrors.Retransmits = %v, want = %v", got, want)
-	}
-
-	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 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(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 += 9
-		}
-		expected++
-	}
-}
diff --git a/pkg/tcpip/transport/tcp/tcp_segment_list.go b/pkg/tcpip/transport/tcp/tcp_segment_list.go
new file mode 100755
index 0000000..27f17f0
--- /dev/null
+++ b/pkg/tcpip/transport/tcp/tcp_segment_list.go
@@ -0,0 +1,186 @@
+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.
+func (l *segmentList) Empty() bool {
+	return l.head == nil
+}
+
+// Front returns the first element of list l or nil.
+func (l *segmentList) Front() *segment {
+	return l.head
+}
+
+// Back returns the last element of list l or nil.
+func (l *segmentList) Back() *segment {
+	return l.tail
+}
+
+// PushFront inserts the element e at the front of list l.
+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.
+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.
+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.
+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.
+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.
+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 {
+		l.head = next
+	}
+
+	if next != nil {
+		segmentElementMapper{}.linkerFor(next).SetPrev(prev)
+	} else {
+		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.
+func (e *segmentEntry) Next() *segment {
+	return e.next
+}
+
+// Prev returns the entry that precedes e in the list.
+func (e *segmentEntry) Prev() *segment {
+	return e.prev
+}
+
+// SetNext assigns 'entry' as the entry that follows e in the list.
+func (e *segmentEntry) SetNext(elem *segment) {
+	e.next = elem
+}
+
+// SetPrev assigns 'entry' as the entry that precedes e in the list.
+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 100755
index 0000000..b3cb5f9
--- /dev/null
+++ b/pkg/tcpip/transport/tcp/tcp_state_autogen.go
@@ -0,0 +1,535 @@
+// automatically generated by stateify.
+
+package tcp
+
+import (
+	"gvisor.dev/gvisor/pkg/state"
+	"gvisor.dev/gvisor/pkg/tcpip/buffer"
+)
+
+func (x *cubicState) beforeSave() {}
+func (x *cubicState) save(m state.Map) {
+	x.beforeSave()
+	var t unixTime = x.saveT()
+	m.SaveValue("t", t)
+	m.Save("wLastMax", &x.wLastMax)
+	m.Save("wMax", &x.wMax)
+	m.Save("numCongestionEvents", &x.numCongestionEvents)
+	m.Save("c", &x.c)
+	m.Save("k", &x.k)
+	m.Save("beta", &x.beta)
+	m.Save("wC", &x.wC)
+	m.Save("wEst", &x.wEst)
+	m.Save("s", &x.s)
+}
+
+func (x *cubicState) afterLoad() {}
+func (x *cubicState) load(m state.Map) {
+	m.Load("wLastMax", &x.wLastMax)
+	m.Load("wMax", &x.wMax)
+	m.Load("numCongestionEvents", &x.numCongestionEvents)
+	m.Load("c", &x.c)
+	m.Load("k", &x.k)
+	m.Load("beta", &x.beta)
+	m.Load("wC", &x.wC)
+	m.Load("wEst", &x.wEst)
+	m.Load("s", &x.s)
+	m.LoadValue("t", new(unixTime), func(y interface{}) { x.loadT(y.(unixTime)) })
+}
+
+func (x *SACKInfo) beforeSave() {}
+func (x *SACKInfo) save(m state.Map) {
+	x.beforeSave()
+	m.Save("Blocks", &x.Blocks)
+	m.Save("NumBlocks", &x.NumBlocks)
+}
+
+func (x *SACKInfo) afterLoad() {}
+func (x *SACKInfo) load(m state.Map) {
+	m.Load("Blocks", &x.Blocks)
+	m.Load("NumBlocks", &x.NumBlocks)
+}
+
+func (x *rcvBufAutoTuneParams) beforeSave() {}
+func (x *rcvBufAutoTuneParams) save(m state.Map) {
+	x.beforeSave()
+	var measureTime unixTime = x.saveMeasureTime()
+	m.SaveValue("measureTime", measureTime)
+	var rttMeasureTime unixTime = x.saveRttMeasureTime()
+	m.SaveValue("rttMeasureTime", rttMeasureTime)
+	m.Save("copied", &x.copied)
+	m.Save("prevCopied", &x.prevCopied)
+	m.Save("rtt", &x.rtt)
+	m.Save("rttMeasureSeqNumber", &x.rttMeasureSeqNumber)
+	m.Save("disabled", &x.disabled)
+}
+
+func (x *rcvBufAutoTuneParams) afterLoad() {}
+func (x *rcvBufAutoTuneParams) load(m state.Map) {
+	m.Load("copied", &x.copied)
+	m.Load("prevCopied", &x.prevCopied)
+	m.Load("rtt", &x.rtt)
+	m.Load("rttMeasureSeqNumber", &x.rttMeasureSeqNumber)
+	m.Load("disabled", &x.disabled)
+	m.LoadValue("measureTime", new(unixTime), func(y interface{}) { x.loadMeasureTime(y.(unixTime)) })
+	m.LoadValue("rttMeasureTime", new(unixTime), func(y interface{}) { x.loadRttMeasureTime(y.(unixTime)) })
+}
+
+func (x *EndpointInfo) beforeSave() {}
+func (x *EndpointInfo) save(m state.Map) {
+	x.beforeSave()
+	var HardError string = x.saveHardError()
+	m.SaveValue("HardError", HardError)
+	m.Save("TransportEndpointInfo", &x.TransportEndpointInfo)
+}
+
+func (x *EndpointInfo) afterLoad() {}
+func (x *EndpointInfo) load(m state.Map) {
+	m.Load("TransportEndpointInfo", &x.TransportEndpointInfo)
+	m.LoadValue("HardError", new(string), func(y interface{}) { x.loadHardError(y.(string)) })
+}
+
+func (x *endpoint) save(m state.Map) {
+	x.beforeSave()
+	var lastError string = x.saveLastError()
+	m.SaveValue("lastError", lastError)
+	var state EndpointState = x.saveState()
+	m.SaveValue("state", state)
+	var acceptedChan []*endpoint = x.saveAcceptedChan()
+	m.SaveValue("acceptedChan", acceptedChan)
+	m.Save("EndpointInfo", &x.EndpointInfo)
+	m.Save("waiterQueue", &x.waiterQueue)
+	m.Save("uniqueID", &x.uniqueID)
+	m.Save("rcvList", &x.rcvList)
+	m.Save("rcvClosed", &x.rcvClosed)
+	m.Save("rcvBufSize", &x.rcvBufSize)
+	m.Save("rcvBufUsed", &x.rcvBufUsed)
+	m.Save("rcvAutoParams", &x.rcvAutoParams)
+	m.Save("ownedByUser", &x.ownedByUser)
+	m.Save("isRegistered", &x.isRegistered)
+	m.Save("ttl", &x.ttl)
+	m.Save("v6only", &x.v6only)
+	m.Save("isConnectNotified", &x.isConnectNotified)
+	m.Save("broadcast", &x.broadcast)
+	m.Save("boundBindToDevice", &x.boundBindToDevice)
+	m.Save("boundPortFlags", &x.boundPortFlags)
+	m.Save("workerRunning", &x.workerRunning)
+	m.Save("workerCleanup", &x.workerCleanup)
+	m.Save("sendTSOk", &x.sendTSOk)
+	m.Save("recentTS", &x.recentTS)
+	m.Save("tsOffset", &x.tsOffset)
+	m.Save("shutdownFlags", &x.shutdownFlags)
+	m.Save("sackPermitted", &x.sackPermitted)
+	m.Save("sack", &x.sack)
+	m.Save("reusePort", &x.reusePort)
+	m.Save("bindToDevice", &x.bindToDevice)
+	m.Save("delay", &x.delay)
+	m.Save("cork", &x.cork)
+	m.Save("scoreboard", &x.scoreboard)
+	m.Save("reuseAddr", &x.reuseAddr)
+	m.Save("slowAck", &x.slowAck)
+	m.Save("segmentQueue", &x.segmentQueue)
+	m.Save("synRcvdCount", &x.synRcvdCount)
+	m.Save("userMSS", &x.userMSS)
+	m.Save("sndBufSize", &x.sndBufSize)
+	m.Save("sndBufUsed", &x.sndBufUsed)
+	m.Save("sndClosed", &x.sndClosed)
+	m.Save("sndBufInQueue", &x.sndBufInQueue)
+	m.Save("sndQueue", &x.sndQueue)
+	m.Save("cc", &x.cc)
+	m.Save("packetTooBigCount", &x.packetTooBigCount)
+	m.Save("sndMTU", &x.sndMTU)
+	m.Save("keepalive", &x.keepalive)
+	m.Save("userTimeout", &x.userTimeout)
+	m.Save("deferAccept", &x.deferAccept)
+	m.Save("rcv", &x.rcv)
+	m.Save("snd", &x.snd)
+	m.Save("connectingAddress", &x.connectingAddress)
+	m.Save("amss", &x.amss)
+	m.Save("sendTOS", &x.sendTOS)
+	m.Save("gso", &x.gso)
+	m.Save("tcpLingerTimeout", &x.tcpLingerTimeout)
+	m.Save("closed", &x.closed)
+	m.Save("txHash", &x.txHash)
+	m.Save("owner", &x.owner)
+}
+
+func (x *endpoint) load(m state.Map) {
+	m.Load("EndpointInfo", &x.EndpointInfo)
+	m.LoadWait("waiterQueue", &x.waiterQueue)
+	m.Load("uniqueID", &x.uniqueID)
+	m.LoadWait("rcvList", &x.rcvList)
+	m.Load("rcvClosed", &x.rcvClosed)
+	m.Load("rcvBufSize", &x.rcvBufSize)
+	m.Load("rcvBufUsed", &x.rcvBufUsed)
+	m.Load("rcvAutoParams", &x.rcvAutoParams)
+	m.Load("ownedByUser", &x.ownedByUser)
+	m.Load("isRegistered", &x.isRegistered)
+	m.Load("ttl", &x.ttl)
+	m.Load("v6only", &x.v6only)
+	m.Load("isConnectNotified", &x.isConnectNotified)
+	m.Load("broadcast", &x.broadcast)
+	m.Load("boundBindToDevice", &x.boundBindToDevice)
+	m.Load("boundPortFlags", &x.boundPortFlags)
+	m.Load("workerRunning", &x.workerRunning)
+	m.Load("workerCleanup", &x.workerCleanup)
+	m.Load("sendTSOk", &x.sendTSOk)
+	m.Load("recentTS", &x.recentTS)
+	m.Load("tsOffset", &x.tsOffset)
+	m.Load("shutdownFlags", &x.shutdownFlags)
+	m.Load("sackPermitted", &x.sackPermitted)
+	m.Load("sack", &x.sack)
+	m.Load("reusePort", &x.reusePort)
+	m.Load("bindToDevice", &x.bindToDevice)
+	m.Load("delay", &x.delay)
+	m.Load("cork", &x.cork)
+	m.Load("scoreboard", &x.scoreboard)
+	m.Load("reuseAddr", &x.reuseAddr)
+	m.Load("slowAck", &x.slowAck)
+	m.LoadWait("segmentQueue", &x.segmentQueue)
+	m.Load("synRcvdCount", &x.synRcvdCount)
+	m.Load("userMSS", &x.userMSS)
+	m.Load("sndBufSize", &x.sndBufSize)
+	m.Load("sndBufUsed", &x.sndBufUsed)
+	m.Load("sndClosed", &x.sndClosed)
+	m.Load("sndBufInQueue", &x.sndBufInQueue)
+	m.LoadWait("sndQueue", &x.sndQueue)
+	m.Load("cc", &x.cc)
+	m.Load("packetTooBigCount", &x.packetTooBigCount)
+	m.Load("sndMTU", &x.sndMTU)
+	m.Load("keepalive", &x.keepalive)
+	m.Load("userTimeout", &x.userTimeout)
+	m.Load("deferAccept", &x.deferAccept)
+	m.LoadWait("rcv", &x.rcv)
+	m.LoadWait("snd", &x.snd)
+	m.Load("connectingAddress", &x.connectingAddress)
+	m.Load("amss", &x.amss)
+	m.Load("sendTOS", &x.sendTOS)
+	m.Load("gso", &x.gso)
+	m.Load("tcpLingerTimeout", &x.tcpLingerTimeout)
+	m.Load("closed", &x.closed)
+	m.Load("txHash", &x.txHash)
+	m.Load("owner", &x.owner)
+	m.LoadValue("lastError", new(string), func(y interface{}) { x.loadLastError(y.(string)) })
+	m.LoadValue("state", new(EndpointState), func(y interface{}) { x.loadState(y.(EndpointState)) })
+	m.LoadValue("acceptedChan", new([]*endpoint), func(y interface{}) { x.loadAcceptedChan(y.([]*endpoint)) })
+	m.AfterLoad(x.afterLoad)
+}
+
+func (x *keepalive) beforeSave() {}
+func (x *keepalive) save(m state.Map) {
+	x.beforeSave()
+	m.Save("enabled", &x.enabled)
+	m.Save("idle", &x.idle)
+	m.Save("interval", &x.interval)
+	m.Save("count", &x.count)
+	m.Save("unacked", &x.unacked)
+}
+
+func (x *keepalive) afterLoad() {}
+func (x *keepalive) load(m state.Map) {
+	m.Load("enabled", &x.enabled)
+	m.Load("idle", &x.idle)
+	m.Load("interval", &x.interval)
+	m.Load("count", &x.count)
+	m.Load("unacked", &x.unacked)
+}
+
+func (x *receiver) beforeSave() {}
+func (x *receiver) save(m state.Map) {
+	x.beforeSave()
+	var lastRcvdAckTime unixTime = x.saveLastRcvdAckTime()
+	m.SaveValue("lastRcvdAckTime", lastRcvdAckTime)
+	m.Save("ep", &x.ep)
+	m.Save("rcvNxt", &x.rcvNxt)
+	m.Save("rcvAcc", &x.rcvAcc)
+	m.Save("rcvWnd", &x.rcvWnd)
+	m.Save("rcvWndScale", &x.rcvWndScale)
+	m.Save("closed", &x.closed)
+	m.Save("pendingRcvdSegments", &x.pendingRcvdSegments)
+	m.Save("pendingBufUsed", &x.pendingBufUsed)
+	m.Save("pendingBufSize", &x.pendingBufSize)
+}
+
+func (x *receiver) afterLoad() {}
+func (x *receiver) load(m state.Map) {
+	m.Load("ep", &x.ep)
+	m.Load("rcvNxt", &x.rcvNxt)
+	m.Load("rcvAcc", &x.rcvAcc)
+	m.Load("rcvWnd", &x.rcvWnd)
+	m.Load("rcvWndScale", &x.rcvWndScale)
+	m.Load("closed", &x.closed)
+	m.Load("pendingRcvdSegments", &x.pendingRcvdSegments)
+	m.Load("pendingBufUsed", &x.pendingBufUsed)
+	m.Load("pendingBufSize", &x.pendingBufSize)
+	m.LoadValue("lastRcvdAckTime", new(unixTime), func(y interface{}) { x.loadLastRcvdAckTime(y.(unixTime)) })
+}
+
+func (x *renoState) beforeSave() {}
+func (x *renoState) save(m state.Map) {
+	x.beforeSave()
+	m.Save("s", &x.s)
+}
+
+func (x *renoState) afterLoad() {}
+func (x *renoState) load(m state.Map) {
+	m.Load("s", &x.s)
+}
+
+func (x *SACKScoreboard) beforeSave() {}
+func (x *SACKScoreboard) save(m state.Map) {
+	x.beforeSave()
+	m.Save("smss", &x.smss)
+	m.Save("maxSACKED", &x.maxSACKED)
+}
+
+func (x *SACKScoreboard) afterLoad() {}
+func (x *SACKScoreboard) load(m state.Map) {
+	m.Load("smss", &x.smss)
+	m.Load("maxSACKED", &x.maxSACKED)
+}
+
+func (x *segment) beforeSave() {}
+func (x *segment) save(m state.Map) {
+	x.beforeSave()
+	var data buffer.VectorisedView = x.saveData()
+	m.SaveValue("data", data)
+	var options []byte = x.saveOptions()
+	m.SaveValue("options", options)
+	var rcvdTime unixTime = x.saveRcvdTime()
+	m.SaveValue("rcvdTime", rcvdTime)
+	var xmitTime unixTime = x.saveXmitTime()
+	m.SaveValue("xmitTime", xmitTime)
+	m.Save("segmentEntry", &x.segmentEntry)
+	m.Save("refCnt", &x.refCnt)
+	m.Save("viewToDeliver", &x.viewToDeliver)
+	m.Save("sequenceNumber", &x.sequenceNumber)
+	m.Save("ackNumber", &x.ackNumber)
+	m.Save("flags", &x.flags)
+	m.Save("window", &x.window)
+	m.Save("csum", &x.csum)
+	m.Save("csumValid", &x.csumValid)
+	m.Save("parsedOptions", &x.parsedOptions)
+	m.Save("hasNewSACKInfo", &x.hasNewSACKInfo)
+	m.Save("xmitCount", &x.xmitCount)
+}
+
+func (x *segment) afterLoad() {}
+func (x *segment) load(m state.Map) {
+	m.Load("segmentEntry", &x.segmentEntry)
+	m.Load("refCnt", &x.refCnt)
+	m.Load("viewToDeliver", &x.viewToDeliver)
+	m.Load("sequenceNumber", &x.sequenceNumber)
+	m.Load("ackNumber", &x.ackNumber)
+	m.Load("flags", &x.flags)
+	m.Load("window", &x.window)
+	m.Load("csum", &x.csum)
+	m.Load("csumValid", &x.csumValid)
+	m.Load("parsedOptions", &x.parsedOptions)
+	m.Load("hasNewSACKInfo", &x.hasNewSACKInfo)
+	m.Load("xmitCount", &x.xmitCount)
+	m.LoadValue("data", new(buffer.VectorisedView), func(y interface{}) { x.loadData(y.(buffer.VectorisedView)) })
+	m.LoadValue("options", new([]byte), func(y interface{}) { x.loadOptions(y.([]byte)) })
+	m.LoadValue("rcvdTime", new(unixTime), func(y interface{}) { x.loadRcvdTime(y.(unixTime)) })
+	m.LoadValue("xmitTime", new(unixTime), func(y interface{}) { x.loadXmitTime(y.(unixTime)) })
+}
+
+func (x *segmentQueue) beforeSave() {}
+func (x *segmentQueue) save(m state.Map) {
+	x.beforeSave()
+	m.Save("list", &x.list)
+	m.Save("limit", &x.limit)
+	m.Save("used", &x.used)
+}
+
+func (x *segmentQueue) afterLoad() {}
+func (x *segmentQueue) load(m state.Map) {
+	m.LoadWait("list", &x.list)
+	m.Load("limit", &x.limit)
+	m.Load("used", &x.used)
+}
+
+func (x *sender) beforeSave() {}
+func (x *sender) save(m state.Map) {
+	x.beforeSave()
+	var lastSendTime unixTime = x.saveLastSendTime()
+	m.SaveValue("lastSendTime", lastSendTime)
+	var rttMeasureTime unixTime = x.saveRttMeasureTime()
+	m.SaveValue("rttMeasureTime", rttMeasureTime)
+	var firstRetransmittedSegXmitTime unixTime = x.saveFirstRetransmittedSegXmitTime()
+	m.SaveValue("firstRetransmittedSegXmitTime", firstRetransmittedSegXmitTime)
+	m.Save("ep", &x.ep)
+	m.Save("dupAckCount", &x.dupAckCount)
+	m.Save("fr", &x.fr)
+	m.Save("sndCwnd", &x.sndCwnd)
+	m.Save("sndSsthresh", &x.sndSsthresh)
+	m.Save("sndCAAckCount", &x.sndCAAckCount)
+	m.Save("outstanding", &x.outstanding)
+	m.Save("sndWnd", &x.sndWnd)
+	m.Save("sndUna", &x.sndUna)
+	m.Save("sndNxt", &x.sndNxt)
+	m.Save("rttMeasureSeqNum", &x.rttMeasureSeqNum)
+	m.Save("closed", &x.closed)
+	m.Save("writeNext", &x.writeNext)
+	m.Save("writeList", &x.writeList)
+	m.Save("rtt", &x.rtt)
+	m.Save("rto", &x.rto)
+	m.Save("maxPayloadSize", &x.maxPayloadSize)
+	m.Save("gso", &x.gso)
+	m.Save("sndWndScale", &x.sndWndScale)
+	m.Save("maxSentAck", &x.maxSentAck)
+	m.Save("state", &x.state)
+	m.Save("cc", &x.cc)
+}
+
+func (x *sender) load(m state.Map) {
+	m.Load("ep", &x.ep)
+	m.Load("dupAckCount", &x.dupAckCount)
+	m.Load("fr", &x.fr)
+	m.Load("sndCwnd", &x.sndCwnd)
+	m.Load("sndSsthresh", &x.sndSsthresh)
+	m.Load("sndCAAckCount", &x.sndCAAckCount)
+	m.Load("outstanding", &x.outstanding)
+	m.Load("sndWnd", &x.sndWnd)
+	m.Load("sndUna", &x.sndUna)
+	m.Load("sndNxt", &x.sndNxt)
+	m.Load("rttMeasureSeqNum", &x.rttMeasureSeqNum)
+	m.Load("closed", &x.closed)
+	m.Load("writeNext", &x.writeNext)
+	m.Load("writeList", &x.writeList)
+	m.Load("rtt", &x.rtt)
+	m.Load("rto", &x.rto)
+	m.Load("maxPayloadSize", &x.maxPayloadSize)
+	m.Load("gso", &x.gso)
+	m.Load("sndWndScale", &x.sndWndScale)
+	m.Load("maxSentAck", &x.maxSentAck)
+	m.Load("state", &x.state)
+	m.Load("cc", &x.cc)
+	m.LoadValue("lastSendTime", new(unixTime), func(y interface{}) { x.loadLastSendTime(y.(unixTime)) })
+	m.LoadValue("rttMeasureTime", new(unixTime), func(y interface{}) { x.loadRttMeasureTime(y.(unixTime)) })
+	m.LoadValue("firstRetransmittedSegXmitTime", new(unixTime), func(y interface{}) { x.loadFirstRetransmittedSegXmitTime(y.(unixTime)) })
+	m.AfterLoad(x.afterLoad)
+}
+
+func (x *rtt) beforeSave() {}
+func (x *rtt) save(m state.Map) {
+	x.beforeSave()
+	m.Save("srtt", &x.srtt)
+	m.Save("rttvar", &x.rttvar)
+	m.Save("srttInited", &x.srttInited)
+}
+
+func (x *rtt) afterLoad() {}
+func (x *rtt) load(m state.Map) {
+	m.Load("srtt", &x.srtt)
+	m.Load("rttvar", &x.rttvar)
+	m.Load("srttInited", &x.srttInited)
+}
+
+func (x *fastRecovery) beforeSave() {}
+func (x *fastRecovery) save(m state.Map) {
+	x.beforeSave()
+	m.Save("active", &x.active)
+	m.Save("first", &x.first)
+	m.Save("last", &x.last)
+	m.Save("maxCwnd", &x.maxCwnd)
+	m.Save("highRxt", &x.highRxt)
+	m.Save("rescueRxt", &x.rescueRxt)
+}
+
+func (x *fastRecovery) afterLoad() {}
+func (x *fastRecovery) load(m state.Map) {
+	m.Load("active", &x.active)
+	m.Load("first", &x.first)
+	m.Load("last", &x.last)
+	m.Load("maxCwnd", &x.maxCwnd)
+	m.Load("highRxt", &x.highRxt)
+	m.Load("rescueRxt", &x.rescueRxt)
+}
+
+func (x *unixTime) beforeSave() {}
+func (x *unixTime) save(m state.Map) {
+	x.beforeSave()
+	m.Save("second", &x.second)
+	m.Save("nano", &x.nano)
+}
+
+func (x *unixTime) afterLoad() {}
+func (x *unixTime) load(m state.Map) {
+	m.Load("second", &x.second)
+	m.Load("nano", &x.nano)
+}
+
+func (x *endpointList) beforeSave() {}
+func (x *endpointList) save(m state.Map) {
+	x.beforeSave()
+	m.Save("head", &x.head)
+	m.Save("tail", &x.tail)
+}
+
+func (x *endpointList) afterLoad() {}
+func (x *endpointList) load(m state.Map) {
+	m.Load("head", &x.head)
+	m.Load("tail", &x.tail)
+}
+
+func (x *endpointEntry) beforeSave() {}
+func (x *endpointEntry) save(m state.Map) {
+	x.beforeSave()
+	m.Save("next", &x.next)
+	m.Save("prev", &x.prev)
+}
+
+func (x *endpointEntry) afterLoad() {}
+func (x *endpointEntry) load(m state.Map) {
+	m.Load("next", &x.next)
+	m.Load("prev", &x.prev)
+}
+
+func (x *segmentList) beforeSave() {}
+func (x *segmentList) save(m state.Map) {
+	x.beforeSave()
+	m.Save("head", &x.head)
+	m.Save("tail", &x.tail)
+}
+
+func (x *segmentList) afterLoad() {}
+func (x *segmentList) load(m state.Map) {
+	m.Load("head", &x.head)
+	m.Load("tail", &x.tail)
+}
+
+func (x *segmentEntry) beforeSave() {}
+func (x *segmentEntry) save(m state.Map) {
+	x.beforeSave()
+	m.Save("next", &x.next)
+	m.Save("prev", &x.prev)
+}
+
+func (x *segmentEntry) afterLoad() {}
+func (x *segmentEntry) load(m state.Map) {
+	m.Load("next", &x.next)
+	m.Load("prev", &x.prev)
+}
+
+func init() {
+	state.Register("pkg/tcpip/transport/tcp.cubicState", (*cubicState)(nil), state.Fns{Save: (*cubicState).save, Load: (*cubicState).load})
+	state.Register("pkg/tcpip/transport/tcp.SACKInfo", (*SACKInfo)(nil), state.Fns{Save: (*SACKInfo).save, Load: (*SACKInfo).load})
+	state.Register("pkg/tcpip/transport/tcp.rcvBufAutoTuneParams", (*rcvBufAutoTuneParams)(nil), state.Fns{Save: (*rcvBufAutoTuneParams).save, Load: (*rcvBufAutoTuneParams).load})
+	state.Register("pkg/tcpip/transport/tcp.EndpointInfo", (*EndpointInfo)(nil), state.Fns{Save: (*EndpointInfo).save, Load: (*EndpointInfo).load})
+	state.Register("pkg/tcpip/transport/tcp.endpoint", (*endpoint)(nil), state.Fns{Save: (*endpoint).save, Load: (*endpoint).load})
+	state.Register("pkg/tcpip/transport/tcp.keepalive", (*keepalive)(nil), state.Fns{Save: (*keepalive).save, Load: (*keepalive).load})
+	state.Register("pkg/tcpip/transport/tcp.receiver", (*receiver)(nil), state.Fns{Save: (*receiver).save, Load: (*receiver).load})
+	state.Register("pkg/tcpip/transport/tcp.renoState", (*renoState)(nil), state.Fns{Save: (*renoState).save, Load: (*renoState).load})
+	state.Register("pkg/tcpip/transport/tcp.SACKScoreboard", (*SACKScoreboard)(nil), state.Fns{Save: (*SACKScoreboard).save, Load: (*SACKScoreboard).load})
+	state.Register("pkg/tcpip/transport/tcp.segment", (*segment)(nil), state.Fns{Save: (*segment).save, Load: (*segment).load})
+	state.Register("pkg/tcpip/transport/tcp.segmentQueue", (*segmentQueue)(nil), state.Fns{Save: (*segmentQueue).save, Load: (*segmentQueue).load})
+	state.Register("pkg/tcpip/transport/tcp.sender", (*sender)(nil), state.Fns{Save: (*sender).save, Load: (*sender).load})
+	state.Register("pkg/tcpip/transport/tcp.rtt", (*rtt)(nil), state.Fns{Save: (*rtt).save, Load: (*rtt).load})
+	state.Register("pkg/tcpip/transport/tcp.fastRecovery", (*fastRecovery)(nil), state.Fns{Save: (*fastRecovery).save, Load: (*fastRecovery).load})
+	state.Register("pkg/tcpip/transport/tcp.unixTime", (*unixTime)(nil), state.Fns{Save: (*unixTime).save, Load: (*unixTime).load})
+	state.Register("pkg/tcpip/transport/tcp.endpointList", (*endpointList)(nil), state.Fns{Save: (*endpointList).save, Load: (*endpointList).load})
+	state.Register("pkg/tcpip/transport/tcp.endpointEntry", (*endpointEntry)(nil), state.Fns{Save: (*endpointEntry).save, Load: (*endpointEntry).load})
+	state.Register("pkg/tcpip/transport/tcp.segmentList", (*segmentList)(nil), state.Fns{Save: (*segmentList).save, Load: (*segmentList).load})
+	state.Register("pkg/tcpip/transport/tcp.segmentEntry", (*segmentEntry)(nil), state.Fns{Save: (*segmentEntry).save, Load: (*segmentEntry).load})
+}
diff --git a/pkg/tcpip/transport/tcp/tcp_test.go b/pkg/tcpip/transport/tcp/tcp_test.go
deleted file mode 100644
index ce3df74..0000000
--- a/pkg/tcpip/transport/tcp/tcp_test.go
+++ /dev/null
@@ -1,7000 +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"
-	"math"
-	"testing"
-	"time"
-
-	"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/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/ports"
-	"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/waiter"
-)
-
-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: %v", err)
-	}
-
-	// Register for notification, then start connection attempt.
-	waitEntry, notifyCh := waiter.NewChannelEntry(nil)
-	wq.EventRegister(&waitEntry, waiter.EventOut)
-	defer wq.EventUnregister(&waitEntry)
-
-	if err := ep.Connect(tcpip.FullAddress{Addr: context.TestAddr, Port: context.TestPort}); err != tcpip.ErrConnectStarted {
-		t.Fatalf("got ep.Connect(...) = %v, want = %v", err, tcpip.ErrConnectStarted)
-	}
-
-	// Close the connection, wait for completion.
-	ep.Close()
-
-	// Wait for ep to become writable.
-	<-notifyCh
-	if err := ep.GetSockOpt(tcpip.ErrorOption{}); err != tcpip.ErrAborted {
-		t.Fatalf("got ep.GetSockOpt(tcpip.ErrorOption{}) = %v, want = %v", err, tcpip.ErrAborted)
-	}
-
-	// Call Connect again to retreive the handshake failure status
-	// and stats updates.
-	if err := ep.Connect(tcpip.FullAddress{Addr: context.TestAddr, Port: context.TestPort}); err != tcpip.ErrAborted {
-		t.Fatalf("got ep.Connect(...) = %v, want = %v", err, tcpip.ErrAborted)
-	}
-
-	if got := c.Stack().Stats().TCP.FailedConnectionAttempts.Value(); got != 1 {
-		t.Errorf("got stats.TCP.FailedConnectionAttempts.Value() = %v, want = 1", got)
-	}
-
-	if got := c.Stack().Stats().TCP.CurrentEstablished.Value(); got != 0 {
-		t.Errorf("got stats.TCP.CurrentEstablished.Value() = %v, 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(789, 30000, -1 /* epRcvBuf */)
-	if got := stats.TCP.ActiveConnectionOpenings.Value(); got != want {
-		t.Errorf("got stats.TCP.ActtiveConnectionOpenings.Value() = %v, want = %v", 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(789, 30000, -1 /* epRcvBuf */)
-	if got := stats.TCP.FailedConnectionAttempts.Value(); got != want {
-		t.Errorf("got stats.TCP.FailedConnectionAttempts.Value() = %v, want = %v", got, want)
-	}
-	if got := c.EP.Stats().(*tcp.Stats).FailedConnectionAttempts.Value(); got != want {
-		t.Errorf("got EP stats.FailedConnectionAttempts = %v, want = %v", 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: %v", err)
-	}
-	c.EP = ep
-	want := stats.TCP.FailedConnectionAttempts.Value() + 1
-
-	if err := c.EP.Connect(tcpip.FullAddress{NIC: 2, Addr: context.TestAddr, Port: context.TestPort}); err != tcpip.ErrNoRoute {
-		t.Errorf("got c.EP.Connect(...) = %v, want = %v", err, tcpip.ErrNoRoute)
-	}
-
-	if got := stats.TCP.FailedConnectionAttempts.Value(); got != want {
-		t.Errorf("got stats.TCP.FailedConnectionAttempts.Value() = %v, want = %v", got, want)
-	}
-	if got := c.EP.Stats().(*tcp.Stats).FailedConnectionAttempts.Value(); got != want {
-		t.Errorf("got EP stats FailedConnectionAttempts = %v, want = %v", got, want)
-	}
-}
-
-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(789, 30000, -1 /* epRcvBuf */)
-
-	if got := stats.TCP.SegmentsSent.Value(); got != want {
-		t.Errorf("got stats.TCP.SegmentsSent.Value() = %v, want = %v", got, want)
-	}
-	if got := c.EP.Stats().(*tcp.Stats).SegmentsSent.Value(); got != want {
-		t.Errorf("got EP stats SegmentsSent.Value() = %v, want = %v", 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: %v", err)
-	}
-	want := stats.TCP.SegmentsSent.Value() + 1
-
-	if err := ep.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %v", err)
-	}
-
-	if err := ep.Listen(10); err != nil {
-		t.Fatalf("Listen failed: %v", err)
-	}
-
-	// Send a SYN request.
-	iss := seqnum.Value(789)
-	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()
-	if got := stats.TCP.ResetsSent.Value(); got != want {
-		t.Errorf("got stats.TCP.ResetsSent.Value() = %v, want = %v", 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(789)
-	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()
-	if err == tcpip.ErrWouldBlock {
-		// Wait for connection to be established.
-		select {
-		case <-ch:
-			c.EP, _, err = ep.Accept()
-			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("e.stack.SetTransportProtocolOption(%d, %s) = %s", tcp.ProtocolNumber, tcpTW, err)
-	}
-
-	c.EP.Close()
-	checker.IPv4(t, c.GetPacket(), checker.TCP(
-		checker.SrcPort(context.StackPort),
-		checker.DstPort(context.TestPort),
-		checker.SeqNum(uint32(c.IRS+1)),
-		checker.AckNum(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.SeqNum(uint32(c.IRS+1)),
-		checker.AckNum(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(789)
-	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() = %v, want = %v", 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(789)
-	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() = %v, want = %v", 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(789, 30000, -1 /* epRcvBuf */)
-}
-
-func TestNonBlockingClose(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateConnected(789, 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: %v", 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
-	if err := c.Stack().SetTransportProtocolOption(tcp.ProtocolNumber, tcpip.TCPLingerTimeoutOption(tcpLingerTimeout)); err != nil {
-		t.Fatalf("c.stack.SetTransportProtocolOption(tcp, tcpip.TCPLingerTimeoutOption(%d) failed: %s", tcpLingerTimeout, err)
-	}
-
-	c.CreateConnected(789, 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()
-	checker.IPv4(t, c.GetPacket(),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.SeqNum(uint32(c.IRS)+1),
-			checker.AckNum(790),
-			checker.TCPFlags(header.TCPFlagAck|header.TCPFlagFin),
-		),
-	)
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  790,
-		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:  790,
-		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.SeqNum(uint32(c.IRS)+2),
-				checker.AckNum(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
-	if err := c.Stack().SetTransportProtocolOption(tcp.ProtocolNumber, tcpip.TCPTimeWaitTimeoutOption(tcpTimeWaitTimeout)); err != nil {
-		t.Fatalf("c.stack.SetTransportProtocolOption(tcp, tcpip.TCPTimeWaitTimeout(%d) failed: %s", tcpTimeWaitTimeout, err)
-	}
-
-	c.CreateConnected(789, 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() = %v, want = 1", got)
-	}
-	gotConnected := c.Stack().Stats().TCP.CurrentConnected.Value()
-	if gotConnected != 1 {
-		t.Errorf("got stats.TCP.CurrentConnected.Value() = %v, want = 1", gotConnected)
-	}
-
-	ep.Close()
-
-	checker.IPv4(t, c.GetPacket(),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.SeqNum(uint32(c.IRS)+1),
-			checker.AckNum(790),
-			checker.TCPFlags(header.TCPFlagAck|header.TCPFlagFin),
-		),
-	)
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  790,
-		AckNum:  c.IRS.Add(2),
-		RcvWnd:  30000,
-	})
-
-	if got := c.Stack().Stats().TCP.CurrentEstablished.Value(); got != 0 {
-		t.Errorf("got stats.TCP.CurrentEstablished.Value() = %v, want = 0", got)
-	}
-	if got := c.Stack().Stats().TCP.CurrentConnected.Value(); got != gotConnected {
-		t.Errorf("got stats.TCP.CurrentConnected.Value() = %v, want = %v", 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:  790,
-		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.SeqNum(uint32(c.IRS)+2),
-			checker.AckNum(791),
-			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() = %v, want = 0", got)
-	}
-	if got := c.Stack().Stats().TCP.CurrentConnected.Value(); got != 0 {
-		t.Errorf("got stats.TCP.CurrentConnected.Value() = %v, 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(789, 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 %v, got %v", want, got)
-	}
-
-	// Send a FIN for ESTABLISHED --> CLOSED-WAIT
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagFin | header.TCPFlagAck,
-		SeqNum:  790,
-		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.SeqNum(uint32(c.IRS)+1),
-			checker.AckNum(791),
-			checker.TCPFlags(header.TCPFlagAck),
-		),
-	)
-
-	if got, want := tcp.EndpointState(ep.State()), tcp.StateCloseWait; got != want {
-		t.Errorf("Unexpected endpoint state: want %v, got %v", 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.SeqNum(uint32(c.IRS)+1),
-			checker.AckNum(791),
-			checker.TCPFlags(header.TCPFlagAck|header.TCPFlagFin),
-		),
-	)
-
-	if got, want := tcp.EndpointState(ep.State()), tcp.StateLastAck; got != want {
-		t.Errorf("Unexpected endpoint state: want %v, got %v", 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:  791,
-		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:  792,
-		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 %v, got %v", want, got)
-	}
-
-	if got := c.Stack().Stats().TCP.EstablishedClosed.Value(); got != 1 {
-		t.Errorf("got c.Stack().Stats().TCP.EstablishedClosed = %v, want = 1", got)
-	}
-
-	if got := c.Stack().Stats().TCP.CurrentEstablished.Value(); got != 0 {
-		t.Errorf("got stats.TCP.CurrentEstablished.Value() = %v, 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.SeqNum(uint32(c.IRS)+2),
-			checker.AckNum(0),
-			checker.TCPFlags(header.TCPFlagRst),
-		),
-	)
-}
-
-func TestSimpleReceive(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateConnected(789, 30000, -1 /* epRcvBuf */)
-
-	we, ch := waiter.NewChannelEntry(nil)
-	c.WQ.EventRegister(&we, waiter.EventIn)
-	defer c.WQ.EventUnregister(&we)
-
-	if _, _, err := c.EP.Read(nil); err != tcpip.ErrWouldBlock {
-		t.Fatalf("got c.EP.Read(nil) = %v, want = %v", err, tcpip.ErrWouldBlock)
-	}
-
-	data := []byte{1, 2, 3}
-	c.SendPacket(data, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  790,
-		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, _, err := c.EP.Read(nil)
-	if err != nil {
-		t.Fatalf("Read failed: %v", err)
-	}
-
-	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.SeqNum(uint32(c.IRS)+1),
-			checker.AckNum(uint32(790+len(data))),
-			checker.TCPFlags(header.TCPFlagAck),
-		),
-	)
-}
-
-// TestUserSuppliedMSSOnConnectV4 tests that the user supplied MSS is used when
-// creating a new active IPv4 TCP socket. It should be present in the sent TCP
-// SYN segment.
-func TestUserSuppliedMSSOnConnectV4(t *testing.T) {
-	const mtu = 5000
-	const maxMSS = mtu - header.IPv4MinimumSize - header.TCPMinimumSize
-	tests := []struct {
-		name   string
-		setMSS uint16
-		expMSS uint16
-	}{
-		{
-			"EqualToMaxMSS",
-			maxMSS,
-			maxMSS,
-		},
-		{
-			"LessThanMTU",
-			maxMSS - 1,
-			maxMSS - 1,
-		},
-		{
-			"GreaterThanMTU",
-			maxMSS + 1,
-			maxMSS,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			c := context.New(t, mtu)
-			defer c.Cleanup()
-
-			c.Create(-1)
-
-			// Set the MSS socket option.
-			opt := tcpip.MaxSegOption(test.setMSS)
-			if err := c.EP.SetSockOpt(opt); err != nil {
-				t.Fatalf("SetSockOpt(%#v) failed: %s", opt, err)
-			}
-
-			// Get expected window size.
-			rcvBufSize, err := c.EP.GetSockOptInt(tcpip.ReceiveBufferSizeOption)
-			if err != nil {
-				t.Fatalf("GetSockOpt(%v) failed: %s", tcpip.ReceiveBufferSizeOption, err)
-			}
-			ws := tcp.FindWndScale(seqnum.Size(rcvBufSize))
-
-			// Start connection attempt to IPv4 address.
-			if err := c.EP.Connect(tcpip.FullAddress{Addr: context.TestAddr, Port: context.TestPort}); err != tcpip.ErrConnectStarted {
-				t.Fatalf("Unexpected return value from Connect: %v", err)
-			}
-
-			// Receive SYN packet with our user supplied MSS.
-			checker.IPv4(t, c.GetPacket(), checker.TCP(
-				checker.DstPort(context.TestPort),
-				checker.TCPFlags(header.TCPFlagSyn),
-				checker.TCPSynOptions(header.TCPSynOptions{MSS: test.expMSS, WS: ws})))
-		})
-	}
-}
-
-// TestUserSuppliedMSSOnConnectV6 tests that the user supplied MSS is used when
-// creating a new active IPv6 TCP socket. It should be present in the sent TCP
-// SYN segment.
-func TestUserSuppliedMSSOnConnectV6(t *testing.T) {
-	const mtu = 5000
-	const maxMSS = mtu - header.IPv6MinimumSize - header.TCPMinimumSize
-	tests := []struct {
-		name   string
-		setMSS uint16
-		expMSS uint16
-	}{
-		{
-			"EqualToMaxMSS",
-			maxMSS,
-			maxMSS,
-		},
-		{
-			"LessThanMTU",
-			maxMSS - 1,
-			maxMSS - 1,
-		},
-		{
-			"GreaterThanMTU",
-			maxMSS + 1,
-			maxMSS,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			c := context.New(t, mtu)
-			defer c.Cleanup()
-
-			c.CreateV6Endpoint(true)
-
-			// Set the MSS socket option.
-			opt := tcpip.MaxSegOption(test.setMSS)
-			if err := c.EP.SetSockOpt(opt); err != nil {
-				t.Fatalf("SetSockOpt(%#v) failed: %s", opt, err)
-			}
-
-			// Get expected window size.
-			rcvBufSize, err := c.EP.GetSockOptInt(tcpip.ReceiveBufferSizeOption)
-			if err != nil {
-				t.Fatalf("GetSockOpt(%v) failed: %s", tcpip.ReceiveBufferSizeOption, err)
-			}
-			ws := tcp.FindWndScale(seqnum.Size(rcvBufSize))
-
-			// Start connection attempt to IPv6 address.
-			if err := c.EP.Connect(tcpip.FullAddress{Addr: context.TestV6Addr, Port: context.TestPort}); err != tcpip.ErrConnectStarted {
-				t.Fatalf("Unexpected return value from Connect: %v", err)
-			}
-
-			// Receive SYN packet with our user supplied MSS.
-			checker.IPv6(t, c.GetV6Packet(), checker.TCP(
-				checker.DstPort(context.TestPort),
-				checker.TCPFlags(header.TCPFlagSyn),
-				checker.TCPSynOptions(header.TCPSynOptions{MSS: test.expMSS, WS: ws})))
-		})
-	}
-}
-
-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.SeqNum(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.SeqNum(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.SeqNum(uint32(iss+1)),
-		checker.AckNum(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.SeqNum(uint32(iss+1)),
-		checker.AckNum(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.SeqNum(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.SeqNum(200)))
-}
-
-// TestListenShutdown tests for the listening endpoint not processing
-// any receive when it is 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(10 /* backlog */); err != nil {
-		t.Fatal("Listen failed:", err)
-	}
-
-	if err := c.EP.Shutdown(tcpip.ShutdownRead); err != nil {
-		t.Fatal("Shutdown failed:", err)
-	}
-
-	// Wait for the endpoint state to be propagated.
-	time.Sleep(10 * time.Millisecond)
-
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagSyn,
-		SeqNum:  100,
-		AckNum:  200,
-	})
-
-	c.CheckNoPacket("Packet received when listening socket was shutdown")
-}
-
-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.SetSockOpt(tcpip.IPv4TOSOption(tos)); err != nil {
-		t.Errorf("SetSockOpt(%#v) failed: %s", tcpip.IPv4TOSOption(tos), err)
-	}
-
-	var v tcpip.IPv4TOSOption
-	if err := c.EP.GetSockOpt(&v); err != nil {
-		t.Errorf("GetSockopt failed: %s", err)
-	}
-
-	if want := tcpip.IPv4TOSOption(tos); v != want {
-		t.Errorf("got GetSockOpt(...) = %#v, want = %#v", v, want)
-	}
-
-	testV4Connect(t, c, checker.TOS(tos, 0))
-
-	data := []byte{1, 2, 3}
-	view := buffer.NewView(len(data))
-	copy(view, data)
-
-	if _, _, err := c.EP.Write(tcpip.SlicePayload(view), 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.SeqNum(uint32(c.IRS)+1),
-			checker.AckNum(790), // Acknum is initial sequence number + 1
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(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.SetSockOpt(tcpip.IPv6TrafficClassOption(tos)); err != nil {
-		t.Errorf("SetSockOpt(%#v) failed: %s", tcpip.IPv6TrafficClassOption(tos), err)
-	}
-
-	var v tcpip.IPv6TrafficClassOption
-	if err := c.EP.GetSockOpt(&v); err != nil {
-		t.Fatalf("GetSockopt failed: %s", err)
-	}
-
-	if want := tcpip.IPv6TrafficClassOption(tos); v != want {
-		t.Errorf("got GetSockOpt(...) = %#v, want = %#v", v, want)
-	}
-
-	// Test the connection request.
-	testV6Connect(t, c, checker.TOS(tos, 0))
-
-	data := []byte{1, 2, 3}
-	view := buffer.NewView(len(data))
-	copy(view, data)
-
-	if _, _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %s", err)
-	}
-
-	// Check that data is received.
-	b := c.GetV6Packet()
-	checker.IPv6(t, b,
-		checker.PayloadLen(len(data)+header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.SeqNum(uint32(c.IRS)+1),
-			checker.AckNum(790),
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(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)
-			bindToDevice := tcpip.BindToDeviceOption(test.device)
-			c.EP.SetSockOpt(bindToDevice)
-			// Start connection attempt.
-			waitEntry, _ := waiter.NewChannelEntry(nil)
-			c.WQ.EventRegister(&waitEntry, waiter.EventOut)
-			defer c.WQ.EventUnregister(&waitEntry)
-
-			if err := c.EP.Connect(tcpip.FullAddress{Addr: context.TestAddr, Port: context.TestPort}); err != tcpip.ErrConnectStarted {
-				t.Fatalf("Unexpected return value from Connect: %v", 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 %v, got %v", want, got)
-			}
-			tcpHdr := header.TCP(header.IPv4(b).Payload())
-			c.IRS = seqnum.Value(tcpHdr.SequenceNumber())
-
-			iss := seqnum.Value(789)
-			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 %v, got %v", want, got)
-			}
-		})
-	}
-}
-
-func TestRstOnSynSent(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.EventOut)
-	defer c.WQ.EventUnregister(&waitEntry)
-
-	addr := tcpip.FullAddress{Addr: context.TestAddr, Port: context.TestPort}
-	if err := c.EP.Connect(addr); err != tcpip.ErrConnectStarted {
-		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),
-		),
-	)
-
-	// Ensure that we've reached SynSent state
-	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())
-
-	// Send a packet with a proper ACK and a RST flag to cause the socket
-	// to Error and close out
-	iss := seqnum.Value(789)
-	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,
-	})
-
-	// Wait for receive to be notified.
-	select {
-	case <-ch:
-	case <-time.After(3 * time.Second):
-		t.Fatal("timed out waiting for packet to arrive")
-	}
-
-	if _, _, err := c.EP.Read(nil); err != tcpip.ErrConnectionRefused {
-		t.Fatalf("got c.EP.Read(nil) = %v, want = %s", err, tcpip.ErrConnectionRefused)
-	}
-
-	// 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(789, 30000, -1 /* epRcvBuf */)
-
-	we, ch := waiter.NewChannelEntry(nil)
-	c.WQ.EventRegister(&we, waiter.EventIn)
-	defer c.WQ.EventUnregister(&we)
-
-	if _, _, err := c.EP.Read(nil); err != tcpip.ErrWouldBlock {
-		t.Fatalf("got c.EP.Read(nil) = %v, want = %v", err, tcpip.ErrWouldBlock)
-	}
-
-	// Send second half of data first, with seqnum 3 ahead of expected.
-	data := []byte{1, 2, 3, 4, 5, 6}
-	c.SendPacket(data[3:], &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  793,
-		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.SeqNum(uint32(c.IRS)+1),
-			checker.AckNum(790),
-			checker.TCPFlags(header.TCPFlagAck),
-		),
-	)
-
-	// Wait 200ms and check that no data has been received.
-	time.Sleep(200 * time.Millisecond)
-	if _, _, err := c.EP.Read(nil); err != tcpip.ErrWouldBlock {
-		t.Fatalf("got c.EP.Read(nil) = %v, want = %v", err, tcpip.ErrWouldBlock)
-	}
-
-	// Send the first 3 bytes now.
-	c.SendPacket(data[:3], &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  790,
-		AckNum:  c.IRS.Add(1),
-		RcvWnd:  30000,
-	})
-
-	// Receive data.
-	read := make([]byte, 0, 6)
-	for len(read) < len(data) {
-		v, _, err := c.EP.Read(nil)
-		if err != nil {
-			if err == tcpip.ErrWouldBlock {
-				// Wait for receive to be notified.
-				select {
-				case <-ch:
-				case <-time.After(5 * time.Second):
-					t.Fatalf("Timed out waiting for data to arrive")
-				}
-				continue
-			}
-			t.Fatalf("Read failed: %v", err)
-		}
-
-		read = append(read, v...)
-	}
-
-	// 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.SeqNum(uint32(c.IRS)+1),
-			checker.AckNum(uint32(790+len(data))),
-			checker.TCPFlags(header.TCPFlagAck),
-		),
-	)
-}
-
-func TestOutOfOrderFlood(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	// Create a new connection with initial window size of 10.
-	c.CreateConnected(789, 30000, 10)
-
-	if _, _, err := c.EP.Read(nil); err != tcpip.ErrWouldBlock {
-		t.Fatalf("got c.EP.Read(nil) = %v, want = %v", err, tcpip.ErrWouldBlock)
-	}
-
-	// Send 100 packets before the actual one that is expected.
-	data := []byte{1, 2, 3, 4, 5, 6}
-	for i := 0; i < 100; i++ {
-		c.SendPacket(data[3:], &context.Headers{
-			SrcPort: context.TestPort,
-			DstPort: c.Port,
-			Flags:   header.TCPFlagAck,
-			SeqNum:  796,
-			AckNum:  c.IRS.Add(1),
-			RcvWnd:  30000,
-		})
-
-		checker.IPv4(t, c.GetPacket(),
-			checker.TCP(
-				checker.DstPort(context.TestPort),
-				checker.SeqNum(uint32(c.IRS)+1),
-				checker.AckNum(790),
-				checker.TCPFlags(header.TCPFlagAck),
-			),
-		)
-	}
-
-	// Send packet with seqnum 793. 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:  793,
-		AckNum:  c.IRS.Add(1),
-		RcvWnd:  30000,
-	})
-
-	checker.IPv4(t, c.GetPacket(),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.SeqNum(uint32(c.IRS)+1),
-			checker.AckNum(790),
-			checker.TCPFlags(header.TCPFlagAck),
-		),
-	)
-
-	// Now send the expected packet, seqnum 790.
-	c.SendPacket(data[:3], &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  790,
-		AckNum:  c.IRS.Add(1),
-		RcvWnd:  30000,
-	})
-
-	// Check that only packet 790 is acknowledged.
-	checker.IPv4(t, c.GetPacket(),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.SeqNum(uint32(c.IRS)+1),
-			checker.AckNum(793),
-			checker.TCPFlags(header.TCPFlagAck),
-		),
-	)
-}
-
-func TestRstOnCloseWithUnreadData(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateConnected(789, 30000, -1 /* epRcvBuf */)
-
-	we, ch := waiter.NewChannelEntry(nil)
-	c.WQ.EventRegister(&we, waiter.EventIn)
-	defer c.WQ.EventUnregister(&we)
-
-	if _, _, err := c.EP.Read(nil); err != tcpip.ErrWouldBlock {
-		t.Fatalf("got c.EP.Read(nil) = %v, want = %v", err, tcpip.ErrWouldBlock)
-	}
-
-	data := []byte{1, 2, 3}
-	c.SendPacket(data, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  790,
-		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.SeqNum(uint32(c.IRS)+1),
-			checker.AckNum(uint32(790+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.SeqNum(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 %v, got %v", 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:  seqnum.Value(790 + 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(789, 30000, -1 /* epRcvBuf */)
-
-	we, ch := waiter.NewChannelEntry(nil)
-	c.WQ.EventRegister(&we, waiter.EventIn)
-	defer c.WQ.EventUnregister(&we)
-
-	if _, _, err := c.EP.Read(nil); err != tcpip.ErrWouldBlock {
-		t.Fatalf("got c.EP.Read(nil) = %v, want = %v", err, tcpip.ErrWouldBlock)
-	}
-
-	data := []byte{1, 2, 3}
-	c.SendPacket(data, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  790,
-		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.SeqNum(uint32(c.IRS)+1),
-			checker.AckNum(uint32(790+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.SeqNum(uint32(c.IRS)+1),
-		))
-
-	if got, want := tcp.EndpointState(c.EP.State()), tcp.StateFinWait1; got != want {
-		t.Errorf("Unexpected endpoint state: want %v, got %v", 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.SeqNum(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 %v, got %v", 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:  seqnum.Value(790 + 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(789, 30000, -1 /* epRcvBuf */)
-
-	if _, _, err := c.EP.Read(nil); err != tcpip.ErrWouldBlock {
-		t.Fatalf("got c.EP.Read(nil) = %v, want = %v", err, tcpip.ErrWouldBlock)
-	}
-
-	if err := c.EP.Shutdown(tcpip.ShutdownRead); err != nil {
-		t.Fatalf("Shutdown failed: %v", err)
-	}
-
-	if _, _, err := c.EP.Read(nil); err != tcpip.ErrClosedForReceive {
-		t.Fatalf("got c.EP.Read(nil) = %v, want = %v", err, 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 %v want %v", got, want)
-	}
-}
-
-func TestFullWindowReceive(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateConnected(789, 30000, 10)
-
-	we, ch := waiter.NewChannelEntry(nil)
-	c.WQ.EventRegister(&we, waiter.EventIn)
-	defer c.WQ.EventUnregister(&we)
-
-	_, _, err := c.EP.Read(nil)
-	if err != tcpip.ErrWouldBlock {
-		t.Fatalf("Read failed: %v", err)
-	}
-
-	// Fill up the window.
-	data := []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
-	c.SendPacket(data, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  790,
-		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.SeqNum(uint32(c.IRS)+1),
-			checker.AckNum(uint32(790+len(data))),
-			checker.TCPFlags(header.TCPFlagAck),
-			checker.Window(0),
-		),
-	)
-
-	// Receive data and check it.
-	v, _, err := c.EP.Read(nil)
-	if err != nil {
-		t.Fatalf("Read failed: %v", err)
-	}
-
-	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 %v want %v", 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.SeqNum(uint32(c.IRS)+1),
-			checker.AckNum(uint32(790+len(data))),
-			checker.TCPFlags(header.TCPFlagAck),
-			checker.Window(10),
-		),
-	)
-}
-
-func TestNoWindowShrinking(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	// Start off with a window size of 10, then shrink it to 5.
-	c.CreateConnected(789, 30000, 10)
-
-	if err := c.EP.SetSockOptInt(tcpip.ReceiveBufferSizeOption, 5); err != nil {
-		t.Fatalf("SetSockOpt failed: %v", err)
-	}
-
-	we, ch := waiter.NewChannelEntry(nil)
-	c.WQ.EventRegister(&we, waiter.EventIn)
-	defer c.WQ.EventUnregister(&we)
-
-	if _, _, err := c.EP.Read(nil); err != tcpip.ErrWouldBlock {
-		t.Fatalf("got c.EP.Read(nil) = %v, want = %v", err, tcpip.ErrWouldBlock)
-	}
-
-	// Send 3 bytes, check that the peer acknowledges them.
-	data := []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
-	c.SendPacket(data[:3], &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  790,
-		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 that window doesn't go to zero
-	// just yet because it was previously set to 10. It must go to 7 now.
-	checker.IPv4(t, c.GetPacket(),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.SeqNum(uint32(c.IRS)+1),
-			checker.AckNum(793),
-			checker.TCPFlags(header.TCPFlagAck),
-			checker.Window(7),
-		),
-	)
-
-	// Send 7 more bytes, check that the window fills up.
-	c.SendPacket(data[3:], &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  793,
-		AckNum:  c.IRS.Add(1),
-		RcvWnd:  30000,
-	})
-
-	select {
-	case <-ch:
-	case <-time.After(5 * time.Second):
-		t.Fatalf("Timed out waiting for data to arrive")
-	}
-
-	checker.IPv4(t, c.GetPacket(),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.SeqNum(uint32(c.IRS)+1),
-			checker.AckNum(uint32(790+len(data))),
-			checker.TCPFlags(header.TCPFlagAck),
-			checker.Window(0),
-		),
-	)
-
-	// Receive data and check it.
-	read := make([]byte, 0, 10)
-	for len(read) < len(data) {
-		v, _, err := c.EP.Read(nil)
-		if err != nil {
-			t.Fatalf("Read failed: %v", err)
-		}
-
-		read = append(read, v...)
-	}
-
-	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 size.
-	checker.IPv4(t, c.GetPacket(),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.SeqNum(uint32(c.IRS)+1),
-			checker.AckNum(uint32(790+len(data))),
-			checker.TCPFlags(header.TCPFlagAck),
-			checker.Window(5),
-		),
-	)
-}
-
-func TestSimpleSend(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateConnected(789, 30000, -1 /* epRcvBuf */)
-
-	data := []byte{1, 2, 3}
-	view := buffer.NewView(len(data))
-	copy(view, data)
-
-	if _, _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %v", 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.SeqNum(uint32(c.IRS)+1),
-			checker.AckNum(790),
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(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:  790,
-		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(789, 0, -1 /* epRcvBuf */)
-
-	data := []byte{1, 2, 3}
-	view := buffer.NewView(len(data))
-	copy(view, data)
-
-	_, _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{})
-	if err != nil {
-		t.Fatalf("Write failed: %v", err)
-	}
-
-	// Since the window is currently zero, check that no packet is received.
-	c.CheckNoPacket("Packet received when window is zero")
-
-	// Open up the window. Data should be received now.
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  790,
-		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.SeqNum(uint32(c.IRS)+1),
-			checker.AckNum(790),
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(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:  790,
-		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(789, 30000, 65535*3, []byte{
-		header.TCPOptionWS, 3, 0, header.TCPOptionNOP,
-	})
-
-	data := []byte{1, 2, 3}
-	view := buffer.NewView(len(data))
-	copy(view, data)
-
-	if _, _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %v", err)
-	}
-
-	// Check that data is received, and that advertised window is 0xbfff,
-	// that is, that it is scaled.
-	b := c.GetPacket()
-	checker.IPv4(t, b,
-		checker.PayloadLen(len(data)+header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.SeqNum(uint32(c.IRS)+1),
-			checker.AckNum(790),
-			checker.Window(0xbfff),
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(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(789, 30000, 65535*3)
-
-	data := []byte{1, 2, 3}
-	view := buffer.NewView(len(data))
-	copy(view, data)
-
-	if _, _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %v", err)
-	}
-
-	// Check that data is received, and that advertised window is 0xffff,
-	// that is, that it's not scaled.
-	b := c.GetPacket()
-	checker.IPv4(t, b,
-		checker.PayloadLen(len(data)+header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.SeqNum(uint32(c.IRS)+1),
-			checker.AckNum(790),
-			checker.Window(0xffff),
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(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: %v", 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("SetSockOpt failed failed: %v", err)
-	}
-
-	if err := ep.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %v", err)
-	}
-
-	if err := ep.Listen(10); err != nil {
-		t.Fatalf("Listen failed: %v", err)
-	}
-
-	// Do 3-way handshake.
-	c.PassiveConnectWithOptions(100, 2, 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()
-	if err == tcpip.ErrWouldBlock {
-		// Wait for connection to be established.
-		select {
-		case <-ch:
-			c.EP, _, err = ep.Accept()
-			if err != nil {
-				t.Fatalf("Accept failed: %v", err)
-			}
-
-		case <-time.After(1 * time.Second):
-			t.Fatalf("Timed out waiting for accept")
-		}
-	}
-
-	data := []byte{1, 2, 3}
-	view := buffer.NewView(len(data))
-	copy(view, data)
-
-	if _, _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %v", err)
-	}
-
-	// Check that data is received, and that advertised window is 0xbfff,
-	// that is, that it is scaled.
-	b := c.GetPacket()
-	checker.IPv4(t, b,
-		checker.PayloadLen(len(data)+header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.SeqNum(uint32(c.IRS)+1),
-			checker.AckNum(790),
-			checker.Window(0xbfff),
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(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: %v", 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("SetSockOpt failed failed: %v", err)
-	}
-
-	if err := ep.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %v", err)
-	}
-
-	if err := ep.Listen(10); err != nil {
-		t.Fatalf("Listen failed: %v", 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()
-	if err == tcpip.ErrWouldBlock {
-		// Wait for connection to be established.
-		select {
-		case <-ch:
-			c.EP, _, err = ep.Accept()
-			if err != nil {
-				t.Fatalf("Accept failed: %v", err)
-			}
-
-		case <-time.After(1 * time.Second):
-			t.Fatalf("Timed out waiting for accept")
-		}
-	}
-
-	data := []byte{1, 2, 3}
-	view := buffer.NewView(len(data))
-	copy(view, data)
-
-	if _, _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %v", err)
-	}
-
-	// Check that data is received, and that advertised window is 0xffff,
-	// that is, that it's not scaled.
-	b := c.GetPacket()
-	checker.IPv4(t, b,
-		checker.PayloadLen(len(data)+header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.SeqNum(uint32(c.IRS)+1),
-			checker.AckNum(790),
-			checker.Window(0xffff),
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(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 window size such that a window scale of 4 will be used.
-	const wnd = 65535 * 10
-	const ws = uint32(4)
-	c.CreateConnectedWithRawOptions(789, 30000, wnd, []byte{
-		header.TCPOptionWS, 3, 0, header.TCPOptionNOP,
-	})
-
-	// Write chunks of 50000 bytes.
-	remain := wnd
-	sent := 0
-	data := make([]byte, 50000)
-	for remain > len(data) {
-		c.SendPacket(data, &context.Headers{
-			SrcPort: context.TestPort,
-			DstPort: c.Port,
-			Flags:   header.TCPFlagAck,
-			SeqNum:  seqnum.Value(790 + 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.SeqNum(uint32(c.IRS)+1),
-				checker.AckNum(uint32(790+sent)),
-				checker.Window(uint16(remain>>ws)),
-				checker.TCPFlags(header.TCPFlagAck),
-			),
-		)
-	}
-
-	// Make the window non-zero, but the scaled window zero.
-	if remain >= 16 {
-		data = data[:remain-15]
-		c.SendPacket(data, &context.Headers{
-			SrcPort: context.TestPort,
-			DstPort: c.Port,
-			Flags:   header.TCPFlagAck,
-			SeqNum:  seqnum.Value(790 + 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.SeqNum(uint32(c.IRS)+1),
-				checker.AckNum(uint32(790+sent)),
-				checker.Window(0),
-				checker.TCPFlags(header.TCPFlagAck),
-			),
-		)
-	}
-
-	// Read at least 1MSS of data. An ack should be sent in response to that.
-	sz := 0
-	for sz < defaultMTU {
-		v, _, err := c.EP.Read(nil)
-		if err != nil {
-			t.Fatalf("Read failed: %v", err)
-		}
-		sz += len(v)
-	}
-
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.SeqNum(uint32(c.IRS)+1),
-			checker.AckNum(uint32(790+sent)),
-			checker.Window(uint16(sz>>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.SetSockOpt(tcpip.CorkOption(1))
-			},
-			func(ep tcpip.Endpoint) {
-				ep.SetSockOpt(tcpip.CorkOption(0))
-			},
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			c := context.New(t, defaultMTU)
-			defer c.Cleanup()
-
-			c.CreateConnected(789, 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.
-			for i := 0; i < tcp.InitialCwnd; i++ {
-				view := buffer.NewViewFromBytes([]byte{0})
-				if _, _, err := c.EP.Write(tcpip.SlicePayload(view), 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...)
-				view := buffer.NewViewFromBytes(data)
-				if _, _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil {
-					t.Fatalf("Write #%d failed: %v", i+1, err)
-				}
-			}
-
-			// Check that we get tcp.InitialCwnd packets.
-			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.SeqNum(uint32(c.IRS)+uint32(i)+1),
-						checker.AckNum(790),
-						checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(header.TCPFlagPsh)),
-					),
-				)
-			}
-
-			// Acknowledge the data.
-			c.SendPacket(nil, &context.Headers{
-				SrcPort: context.TestPort,
-				DstPort: c.Port,
-				Flags:   header.TCPFlagAck,
-				SeqNum:  790,
-				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.SeqNum(uint32(c.IRS)+11),
-					checker.AckNum(790),
-					checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(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:  790,
-				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(789, 30000, -1 /* epRcvBuf */)
-
-	c.EP.SetSockOptInt(tcpip.DelayOption, 1)
-
-	var allData []byte
-	for i, data := range [][]byte{{0}, {1, 2, 3, 4}, {5, 6, 7}, {8, 9}, {10}, {11}} {
-		allData = append(allData, data...)
-		view := buffer.NewViewFromBytes(data)
-		if _, _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil {
-			t.Fatalf("Write #%d failed: %v", i+1, err)
-		}
-	}
-
-	seq := c.IRS.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.SeqNum(uint32(seq)),
-				checker.AckNum(790),
-				checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(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:  790,
-			AckNum:  seq,
-			RcvWnd:  30000,
-		})
-	}
-}
-
-func TestUndelay(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateConnected(789, 30000, -1 /* epRcvBuf */)
-
-	c.EP.SetSockOptInt(tcpip.DelayOption, 1)
-
-	allData := [][]byte{{0}, {1, 2, 3}}
-	for i, data := range allData {
-		view := buffer.NewViewFromBytes(data)
-		if _, _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil {
-			t.Fatalf("Write #%d failed: %v", i+1, err)
-		}
-	}
-
-	seq := c.IRS.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.SeqNum(uint32(seq)),
-			checker.AckNum(790),
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(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.SetSockOptInt(tcpip.DelayOption, 0)
-
-	// 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.SeqNum(uint32(seq)),
-			checker.AckNum(790),
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(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:  790,
-		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.SetSockOptInt(tcpip.DelayOption, 1) }},
-		{"cork", func(ep tcpip.Endpoint) { ep.SetSockOpt(tcpip.CorkOption(1)) }},
-	}
-
-	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(789, 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 {
-				view := buffer.NewViewFromBytes(data)
-				if _, _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil {
-					t.Fatalf("Write #%d failed: %v", i+1, err)
-				}
-			}
-
-			seq := c.IRS.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.SeqNum(uint32(seq)),
-						checker.AckNum(790),
-						checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(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:  790,
-				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)
-	}
-
-	view := buffer.NewView(len(data))
-	copy(view, data)
-
-	if _, _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %v", err)
-	}
-
-	// Check that data is received in chunks.
-	bytesReceived := 0
-	numPackets := 0
-	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.SeqNum(uint32(c.IRS)+1+uint32(bytesReceived)),
-				checker.AckNum(790),
-				checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(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:  790,
-			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(789, 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: %v", err)
-			}
-
-			if err := c.EP.SetSockOpt(tcpip.TTLOption(wantTTL)); err != nil {
-				t.Fatalf("SetSockOpt failed: %v", err)
-			}
-
-			if err := c.EP.Connect(tcpip.FullAddress{Addr: context.TestAddr, Port: context.TestPort}); err != tcpip.ErrConnectStarted {
-				t.Fatalf("Unexpected return value from Connect: %v", 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(789, 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: %v", 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("SetSockOpt failed failed: %v", err)
-	}
-
-	if err := ep.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %v", err)
-	}
-
-	if err := ep.Listen(10); err != nil {
-		t.Fatalf("Listen failed: %v", 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()
-	if err == tcpip.ErrWouldBlock {
-		// Wait for connection to be established.
-		select {
-		case <-ch:
-			c.EP, _, err = ep.Accept()
-			if err != nil {
-				t.Fatalf("Accept failed: %v", 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.
-	saved := tcp.SynRcvdCountThreshold
-	defer func() {
-		tcp.SynRcvdCountThreshold = saved
-	}()
-	tcp.SynRcvdCountThreshold = 0
-
-	// 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: %v", err)
-	}
-	defer ep.Close()
-
-	if err := ep.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %v", err)
-	}
-
-	if err := ep.Listen(10); err != nil {
-		t.Fatalf("Listen failed: %v", 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()
-	if err == tcpip.ErrWouldBlock {
-		// Wait for connection to be established.
-		select {
-		case <-ch:
-			c.EP, _, err = ep.Accept()
-			if err != nil {
-				t.Fatalf("Accept failed: %v", 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: %v", 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: %v", err)
-	}
-
-	// Set the buffer size to a deterministic size so that we can check the
-	// window scaling option.
-	const rcvBufferSize = 0x20000
-	const wndScale = 2
-	if err := c.EP.SetSockOptInt(tcpip.ReceiveBufferSizeOption, rcvBufferSize); err != nil {
-		t.Fatalf("SetSockOpt failed failed: %v", err)
-	}
-
-	// Start connection attempt.
-	we, ch := waiter.NewChannelEntry(nil)
-	c.WQ.EventRegister(&we, waiter.EventOut)
-	defer c.WQ.EventUnregister(&we)
-
-	if err := c.EP.Connect(tcpip.FullAddress{Addr: context.TestAddr, Port: context.TestPort}); err != tcpip.ErrConnectStarted {
-		t.Fatalf("got c.EP.Connect(...) = %v, want = %v", 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.SeqNum(tcpHdr.SequenceNumber()),
-			checker.TCPSynOptions(header.TCPSynOptions{MSS: mss, WS: wndScale}),
-		),
-	)
-
-	// Send SYN-ACK.
-	iss := seqnum.Value(789)
-	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.SeqNum(uint32(c.IRS)+1),
-			checker.AckNum(uint32(iss)+1),
-		),
-	)
-
-	// Wait for connection to be established.
-	select {
-	case <-ch:
-		if err := c.EP.GetSockOpt(tcpip.ErrorOption{}); err != nil {
-			t.Fatalf("GetSockOpt failed: %v", 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: %v", err)
-	}
-
-	if err := ep.Bind(tcpip.FullAddress{}); err != nil {
-		t.Fatalf("Bind failed: %v", err)
-	}
-
-	if err := ep.Listen(10); err != nil {
-		t.Fatalf("Listen failed: %v", 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: %v", diff)
-	}
-}
-
-func TestReceiveOnResetConnection(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateConnected(789, 30000, -1 /* epRcvBuf */)
-
-	// Send RST segment.
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagRst,
-		SeqNum:  790,
-		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(nil); err {
-		case tcpip.ErrWouldBlock:
-			select {
-			case <-ch:
-			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 = %v", err, tcpip.ErrConnectionReset)
-		}
-	}
-	// Expect the state to be StateError and subsequent Reads to fail with HardError.
-	if _, _, err := c.EP.Read(nil); err != tcpip.ErrConnectionReset {
-		t.Fatalf("got c.EP.Read(nil) = %v, want = %v", 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() = %v, want = 1", got)
-	}
-	if got := c.Stack().Stats().TCP.CurrentEstablished.Value(); got != 0 {
-		t.Errorf("got stats.TCP.CurrentEstablished.Value() = %v, want = 0", got)
-	}
-}
-
-func TestSendOnResetConnection(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateConnected(789, 30000, -1 /* epRcvBuf */)
-
-	// Send RST segment.
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagRst,
-		SeqNum:  790,
-		RcvWnd:  30000,
-	})
-
-	// Wait for the RST to be received.
-	time.Sleep(1 * time.Second)
-
-	// Try to write.
-	view := buffer.NewView(10)
-	if _, _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != tcpip.ErrConnectionReset {
-		t.Fatalf("got c.EP.Write(...) = %v, want = %v", err, tcpip.ErrConnectionReset)
-	}
-}
-
-func TestFinImmediately(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateConnected(789, 30000, -1 /* epRcvBuf */)
-
-	// Shutdown immediately, check that we get a FIN.
-	if err := c.EP.Shutdown(tcpip.ShutdownWrite); err != nil {
-		t.Fatalf("Shutdown failed: %v", err)
-	}
-
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.SeqNum(uint32(c.IRS)+1),
-			checker.AckNum(790),
-			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:  790,
-		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.SeqNum(uint32(c.IRS)+2),
-			checker.AckNum(791),
-			checker.TCPFlags(header.TCPFlagAck),
-		),
-	)
-}
-
-func TestFinRetransmit(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateConnected(789, 30000, -1 /* epRcvBuf */)
-
-	// Shutdown immediately, check that we get a FIN.
-	if err := c.EP.Shutdown(tcpip.ShutdownWrite); err != nil {
-		t.Fatalf("Shutdown failed: %v", err)
-	}
-
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.SeqNum(uint32(c.IRS)+1),
-			checker.AckNum(790),
-			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.SeqNum(uint32(c.IRS)+1),
-			checker.AckNum(790),
-			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:  790,
-		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.SeqNum(uint32(c.IRS)+2),
-			checker.AckNum(791),
-			checker.TCPFlags(header.TCPFlagAck),
-		),
-	)
-}
-
-func TestFinWithNoPendingData(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateConnected(789, 30000, -1 /* epRcvBuf */)
-
-	// Write something out, and have it acknowledged.
-	view := buffer.NewView(10)
-	if _, _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %v", err)
-	}
-
-	next := uint32(c.IRS) + 1
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(len(view)+header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.SeqNum(next),
-			checker.AckNum(790),
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(header.TCPFlagPsh)),
-		),
-	)
-	next += uint32(len(view))
-
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  790,
-		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: %v", err)
-	}
-
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.SeqNum(next),
-			checker.AckNum(790),
-			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:  790,
-		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.SeqNum(next),
-			checker.AckNum(791),
-			checker.TCPFlags(header.TCPFlagAck),
-		),
-	)
-}
-
-func TestFinWithPendingDataCwndFull(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateConnected(789, 30000, -1 /* epRcvBuf */)
-
-	// Write enough segments to fill the congestion window before ACK'ing
-	// any of them.
-	view := buffer.NewView(10)
-	for i := tcp.InitialCwnd; i > 0; i-- {
-		if _, _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil {
-			t.Fatalf("Write failed: %v", err)
-		}
-	}
-
-	next := uint32(c.IRS) + 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.SeqNum(next),
-				checker.AckNum(790),
-				checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(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: %v", err)
-	}
-
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(len(view)+header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.SeqNum(uint32(c.IRS)+1),
-			checker.AckNum(790),
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(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:  790,
-		AckNum:  seqnum.Value(next),
-		RcvWnd:  30000,
-	})
-
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.SeqNum(next),
-			checker.AckNum(790),
-			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:  790,
-		AckNum:  seqnum.Value(next),
-		RcvWnd:  30000,
-	})
-
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.SeqNum(next),
-			checker.AckNum(791),
-			checker.TCPFlags(header.TCPFlagAck),
-		),
-	)
-}
-
-func TestFinWithPendingData(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateConnected(789, 30000, -1 /* epRcvBuf */)
-
-	// Write something out, and acknowledge it to get cwnd to 2.
-	view := buffer.NewView(10)
-	if _, _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %v", err)
-	}
-
-	next := uint32(c.IRS) + 1
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(len(view)+header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.SeqNum(next),
-			checker.AckNum(790),
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(header.TCPFlagPsh)),
-		),
-	)
-	next += uint32(len(view))
-
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  790,
-		AckNum:  seqnum.Value(next),
-		RcvWnd:  30000,
-	})
-
-	// Write new data, but don't acknowledge it.
-	if _, _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %v", err)
-	}
-
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(len(view)+header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.SeqNum(next),
-			checker.AckNum(790),
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(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: %v", err)
-	}
-
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.SeqNum(next),
-			checker.AckNum(790),
-			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:  790,
-		AckNum:  seqnum.Value(next),
-		RcvWnd:  30000,
-	})
-
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.SeqNum(next),
-			checker.AckNum(791),
-			checker.TCPFlags(header.TCPFlagAck),
-		),
-	)
-}
-
-func TestFinWithPartialAck(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateConnected(789, 30000, -1 /* epRcvBuf */)
-
-	// Write something out, and acknowledge it to get cwnd to 2. Also send
-	// FIN from the test side.
-	view := buffer.NewView(10)
-	if _, _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %v", err)
-	}
-
-	next := uint32(c.IRS) + 1
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(len(view)+header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.SeqNum(next),
-			checker.AckNum(790),
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(header.TCPFlagPsh)),
-		),
-	)
-	next += uint32(len(view))
-
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck | header.TCPFlagFin,
-		SeqNum:  790,
-		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.SeqNum(next),
-			checker.AckNum(791),
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(header.TCPFlagPsh)),
-		),
-	)
-
-	// Write new data, but don't acknowledge it.
-	if _, _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %v", err)
-	}
-
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(len(view)+header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.SeqNum(next),
-			checker.AckNum(791),
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(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: %v", err)
-	}
-
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.SeqNum(next),
-			checker.AckNum(791),
-			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:  791,
-		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:  791,
-		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: %v", err)
-	}
-
-	if err := ep.Bind(tcpip.FullAddress{}); err != nil {
-		t.Fatalf("Bind failed: %v", err)
-	}
-
-	if err := ep.Listen(10); err != nil {
-		t.Fatalf("Listen failed: %v", 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: %v", 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(789, 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.
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  790,
-		AckNum:  c.IRS.Add(1),
-		RcvWnd:  1,
-	})
-
-	// Send some data. Check that it's capped by the window size.
-	view := buffer.NewView(65535)
-	if _, _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %v", 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.SeqNum(uint32(c.IRS)+1),
-			checker.AckNum(790),
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(header.TCPFlagPsh)),
-		),
-	)
-
-	// Reset the connection to free resources.
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagRst,
-		SeqNum:  790,
-	})
-}
-
-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(789, 30000, -1 /* epRcvBuf */)
-	stats := c.Stack().Stats()
-	want := stats.TCP.ValidSegmentsReceived.Value() + 1
-
-	c.SendPacket(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  seqnum.Value(790),
-		AckNum:  c.IRS.Add(1),
-		RcvWnd:  30000,
-	})
-
-	if got := stats.TCP.ValidSegmentsReceived.Value(); got != want {
-		t.Errorf("got stats.TCP.ValidSegmentsReceived.Value() = %v, want = %v", got, want)
-	}
-	if got := c.EP.Stats().(*tcp.Stats).SegmentsReceived.Value(); got != want {
-		t.Errorf("got EP stats Stats.SegmentsReceived = %v, want = %v", 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 = %v, want = %v", got, 0)
-	}
-	if got := c.EP.Stats().(*tcp.Stats).SendErrors.NoLinkAddr.Value(); got != 0 {
-		t.Errorf("got EP stats Stats.SendErrors.NoLinkAddr = %v, want = %v", got, 0)
-	}
-}
-
-func TestReceivedInvalidSegmentCountIncrement(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-	c.CreateConnected(789, 30000, -1 /* epRcvBuf */)
-	stats := c.Stack().Stats()
-	want := stats.TCP.InvalidSegmentsReceived.Value() + 1
-	vv := c.BuildSegment(nil, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  seqnum.Value(790),
-		AckNum:  c.IRS.Add(1),
-		RcvWnd:  30000,
-	})
-	tcpbuf := vv.First()[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() = %v, want = %v", got, want)
-	}
-	if got := c.EP.Stats().(*tcp.Stats).ReceiveErrors.MalformedPacketsReceived.Value(); got != want {
-		t.Errorf("got EP Stats.ReceiveErrors.MalformedPacketsReceived stats = %v, want = %v", got, want)
-	}
-}
-
-func TestReceivedIncorrectChecksumIncrement(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-	c.CreateConnected(789, 30000, -1 /* epRcvBuf */)
-	stats := c.Stack().Stats()
-	want := stats.TCP.ChecksumErrors.Value() + 1
-	vv := c.BuildSegment([]byte{0x1, 0x2, 0x3}, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  seqnum.Value(790),
-		AckNum:  c.IRS.Add(1),
-		RcvWnd:  30000,
-	})
-	tcpbuf := vv.First()[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(789, 30000, -1 /* epRcvBuf */)
-
-	// Send 200 segments.
-	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:  seqnum.Value(790 + i*len(data)),
-			AckNum:  c.IRS.Add(1),
-			RcvWnd:  30000,
-		})
-	}
-
-	// Receive ACKs for all segments.
-	last := seqnum.Value(790 + 200*len(data))
-	for {
-		b := c.GetPacket()
-		checker.IPv4(t, b,
-			checker.TCP(
-				checker.DstPort(context.TestPort),
-				checker.SeqNum(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
-	if err := c.Stack().SetTransportProtocolOption(tcp.ProtocolNumber, tcpip.TCPTimeWaitTimeoutOption(tcpTimeWaitTimeout)); err != nil {
-		t.Fatalf("c.stack.SetTransportProtocolOption(tcp, tcpip.TCPTimeWaitTimeout(%d) failed: %s", tcpTimeWaitTimeout, err)
-	}
-
-	c.CreateConnected(789, 30000, -1 /* epRcvBuf */)
-
-	we, ch := waiter.NewChannelEntry(nil)
-	c.WQ.EventRegister(&we, waiter.EventIn)
-	defer c.WQ.EventUnregister(&we)
-
-	if _, _, err := c.EP.Read(nil); err != tcpip.ErrWouldBlock {
-		t.Fatalf("got c.EP.Read(nil) = %v, want = %s", err, 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)
-	}
-
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.SeqNum(uint32(c.IRS)+1),
-			checker.AckNum(790),
-			checker.TCPFlags(header.TCPFlagAck|header.TCPFlagFin),
-		),
-	)
-
-	if got, want := tcp.EndpointState(c.EP.State()), tcp.StateFinWait1; got != want {
-		t.Errorf("Unexpected endpoint state: want %v, got %v", 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:  790,
-		AckNum:  c.IRS.Add(2),
-		RcvWnd:  30000,
-	})
-
-	// Check that ACK is received.
-	checker.IPv4(t, c.GetPacket(),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.SeqNum(uint32(c.IRS)+2),
-			checker.AckNum(uint32(791+len(data))),
-			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 %v, got %v", 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.
-	peekBuf := make([]byte, 10)
-	n, _, err := c.EP.Peek([][]byte{peekBuf})
-	if err != nil {
-		t.Fatalf("Peek failed: %s", err)
-	}
-
-	peekBuf = peekBuf[:n]
-	if !bytes.Equal(data, peekBuf) {
-		t.Fatalf("got data = %v, want = %v", peekBuf, data)
-	}
-
-	// Receive data.
-	v, _, err := c.EP.Read(nil)
-	if err != nil {
-		t.Fatalf("Read failed: %s", err)
-	}
-
-	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.
-	if _, _, err := c.EP.Read(nil); err != tcpip.ErrClosedForReceive {
-		t.Fatalf("got c.EP.Read(nil) = %v, want = %s", err, tcpip.ErrClosedForReceive)
-	}
-
-	if _, _, err := c.EP.Peek([][]byte{peekBuf}); err != tcpip.ErrClosedForReceive {
-		t.Fatalf("got c.EP.Peek(...) = %v, want = %s", 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; %v", err)
-	}
-	if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %v", err)
-	}
-
-	c.EP.Close()
-	c.EP, err = c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &waiter.Queue{})
-	if err != nil {
-		t.Fatalf("NewEndpoint failed; %v", err)
-	}
-	if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %v", 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; %v", err)
-	}
-	if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %v", err)
-	}
-	if err := c.EP.Connect(tcpip.FullAddress{Addr: context.TestAddr, Port: context.TestPort}); err != tcpip.ErrConnectStarted {
-		t.Fatalf("got c.EP.Connect(...) = %v, want = %v", 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; %v", err)
-	}
-	if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %v", 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; %v", err)
-	}
-	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)
-	}
-	c.EP.Close()
-
-	c.EP, err = c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &waiter.Queue{})
-	if err != nil {
-		t.Fatalf("NewEndpoint failed; %v", err)
-	}
-	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)
-	}
-}
-
-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: %v", err)
-	}
-
-	if int(s) != v {
-		t.Fatalf("got receive buffer size = %v, want = %v", s, v)
-	}
-}
-
-func checkSendBufferSize(t *testing.T, ep tcpip.Endpoint, v int) {
-	t.Helper()
-
-	s, err := ep.GetSockOptInt(tcpip.SendBufferSizeOption)
-	if err != nil {
-		t.Fatalf("GetSockOpt failed: %v", err)
-	}
-
-	if int(s) != v {
-		t.Fatalf("got send buffer size = %v, want = %v", s, v)
-	}
-}
-
-func TestDefaultBufferSizes(t *testing.T) {
-	s := stack.New(stack.Options{
-		NetworkProtocols:   []stack.NetworkProtocol{ipv4.NewProtocol()},
-		TransportProtocols: []stack.TransportProtocol{tcp.NewProtocol()},
-	})
-
-	// Check the default values.
-	ep, err := s.NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &waiter.Queue{})
-	if err != nil {
-		t.Fatalf("NewEndpoint failed; %v", err)
-	}
-	defer func() {
-		if ep != nil {
-			ep.Close()
-		}
-	}()
-
-	checkSendBufferSize(t, ep, tcp.DefaultSendBufferSize)
-	checkRecvBufferSize(t, ep, tcp.DefaultReceiveBufferSize)
-
-	// Change the default send buffer size.
-	if err := s.SetTransportProtocolOption(tcp.ProtocolNumber, tcp.SendBufferSizeOption{1, tcp.DefaultSendBufferSize * 2, tcp.DefaultSendBufferSize * 20}); err != nil {
-		t.Fatalf("SetTransportProtocolOption failed: %v", err)
-	}
-
-	ep.Close()
-	ep, err = s.NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &waiter.Queue{})
-	if err != nil {
-		t.Fatalf("NewEndpoint failed; %v", err)
-	}
-
-	checkSendBufferSize(t, ep, tcp.DefaultSendBufferSize*2)
-	checkRecvBufferSize(t, ep, tcp.DefaultReceiveBufferSize)
-
-	// Change the default receive buffer size.
-	if err := s.SetTransportProtocolOption(tcp.ProtocolNumber, tcp.ReceiveBufferSizeOption{1, tcp.DefaultReceiveBufferSize * 3, tcp.DefaultReceiveBufferSize * 30}); err != nil {
-		t.Fatalf("SetTransportProtocolOption failed: %v", err)
-	}
-
-	ep.Close()
-	ep, err = s.NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &waiter.Queue{})
-	if err != nil {
-		t.Fatalf("NewEndpoint failed; %v", 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.NetworkProtocol{ipv4.NewProtocol()},
-		TransportProtocols: []stack.TransportProtocol{tcp.NewProtocol()},
-	})
-
-	// Check the default values.
-	ep, err := s.NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &waiter.Queue{})
-	if err != nil {
-		t.Fatalf("NewEndpoint failed; %v", err)
-	}
-	defer ep.Close()
-
-	// Change the min/max values for send/receive
-	if err := s.SetTransportProtocolOption(tcp.ProtocolNumber, tcp.ReceiveBufferSizeOption{200, tcp.DefaultReceiveBufferSize * 2, tcp.DefaultReceiveBufferSize * 20}); err != nil {
-		t.Fatalf("SetTransportProtocolOption failed: %v", err)
-	}
-
-	if err := s.SetTransportProtocolOption(tcp.ProtocolNumber, tcp.SendBufferSizeOption{300, tcp.DefaultSendBufferSize * 3, tcp.DefaultSendBufferSize * 30}); err != nil {
-		t.Fatalf("SetTransportProtocolOption failed: %v", err)
-	}
-
-	// Set values below the min.
-	if err := ep.SetSockOptInt(tcpip.ReceiveBufferSizeOption, 199); err != nil {
-		t.Fatalf("GetSockOpt failed: %v", err)
-	}
-
-	checkRecvBufferSize(t, ep, 200)
-
-	if err := ep.SetSockOptInt(tcpip.SendBufferSizeOption, 299); err != nil {
-		t.Fatalf("GetSockOpt failed: %v", err)
-	}
-
-	checkSendBufferSize(t, ep, 300)
-
-	// Set values above the max.
-	if err := ep.SetSockOptInt(tcpip.ReceiveBufferSizeOption, 1+tcp.DefaultReceiveBufferSize*20); err != nil {
-		t.Fatalf("GetSockOpt failed: %v", err)
-	}
-
-	checkRecvBufferSize(t, ep, tcp.DefaultReceiveBufferSize*20)
-
-	if err := ep.SetSockOptInt(tcpip.SendBufferSizeOption, 1+tcp.DefaultSendBufferSize*30); err != nil {
-		t.Fatalf("GetSockOpt failed: %v", err)
-	}
-
-	checkSendBufferSize(t, ep, tcp.DefaultSendBufferSize*30)
-}
-
-func TestBindToDeviceOption(t *testing.T) {
-	s := stack.New(stack.Options{
-		NetworkProtocols:   []stack.NetworkProtocol{ipv4.NewProtocol()},
-		TransportProtocols: []stack.TransportProtocol{tcp.NewProtocol()}})
-
-	ep, err := s.NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &waiter.Queue{})
-	if err != nil {
-		t.Fatalf("NewEndpoint failed; %v", err)
-	}
-	defer ep.Close()
-
-	if err := s.CreateNIC(321, loopback.New()); err != nil {
-		t.Errorf("CreateNIC failed: %v", 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      tcpip.BindToDeviceOption
-	}{
-		{"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 := tcpip.BindToDeviceOption(*testAction.setBindToDevice)
-				if gotErr, wantErr := ep.SetSockOpt(bindToDevice), testAction.setBindToDeviceError; gotErr != wantErr {
-					t.Errorf("SetSockOpt(%v) got %v, want %v", bindToDevice, gotErr, wantErr)
-				}
-			}
-			bindToDevice := tcpip.BindToDeviceOption(88888)
-			if err := ep.GetSockOpt(&bindToDevice); err != nil {
-				t.Errorf("GetSockOpt got %v, want %v", err, nil)
-			}
-			if got, want := bindToDevice, testAction.getBindToDevice; got != want {
-				t.Errorf("bindToDevice got %d, want %d", got, want)
-			}
-		})
-	}
-}
-
-func makeStack() (*stack.Stack, *tcpip.Error) {
-	s := stack.New(stack.Options{
-		NetworkProtocols: []stack.NetworkProtocol{
-			ipv4.NewProtocol(),
-			ipv6.NewProtocol(),
-		},
-		TransportProtocols: []stack.TransportProtocol{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: %v", err)
-	}
-	defer ep.Close()
-
-	if err := ep.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %v", err)
-	}
-
-	// Register for notification, then start connection attempt.
-	waitEntry, notifyCh := waiter.NewChannelEntry(nil)
-	wq.EventRegister(&waitEntry, waiter.EventOut)
-	defer wq.EventUnregister(&waitEntry)
-
-	if err := ep.Connect(tcpip.FullAddress{Addr: context.StackAddr, Port: context.StackPort}); err != tcpip.ErrConnectStarted {
-		t.Fatalf("got ep.Connect(...) = %v, want = %v", err, tcpip.ErrConnectStarted)
-	}
-
-	<-notifyCh
-	if err := ep.GetSockOpt(tcpip.ErrorOption{}); err != nil {
-		t.Fatalf("Connect failed: %v", err)
-	}
-
-	// Write something.
-	data := []byte{1, 2, 3}
-	view := buffer.NewView(len(data))
-	copy(view, data)
-	if _, _, err := ep.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %v", err)
-	}
-
-	// Read back what was written.
-	wq.EventUnregister(&waitEntry)
-	wq.EventRegister(&waitEntry, waiter.EventIn)
-	rd, _, err := ep.Read(nil)
-	if err != nil {
-		if err != tcpip.ErrWouldBlock {
-			t.Fatalf("Read failed: %v", err)
-		}
-		<-notifyCh
-		rd, _, err = ep.Read(nil)
-		if err != nil {
-			t.Fatalf("Read failed: %v", err)
-		}
-	}
-
-	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: %v", err)
-												}
-												eps = append(eps, ep)
-												switch network {
-												case "ipv4":
-												case "ipv6":
-													if err := ep.SetSockOptBool(tcpip.V6OnlyOption, true); err != nil {
-														t.Fatalf("SetSockOpt(V6OnlyOption(true)) failed: %v", err)
-													}
-												case "dual":
-													if err := ep.SetSockOptBool(tcpip.V6OnlyOption, false); err != nil {
-														t.Fatalf("SetSockOpt(V6OnlyOption(false)) failed: %v", err)
-													}
-												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)
-											}
-
-											for i := ports.FirstEphemeral; i <= math.MaxUint16; i++ {
-												if makeEP(exhaustedNetwork).Bind(tcpip.FullAddress{Addr: address(t, exhaustedAddressType, isAny), Port: uint16(i)}); err != nil {
-													t.Fatalf("Bind(%d) failed: %v", i, err)
-												}
-											}
-											want := 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(..) = %v, want = %v", 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(789, 30000, -1 /* epRcvBuf */, []byte{
-		header.TCPOptionMSS, 4, byte(maxPayload / 256), byte(maxPayload % 256),
-	})
-
-	// Send 3200 bytes of data.
-	const writeSize = 3200
-	data := buffer.NewView(writeSize)
-	for i := range data {
-		data[i] = byte(i)
-	}
-
-	if _, _, err := c.EP.Write(tcpip.SlicePayload(data), tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %v", err)
-	}
-
-	receivePackets := func(c *context.Context, sizes []int, which int, seqNum uint32) []byte {
-		var ret []byte
-		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.SeqNum(seqNum),
-					checker.AckNum(790),
-					checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(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(789, 30000, -1 /* epRcvBuf */)
-
-	data := []byte{1, 2, 3}
-	c.SendPacket(data, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  790,
-		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) = %v", tcp.ProtocolNumber, &oldCC, err)
-			}
-
-			if err := s.SetTransportProtocolOption(tcp.ProtocolNumber, tc.cc); err != tc.err {
-				t.Fatalf("s.SetTransportProtocolOption(%v, %v) = %v, want %v", tcp.ProtocolNumber, 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.AvailableCongestionControlOption
-	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.AvailableCongestionControlOption("reno cubic"); got != want {
-		t.Fatalf("got tcpip.AvailableCongestionControlOption: %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.AvailableCongestionControlOption("xyz")
-	if err := s.SetTransportProtocolOption(tcp.ProtocolNumber, &aCC); err == nil {
-		t.Fatalf("s.TransportProtocolOption(%v, %v) = nil, want non-nil", tcp.ProtocolNumber, &aCC)
-	}
-
-	// Verify that we still get the expected list of congestion control options.
-	var cc tcpip.AvailableCongestionControlOption
-	if err := s.TransportProtocolOption(tcp.ProtocolNumber, &cc); err != nil {
-		t.Fatalf("s.TransportProtocolOption(%v, %v) = %v", tcp.ProtocolNumber, &cc, err)
-	}
-	if got, want := cc, tcpip.AvailableCongestionControlOption("reno cubic"); got != want {
-		t.Fatalf("got tcpip.AvailableCongestionControlOption: %v, want: %v", 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: %v", err)
-				}
-
-				var oldCC tcpip.CongestionControlOption
-				if err := c.EP.GetSockOpt(&oldCC); err != nil {
-					t.Fatalf("c.EP.SockOpt(%v) = %v", &oldCC, err)
-				}
-
-				if connected {
-					c.Connect(789 /* iss */, 32768 /* rcvWnd */, nil)
-				}
-
-				if err := c.EP.SetSockOpt(tc.cc); err != tc.err {
-					t.Fatalf("c.EP.SetSockOpt(%v) = %v, want %v", tc.cc, err, tc.err)
-				}
-
-				var cc tcpip.CongestionControlOption
-				if err := c.EP.GetSockOpt(&cc); err != nil {
-					t.Fatalf("c.EP.SockOpt(%v) = %v", &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("c.s.SetTransportProtocolOption(tcp.ProtocolNumber, %v = %v", opt, err)
-	}
-}
-
-func TestKeepalive(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateConnected(789, 30000, -1 /* epRcvBuf */)
-
-	const keepAliveInterval = 10 * time.Millisecond
-	c.EP.SetSockOpt(tcpip.KeepaliveIdleOption(10 * time.Millisecond))
-	c.EP.SetSockOpt(tcpip.KeepaliveIntervalOption(keepAliveInterval))
-	c.EP.SetSockOpt(tcpip.KeepaliveCountOption(5))
-	c.EP.SetSockOpt(tcpip.KeepaliveEnabledOption(1))
-
-	// 5 unacked keepalives are sent. ACK each one, and check that the
-	// connection stays alive after 5.
-	for i := 0; i < 10; i++ {
-		b := c.GetPacket()
-		checker.IPv4(t, b,
-			checker.TCP(
-				checker.DstPort(context.TestPort),
-				checker.SeqNum(uint32(c.IRS)),
-				checker.AckNum(uint32(790)),
-				checker.TCPFlags(header.TCPFlagAck),
-			),
-		)
-
-		// Acknowledge the keepalive.
-		c.SendPacket(nil, &context.Headers{
-			SrcPort: context.TestPort,
-			DstPort: c.Port,
-			Flags:   header.TCPFlagAck,
-			SeqNum:  790,
-			AckNum:  c.IRS,
-			RcvWnd:  30000,
-		})
-	}
-
-	// Check that the connection is still alive.
-	if _, _, err := c.EP.Read(nil); err != tcpip.ErrWouldBlock {
-		t.Fatalf("got c.EP.Read(nil) = %v, want = %v", err, tcpip.ErrWouldBlock)
-	}
-
-	// Send some data and wait before ACKing it. Keepalives should be disabled
-	// during this period.
-	view := buffer.NewView(3)
-	if _, _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %v", err)
-	}
-
-	next := uint32(c.IRS) + 1
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(len(view)+header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.SeqNum(next),
-			checker.AckNum(790),
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(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.SeqNum(next),
-			checker.AckNum(790),
-			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:  790,
-		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.SeqNum(uint32(next-1)),
-				checker.AckNum(uint32(790)),
-				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 + 5*time.Millisecond)
-
-	// 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:  790,
-		AckNum:  seqnum.Value(next),
-		RcvWnd:  30000,
-	})
-
-	checker.IPv4(t, c.GetPacket(),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.SeqNum(uint32(next)),
-			checker.AckNum(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() = %v, want = 1", got)
-	}
-
-	if _, _, err := c.EP.Read(nil); err != tcpip.ErrTimeout {
-		t.Fatalf("got c.EP.Read(nil) = %v, want = %v", err, tcpip.ErrTimeout)
-	}
-
-	if got := c.Stack().Stats().TCP.CurrentEstablished.Value(); got != 0 {
-		t.Errorf("got stats.TCP.CurrentEstablished.Value() = %v, want = 0", got)
-	}
-}
-
-func executeHandshake(t *testing.T, c *context.Context, srcPort uint16, synCookieInUse bool) (irs, iss seqnum.Value) {
-	// Send a SYN request.
-	irs = seqnum.Value(789)
-	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.AckNum(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) {
-	// Send a SYN request.
-	irs = seqnum.Value(789)
-	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.AckNum(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: %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.
-	// Start listening.
-	listenBacklog := 2
-	if err := c.EP.Listen(listenBacklog); err != nil {
-		t.Fatalf("Listen failed: %v", err)
-	}
-
-	for i := 0; i < listenBacklog; i++ {
-		executeHandshake(t, c, context.TestPort+uint16(i), 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 + 2,
-		DstPort: context.StackPort,
-		Flags:   header.TCPFlagSyn,
-		SeqNum:  seqnum.Value(789),
-		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()
-		if err == tcpip.ErrWouldBlock {
-			// Wait for connection to be established.
-			select {
-			case <-ch:
-				_, _, err = c.EP.Accept()
-				if err != nil {
-					t.Fatalf("Accept failed: %v", 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()
-	if err != tcpip.ErrWouldBlock {
-		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+2, false /*synCookieInUse */)
-
-	newEP, _, err := c.EP.Accept()
-	if err == tcpip.ErrWouldBlock {
-		// Wait for connection to be established.
-		select {
-		case <-ch:
-			newEP, _, err = c.EP.Accept()
-			if err != nil {
-				t.Fatalf("Accept failed: %v", 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"
-	newEP.Write(tcpip.SlicePayload(buffer.NewViewFromBytes([]byte(data))), 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)
-	}
-}
-
-// 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")
-
-	tests := []struct {
-		name    string
-		srcAddr tcpip.Address
-		dstAddr tcpip.Address
-	}{
-		{
-			"SourceUnspecified",
-			header.IPv4Any,
-			context.StackAddr,
-		},
-		{
-			"SourceBroadcast",
-			header.IPv4Broadcast,
-			context.StackAddr,
-		},
-		{
-			"SourceOurMulticast",
-			multicastAddr,
-			context.StackAddr,
-		},
-		{
-			"SourceOtherMulticast",
-			otherMulticastAddr,
-			context.StackAddr,
-		},
-		{
-			"DestUnspecified",
-			context.TestAddr,
-			header.IPv4Any,
-		},
-		{
-			"DestBroadcast",
-			context.TestAddr,
-			header.IPv4Broadcast,
-		},
-		{
-			"DestOurMulticast",
-			context.TestAddr,
-			multicastAddr,
-		},
-		{
-			"DestOtherMulticast",
-			context.TestAddr,
-			otherMulticastAddr,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			t.Parallel()
-
-			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(789)
-			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.AckNum(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\x01\x01")
-	otherMulticastAddr := tcpip.Address("\xff\x0e\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) {
-			t.Parallel()
-
-			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(789)
-			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.AckNum(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: %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.
-	// Start listening.
-	listenBacklog := 1
-	if err := c.EP.Listen(listenBacklog); err != nil {
-		t.Fatalf("Listen failed: %v", 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(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())
-	tcpCheckers := []checker.TransportChecker{
-		checker.SrcPort(context.StackPort),
-		checker.DstPort(context.TestPort),
-		checker.TCPFlags(header.TCPFlagAck | header.TCPFlagSyn),
-		checker.AckNum(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()
-	if err == tcpip.ErrWouldBlock {
-		// Wait for connection to be established.
-		select {
-		case <-ch:
-			newEP, _, err = c.EP.Accept()
-			if err != nil {
-				t.Fatalf("Accept failed: %v", 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"
-	newEP.Write(tcpip.SlicePayload(buffer.NewViewFromBytes([]byte(data))), tcpip.WriteOptions{})
-	pkt := c.GetPacket()
-	tcp = header.TCP(header.IPv4(pkt).Payload())
-	if string(tcp.Payload()) != data {
-		t.Fatalf("Unexpected data: got %v, want %v", string(tcp.Payload()), data)
-	}
-}
-
-func TestListenBacklogFullSynCookieInUse(t *testing.T) {
-	saved := tcp.SynRcvdCountThreshold
-	defer func() {
-		tcp.SynRcvdCountThreshold = saved
-	}()
-	tcp.SynRcvdCountThreshold = 1
-
-	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.
-	// Start listening.
-	listenBacklog := 1
-	portOffset := uint16(0)
-	if err := c.EP.Listen(listenBacklog); err != nil {
-		t.Fatalf("Listen failed: %v", err)
-	}
-
-	executeHandshake(t, c, context.TestPort+portOffset, false)
-	portOffset++
-	// Wait for this to be delivered to the accept queue.
-	time.Sleep(50 * time.Millisecond)
-
-	// Send a SYN request.
-	irs := seqnum.Value(789)
-	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()
-	if err == tcpip.ErrWouldBlock {
-		// Wait for connection to be established.
-		select {
-		case <-ch:
-			_, _, err = c.EP.Accept()
-			if err != nil {
-				t.Fatalf("Accept failed: %v", 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()
-	if err != tcpip.ErrWouldBlock {
-		select {
-		case <-ch:
-			t.Fatalf("unexpected endpoint delivered on Accept: %+v", c.EP)
-		case <-time.After(1 * time.Second):
-		}
-	}
-}
-
-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(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()
-	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.AckNum(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.AckNum(uint32(irs) + 1),
-		checker.SeqNum(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()
-
-	if err != nil && err != tcpip.ErrWouldBlock {
-		t.Fatalf("Accept failed: %s", err)
-	}
-
-	if err == tcpip.ErrWouldBlock {
-		// 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()
-			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"
-	_, _, err = newEP.Write(tcpip.SlicePayload(buffer.NewViewFromBytes([]byte(data))), tcpip.WriteOptions{})
-
-	if 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: %v", err)
-	}
-	c.EP = ep
-	if err := ep.Bind(tcpip.FullAddress{Addr: context.StackAddr, Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %v", err)
-	}
-	if got, want := tcp.EndpointState(ep.State()), tcp.StateBound; got != want {
-		t.Errorf("Unexpected endpoint state: want %v, got %v", want, got)
-	}
-	if err := c.EP.Listen(1); err != nil {
-		t.Fatalf("Listen failed: %v", err)
-	}
-	if got, want := tcp.EndpointState(c.EP.State()), tcp.StateListen; got != want {
-		t.Errorf("Unexpected endpoint state: want %v, got %v", 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()
-	if err == tcpip.ErrWouldBlock {
-		// Wait for connection to be established.
-		select {
-		case <-ch:
-			_, _, err = c.EP.Accept()
-			if err != nil {
-				t.Fatalf("Accept failed: %v", 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() = %v, want = %v", 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: %v", err)
-	}
-	c.EP = ep
-	if err := c.EP.Bind(tcpip.FullAddress{Addr: context.StackAddr, Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %v", err)
-	}
-	if err := c.EP.Listen(1); err != nil {
-		t.Fatalf("Listen failed: %v", 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(789),
-		RcvWnd:  30000,
-	})
-
-	time.Sleep(50 * time.Millisecond)
-	if got := stats.TCP.ListenOverflowSynDrop.Value(); got != want {
-		t.Errorf("got stats.TCP.ListenOverflowSynDrop.Value() = %v, want = %v", got, want)
-	}
-	if got := c.EP.Stats().(*tcp.Stats).ReceiveErrors.ListenOverflowSynDrop.Value(); got != want {
-		t.Errorf("got EP stats Stats.ReceiveErrors.ListenOverflowSynDrop = %v, want = %v", 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()
-	if err == tcpip.ErrWouldBlock {
-		// Wait for connection to be established.
-		select {
-		case <-ch:
-			_, _, err = c.EP.Accept()
-			if err != nil {
-				t.Fatalf("Accept failed: %v", 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: %v", err)
-	}
-
-	if err := ep.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
-		t.Fatalf("Bind failed: %v", err)
-	}
-	if got, want := tcp.EndpointState(ep.State()), tcp.StateBound; got != want {
-		t.Errorf("Unexpected endpoint state: want %v, got %v", want, got)
-	}
-
-	if _, _, err := ep.Read(nil); err != tcpip.ErrNotConnected {
-		t.Errorf("got c.EP.Read(nil) = %v, want = %v", err, tcpip.ErrNotConnected)
-	}
-	if got := ep.Stats().(*tcp.Stats).ReadErrors.NotConnected.Value(); got != 1 {
-		t.Errorf("got EP stats Stats.ReadErrors.NotConnected got %v want %v", got, 1)
-	}
-
-	if err := ep.Listen(10); err != nil {
-		t.Fatalf("Listen failed: %v", err)
-	}
-	if got, want := tcp.EndpointState(ep.State()), tcp.StateListen; got != want {
-		t.Errorf("Unexpected endpoint state: want %v, got %v", 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()
-	if err == tcpip.ErrWouldBlock {
-		// Wait for connection to be established.
-		select {
-		case <-ch:
-			aep, _, err = ep.Accept()
-			if err != nil {
-				t.Fatalf("Accept failed: %v", 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 %v, got %v", want, got)
-	}
-	if err := aep.Connect(tcpip.FullAddress{Addr: context.TestAddr, Port: context.TestPort}); err != tcpip.ErrAlreadyConnected {
-		t.Errorf("Unexpected error attempting to call connect on an established endpoint, got: %v, want: %v", 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 %v, got %v", 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 %v, got %v", 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 %v, got %v", 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
-	if err := stk.SetTransportProtocolOption(tcp.ProtocolNumber, tcp.ReceiveBufferSizeOption{1, receiveBufferSize, maxReceiveBufferSize}); err != nil {
-		t.Fatalf("SetTransportProtocolOption failed: %v", err)
-	}
-
-	// Enable auto-tuning.
-	if err := stk.SetTransportProtocolOption(tcp.ProtocolNumber, tcpip.ModerateReceiveBufferOption(true)); err != nil {
-		t.Fatalf("SetTransportProtocolOption failed: %v", 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)
-	rawEP.SendPacketWithTS([]byte{1}, tsVal)
-
-	// Verify that the ACK has the expected window.
-	wantRcvWnd := receiveBufferSize
-	wantRcvWnd = (wantRcvWnd >> uint32(c.WindowScale))
-	rawEP.VerifyACKRcvWnd(uint16(wantRcvWnd - 1))
-	time.Sleep(25 * time.Millisecond)
-
-	// Allocate a large enough payload for the test.
-	b := make([]byte, int(receiveBufferSize)*2)
-	offset := 0
-	payloadSize := receiveBufferSize - 1
-	worker := (c.EP).(interface {
-		StopWork()
-		ResumeWork()
-	})
-	tsVal++
-
-	// Stop the worker goroutine.
-	worker.StopWork()
-	start := offset
-	end := offset + payloadSize
-	packetsSent := 0
-	for ; start < end; start += mss {
-		rawEP.SendPacketWithTS(b[start:start+mss], 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 read no bytes the window should goto zero till the
-	// application reads some of the data.
-	// Discard all intermediate acks except the last one.
-	if packetsSent > 100 {
-		for i := 0; i < (packetsSent / 100); i++ {
-			_ = c.GetPacket()
-		}
-	}
-	rawEP.VerifyACKRcvWnd(0)
-
-	time.Sleep(25 * time.Millisecond)
-	// Verify that sending more data when window is closed is dropped and
-	// not acked.
-	rawEP.SendPacketWithTS(b[start:start+mss], tsVal)
-
-	// Verify that the stack sends us back an ACK with the sequence number
-	// of the last packet sent indicating it was dropped.
-	p := c.GetPacket()
-	checker.IPv4(t, p, checker.TCP(
-		checker.AckNum(uint32(rawEP.NextSeqNum)-uint32(mss)),
-		checker.Window(0),
-	))
-
-	// 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(nil)
-		if err == tcpip.ErrWouldBlock {
-			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.AckNum(uint32(rawEP.NextSeqNum)-uint32(mss)),
-		func(t *testing.T, h header.Transport) {
-			tcp, ok := h.(header.TCP)
-			if !ok {
-				return
-			}
-			if w := tcp.WindowSize(); w == 0 || w > uint16(wantRcvWnd) {
-				t.Errorf("expected a non-zero window: got %d, want <= wantRcvWnd", w, wantRcvWnd)
-			}
-		},
-	))
-}
-
-// This test verifies that the auto tuning does not grow the receive buffer if
-// the application is not reading the data actively.
-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()
-	// 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 300.
-	const receiveBufferSize = 80 << 10 // 80KB.
-	const maxReceiveBufferSize = receiveBufferSize * 10
-	if err := stk.SetTransportProtocolOption(tcp.ProtocolNumber, tcp.ReceiveBufferSizeOption{1, receiveBufferSize, maxReceiveBufferSize}); err != nil {
-		t.Fatalf("SetTransportProtocolOption failed: %v", err)
-	}
-
-	// Enable auto-tuning.
-	if err := stk.SetTransportProtocolOption(tcp.ProtocolNumber, tcpip.ModerateReceiveBufferOption(true)); err != nil {
-		t.Fatalf("SetTransportProtocolOption failed: %v", 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})
-
-	wantRcvWnd := receiveBufferSize
-	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()
-	})
-	tsVal := rawEP.TSVal
-	// We are going to do our own computation of what the moderated receive
-	// buffer should be based on sent/copied data per RTT and verify that
-	// the advertised window by the stack matches our calculations.
-	prevCopied := 0
-	done := false
-	latency := 1 * time.Millisecond
-	for i := 0; !done; 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)
-
-		// Verify that the advertised window on the ACK is reduced by
-		// the total bytes sent.
-		expectedWnd := wantRcvWnd - totalSent
-		if packetsSent > 100 {
-			for i := 0; i < (packetsSent / 100); i++ {
-				_ = c.GetPacket()
-			}
-		}
-		rawEP.VerifyACKRcvWnd(scaleRcvWnd(expectedWnd))
-
-		// 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 {
-			b, _, err := c.EP.Read(nil)
-			if err == tcpip.ErrWouldBlock {
-				break
-			}
-			totalCopied += len(b)
-		}
-
-		// 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 user-space 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(wantRcvWnd))
-			prevCopied = totalCopied
-		} else {
-			rttCopied := totalCopied
-			if i == 1 {
-				// The moderation code accumulates copied bytes till
-				// RTT is established. So add in the bytes sent in
-				// the first iteration to the total bytes for this
-				// RTT.
-				rttCopied += prevCopied
-				// Now reset it to the initial value used by the
-				// auto tuning logic.
-				prevCopied = tcp.InitialCwnd * mss * 2
-			}
-			newWnd := rttCopied<<1 + 16*mss
-			grow := (newWnd * (rttCopied - prevCopied)) / prevCopied
-			newWnd += (grow << 1)
-			if newWnd > maxReceiveBufferSize {
-				newWnd = maxReceiveBufferSize
-				done = true
-			}
-			rawEP.VerifyACKRcvWnd(scaleRcvWnd(newWnd))
-			wantRcvWnd = newWnd
-			prevCopied = rttCopied
-			// 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
-	}
-}
-
-func TestDelayEnabled(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-	checkDelayOption(t, c, false, 0) // Delay is disabled by default.
-
-	for _, v := range []struct {
-		delayEnabled    tcp.DelayEnabled
-		wantDelayOption int
-	}{
-		{delayEnabled: false, wantDelayOption: 0},
-		{delayEnabled: true, wantDelayOption: 1},
-	} {
-		c := context.New(t, defaultMTU)
-		defer c.Cleanup()
-		if err := c.Stack().SetTransportProtocolOption(tcp.ProtocolNumber, v.delayEnabled); err != nil {
-			t.Fatalf("SetTransportProtocolOption(tcp, %t) failed: %v", v.delayEnabled, err)
-		}
-		checkDelayOption(t, c, v.delayEnabled, v.wantDelayOption)
-	}
-}
-
-func checkDelayOption(t *testing.T, c *context.Context, wantDelayEnabled tcp.DelayEnabled, wantDelayOption int) {
-	t.Helper()
-
-	var gotDelayEnabled tcp.DelayEnabled
-	if err := c.Stack().TransportProtocolOption(tcp.ProtocolNumber, &gotDelayEnabled); err != nil {
-		t.Fatalf("TransportProtocolOption(tcp, &gotDelayEnabled) failed: %v", 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: %v", err)
-	}
-	gotDelayOption, err := ep.GetSockOptInt(tcpip.DelayOption)
-	if err != nil {
-		t.Fatalf("ep.GetSockOptInt(tcpip.DelayOption) failed: %v", err)
-	}
-	if gotDelayOption != wantDelayOption {
-		t.Errorf("ep.GetSockOptInt(tcpip.DelayOption) got: %d, want: %d", gotDelayOption, wantDelayOption)
-	}
-}
-
-func TestTCPLingerTimeout(t *testing.T) {
-	c := context.New(t, 1500 /* mtu */)
-	defer c.Cleanup()
-
-	c.CreateConnected(789, 30000, -1 /* epRcvBuf */)
-
-	testCases := []struct {
-		name             string
-		tcpLingerTimeout time.Duration
-		want             time.Duration
-	}{
-		{"NegativeLingerTimeout", -123123, 0},
-		{"ZeroLingerTimeout", 0, 0},
-		{"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", 65 * time.Second, 60 * time.Second},
-	}
-	for _, tc := range testCases {
-		t.Run(tc.name, func(t *testing.T) {
-			if err := c.EP.SetSockOpt(tcpip.TCPLingerTimeoutOption(tc.tcpLingerTimeout)); err != nil {
-				t.Fatalf("SetSockOpt(%s) = %s", tc.tcpLingerTimeout, err)
-			}
-			var v tcpip.TCPLingerTimeoutOption
-			if err := c.EP.GetSockOpt(&v); err != nil {
-				t.Fatalf("GetSockOpt(tcpip.TCPLingerTimeoutOption) = %s", err)
-			}
-			if got, want := time.Duration(v), tc.want; got != want {
-				t.Fatalf("unexpected linger timeout got: %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(789)
-	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()
-	if err == tcpip.ErrWouldBlock {
-		// Wait for connection to be established.
-		select {
-		case <-ch:
-			c.EP, _, err = ep.Accept()
-			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.SeqNum(uint32(c.IRS+1)),
-		checker.AckNum(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.SeqNum(uint32(c.IRS+2)),
-		checker.AckNum(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.SeqNum(uint32(c.IRS+2)),
-		checker.AckNum(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(789)
-	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()
-	if err == tcpip.ErrWouldBlock {
-		// Wait for connection to be established.
-		select {
-		case <-ch:
-			c.EP, _, err = ep.Accept()
-			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.SeqNum(uint32(c.IRS+1)),
-		checker.AckNum(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.SeqNum(uint32(c.IRS+2)),
-		checker.AckNum(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.SeqNum(uint32(c.IRS+2)),
-		checker.AckNum(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(789)
-	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()
-	if err == tcpip.ErrWouldBlock {
-		// Wait for connection to be established.
-		select {
-		case <-ch:
-			c.EP, _, err = ep.Accept()
-			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.SeqNum(uint32(c.IRS+1)),
-		checker.AckNum(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.SeqNum(uint32(c.IRS+2)),
-		checker.AckNum(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(789)
-	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)
-
-	// Send a SYN request w/ sequence number higher than
-	// the highest sequence number sent.
-	iss = seqnum.Value(792)
-	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()
-	if err == tcpip.ErrWouldBlock {
-		// Wait for connection to be established.
-		select {
-		case <-ch:
-			c.EP, _, err = ep.Accept()
-			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
-	if err := c.Stack().SetTransportProtocolOption(tcp.ProtocolNumber, tcpip.TCPTimeWaitTimeoutOption(tcpTimeWaitTimeout)); err != nil {
-		t.Fatalf("c.stack.SetTransportProtocolOption(tcp, tcpip.TCPLingerTimeoutOption(%d) failed: %s", 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(789)
-	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()
-	if err == tcpip.ErrWouldBlock {
-		// Wait for connection to be established.
-		select {
-		case <-ch:
-			c.EP, _, err = ep.Accept()
-			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.SeqNum(uint32(c.IRS+1)),
-		checker.AckNum(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.SeqNum(uint32(c.IRS+2)),
-		checker.AckNum(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.SeqNum(uint32(c.IRS+2)),
-		checker.AckNum(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.SeqNum(uint32(ackHeaders.AckNum)),
-		checker.AckNum(0),
-		checker.TCPFlags(header.TCPFlagRst)))
-
-	if got := c.Stack().Stats().TCP.EstablishedClosed.Value(); got != want {
-		t.Errorf("got c.Stack().Stats().TCP.EstablishedClosed = %v, want = %v", got, want)
-	}
-	if got := c.Stack().Stats().TCP.CurrentEstablished.Value(); got != 0 {
-		t.Errorf("got stats.TCP.CurrentEstablished.Value() = %v, 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
-	if err := c.Stack().SetTransportProtocolOption(tcp.ProtocolNumber, tcpip.TCPTimeWaitTimeoutOption(tcpTimeWaitTimeout)); err != nil {
-		t.Fatalf("c.stack.SetTransportProtocolOption(tcp, tcpip.TCPLingerTimeoutOption(%d) failed: %s", 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(789)
-	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()
-	if err == tcpip.ErrWouldBlock {
-		// Wait for connection to be established.
-		select {
-		case <-ch:
-			c.EP, _, err = ep.Accept()
-			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.SeqNum(uint32(c.IRS+1)),
-		checker.AckNum(uint32(iss)+2),
-		checker.TCPFlags(header.TCPFlagAck)))
-
-	// Now write a few bytes and then close the endpoint.
-	data := []byte{1, 2, 3}
-	view := buffer.NewView(len(data))
-	copy(view, data)
-
-	if _, _, err := c.EP.Write(tcpip.SlicePayload(view), 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.SeqNum(uint32(c.IRS)+1),
-			checker.AckNum(uint32(iss)+2), // Acknum is initial sequence number + 1
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(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.SeqNum(uint32(c.IRS+1)+uint32(len(data))),
-		checker.AckNum(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.SeqNum(uint32(ackHeaders.AckNum)),
-		checker.AckNum(0),
-		checker.TCPFlags(header.TCPFlagRst)))
-}
-
-func TestTCPUserTimeout(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateConnected(789, 30000, -1 /* epRcvBuf */)
-
-	origEstablishedTimedout := c.Stack().Stats().TCP.EstablishedTimedout.Value()
-
-	userTimeout := 50 * time.Millisecond
-	c.EP.SetSockOpt(tcpip.TCPUserTimeoutOption(userTimeout))
-
-	// Send some data and wait before ACKing it.
-	view := buffer.NewView(3)
-	if _, _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Write failed: %v", err)
-	}
-
-	next := uint32(c.IRS) + 1
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(len(view)+header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.SeqNum(next),
-			checker.AckNum(790),
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(header.TCPFlagPsh)),
-		),
-	)
-
-	// Wait for a little over the minimum retransmit timeout of 200ms for
-	// the retransmitTimer to fire and close the connection.
-	time.Sleep(tcp.MinRTO + 10*time.Millisecond)
-
-	// 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:  790,
-		AckNum:  seqnum.Value(next),
-		RcvWnd:  30000,
-	})
-
-	checker.IPv4(t, c.GetPacket(),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.SeqNum(uint32(next)),
-			checker.AckNum(uint32(0)),
-			checker.TCPFlags(header.TCPFlagRst),
-		),
-	)
-
-	if _, _, err := c.EP.Read(nil); err != tcpip.ErrTimeout {
-		t.Fatalf("got c.EP.Read(nil) = %v, want = %v", err, tcpip.ErrTimeout)
-	}
-
-	if got, want := c.Stack().Stats().TCP.EstablishedTimedout.Value(), origEstablishedTimedout+1; got != want {
-		t.Errorf("got c.Stack().Stats().TCP.EstablishedTimedout = %v, want = %v", got, want)
-	}
-}
-
-func TestKeepaliveWithUserTimeout(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	c.CreateConnected(789, 30000, -1 /* epRcvBuf */)
-
-	origEstablishedTimedout := c.Stack().Stats().TCP.EstablishedTimedout.Value()
-
-	const keepAliveInterval = 10 * time.Millisecond
-	c.EP.SetSockOpt(tcpip.KeepaliveIdleOption(10 * time.Millisecond))
-	c.EP.SetSockOpt(tcpip.KeepaliveIntervalOption(keepAliveInterval))
-	c.EP.SetSockOpt(tcpip.KeepaliveCountOption(10))
-	c.EP.SetSockOpt(tcpip.KeepaliveEnabledOption(1))
-
-	// Set userTimeout to be the duration for 3 keepalive probes.
-	userTimeout := 30 * time.Millisecond
-	c.EP.SetSockOpt(tcpip.TCPUserTimeoutOption(userTimeout))
-
-	// Check that the connection is still alive.
-	if _, _, err := c.EP.Read(nil); err != tcpip.ErrWouldBlock {
-		t.Fatalf("got c.EP.Read(nil) = %v, want = %v", err, tcpip.ErrWouldBlock)
-	}
-
-	// Now receive 2 keepalives, but don't ACK them. The connection should
-	// be reset when the 3rd one should be sent due to userTimeout being
-	// 30ms and each keepalive probe should be sent 10ms apart as set above after
-	// the connection has been idle for 10ms.
-	for i := 0; i < 2; i++ {
-		b := c.GetPacket()
-		checker.IPv4(t, b,
-			checker.TCP(
-				checker.DstPort(context.TestPort),
-				checker.SeqNum(uint32(c.IRS)),
-				checker.AckNum(uint32(790)),
-				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 + 5*time.Millisecond)
-
-	// The connection should be terminated after 30ms.
-	// 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:  790,
-		AckNum:  seqnum.Value(c.IRS + 1),
-		RcvWnd:  30000,
-	})
-
-	checker.IPv4(t, c.GetPacket(),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.SeqNum(uint32(c.IRS+1)),
-			checker.AckNum(uint32(0)),
-			checker.TCPFlags(header.TCPFlagRst),
-		),
-	)
-
-	if _, _, err := c.EP.Read(nil); err != tcpip.ErrTimeout {
-		t.Fatalf("got c.EP.Read(nil) = %v, want = %v", err, tcpip.ErrTimeout)
-	}
-	if got, want := c.Stack().Stats().TCP.EstablishedTimedout.Value(), origEstablishedTimedout+1; got != want {
-		t.Errorf("got c.Stack().Stats().TCP.EstablishedTimedout = %v, want = %v", got, want)
-	}
-}
-
-func TestIncreaseWindowOnReceive(t *testing.T) {
-	// This test ensures that the endpoint sends an ack,
-	// after recv() when the window grows to more than 1 MSS.
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	const rcvBuf = 65535 * 10
-	c.CreateConnected(789, 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)
-	lastWnd := uint16(0)
-
-	for remain > len(data) {
-		c.SendPacket(data, &context.Headers{
-			SrcPort: context.TestPort,
-			DstPort: c.Port,
-			Flags:   header.TCPFlagAck,
-			SeqNum:  seqnum.Value(790 + sent),
-			AckNum:  c.IRS.Add(1),
-			RcvWnd:  30000,
-		})
-		sent += len(data)
-		remain -= len(data)
-
-		lastWnd = uint16(remain)
-		if remain > 0xffff {
-			lastWnd = 0xffff
-		}
-		checker.IPv4(t, c.GetPacket(),
-			checker.PayloadLen(header.TCPMinimumSize),
-			checker.TCP(
-				checker.DstPort(context.TestPort),
-				checker.SeqNum(uint32(c.IRS)+1),
-				checker.AckNum(uint32(790+sent)),
-				checker.Window(lastWnd),
-				checker.TCPFlags(header.TCPFlagAck),
-			),
-		)
-	}
-
-	if lastWnd == 0xffff || lastWnd == 0 {
-		t.Fatalf("expected small, non-zero window: %d", lastWnd)
-	}
-
-	// We now have < 1 MSS in the buffer space. Read the data! An
-	// ack should be sent in response to that. The window was not
-	// zero, but it grew to larger than MSS.
-	if _, _, err := c.EP.Read(nil); err != nil {
-		t.Fatalf("Read failed: %v", err)
-	}
-
-	if _, _, err := c.EP.Read(nil); err != nil {
-		t.Fatalf("Read failed: %v", err)
-	}
-
-	// After reading two packets, we surely crossed MSS. See the ack:
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.SeqNum(uint32(c.IRS)+1),
-			checker.AckNum(uint32(790+sent)),
-			checker.Window(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(789, 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)
-	lastWnd := uint16(0)
-
-	for remain > len(data) {
-		c.SendPacket(data, &context.Headers{
-			SrcPort: context.TestPort,
-			DstPort: c.Port,
-			Flags:   header.TCPFlagAck,
-			SeqNum:  seqnum.Value(790 + sent),
-			AckNum:  c.IRS.Add(1),
-			RcvWnd:  30000,
-		})
-		sent += len(data)
-		remain -= len(data)
-
-		lastWnd = uint16(remain)
-		if remain > 0xffff {
-			lastWnd = 0xffff
-		}
-		checker.IPv4(t, c.GetPacket(),
-			checker.PayloadLen(header.TCPMinimumSize),
-			checker.TCP(
-				checker.DstPort(context.TestPort),
-				checker.SeqNum(uint32(c.IRS)+1),
-				checker.AckNum(uint32(790+sent)),
-				checker.Window(lastWnd),
-				checker.TCPFlags(header.TCPFlagAck),
-			),
-		)
-	}
-
-	if lastWnd == 0xffff || lastWnd == 0 {
-		t.Fatalf("expected small, non-zero window: %d", lastWnd)
-	}
-
-	// 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)
-
-	// After reading two packets, we surely crossed MSS. See the ack:
-	checker.IPv4(t, c.GetPacket(),
-		checker.PayloadLen(header.TCPMinimumSize),
-		checker.TCP(
-			checker.DstPort(context.TestPort),
-			checker.SeqNum(uint32(c.IRS)+1),
-			checker.AckNum(uint32(790+sent)),
-			checker.Window(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
-	if err := c.EP.SetSockOpt(tcpip.TCPDeferAcceptOption(tcpDeferAccept)); err != nil {
-		t.Fatalf("c.EP.SetSockOpt(TCPDeferAcceptOption(%s) failed: %v", tcpDeferAccept, err)
-	}
-
-	irs, iss := executeHandshake(t, c, context.TestPort, false /* synCookiesInUse */)
-
-	if _, _, err := c.EP.Accept(); err != tcpip.ErrWouldBlock {
-		t.Fatalf("c.EP.Accept() returned unexpected error got: %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.SeqNum(uint32(iss+1)),
-		checker.AckNum(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()
-	if err != nil {
-		t.Fatalf("c.EP.Accept() returned unexpected error got: %v, 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.SeqNum(uint32(iss+1)),
-		checker.AckNum(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
-	if err := c.EP.SetSockOpt(tcpip.TCPDeferAcceptOption(tcpDeferAccept)); err != nil {
-		t.Fatalf("c.EP.SetSockOpt(TCPDeferAcceptOption(%s) failed: %v", tcpDeferAccept, err)
-	}
-
-	irs, iss := executeHandshake(t, c, context.TestPort, false /* synCookiesInUse */)
-
-	if _, _, err := c.EP.Accept(); err != tcpip.ErrWouldBlock {
-		t.Fatalf("c.EP.Accept() returned unexpected error got: %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.AckNum(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.SeqNum(uint32(iss+1)),
-		checker.AckNum(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()
-	if err != nil {
-		t.Fatalf("c.EP.Accept() returned unexpected error got: %v, 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.SeqNum(uint32(iss+1)),
-		checker.AckNum(uint32(irs+5))))
-}
-
-func TestResetDuringClose(t *testing.T) {
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	iss := seqnum.Value(789)
-	c.CreateConnected(iss, 30000, -1 /* epRecvBuf */)
-	// Send some data to make sure there is some unread
-	// data to trigger a reset on c.Close.
-	irs := c.IRS
-	c.SendPacket([]byte{1, 2, 3, 4}, &context.Headers{
-		SrcPort: context.TestPort,
-		DstPort: c.Port,
-		Flags:   header.TCPFlagAck,
-		SeqNum:  iss.Add(1),
-		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.SeqNum(uint32(irs.Add(1))),
-		checker.AckNum(uint32(iss.Add(5)))))
-
-	// 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(5),
-			AckNum:  c.IRS.Add(5),
-			RcvWnd:  30000,
-			Flags:   header.TCPFlagRst,
-		})
-	}()
-
-	wg.Add(1)
-	go func() {
-		defer wg.Done()
-		c.EP.Close()
-	}()
-
-	wg.Wait()
-}
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 a641e95..0000000
--- a/pkg/tcpip/transport/tcp/tcp_timestamp_test.go
+++ /dev/null
@@ -1,295 +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"
-
-	"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/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++ {
-		got, _, err := c.EP.Read(nil)
-		if err != nil {
-			t.Fatalf("Unexpected error from Read: %v", err)
-		}
-		if want := 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) {
-	savedSynCountThreshold := tcp.SynRcvdCountThreshold
-	defer func() {
-		tcp.SynRcvdCountThreshold = savedSynCountThreshold
-	}()
-
-	if cookieEnabled {
-		tcp.SynRcvdCountThreshold = 0
-	}
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	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}
-	view := buffer.NewView(len(data))
-	copy(view, data)
-
-	if _, _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Unexpected error from Write: %v", 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.SeqNum(uint32(c.IRS)+1),
-			checker.AckNum(790),
-			checker.Window(wndSize),
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(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.
-		{false, 5, 0x8000}, // DefaultReceiveBufferSize is 1MB >> 5.
-	}
-	for _, tc := range testCases {
-		timeStampEnabledAccept(t, tc.cookieEnabled, tc.wndScale, tc.wndSize)
-	}
-}
-
-func timeStampDisabledAccept(t *testing.T, cookieEnabled bool, wndScale int, wndSize uint16) {
-	savedSynCountThreshold := tcp.SynRcvdCountThreshold
-	defer func() {
-		tcp.SynRcvdCountThreshold = savedSynCountThreshold
-	}()
-	if cookieEnabled {
-		tcp.SynRcvdCountThreshold = 0
-	}
-
-	c := context.New(t, defaultMTU)
-	defer c.Cleanup()
-
-	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}
-	view := buffer.NewView(len(data))
-	copy(view, data)
-
-	if _, _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil {
-		t.Fatalf("Unexpected error from Write: %v", 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.SeqNum(uint32(c.IRS)+1),
-			checker.AckNum(790),
-			checker.Window(wndSize),
-			checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(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.
-		{false, 5, 0x8000}, // DefaultReceiveBufferSize is 1MB >> 5.
-	}
-	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.
-	got, _, err := c.EP.Read(nil)
-	if err != nil {
-		t.Fatalf("Unexpected error from Read: %v", err)
-	}
-	if want := data; bytes.Compare(got, want) != 0 {
-		t.Fatalf("Data is different: got: %v, want: %v", got, want)
-	}
-}
diff --git a/pkg/tcpip/transport/udp/udp_packet_list.go b/pkg/tcpip/transport/udp/udp_packet_list.go
new file mode 100755
index 0000000..2ae846e
--- /dev/null
+++ b/pkg/tcpip/transport/udp/udp_packet_list.go
@@ -0,0 +1,186 @@
+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.
+func (l *udpPacketList) Empty() bool {
+	return l.head == nil
+}
+
+// Front returns the first element of list l or nil.
+func (l *udpPacketList) Front() *udpPacket {
+	return l.head
+}
+
+// Back returns the last element of list l or nil.
+func (l *udpPacketList) Back() *udpPacket {
+	return l.tail
+}
+
+// PushFront inserts the element e at the front of list l.
+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.
+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.
+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.
+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.
+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.
+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 {
+		l.head = next
+	}
+
+	if next != nil {
+		udpPacketElementMapper{}.linkerFor(next).SetPrev(prev)
+	} else {
+		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.
+func (e *udpPacketEntry) Next() *udpPacket {
+	return e.next
+}
+
+// Prev returns the entry that precedes e in the list.
+func (e *udpPacketEntry) Prev() *udpPacket {
+	return e.prev
+}
+
+// SetNext assigns 'entry' as the entry that follows e in the list.
+func (e *udpPacketEntry) SetNext(elem *udpPacket) {
+	e.next = elem
+}
+
+// SetPrev assigns 'entry' as the entry that precedes e in the list.
+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 100755
index 0000000..e8ab820
--- /dev/null
+++ b/pkg/tcpip/transport/udp/udp_state_autogen.go
@@ -0,0 +1,146 @@
+// automatically generated by stateify.
+
+package udp
+
+import (
+	"gvisor.dev/gvisor/pkg/state"
+	"gvisor.dev/gvisor/pkg/tcpip/buffer"
+)
+
+func (x *udpPacket) beforeSave() {}
+func (x *udpPacket) save(m state.Map) {
+	x.beforeSave()
+	var data buffer.VectorisedView = x.saveData()
+	m.SaveValue("data", data)
+	m.Save("udpPacketEntry", &x.udpPacketEntry)
+	m.Save("senderAddress", &x.senderAddress)
+	m.Save("packetInfo", &x.packetInfo)
+	m.Save("timestamp", &x.timestamp)
+	m.Save("tos", &x.tos)
+}
+
+func (x *udpPacket) afterLoad() {}
+func (x *udpPacket) load(m state.Map) {
+	m.Load("udpPacketEntry", &x.udpPacketEntry)
+	m.Load("senderAddress", &x.senderAddress)
+	m.Load("packetInfo", &x.packetInfo)
+	m.Load("timestamp", &x.timestamp)
+	m.Load("tos", &x.tos)
+	m.LoadValue("data", new(buffer.VectorisedView), func(y interface{}) { x.loadData(y.(buffer.VectorisedView)) })
+}
+
+func (x *endpoint) save(m state.Map) {
+	x.beforeSave()
+	var rcvBufSizeMax int = x.saveRcvBufSizeMax()
+	m.SaveValue("rcvBufSizeMax", rcvBufSizeMax)
+	m.Save("TransportEndpointInfo", &x.TransportEndpointInfo)
+	m.Save("waiterQueue", &x.waiterQueue)
+	m.Save("uniqueID", &x.uniqueID)
+	m.Save("rcvReady", &x.rcvReady)
+	m.Save("rcvList", &x.rcvList)
+	m.Save("rcvBufSize", &x.rcvBufSize)
+	m.Save("rcvClosed", &x.rcvClosed)
+	m.Save("sndBufSize", &x.sndBufSize)
+	m.Save("state", &x.state)
+	m.Save("dstPort", &x.dstPort)
+	m.Save("v6only", &x.v6only)
+	m.Save("ttl", &x.ttl)
+	m.Save("multicastTTL", &x.multicastTTL)
+	m.Save("multicastAddr", &x.multicastAddr)
+	m.Save("multicastNICID", &x.multicastNICID)
+	m.Save("multicastLoop", &x.multicastLoop)
+	m.Save("reusePort", &x.reusePort)
+	m.Save("bindToDevice", &x.bindToDevice)
+	m.Save("broadcast", &x.broadcast)
+	m.Save("boundBindToDevice", &x.boundBindToDevice)
+	m.Save("boundPortFlags", &x.boundPortFlags)
+	m.Save("sendTOS", &x.sendTOS)
+	m.Save("receiveTOS", &x.receiveTOS)
+	m.Save("receiveTClass", &x.receiveTClass)
+	m.Save("receiveIPPacketInfo", &x.receiveIPPacketInfo)
+	m.Save("shutdownFlags", &x.shutdownFlags)
+	m.Save("multicastMemberships", &x.multicastMemberships)
+	m.Save("effectiveNetProtos", &x.effectiveNetProtos)
+	m.Save("owner", &x.owner)
+}
+
+func (x *endpoint) load(m state.Map) {
+	m.Load("TransportEndpointInfo", &x.TransportEndpointInfo)
+	m.Load("waiterQueue", &x.waiterQueue)
+	m.Load("uniqueID", &x.uniqueID)
+	m.Load("rcvReady", &x.rcvReady)
+	m.Load("rcvList", &x.rcvList)
+	m.Load("rcvBufSize", &x.rcvBufSize)
+	m.Load("rcvClosed", &x.rcvClosed)
+	m.Load("sndBufSize", &x.sndBufSize)
+	m.Load("state", &x.state)
+	m.Load("dstPort", &x.dstPort)
+	m.Load("v6only", &x.v6only)
+	m.Load("ttl", &x.ttl)
+	m.Load("multicastTTL", &x.multicastTTL)
+	m.Load("multicastAddr", &x.multicastAddr)
+	m.Load("multicastNICID", &x.multicastNICID)
+	m.Load("multicastLoop", &x.multicastLoop)
+	m.Load("reusePort", &x.reusePort)
+	m.Load("bindToDevice", &x.bindToDevice)
+	m.Load("broadcast", &x.broadcast)
+	m.Load("boundBindToDevice", &x.boundBindToDevice)
+	m.Load("boundPortFlags", &x.boundPortFlags)
+	m.Load("sendTOS", &x.sendTOS)
+	m.Load("receiveTOS", &x.receiveTOS)
+	m.Load("receiveTClass", &x.receiveTClass)
+	m.Load("receiveIPPacketInfo", &x.receiveIPPacketInfo)
+	m.Load("shutdownFlags", &x.shutdownFlags)
+	m.Load("multicastMemberships", &x.multicastMemberships)
+	m.Load("effectiveNetProtos", &x.effectiveNetProtos)
+	m.Load("owner", &x.owner)
+	m.LoadValue("rcvBufSizeMax", new(int), func(y interface{}) { x.loadRcvBufSizeMax(y.(int)) })
+	m.AfterLoad(x.afterLoad)
+}
+
+func (x *multicastMembership) beforeSave() {}
+func (x *multicastMembership) save(m state.Map) {
+	x.beforeSave()
+	m.Save("nicID", &x.nicID)
+	m.Save("multicastAddr", &x.multicastAddr)
+}
+
+func (x *multicastMembership) afterLoad() {}
+func (x *multicastMembership) load(m state.Map) {
+	m.Load("nicID", &x.nicID)
+	m.Load("multicastAddr", &x.multicastAddr)
+}
+
+func (x *udpPacketList) beforeSave() {}
+func (x *udpPacketList) save(m state.Map) {
+	x.beforeSave()
+	m.Save("head", &x.head)
+	m.Save("tail", &x.tail)
+}
+
+func (x *udpPacketList) afterLoad() {}
+func (x *udpPacketList) load(m state.Map) {
+	m.Load("head", &x.head)
+	m.Load("tail", &x.tail)
+}
+
+func (x *udpPacketEntry) beforeSave() {}
+func (x *udpPacketEntry) save(m state.Map) {
+	x.beforeSave()
+	m.Save("next", &x.next)
+	m.Save("prev", &x.prev)
+}
+
+func (x *udpPacketEntry) afterLoad() {}
+func (x *udpPacketEntry) load(m state.Map) {
+	m.Load("next", &x.next)
+	m.Load("prev", &x.prev)
+}
+
+func init() {
+	state.Register("pkg/tcpip/transport/udp.udpPacket", (*udpPacket)(nil), state.Fns{Save: (*udpPacket).save, Load: (*udpPacket).load})
+	state.Register("pkg/tcpip/transport/udp.endpoint", (*endpoint)(nil), state.Fns{Save: (*endpoint).save, Load: (*endpoint).load})
+	state.Register("pkg/tcpip/transport/udp.multicastMembership", (*multicastMembership)(nil), state.Fns{Save: (*multicastMembership).save, Load: (*multicastMembership).load})
+	state.Register("pkg/tcpip/transport/udp.udpPacketList", (*udpPacketList)(nil), state.Fns{Save: (*udpPacketList).save, Load: (*udpPacketList).load})
+	state.Register("pkg/tcpip/transport/udp.udpPacketEntry", (*udpPacketEntry)(nil), state.Fns{Save: (*udpPacketEntry).save, Load: (*udpPacketEntry).load})
+}
diff --git a/pkg/tcpip/transport/udp/udp_test.go b/pkg/tcpip/transport/udp/udp_test.go
deleted file mode 100644
index 0905726..0000000
--- a/pkg/tcpip/transport/udp/udp_test.go
+++ /dev/null
@@ -1,1802 +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"
-	"math/rand"
-	"testing"
-	"time"
-
-	"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/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           = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"
-	testV6Addr            = "\x00\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
-	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
-)
-
-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"
-	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
-		}
-	}
-	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:
-		return ipv6.ProtocolNumber
-	case unicastV4, multicastV4, broadcast:
-		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:
-		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:
-		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:
-		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:
-		return false
-	default:
-		panic(fmt.Sprintf("invalid testFlow given: %d", flow))
-	}
-}
-
-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.NetworkProtocol{ipv4.NewProtocol(), ipv6.NewProtocol()},
-		TransportProtocols: []stack.TransportProtocol{udp.NewProtocol()},
-	})
-}
-
-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: %v", err)
-	}
-
-	if err := s.AddAddress(1, ipv4.ProtocolNumber, stackAddr); err != nil {
-		t.Fatalf("AddAddress failed: %v", err)
-	}
-
-	if err := s.AddAddress(1, ipv6.ProtocolNumber, stackV6Addr); err != nil {
-		t.Fatalf("AddAddress failed: %v", 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() {
-		if err := c.ep.SetSockOptBool(tcpip.V6OnlyOption, true); err != nil {
-			c.t.Fatalf("SetSockOpt failed: %v", err)
-		}
-	} else if flow.isBroadcast() {
-		if err := c.ep.SetSockOpt(tcpip.BroadcastOption(1)); err != nil {
-			c.t.Fatal("SetSockOpt failed:", err)
-		}
-	}
-}
-
-// 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, _ := context.WithTimeout(context.Background(), 2*time.Second)
-	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())
-	}
-
-	hdr := p.Pkt.Header.View()
-	b := append(hdr[:len(hdr):len(hdr)], p.Pkt.Data.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.
-func (c *testContext) injectPacket(flow testFlow, payload []byte) {
-	c.t.Helper()
-
-	h := flow.header4Tuple(incoming)
-	if flow.isV4() {
-		c.injectV4Packet(payload, &h, true /* valid */)
-	} else {
-		c.injectV6Packet(payload, &h, true /* valid */)
-	}
-}
-
-// injectV6Packet creates a V6 test packet with the given payload and header
-// values, and injects it into the link endpoint. valid indicates if the
-// caller intends to inject a packet with a valid or an invalid UDP header.
-// We can invalidate the header by corrupting the UDP payload length.
-func (c *testContext) injectV6Packet(payload []byte, h *header4Tuple, valid bool) {
-	// 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)),
-		NextHeader:    uint8(udp.ProtocolNumber),
-		HopLimit:      65,
-		SrcAddr:       h.srcAddr.Addr,
-		DstAddr:       h.dstAddr.Addr,
-	})
-
-	// Initialize the UDP header.
-	u := header.UDP(buf[header.IPv6MinimumSize:])
-	l := uint16(header.UDPMinimumSize + len(payload))
-	if !valid {
-		// Change the UDP payload length to corrupt the header
-		// as requested by the caller.
-		l++
-	}
-	u.Encode(&header.UDPFields{
-		SrcPort: h.srcAddr.Port,
-		DstPort: h.dstAddr.Port,
-		Length:  l,
-	})
-
-	// 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))
-
-	// Inject packet.
-	c.linkEP.InjectInbound(ipv6.ProtocolNumber, stack.PacketBuffer{
-		Data:            buf.ToVectorisedView(),
-		NetworkHeader:   buffer.View(ip),
-		TransportHeader: buffer.View(u),
-	})
-}
-
-// injectV4Packet creates a V4 test packet with the given payload and header
-// values, and injects it into the link endpoint. valid indicates if the
-// caller intends to inject a packet with a valid or an invalid UDP header.
-// We can invalidate the header by corrupting the UDP payload length.
-func (c *testContext) injectV4Packet(payload []byte, h *header4Tuple, valid bool) {
-	// 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{
-		IHL:         header.IPv4MinimumSize,
-		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))
-
-	// Inject packet.
-
-	c.linkEP.InjectInbound(ipv4.ProtocolNumber, stack.PacketBuffer{
-		Data:            buf.ToVectorisedView(),
-		NetworkHeader:   buffer.View(ip),
-		TransportHeader: buffer.View(u),
-	})
-}
-
-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.NetworkProtocol{ipv4.NewProtocol()},
-		TransportProtocols: []stack.TransportProtocol{udp.NewProtocol()}})
-
-	ep, err := s.NewEndpoint(udp.ProtocolNumber, ipv4.ProtocolNumber, &waiter.Queue{})
-	if err != nil {
-		t.Fatalf("NewEndpoint failed; %v", 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: %v", 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      tcpip.BindToDeviceOption
-	}{
-		{"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 := tcpip.BindToDeviceOption(*testAction.setBindToDevice)
-				if gotErr, wantErr := ep.SetSockOpt(bindToDevice), testAction.setBindToDeviceError; gotErr != wantErr {
-					t.Errorf("SetSockOpt(%v) got %v, want %v", bindToDevice, gotErr, wantErr)
-				}
-			}
-			bindToDevice := tcpip.BindToDeviceOption(88888)
-			if err := ep.GetSockOpt(&bindToDevice); err != nil {
-				t.Errorf("GetSockOpt got %v, want %v", err, nil)
-			}
-			if got, want := bindToDevice, testAction.getBindToDevice; got != want {
-				t.Errorf("bindToDevice got %d, want %d", got, want)
-			}
-		})
-	}
-}
-
-// 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)
-
-	// 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 addr tcpip.FullAddress
-	v, cm, err := c.ep.Read(&addr)
-	if err == tcpip.ErrWouldBlock {
-		// Wait for data to become available.
-		select {
-		case <-ch:
-			v, cm, err = c.ep.Read(&addr)
-
-		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", addr.Addr)
-	}
-
-	// Check the peer address.
-	h := flow.header4Tuple(incoming)
-	if addr.Addr != h.srcAddr.Addr {
-		c.t.Fatalf("unexpected remote address: got %s, want %s", addr.Addr, h.srcAddr)
-	}
-
-	// Check the payload.
-	if !bytes.Equal(payload, v) {
-		c.t.Fatalf("bad payload: got %x, want %x", v, payload)
-	}
-
-	// Run any checkers against the ControlMessages.
-	for _, f := range checkers {
-		f(c.t, cm)
-	}
-
-	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: %v", 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: %v", err)
-	}
-
-	addr, err := c.ep.GetLocalAddress()
-	if err != nil {
-		t.Fatalf("GetLocalAddress failed: %v", 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: %v", err)
-		}
-		defer ep.Close()
-		if got, want := ep.Bind(addr), tcpip.ErrPortInUse; got != want {
-			t.Fatalf("got ep.Bind(...) = %v, want = %v", got, want)
-		}
-	}
-
-	func() {
-		ep, err := c.s.NewEndpoint(udp.ProtocolNumber, ipv4.ProtocolNumber, &c.wq)
-		if err != nil {
-			t.Fatalf("NewEndpoint failed: %v", 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.
-		if got, want := ep.Bind(tcpip.FullAddress{Port: addr.Port}), tcpip.ErrPortInUse; got != want {
-			t.Fatalf("got ep.Bind(...) = %v, want = %v", got, want)
-		}
-		// 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: %v", 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: %v", err)
-		}
-		defer ep.Close()
-		if err := ep.Bind(tcpip.FullAddress{Port: addr.Port}); err != nil {
-			t.Fatalf("ep.Bind(...) failed: %v", 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: %v", 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: %v", 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: %v", 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: %v", 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.NetworkProtocol{ipv4.NewProtocol(), ipv6.NewProtocol()},
-				TransportProtocols: []stack.TransportProtocol{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
-
-			c.injectV4Packet(payload, &h, true /* valid */)
-
-			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(nil); err != tt.wantErr {
-				t.Errorf("c.ep.Read() got error %v, want %v", 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: %v", 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.Fatal("SetSockOpt failed:", 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 */)
-		})
-	}
-}
-
-// 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)
-
-	payload := buffer.View(newPayload())
-	_, _, gotErr := c.ep.Write(tcpip.SlicePayload(payload), 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 testWriteInternal(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 testWriteInternal(c, flow, false, checkers...)
-}
-
-func testWriteInternal(c *testContext, flow testFlow, setDest bool, checkers ...checker.NetworkChecker) uint16 {
-	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},
-		}
-	}
-	payload := buffer.View(newPayload())
-	n, _, err := c.ep.Write(tcpip.SlicePayload(payload), writeOpts)
-	if err != nil {
-		c.t.Fatalf("Write failed: %v", 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)
-	// 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: %v", 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: %v", 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: %v", 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: %v", 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: %v", 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: %v", err)
-	}
-
-	testWriteWithoutDestination(c, unicastV4)
-}
-
-// 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: %v", 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 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 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.SetSockOpt(tcpip.MulticastTTLOption(multicastTTL)); err != nil {
-				c.t.Fatalf("SetSockOpt failed: %v", err)
-			}
-
-			var wantTTL uint8
-			if flow.isMulticast() {
-				wantTTL = multicastTTL
-			} else {
-				var p stack.NetworkProtocol
-				if flow.isV4() {
-					p = ipv4.NewProtocol()
-				} else {
-					p = ipv6.NewProtocol()
-				}
-				ep, err := p.NewEndpoint(0, tcpip.AddressWithPrefix{}, nil, nil, nil, stack.New(stack.Options{
-					NetworkProtocols:   []stack.NetworkProtocol{ipv4.NewProtocol(), ipv6.NewProtocol()},
-					TransportProtocols: []stack.TransportProtocol{udp.NewProtocol()},
-				}))
-				if err != nil {
-					t.Fatal(err)
-				}
-				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.SetSockOpt(tcpip.TTLOption(wantTTL)); err != nil {
-						c.t.Fatalf("SetSockOpt failed: %v", err)
-					}
-
-					var p stack.NetworkProtocol
-					if flow.isV4() {
-						p = ipv4.NewProtocol()
-					} else {
-						p = ipv6.NewProtocol()
-					}
-					ep, err := p.NewEndpoint(0, tcpip.AddressWithPrefix{}, nil, nil, nil, stack.New(stack.Options{
-						NetworkProtocols:   []stack.NetworkProtocol{ipv4.NewProtocol(), ipv6.NewProtocol()},
-						TransportProtocols: []stack.TransportProtocol{udp.NewProtocol()},
-					}))
-					if err != nil {
-						t.Fatal(err)
-					}
-					ep.Close()
-
-					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
-			var v tcpip.IPv4TOSOption
-			if err := c.ep.GetSockOpt(&v); err != nil {
-				c.t.Errorf("GetSockopt(%T) failed: %s", v, err)
-			}
-			// Test for expected default value.
-			if v != 0 {
-				c.t.Errorf("got GetSockOpt(%T) = 0x%x, want = 0x%x", v, v, 0)
-			}
-
-			if err := c.ep.SetSockOpt(tcpip.IPv4TOSOption(tos)); err != nil {
-				c.t.Errorf("SetSockOpt(%T, 0x%x) failed: %s", v, tcpip.IPv4TOSOption(tos), err)
-			}
-
-			if err := c.ep.GetSockOpt(&v); err != nil {
-				c.t.Errorf("GetSockopt(%T) failed: %s", v, err)
-			}
-
-			if want := tcpip.IPv4TOSOption(tos); v != want {
-				c.t.Errorf("got GetSockOpt(%T) = 0x%x, want = 0x%x", v, v, want)
-			}
-
-			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
-			var v tcpip.IPv6TrafficClassOption
-			if err := c.ep.GetSockOpt(&v); err != nil {
-				c.t.Errorf("GetSockopt(%T) failed: %s", v, err)
-			}
-			// Test for expected default value.
-			if v != 0 {
-				c.t.Errorf("got GetSockOpt(%T) = 0x%x, want = 0x%x", v, v, 0)
-			}
-
-			if err := c.ep.SetSockOpt(tcpip.IPv6TrafficClassOption(tClass)); err != nil {
-				c.t.Errorf("SetSockOpt(%T, 0x%x) failed: %s", v, tcpip.IPv6TrafficClassOption(tClass), err)
-			}
-
-			if err := c.ep.GetSockOpt(&v); err != nil {
-				c.t.Errorf("GetSockopt(%T) failed: %s", v, err)
-			}
-
-			if want := tcpip.IPv6TrafficClassOption(tClass); v != want {
-				c.t.Errorf("got GetSockOpt(%T) = 0x%x, want = 0x%x", v, v, want)
-			}
-
-			// The header getter for TClass is called TOS, so use that checker.
-			testWrite(c, flow, checker.TOS(tClass, 0))
-		})
-	}
-}
-
-func TestReceiveTosTClass(t *testing.T) {
-	testCases := []struct {
-		name             string
-		getReceiveOption tcpip.SockOptBool
-		tests            []testFlow
-	}{
-		{"ReceiveTosOption", tcpip.ReceiveTOSOption, []testFlow{unicastV4, broadcast}},
-		{"ReceiveTClassOption", tcpip.ReceiveTClassOption, []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)
-				option := testCase.getReceiveOption
-				name := testCase.name
-
-				// Verify that setting and reading the option works.
-				v, err := c.ep.GetSockOptBool(option)
-				if err != nil {
-					c.t.Errorf("GetSockoptBool(%s) failed: %s", name, err)
-				}
-				// Test for expected default value.
-				if v != false {
-					c.t.Errorf("got GetSockOptBool(%s) = %t, want = %t", name, v, false)
-				}
-
-				want := true
-				if err := c.ep.SetSockOptBool(option, want); err != nil {
-					c.t.Fatalf("SetSockOptBool(%s, %t) failed: %s", name, want, err)
-				}
-
-				got, err := c.ep.GetSockOptBool(option)
-				if err != nil {
-					c.t.Errorf("GetSockoptBool(%s) failed: %s", name, err)
-				}
-
-				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 option {
-				case tcpip.ReceiveTClassOption:
-					testRead(c, flow, checker.ReceiveTClass(testTOS))
-				case tcpip.ReceiveTOSOption:
-					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: %v", err)
-								}
-							}
-
-							if err := c.ep.SetSockOpt(ifoptSet); err != nil {
-								c.t.Fatalf("SetSockOpt failed: %v", err)
-							}
-
-							// Verify multicast interface addr and NIC were set correctly.
-							// Note that NIC must be 1 since this is our outgoing interface.
-							ifoptWant := tcpip.MulticastInterfaceOption{NIC: 1, InterfaceAddr: ifoptSet.InterfaceAddr}
-							var ifoptGot tcpip.MulticastInterfaceOption
-							if err := c.ep.GetSockOpt(&ifoptGot); err != nil {
-								c.t.Fatalf("GetSockOpt failed: %v", err)
-							}
-							if ifoptGot != ifoptWant {
-								c.t.Errorf("got GetSockOpt() = %#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
-	}{
-		{unicastV4, true, false},
-		{unicastV4, true, true},
-		{multicastV4, false, false},
-		{multicastV4, false, true},
-		{broadcast, false, false},
-		{broadcast, false, true},
-	}
-	for _, tc := range testCases {
-		t.Run(fmt.Sprintf("flow:%s icmpRequired:%t largePayload:%t", tc.flow, tc.icmpRequired, tc.largePayload), func(t *testing.T) {
-			payload := newPayload()
-			if tc.largePayload {
-				payload = newMinPayload(576)
-			}
-			c.injectPacket(tc.flow, payload)
-			if !tc.icmpRequired {
-				ctx, _ := context.WithTimeout(context.Background(), time.Second)
-				if p, ok := c.linkEP.ReadContext(ctx); ok {
-					t.Fatalf("unexpected packet received: %+v", p)
-				}
-				return
-			}
-
-			// ICMP required.
-			ctx, _ := context.WithTimeout(context.Background(), time.Second)
-			p, ok := c.linkEP.ReadContext(ctx)
-			if !ok {
-				t.Fatalf("packet wasn't written out")
-				return
-			}
-
-			var pkt []byte
-			pkt = append(pkt, p.Pkt.Header.View()...)
-			pkt = append(pkt, p.Pkt.Data.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)))
-
-			icmpPkt := header.ICMPv4(hdr.Payload())
-			payloadIPHeader := header.IPv4(icmpPkt.Payload())
-			wantLen := len(payload)
-			if tc.largePayload {
-				wantLen = header.IPv4MinimumProcessableDatagramSize - header.IPv4MinimumSize*2 - header.ICMPv4MinimumSize - header.UDPMinimumSize
-			}
-
-			// In case of large payloads the IP packet may be truncated. Update
-			// the length field before retrieving the udp datagram payload.
-			payloadIPHeader.SetTotalLength(uint16(wantLen + header.UDPMinimumSize + header.IPv4MinimumSize))
-
-			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
-	}{
-		{unicastV6, true, false},
-		{unicastV6, true, true},
-		{multicastV6, false, false},
-		{multicastV6, false, true},
-	}
-	for _, tc := range testCases {
-		t.Run(fmt.Sprintf("flow:%s icmpRequired:%t largePayload:%t", tc.flow, tc.icmpRequired, tc.largePayload), func(t *testing.T) {
-			payload := newPayload()
-			if tc.largePayload {
-				payload = newMinPayload(1280)
-			}
-			c.injectPacket(tc.flow, payload)
-			if !tc.icmpRequired {
-				ctx, _ := context.WithTimeout(context.Background(), time.Second)
-				if p, ok := c.linkEP.ReadContext(ctx); ok {
-					t.Fatalf("unexpected packet received: %+v", p)
-				}
-				return
-			}
-
-			// ICMP required.
-			ctx, _ := context.WithTimeout(context.Background(), time.Second)
-			p, ok := c.linkEP.ReadContext(ctx)
-			if !ok {
-				t.Fatalf("packet wasn't written out")
-				return
-			}
-
-			var pkt []byte
-			pkt = append(pkt, p.Pkt.Header.View()...)
-			pkt = append(pkt, p.Pkt.Data.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 get 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: %v", err)
-	}
-
-	payload := newPayload()
-	c.t.Helper()
-	h := unicastV6.header4Tuple(incoming)
-	c.injectV6Packet(payload, &h, false /* !valid */)
-
-	var want uint64 = 1
-	if got := c.s.Stats().UDP.MalformedPacketsReceived.Value(); got != want {
-		t.Errorf("got stats.UDP.MalformedPacketsReceived.Value() = %v, want = %v", got, want)
-	}
-	if got := c.ep.Stats().(*tcpip.TransportEndpointStats).ReceiveErrors.MalformedPacketsReceived.Value(); got != want {
-		t.Errorf("got EP Stats.ReceiveErrors.MalformedPacketsReceived stats = %v, want = %v", 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: %v", err)
-	}
-
-	if err := c.ep.Connect(tcpip.FullAddress{Addr: testV6Addr, Port: testPort}); err != nil {
-		c.t.Fatalf("Connect failed: %v", err)
-	}
-
-	if err := c.ep.Shutdown(tcpip.ShutdownRead); err != nil {
-		t.Fatalf("Shutdown failed: %v", 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: %v", err)
-	}
-
-	if err := c.ep.Shutdown(tcpip.ShutdownWrite); err != nil {
-		t.Fatalf("Shutdown failed: %v", 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 {
-	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.ErrNoLinkAddress:
-		want.SendErrors.NoLinkAddr.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 {
-	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)
-	}
-}
diff --git a/pkg/waiter/waiter_list.go b/pkg/waiter/waiter_list.go
new file mode 100755
index 0000000..07950fa
--- /dev/null
+++ b/pkg/waiter/waiter_list.go
@@ -0,0 +1,186 @@
+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.
+func (l *waiterList) Empty() bool {
+	return l.head == nil
+}
+
+// Front returns the first element of list l or nil.
+func (l *waiterList) Front() *Entry {
+	return l.head
+}
+
+// Back returns the last element of list l or nil.
+func (l *waiterList) Back() *Entry {
+	return l.tail
+}
+
+// PushFront inserts the element e at the front of list l.
+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.
+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.
+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.
+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.
+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.
+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 {
+		l.head = next
+	}
+
+	if next != nil {
+		waiterElementMapper{}.linkerFor(next).SetPrev(prev)
+	} else {
+		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.
+func (e *waiterEntry) Next() *Entry {
+	return e.next
+}
+
+// Prev returns the entry that precedes e in the list.
+func (e *waiterEntry) Prev() *Entry {
+	return e.prev
+}
+
+// SetNext assigns 'entry' as the entry that follows e in the list.
+func (e *waiterEntry) SetNext(elem *Entry) {
+	e.next = elem
+}
+
+// SetPrev assigns 'entry' as the entry that precedes e in the list.
+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 100755
index 0000000..93acec0
--- /dev/null
+++ b/pkg/waiter/waiter_state_autogen.go
@@ -0,0 +1,69 @@
+// automatically generated by stateify.
+
+package waiter
+
+import (
+	"gvisor.dev/gvisor/pkg/state"
+)
+
+func (x *Entry) beforeSave() {}
+func (x *Entry) save(m state.Map) {
+	x.beforeSave()
+	m.Save("Context", &x.Context)
+	m.Save("Callback", &x.Callback)
+	m.Save("mask", &x.mask)
+	m.Save("waiterEntry", &x.waiterEntry)
+}
+
+func (x *Entry) afterLoad() {}
+func (x *Entry) load(m state.Map) {
+	m.Load("Context", &x.Context)
+	m.Load("Callback", &x.Callback)
+	m.Load("mask", &x.mask)
+	m.Load("waiterEntry", &x.waiterEntry)
+}
+
+func (x *Queue) beforeSave() {}
+func (x *Queue) save(m state.Map) {
+	x.beforeSave()
+	if !state.IsZeroValue(x.list) {
+		m.Failf("list is %v, expected zero", x.list)
+	}
+}
+
+func (x *Queue) afterLoad() {}
+func (x *Queue) load(m state.Map) {
+}
+
+func (x *waiterList) beforeSave() {}
+func (x *waiterList) save(m state.Map) {
+	x.beforeSave()
+	m.Save("head", &x.head)
+	m.Save("tail", &x.tail)
+}
+
+func (x *waiterList) afterLoad() {}
+func (x *waiterList) load(m state.Map) {
+	m.Load("head", &x.head)
+	m.Load("tail", &x.tail)
+}
+
+func (x *waiterEntry) beforeSave() {}
+func (x *waiterEntry) save(m state.Map) {
+	x.beforeSave()
+	m.Save("next", &x.next)
+	m.Save("prev", &x.prev)
+}
+
+func (x *waiterEntry) afterLoad() {}
+func (x *waiterEntry) load(m state.Map) {
+	m.Load("next", &x.next)
+	m.Load("prev", &x.prev)
+}
+
+func init() {
+	state.Register("pkg/waiter.Entry", (*Entry)(nil), state.Fns{Save: (*Entry).save, Load: (*Entry).load})
+	state.Register("pkg/waiter.Queue", (*Queue)(nil), state.Fns{Save: (*Queue).save, Load: (*Queue).load})
+	state.Register("pkg/waiter.waiterList", (*waiterList)(nil), state.Fns{Save: (*waiterList).save, Load: (*waiterList).load})
+	state.Register("pkg/waiter.waiterEntry", (*waiterEntry)(nil), state.Fns{Save: (*waiterEntry).save, Load: (*waiterEntry).load})
+}
diff --git a/pkg/waiter/waiter_test.go b/pkg/waiter/waiter_test.go
deleted file mode 100644
index c1b94a4..0000000
--- a/pkg/waiter/waiter_test.go
+++ /dev/null
@@ -1,192 +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)
-}
-
-// Callback implements EntryCallback.Callback.
-func (c *callbackStub) Callback(e *Entry) {
-	c.f(e)
-}
-
-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) { 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) { 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) {
-				cnt++
-				if entry != &e {
-					t.Errorf("entry = %p, want %p", entry, &e)
-				}
-			}}
-
-			// 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) {
-			atomic.AddInt32(&cnt, 1)
-			if entry != &e {
-				t.Errorf("entry = %p, want %p", entry, &e)
-			}
-		}}
-
-		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)
-	}
-}
