summaryrefslogtreecommitdiffhomepage
path: root/pkg/tcpip/stack
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/tcpip/stack')
-rw-r--r--pkg/tcpip/stack/neighbor_cache_test.go266
-rw-r--r--pkg/tcpip/stack/neighbor_entry.go22
-rw-r--r--pkg/tcpip/stack/neighbor_entry_test.go220
-rw-r--r--pkg/tcpip/stack/nud.go76
-rw-r--r--pkg/tcpip/stack/nud_test.go15
-rw-r--r--pkg/tcpip/stack/stack_test.go2
6 files changed, 297 insertions, 304 deletions
diff --git a/pkg/tcpip/stack/neighbor_cache_test.go b/pkg/tcpip/stack/neighbor_cache_test.go
index 90881169d..7de25fe37 100644
--- a/pkg/tcpip/stack/neighbor_cache_test.go
+++ b/pkg/tcpip/stack/neighbor_cache_test.go
@@ -293,10 +293,10 @@ func addReachableEntryWithRemoved(nudDisp *testNUDDispatcher, clock *faketime.Ma
EventType: entryTestRemoved,
NICID: 1,
Entry: NeighborEntry{
- Addr: removedEntry.Addr,
- LinkAddr: removedEntry.LinkAddr,
- State: Reachable,
- UpdatedAtNanos: clock.NowNanoseconds(),
+ Addr: removedEntry.Addr,
+ LinkAddr: removedEntry.LinkAddr,
+ State: Reachable,
+ UpdatedAt: clock.Now(),
},
})
}
@@ -305,10 +305,10 @@ func addReachableEntryWithRemoved(nudDisp *testNUDDispatcher, clock *faketime.Ma
EventType: entryTestAdded,
NICID: 1,
Entry: NeighborEntry{
- Addr: entry.Addr,
- LinkAddr: "",
- State: Incomplete,
- UpdatedAtNanos: clock.NowNanoseconds(),
+ Addr: entry.Addr,
+ LinkAddr: "",
+ State: Incomplete,
+ UpdatedAt: clock.Now(),
},
})
@@ -339,10 +339,10 @@ func addReachableEntryWithRemoved(nudDisp *testNUDDispatcher, clock *faketime.Ma
EventType: entryTestChanged,
NICID: 1,
Entry: NeighborEntry{
- Addr: entry.Addr,
- LinkAddr: entry.LinkAddr,
- State: Reachable,
- UpdatedAtNanos: clock.NowNanoseconds(),
+ Addr: entry.Addr,
+ LinkAddr: entry.LinkAddr,
+ State: Reachable,
+ UpdatedAt: clock.Now(),
},
},
}
@@ -411,10 +411,10 @@ func TestNeighborCacheRemoveEntry(t *testing.T) {
EventType: entryTestRemoved,
NICID: 1,
Entry: NeighborEntry{
- Addr: entry.Addr,
- LinkAddr: entry.LinkAddr,
- State: Reachable,
- UpdatedAtNanos: clock.NowNanoseconds(),
+ Addr: entry.Addr,
+ LinkAddr: entry.LinkAddr,
+ State: Reachable,
+ UpdatedAt: clock.Now(),
},
},
}
@@ -492,12 +492,12 @@ func (c *testContext) overflowCache(opts overflowOptions) error {
if !ok {
return fmt.Errorf("got c.linkRes.entries.entry(%d) = _, false, want = true", i)
}
- durationReachableNanos := int64(c.linkRes.entries.size()-i-1) * typicalLatency.Nanoseconds()
+ durationReachableNanos := time.Duration(c.linkRes.entries.size()-i-1) * typicalLatency
wantEntry := NeighborEntry{
- Addr: entry.Addr,
- LinkAddr: entry.LinkAddr,
- State: Reachable,
- UpdatedAtNanos: c.clock.NowNanoseconds() - durationReachableNanos,
+ Addr: entry.Addr,
+ LinkAddr: entry.LinkAddr,
+ State: Reachable,
+ UpdatedAt: c.clock.Now().Add(-durationReachableNanos),
}
wantUnorderedEntries = append(wantUnorderedEntries, wantEntry)
}
@@ -563,10 +563,10 @@ func TestNeighborCacheRemoveEntryThenOverflow(t *testing.T) {
EventType: entryTestRemoved,
NICID: 1,
Entry: NeighborEntry{
- Addr: entry.Addr,
- LinkAddr: entry.LinkAddr,
- State: Reachable,
- UpdatedAtNanos: c.clock.NowNanoseconds(),
+ Addr: entry.Addr,
+ LinkAddr: entry.LinkAddr,
+ State: Reachable,
+ UpdatedAt: c.clock.Now(),
},
},
}
@@ -608,10 +608,10 @@ func TestNeighborCacheDuplicateStaticEntryWithSameLinkAddress(t *testing.T) {
EventType: entryTestAdded,
NICID: 1,
Entry: NeighborEntry{
- Addr: entry.Addr,
- LinkAddr: staticLinkAddr,
- State: Static,
- UpdatedAtNanos: c.clock.NowNanoseconds(),
+ Addr: entry.Addr,
+ LinkAddr: staticLinkAddr,
+ State: Static,
+ UpdatedAt: c.clock.Now(),
},
},
}
@@ -655,10 +655,10 @@ func TestNeighborCacheDuplicateStaticEntryWithDifferentLinkAddress(t *testing.T)
EventType: entryTestAdded,
NICID: 1,
Entry: NeighborEntry{
- Addr: entry.Addr,
- LinkAddr: staticLinkAddr,
- State: Static,
- UpdatedAtNanos: c.clock.NowNanoseconds(),
+ Addr: entry.Addr,
+ LinkAddr: staticLinkAddr,
+ State: Static,
+ UpdatedAt: c.clock.Now(),
},
},
}
@@ -681,10 +681,10 @@ func TestNeighborCacheDuplicateStaticEntryWithDifferentLinkAddress(t *testing.T)
EventType: entryTestChanged,
NICID: 1,
Entry: NeighborEntry{
- Addr: entry.Addr,
- LinkAddr: staticLinkAddr,
- State: Static,
- UpdatedAtNanos: c.clock.NowNanoseconds(),
+ Addr: entry.Addr,
+ LinkAddr: staticLinkAddr,
+ State: Static,
+ UpdatedAt: c.clock.Now(),
},
},
}
@@ -725,10 +725,10 @@ func TestNeighborCacheRemoveStaticEntryThenOverflow(t *testing.T) {
EventType: entryTestAdded,
NICID: 1,
Entry: NeighborEntry{
- Addr: entry.Addr,
- LinkAddr: staticLinkAddr,
- State: Static,
- UpdatedAtNanos: c.clock.NowNanoseconds(),
+ Addr: entry.Addr,
+ LinkAddr: staticLinkAddr,
+ State: Static,
+ UpdatedAt: c.clock.Now(),
},
},
}
@@ -750,10 +750,10 @@ func TestNeighborCacheRemoveStaticEntryThenOverflow(t *testing.T) {
EventType: entryTestRemoved,
NICID: 1,
Entry: NeighborEntry{
- Addr: entry.Addr,
- LinkAddr: staticLinkAddr,
- State: Static,
- UpdatedAtNanos: c.clock.NowNanoseconds(),
+ Addr: entry.Addr,
+ LinkAddr: staticLinkAddr,
+ State: Static,
+ UpdatedAt: c.clock.Now(),
},
},
}
@@ -806,20 +806,20 @@ func TestNeighborCacheOverwriteWithStaticEntryThenOverflow(t *testing.T) {
EventType: entryTestRemoved,
NICID: 1,
Entry: NeighborEntry{
- Addr: entry.Addr,
- LinkAddr: entry.LinkAddr,
- State: Reachable,
- UpdatedAtNanos: c.clock.NowNanoseconds(),
+ Addr: entry.Addr,
+ LinkAddr: entry.LinkAddr,
+ State: Reachable,
+ UpdatedAt: c.clock.Now(),
},
},
{
EventType: entryTestAdded,
NICID: 1,
Entry: NeighborEntry{
- Addr: entry.Addr,
- LinkAddr: staticLinkAddr,
- State: Static,
- UpdatedAtNanos: c.clock.NowNanoseconds(),
+ Addr: entry.Addr,
+ LinkAddr: staticLinkAddr,
+ State: Static,
+ UpdatedAt: c.clock.Now(),
},
},
}
@@ -836,10 +836,10 @@ func TestNeighborCacheOverwriteWithStaticEntryThenOverflow(t *testing.T) {
startAtEntryIndex: 1,
wantStaticEntries: []NeighborEntry{
{
- Addr: entry.Addr,
- LinkAddr: staticLinkAddr,
- State: Static,
- UpdatedAtNanos: c.clock.NowNanoseconds(),
+ Addr: entry.Addr,
+ LinkAddr: staticLinkAddr,
+ State: Static,
+ UpdatedAt: c.clock.Now(),
},
},
}
@@ -867,10 +867,10 @@ func TestNeighborCacheAddStaticEntryThenOverflow(t *testing.T) {
t.Errorf("unexpected error from c.linkRes.neigh.entry(%s, \"\", nil): %s", entry.Addr, err)
}
want := NeighborEntry{
- Addr: entry.Addr,
- LinkAddr: entry.LinkAddr,
- State: Static,
- UpdatedAtNanos: c.clock.NowNanoseconds(),
+ Addr: entry.Addr,
+ LinkAddr: entry.LinkAddr,
+ State: Static,
+ UpdatedAt: c.clock.Now(),
}
if diff := cmp.Diff(want, e); diff != "" {
t.Errorf("c.linkRes.neigh.entry(%s, \"\", nil) mismatch (-want, +got):\n%s", entry.Addr, diff)
@@ -882,10 +882,10 @@ func TestNeighborCacheAddStaticEntryThenOverflow(t *testing.T) {
EventType: entryTestAdded,
NICID: 1,
Entry: NeighborEntry{
- Addr: entry.Addr,
- LinkAddr: entry.LinkAddr,
- State: Static,
- UpdatedAtNanos: c.clock.NowNanoseconds(),
+ Addr: entry.Addr,
+ LinkAddr: entry.LinkAddr,
+ State: Static,
+ UpdatedAt: c.clock.Now(),
},
},
}
@@ -902,10 +902,10 @@ func TestNeighborCacheAddStaticEntryThenOverflow(t *testing.T) {
startAtEntryIndex: 1,
wantStaticEntries: []NeighborEntry{
{
- Addr: entry.Addr,
- LinkAddr: entry.LinkAddr,
- State: Static,
- UpdatedAtNanos: c.clock.NowNanoseconds(),
+ Addr: entry.Addr,
+ LinkAddr: entry.LinkAddr,
+ State: Static,
+ UpdatedAt: c.clock.Now(),
},
},
}
@@ -939,10 +939,10 @@ func TestNeighborCacheClear(t *testing.T) {
EventType: entryTestAdded,
NICID: 1,
Entry: NeighborEntry{
- Addr: entryTestAddr1,
- LinkAddr: entryTestLinkAddr1,
- State: Static,
- UpdatedAtNanos: clock.NowNanoseconds(),
+ Addr: entryTestAddr1,
+ LinkAddr: entryTestLinkAddr1,
+ State: Static,
+ UpdatedAt: clock.Now(),
},
},
}
@@ -965,20 +965,20 @@ func TestNeighborCacheClear(t *testing.T) {
EventType: entryTestRemoved,
NICID: 1,
Entry: NeighborEntry{
- Addr: entry.Addr,
- LinkAddr: entry.LinkAddr,
- State: Reachable,
- UpdatedAtNanos: clock.NowNanoseconds(),
+ Addr: entry.Addr,
+ LinkAddr: entry.LinkAddr,
+ State: Reachable,
+ UpdatedAt: clock.Now(),
},
},
{
EventType: entryTestRemoved,
NICID: 1,
Entry: NeighborEntry{
- Addr: entryTestAddr1,
- LinkAddr: entryTestLinkAddr1,
- State: Static,
- UpdatedAtNanos: clock.NowNanoseconds(),
+ Addr: entryTestAddr1,
+ LinkAddr: entryTestLinkAddr1,
+ State: Static,
+ UpdatedAt: clock.Now(),
},
},
}
@@ -1019,10 +1019,10 @@ func TestNeighborCacheClearThenOverflow(t *testing.T) {
EventType: entryTestRemoved,
NICID: 1,
Entry: NeighborEntry{
- Addr: entry.Addr,
- LinkAddr: entry.LinkAddr,
- State: Reachable,
- UpdatedAtNanos: c.clock.NowNanoseconds(),
+ Addr: entry.Addr,
+ LinkAddr: entry.LinkAddr,
+ State: Reachable,
+ UpdatedAt: c.clock.Now(),
},
},
}
@@ -1054,7 +1054,7 @@ func TestNeighborCacheKeepFrequentlyUsed(t *testing.T) {
clock := faketime.NewManualClock()
linkRes := newTestNeighborResolver(&nudDisp, config, clock)
- startedAt := clock.NowNanoseconds()
+ startedAt := clock.Now()
// The following logic is very similar to overflowCache, but
// periodically refreshes the frequently used entry.
@@ -1110,7 +1110,7 @@ func TestNeighborCacheKeepFrequentlyUsed(t *testing.T) {
State: Reachable,
// Can be inferred since the frequently used entry is the first to
// be created and transitioned to Reachable.
- UpdatedAtNanos: startedAt + typicalLatency.Nanoseconds(),
+ UpdatedAt: startedAt.Add(typicalLatency),
},
}
@@ -1119,12 +1119,12 @@ func TestNeighborCacheKeepFrequentlyUsed(t *testing.T) {
if !ok {
t.Fatalf("got linkRes.entries.entry(%d) = _, false, want = true", i)
}
- durationReachableNanos := int64(linkRes.entries.size()-i-1) * typicalLatency.Nanoseconds()
+ durationReachableNanos := time.Duration(linkRes.entries.size()-i-1) * typicalLatency
wantUnsortedEntries = append(wantUnsortedEntries, NeighborEntry{
- Addr: entry.Addr,
- LinkAddr: entry.LinkAddr,
- State: Reachable,
- UpdatedAtNanos: clock.NowNanoseconds() - durationReachableNanos,
+ Addr: entry.Addr,
+ LinkAddr: entry.LinkAddr,
+ State: Reachable,
+ UpdatedAt: clock.Now().Add(-durationReachableNanos),
})
}
@@ -1182,12 +1182,12 @@ func TestNeighborCacheConcurrent(t *testing.T) {
if !ok {
t.Errorf("got linkRes.entries.entry(%d) = _, false, want = true", i)
}
- durationReachableNanos := int64(linkRes.entries.size()-i-1) * typicalLatency.Nanoseconds()
+ durationReachableNanos := time.Duration(linkRes.entries.size()-i-1) * typicalLatency
wantUnsortedEntries = append(wantUnsortedEntries, NeighborEntry{
- Addr: entry.Addr,
- LinkAddr: entry.LinkAddr,
- State: Reachable,
- UpdatedAtNanos: clock.NowNanoseconds() - durationReachableNanos,
+ Addr: entry.Addr,
+ LinkAddr: entry.LinkAddr,
+ State: Reachable,
+ UpdatedAt: clock.Now().Add(-durationReachableNanos),
})
}
@@ -1236,10 +1236,10 @@ func TestNeighborCacheReplace(t *testing.T) {
t.Fatalf("linkRes.neigh.entry(%s, '', nil): %s", entry.Addr, err)
}
want := NeighborEntry{
- Addr: entry.Addr,
- LinkAddr: updatedLinkAddr,
- State: Delay,
- UpdatedAtNanos: clock.NowNanoseconds(),
+ Addr: entry.Addr,
+ LinkAddr: updatedLinkAddr,
+ State: Delay,
+ UpdatedAt: clock.Now(),
}
if diff := cmp.Diff(want, e); diff != "" {
t.Errorf("linkRes.neigh.entry(%s, '', nil) mismatch (-want, +got):\n%s", entry.Addr, diff)
@@ -1255,10 +1255,10 @@ func TestNeighborCacheReplace(t *testing.T) {
t.Errorf("unexpected error from linkRes.neigh.entry(%s, '', nil): %s", entry.Addr, err)
}
want := NeighborEntry{
- Addr: entry.Addr,
- LinkAddr: updatedLinkAddr,
- State: Reachable,
- UpdatedAtNanos: clock.NowNanoseconds(),
+ Addr: entry.Addr,
+ LinkAddr: updatedLinkAddr,
+ State: Reachable,
+ UpdatedAt: clock.Now(),
}
if diff := cmp.Diff(want, e); diff != "" {
t.Errorf("linkRes.neigh.entry(%s, '', nil) mismatch (-want, +got):\n%s", entry.Addr, diff)
@@ -1293,10 +1293,10 @@ func TestNeighborCacheResolutionFailed(t *testing.T) {
t.Fatalf("unexpected error from linkRes.neigh.entry(%s, '', nil): %s", entry.Addr, err)
}
want := NeighborEntry{
- Addr: entry.Addr,
- LinkAddr: entry.LinkAddr,
- State: Reachable,
- UpdatedAtNanos: clock.NowNanoseconds(),
+ Addr: entry.Addr,
+ LinkAddr: entry.LinkAddr,
+ State: Reachable,
+ UpdatedAt: clock.Now(),
}
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("linkRes.neigh.entry(%s, '', nil) mismatch (-want, +got):\n%s", entry.Addr, diff)
@@ -1397,10 +1397,10 @@ func TestNeighborCacheRetryResolution(t *testing.T) {
EventType: entryTestAdded,
NICID: 1,
Entry: NeighborEntry{
- Addr: entry.Addr,
- LinkAddr: "",
- State: Incomplete,
- UpdatedAtNanos: clock.NowNanoseconds(),
+ Addr: entry.Addr,
+ LinkAddr: "",
+ State: Incomplete,
+ UpdatedAt: clock.Now(),
},
},
}
@@ -1428,10 +1428,10 @@ func TestNeighborCacheRetryResolution(t *testing.T) {
EventType: entryTestChanged,
NICID: 1,
Entry: NeighborEntry{
- Addr: entry.Addr,
- LinkAddr: "",
- State: Unreachable,
- UpdatedAtNanos: clock.NowNanoseconds(),
+ Addr: entry.Addr,
+ LinkAddr: "",
+ State: Unreachable,
+ UpdatedAt: clock.Now(),
},
},
}
@@ -1447,10 +1447,10 @@ func TestNeighborCacheRetryResolution(t *testing.T) {
{
wantEntries := []NeighborEntry{
{
- Addr: entry.Addr,
- LinkAddr: "",
- State: Unreachable,
- UpdatedAtNanos: clock.NowNanoseconds(),
+ Addr: entry.Addr,
+ LinkAddr: "",
+ State: Unreachable,
+ UpdatedAt: clock.Now(),
},
}
if diff := cmp.Diff(linkRes.neigh.entries(), wantEntries, unorderedEntriesDiffOpts()...); diff != "" {
@@ -1480,10 +1480,10 @@ func TestNeighborCacheRetryResolution(t *testing.T) {
EventType: entryTestChanged,
NICID: 1,
Entry: NeighborEntry{
- Addr: entry.Addr,
- LinkAddr: "",
- State: Incomplete,
- UpdatedAtNanos: clock.NowNanoseconds(),
+ Addr: entry.Addr,
+ LinkAddr: "",
+ State: Incomplete,
+ UpdatedAt: clock.Now(),
},
},
}
@@ -1510,10 +1510,10 @@ func TestNeighborCacheRetryResolution(t *testing.T) {
EventType: entryTestChanged,
NICID: 1,
Entry: NeighborEntry{
- Addr: entry.Addr,
- LinkAddr: entry.LinkAddr,
- State: Reachable,
- UpdatedAtNanos: clock.NowNanoseconds(),
+ Addr: entry.Addr,
+ LinkAddr: entry.LinkAddr,
+ State: Reachable,
+ UpdatedAt: clock.Now(),
},
},
}
@@ -1533,10 +1533,10 @@ func TestNeighborCacheRetryResolution(t *testing.T) {
}
wantEntry := NeighborEntry{
- Addr: entry.Addr,
- LinkAddr: entry.LinkAddr,
- State: Reachable,
- UpdatedAtNanos: clock.NowNanoseconds(),
+ Addr: entry.Addr,
+ LinkAddr: entry.LinkAddr,
+ State: Reachable,
+ UpdatedAt: clock.Now(),
}
if diff := cmp.Diff(gotEntry, wantEntry); diff != "" {
t.Fatalf("neighbor entry mismatch (-got, +want):\n%s", diff)
diff --git a/pkg/tcpip/stack/neighbor_entry.go b/pkg/tcpip/stack/neighbor_entry.go
index 463d017fc..ab247db2e 100644
--- a/pkg/tcpip/stack/neighbor_entry.go
+++ b/pkg/tcpip/stack/neighbor_entry.go
@@ -31,10 +31,10 @@ const (
// NeighborEntry describes a neighboring device in the local network.
type NeighborEntry struct {
- Addr tcpip.Address
- LinkAddr tcpip.LinkAddress
- State NeighborState
- UpdatedAtNanos int64
+ Addr tcpip.Address
+ LinkAddr tcpip.LinkAddress
+ State NeighborState
+ UpdatedAt time.Time
}
// NeighborState defines the state of a NeighborEntry within the Neighbor
@@ -138,10 +138,10 @@ func newNeighborEntry(cache *neighborCache, remoteAddr tcpip.Address, nudState *
// calling `setStateLocked`.
func newStaticNeighborEntry(cache *neighborCache, addr tcpip.Address, linkAddr tcpip.LinkAddress, state *NUDState) *neighborEntry {
entry := NeighborEntry{
- Addr: addr,
- LinkAddr: linkAddr,
- State: Static,
- UpdatedAtNanos: cache.nic.stack.clock.NowNanoseconds(),
+ Addr: addr,
+ LinkAddr: linkAddr,
+ State: Static,
+ UpdatedAt: cache.nic.stack.clock.Now(),
}
n := &neighborEntry{
cache: cache,
@@ -224,7 +224,7 @@ func (e *neighborEntry) cancelTimerLocked() {
//
// Precondition: e.mu MUST be locked.
func (e *neighborEntry) removeLocked() {
- e.mu.neigh.UpdatedAtNanos = e.cache.nic.stack.clock.NowNanoseconds()
+ e.mu.neigh.UpdatedAt = e.cache.nic.stack.clock.Now()
e.dispatchRemoveEventLocked()
e.cancelTimerLocked()
// TODO(https://gvisor.dev/issues/5583): test the case where this function is
@@ -246,7 +246,7 @@ func (e *neighborEntry) setStateLocked(next NeighborState) {
prev := e.mu.neigh.State
e.mu.neigh.State = next
- e.mu.neigh.UpdatedAtNanos = e.cache.nic.stack.clock.NowNanoseconds()
+ e.mu.neigh.UpdatedAt = e.cache.nic.stack.clock.Now()
config := e.nudState.Config()
switch next {
@@ -354,7 +354,7 @@ func (e *neighborEntry) handlePacketQueuedLocked(localAddr tcpip.Address) {
case Unknown, Unreachable:
prev := e.mu.neigh.State
e.mu.neigh.State = Incomplete
- e.mu.neigh.UpdatedAtNanos = e.cache.nic.stack.clock.NowNanoseconds()
+ e.mu.neigh.UpdatedAt = e.cache.nic.stack.clock.Now()
switch prev {
case Unknown:
diff --git a/pkg/tcpip/stack/neighbor_entry_test.go b/pkg/tcpip/stack/neighbor_entry_test.go
index c2a291244..59d86d6d4 100644
--- a/pkg/tcpip/stack/neighbor_entry_test.go
+++ b/pkg/tcpip/stack/neighbor_entry_test.go
@@ -349,10 +349,10 @@ func unknownToIncomplete(e *neighborEntry, nudDisp *testNUDDispatcher, linkRes *
EventType: entryTestAdded,
NICID: entryTestNICID,
Entry: NeighborEntry{
- Addr: entryTestAddr1,
- LinkAddr: tcpip.LinkAddress(""),
- State: Incomplete,
- UpdatedAtNanos: clock.NowNanoseconds(),
+ Addr: entryTestAddr1,
+ LinkAddr: tcpip.LinkAddress(""),
+ State: Incomplete,
+ UpdatedAt: clock.Now(),
},
},
}
@@ -410,10 +410,10 @@ func unknownToStale(e *neighborEntry, nudDisp *testNUDDispatcher, linkRes *entry
EventType: entryTestAdded,
NICID: entryTestNICID,
Entry: NeighborEntry{
- Addr: entryTestAddr1,
- LinkAddr: entryTestLinkAddr1,
- State: Stale,
- UpdatedAtNanos: clock.NowNanoseconds(),
+ Addr: entryTestAddr1,
+ LinkAddr: entryTestLinkAddr1,
+ State: Stale,
+ UpdatedAt: clock.Now(),
},
},
}
@@ -441,7 +441,7 @@ func TestEntryIncompleteToIncompleteDoesNotChangeUpdatedAt(t *testing.T) {
// UpdatedAt should remain the same during address resolution.
e.mu.Lock()
- startedAt := e.mu.neigh.UpdatedAtNanos
+ startedAt := e.mu.neigh.UpdatedAt
e.mu.Unlock()
// Wait for the rest of the reachability probe transmissions, signifying
@@ -465,7 +465,7 @@ func TestEntryIncompleteToIncompleteDoesNotChangeUpdatedAt(t *testing.T) {
}
e.mu.Lock()
- if got, want := e.mu.neigh.UpdatedAtNanos, startedAt; got != want {
+ if got, want := e.mu.neigh.UpdatedAt, startedAt; got != want {
t.Errorf("got e.mu.neigh.UpdatedAt = %q, want = %q", got, want)
}
e.mu.Unlock()
@@ -480,10 +480,10 @@ func TestEntryIncompleteToIncompleteDoesNotChangeUpdatedAt(t *testing.T) {
EventType: entryTestChanged,
NICID: entryTestNICID,
Entry: NeighborEntry{
- Addr: entryTestAddr1,
- LinkAddr: tcpip.LinkAddress(""),
- State: Unreachable,
- UpdatedAtNanos: clock.NowNanoseconds(),
+ Addr: entryTestAddr1,
+ LinkAddr: tcpip.LinkAddress(""),
+ State: Unreachable,
+ UpdatedAt: clock.Now(),
},
},
}
@@ -542,10 +542,10 @@ func incompleteToReachableWithFlags(e *neighborEntry, nudDisp *testNUDDispatcher
EventType: entryTestChanged,
NICID: entryTestNICID,
Entry: NeighborEntry{
- Addr: entryTestAddr1,
- LinkAddr: entryTestLinkAddr1,
- State: Reachable,
- UpdatedAtNanos: clock.NowNanoseconds(),
+ Addr: entryTestAddr1,
+ LinkAddr: entryTestLinkAddr1,
+ State: Reachable,
+ UpdatedAt: clock.Now(),
},
},
}
@@ -639,10 +639,10 @@ func TestEntryIncompleteToStaleWhenUnsolicitedConfirmation(t *testing.T) {
EventType: entryTestChanged,
NICID: entryTestNICID,
Entry: NeighborEntry{
- Addr: entryTestAddr1,
- LinkAddr: entryTestLinkAddr1,
- State: Stale,
- UpdatedAtNanos: clock.NowNanoseconds(),
+ Addr: entryTestAddr1,
+ LinkAddr: entryTestLinkAddr1,
+ State: Stale,
+ UpdatedAt: clock.Now(),
},
},
}
@@ -673,10 +673,10 @@ func TestEntryIncompleteToStaleWhenProbe(t *testing.T) {
EventType: entryTestChanged,
NICID: entryTestNICID,
Entry: NeighborEntry{
- Addr: entryTestAddr1,
- LinkAddr: entryTestLinkAddr1,
- State: Stale,
- UpdatedAtNanos: clock.NowNanoseconds(),
+ Addr: entryTestAddr1,
+ LinkAddr: entryTestLinkAddr1,
+ State: Stale,
+ UpdatedAt: clock.Now(),
},
},
}
@@ -752,10 +752,10 @@ func incompleteToUnreachable(c NUDConfigurations, e *neighborEntry, nudDisp *tes
EventType: entryTestChanged,
NICID: entryTestNICID,
Entry: NeighborEntry{
- Addr: entryTestAddr1,
- LinkAddr: tcpip.LinkAddress(""),
- State: Unreachable,
- UpdatedAtNanos: clock.NowNanoseconds(),
+ Addr: entryTestAddr1,
+ LinkAddr: tcpip.LinkAddress(""),
+ State: Unreachable,
+ UpdatedAt: clock.Now(),
},
},
}
@@ -938,10 +938,10 @@ func reachableToStale(c NUDConfigurations, e *neighborEntry, nudDisp *testNUDDis
EventType: entryTestChanged,
NICID: entryTestNICID,
Entry: NeighborEntry{
- Addr: entryTestAddr1,
- LinkAddr: entryTestLinkAddr1,
- State: Stale,
- UpdatedAtNanos: clock.NowNanoseconds(),
+ Addr: entryTestAddr1,
+ LinkAddr: entryTestLinkAddr1,
+ State: Stale,
+ UpdatedAt: clock.Now(),
},
},
}
@@ -993,10 +993,10 @@ func TestEntryReachableToStaleWhenProbeWithDifferentAddress(t *testing.T) {
EventType: entryTestChanged,
NICID: entryTestNICID,
Entry: NeighborEntry{
- Addr: entryTestAddr1,
- LinkAddr: entryTestLinkAddr2,
- State: Stale,
- UpdatedAtNanos: clock.NowNanoseconds(),
+ Addr: entryTestAddr1,
+ LinkAddr: entryTestLinkAddr2,
+ State: Stale,
+ UpdatedAt: clock.Now(),
},
},
}
@@ -1045,10 +1045,10 @@ func TestEntryReachableToStaleWhenConfirmationWithDifferentAddress(t *testing.T)
EventType: entryTestChanged,
NICID: entryTestNICID,
Entry: NeighborEntry{
- Addr: entryTestAddr1,
- LinkAddr: entryTestLinkAddr1,
- State: Stale,
- UpdatedAtNanos: clock.NowNanoseconds(),
+ Addr: entryTestAddr1,
+ LinkAddr: entryTestLinkAddr1,
+ State: Stale,
+ UpdatedAt: clock.Now(),
},
},
}
@@ -1097,10 +1097,10 @@ func TestEntryReachableToStaleWhenConfirmationWithDifferentAddressAndOverride(t
EventType: entryTestChanged,
NICID: entryTestNICID,
Entry: NeighborEntry{
- Addr: entryTestAddr1,
- LinkAddr: entryTestLinkAddr2,
- State: Stale,
- UpdatedAtNanos: clock.NowNanoseconds(),
+ Addr: entryTestAddr1,
+ LinkAddr: entryTestLinkAddr2,
+ State: Stale,
+ UpdatedAt: clock.Now(),
},
},
}
@@ -1186,10 +1186,10 @@ func TestEntryStaleToReachableWhenSolicitedOverrideConfirmation(t *testing.T) {
EventType: entryTestChanged,
NICID: entryTestNICID,
Entry: NeighborEntry{
- Addr: entryTestAddr1,
- LinkAddr: entryTestLinkAddr2,
- State: Reachable,
- UpdatedAtNanos: clock.NowNanoseconds(),
+ Addr: entryTestAddr1,
+ LinkAddr: entryTestLinkAddr2,
+ State: Reachable,
+ UpdatedAt: clock.Now(),
},
},
}
@@ -1238,10 +1238,10 @@ func TestEntryStaleToReachableWhenSolicitedConfirmationWithoutAddress(t *testing
EventType: entryTestChanged,
NICID: entryTestNICID,
Entry: NeighborEntry{
- Addr: entryTestAddr1,
- LinkAddr: entryTestLinkAddr1,
- State: Reachable,
- UpdatedAtNanos: clock.NowNanoseconds(),
+ Addr: entryTestAddr1,
+ LinkAddr: entryTestLinkAddr1,
+ State: Reachable,
+ UpdatedAt: clock.Now(),
},
},
}
@@ -1279,10 +1279,10 @@ func TestEntryStaleToStaleWhenOverrideConfirmation(t *testing.T) {
EventType: entryTestChanged,
NICID: entryTestNICID,
Entry: NeighborEntry{
- Addr: entryTestAddr1,
- LinkAddr: entryTestLinkAddr2,
- State: Stale,
- UpdatedAtNanos: clock.NowNanoseconds(),
+ Addr: entryTestAddr1,
+ LinkAddr: entryTestLinkAddr2,
+ State: Stale,
+ UpdatedAt: clock.Now(),
},
},
}
@@ -1327,10 +1327,10 @@ func TestEntryStaleToStaleWhenProbeUpdateAddress(t *testing.T) {
EventType: entryTestChanged,
NICID: entryTestNICID,
Entry: NeighborEntry{
- Addr: entryTestAddr1,
- LinkAddr: entryTestLinkAddr2,
- State: Stale,
- UpdatedAtNanos: clock.NowNanoseconds(),
+ Addr: entryTestAddr1,
+ LinkAddr: entryTestLinkAddr2,
+ State: Stale,
+ UpdatedAt: clock.Now(),
},
},
}
@@ -1386,10 +1386,10 @@ func staleToDelay(e *neighborEntry, nudDisp *testNUDDispatcher, linkRes *entryTe
EventType: entryTestChanged,
NICID: entryTestNICID,
Entry: NeighborEntry{
- Addr: entryTestAddr1,
- LinkAddr: entryTestLinkAddr1,
- State: Delay,
- UpdatedAtNanos: clock.NowNanoseconds(),
+ Addr: entryTestAddr1,
+ LinkAddr: entryTestLinkAddr1,
+ State: Delay,
+ UpdatedAt: clock.Now(),
},
},
}
@@ -1438,10 +1438,10 @@ func TestEntryDelayToReachableWhenUpperLevelConfirmation(t *testing.T) {
EventType: entryTestChanged,
NICID: entryTestNICID,
Entry: NeighborEntry{
- Addr: entryTestAddr1,
- LinkAddr: entryTestLinkAddr1,
- State: Reachable,
- UpdatedAtNanos: clock.NowNanoseconds(),
+ Addr: entryTestAddr1,
+ LinkAddr: entryTestLinkAddr1,
+ State: Reachable,
+ UpdatedAt: clock.Now(),
},
},
}
@@ -1493,10 +1493,10 @@ func TestEntryDelayToReachableWhenSolicitedOverrideConfirmation(t *testing.T) {
EventType: entryTestChanged,
NICID: entryTestNICID,
Entry: NeighborEntry{
- Addr: entryTestAddr1,
- LinkAddr: entryTestLinkAddr2,
- State: Reachable,
- UpdatedAtNanos: clock.NowNanoseconds(),
+ Addr: entryTestAddr1,
+ LinkAddr: entryTestLinkAddr2,
+ State: Reachable,
+ UpdatedAt: clock.Now(),
},
},
}
@@ -1548,10 +1548,10 @@ func TestEntryDelayToReachableWhenSolicitedConfirmationWithoutAddress(t *testing
EventType: entryTestChanged,
NICID: entryTestNICID,
Entry: NeighborEntry{
- Addr: entryTestAddr1,
- LinkAddr: entryTestLinkAddr1,
- State: Reachable,
- UpdatedAtNanos: clock.NowNanoseconds(),
+ Addr: entryTestAddr1,
+ LinkAddr: entryTestLinkAddr1,
+ State: Reachable,
+ UpdatedAt: clock.Now(),
},
},
}
@@ -1640,10 +1640,10 @@ func TestEntryDelayToStaleWhenProbeWithDifferentAddress(t *testing.T) {
EventType: entryTestChanged,
NICID: entryTestNICID,
Entry: NeighborEntry{
- Addr: entryTestAddr1,
- LinkAddr: entryTestLinkAddr2,
- State: Stale,
- UpdatedAtNanos: clock.NowNanoseconds(),
+ Addr: entryTestAddr1,
+ LinkAddr: entryTestLinkAddr2,
+ State: Stale,
+ UpdatedAt: clock.Now(),
},
},
}
@@ -1692,10 +1692,10 @@ func TestEntryDelayToStaleWhenConfirmationWithDifferentAddress(t *testing.T) {
EventType: entryTestChanged,
NICID: entryTestNICID,
Entry: NeighborEntry{
- Addr: entryTestAddr1,
- LinkAddr: entryTestLinkAddr2,
- State: Stale,
- UpdatedAtNanos: clock.NowNanoseconds(),
+ Addr: entryTestAddr1,
+ LinkAddr: entryTestLinkAddr2,
+ State: Stale,
+ UpdatedAt: clock.Now(),
},
},
}
@@ -1765,10 +1765,10 @@ func delayToProbe(c NUDConfigurations, e *neighborEntry, nudDisp *testNUDDispatc
EventType: entryTestChanged,
NICID: entryTestNICID,
Entry: NeighborEntry{
- Addr: entryTestAddr1,
- LinkAddr: entryTestLinkAddr1,
- State: Probe,
- UpdatedAtNanos: clock.NowNanoseconds(),
+ Addr: entryTestAddr1,
+ LinkAddr: entryTestLinkAddr1,
+ State: Probe,
+ UpdatedAt: clock.Now(),
},
},
}
@@ -1822,10 +1822,10 @@ func TestEntryProbeToStaleWhenProbeWithDifferentAddress(t *testing.T) {
EventType: entryTestChanged,
NICID: entryTestNICID,
Entry: NeighborEntry{
- Addr: entryTestAddr1,
- LinkAddr: entryTestLinkAddr2,
- State: Stale,
- UpdatedAtNanos: clock.NowNanoseconds(),
+ Addr: entryTestAddr1,
+ LinkAddr: entryTestLinkAddr2,
+ State: Stale,
+ UpdatedAt: clock.Now(),
},
},
}
@@ -1877,10 +1877,10 @@ func TestEntryProbeToStaleWhenConfirmationWithDifferentAddress(t *testing.T) {
EventType: entryTestChanged,
NICID: entryTestNICID,
Entry: NeighborEntry{
- Addr: entryTestAddr1,
- LinkAddr: entryTestLinkAddr2,
- State: Stale,
- UpdatedAtNanos: clock.NowNanoseconds(),
+ Addr: entryTestAddr1,
+ LinkAddr: entryTestLinkAddr2,
+ State: Stale,
+ UpdatedAt: clock.Now(),
},
},
}
@@ -1998,10 +1998,10 @@ func probeToReachableWithFlags(e *neighborEntry, nudDisp *testNUDDispatcher, lin
EventType: entryTestChanged,
NICID: entryTestNICID,
Entry: NeighborEntry{
- Addr: entryTestAddr1,
- LinkAddr: linkAddr,
- State: Reachable,
- UpdatedAtNanos: clock.NowNanoseconds(),
+ Addr: entryTestAddr1,
+ LinkAddr: linkAddr,
+ State: Reachable,
+ UpdatedAt: clock.Now(),
},
},
}
@@ -2150,10 +2150,10 @@ func probeToUnreachable(c NUDConfigurations, e *neighborEntry, nudDisp *testNUDD
EventType: entryTestChanged,
NICID: entryTestNICID,
Entry: NeighborEntry{
- Addr: entryTestAddr1,
- LinkAddr: entryTestLinkAddr1,
- State: Unreachable,
- UpdatedAtNanos: clock.NowNanoseconds(),
+ Addr: entryTestAddr1,
+ LinkAddr: entryTestLinkAddr1,
+ State: Unreachable,
+ UpdatedAt: clock.Now(),
},
},
}
@@ -2222,10 +2222,10 @@ func unreachableToIncomplete(e *neighborEntry, nudDisp *testNUDDispatcher, linkR
EventType: entryTestChanged,
NICID: entryTestNICID,
Entry: NeighborEntry{
- Addr: entryTestAddr1,
- LinkAddr: tcpip.LinkAddress(""),
- State: Incomplete,
- UpdatedAtNanos: clock.NowNanoseconds(),
+ Addr: entryTestAddr1,
+ LinkAddr: tcpip.LinkAddress(""),
+ State: Incomplete,
+ UpdatedAt: clock.Now(),
},
},
}
diff --git a/pkg/tcpip/stack/nud.go b/pkg/tcpip/stack/nud.go
index 5a94e9ac6..dac94cbe4 100644
--- a/pkg/tcpip/stack/nud.go
+++ b/pkg/tcpip/stack/nud.go
@@ -16,6 +16,7 @@ package stack
import (
"math"
+ "math/rand"
"sync"
"time"
@@ -313,45 +314,34 @@ func calcMaxRandomFactor(minRandomFactor float32) float32 {
return defaultMaxRandomFactor
}
-// A Rand is a source of random numbers.
-type Rand interface {
- // Float32 returns, as a float32, a pseudo-random number in [0.0,1.0).
- Float32() float32
-}
-
// NUDState stores states needed for calculating reachable time.
type NUDState struct {
- rng Rand
+ rng *rand.Rand
- // mu protects the fields below.
- //
- // It is necessary for NUDState to handle its own locking since neighbor
- // entries may access the NUD state from within the goroutine spawned by
- // time.AfterFunc(). This goroutine may run concurrently with the main
- // process for controlling the neighbor cache and would otherwise introduce
- // race conditions if NUDState was not locked properly.
- mu sync.RWMutex
+ mu struct {
+ sync.RWMutex
- config NUDConfigurations
+ config NUDConfigurations
- // reachableTime is the duration to wait for a REACHABLE entry to
- // transition into STALE after inactivity. This value is calculated with
- // the algorithm defined in RFC 4861 section 6.3.2.
- reachableTime time.Duration
+ // reachableTime is the duration to wait for a REACHABLE entry to
+ // transition into STALE after inactivity. This value is calculated with
+ // the algorithm defined in RFC 4861 section 6.3.2.
+ reachableTime time.Duration
- expiration time.Time
- prevBaseReachableTime time.Duration
- prevMinRandomFactor float32
- prevMaxRandomFactor float32
+ expiration time.Time
+ prevBaseReachableTime time.Duration
+ prevMinRandomFactor float32
+ prevMaxRandomFactor float32
+ }
}
// NewNUDState returns new NUDState using c as configuration and the specified
// random number generator for use in recomputing ReachableTime.
-func NewNUDState(c NUDConfigurations, rng Rand) *NUDState {
+func NewNUDState(c NUDConfigurations, rng *rand.Rand) *NUDState {
s := &NUDState{
rng: rng,
}
- s.config = c
+ s.mu.config = c
return s
}
@@ -359,14 +349,14 @@ func NewNUDState(c NUDConfigurations, rng Rand) *NUDState {
func (s *NUDState) Config() NUDConfigurations {
s.mu.RLock()
defer s.mu.RUnlock()
- return s.config
+ return s.mu.config
}
// SetConfig replaces the existing NUD configurations with c.
func (s *NUDState) SetConfig(c NUDConfigurations) {
s.mu.Lock()
defer s.mu.Unlock()
- s.config = c
+ s.mu.config = c
}
// ReachableTime returns the duration to wait for a REACHABLE entry to
@@ -377,13 +367,13 @@ func (s *NUDState) ReachableTime() time.Duration {
s.mu.Lock()
defer s.mu.Unlock()
- if time.Now().After(s.expiration) ||
- s.config.BaseReachableTime != s.prevBaseReachableTime ||
- s.config.MinRandomFactor != s.prevMinRandomFactor ||
- s.config.MaxRandomFactor != s.prevMaxRandomFactor {
+ if time.Now().After(s.mu.expiration) ||
+ s.mu.config.BaseReachableTime != s.mu.prevBaseReachableTime ||
+ s.mu.config.MinRandomFactor != s.mu.prevMinRandomFactor ||
+ s.mu.config.MaxRandomFactor != s.mu.prevMaxRandomFactor {
s.recomputeReachableTimeLocked()
}
- return s.reachableTime
+ return s.mu.reachableTime
}
// recomputeReachableTimeLocked forces a recalculation of ReachableTime using
@@ -408,23 +398,23 @@ func (s *NUDState) ReachableTime() time.Duration {
//
// s.mu MUST be locked for writing.
func (s *NUDState) recomputeReachableTimeLocked() {
- s.prevBaseReachableTime = s.config.BaseReachableTime
- s.prevMinRandomFactor = s.config.MinRandomFactor
- s.prevMaxRandomFactor = s.config.MaxRandomFactor
+ s.mu.prevBaseReachableTime = s.mu.config.BaseReachableTime
+ s.mu.prevMinRandomFactor = s.mu.config.MinRandomFactor
+ s.mu.prevMaxRandomFactor = s.mu.config.MaxRandomFactor
- randomFactor := s.config.MinRandomFactor + s.rng.Float32()*(s.config.MaxRandomFactor-s.config.MinRandomFactor)
+ randomFactor := s.mu.config.MinRandomFactor + s.rng.Float32()*(s.mu.config.MaxRandomFactor-s.mu.config.MinRandomFactor)
// Check for overflow, given that minRandomFactor and maxRandomFactor are
// guaranteed to be positive numbers.
- if float32(math.MaxInt64)/randomFactor < float32(s.config.BaseReachableTime) {
- s.reachableTime = time.Duration(math.MaxInt64)
+ if math.MaxInt64/randomFactor < float32(s.mu.config.BaseReachableTime) {
+ s.mu.reachableTime = time.Duration(math.MaxInt64)
} else if randomFactor == 1 {
// Avoid loss of precision when a large base reachable time is used.
- s.reachableTime = s.config.BaseReachableTime
+ s.mu.reachableTime = s.mu.config.BaseReachableTime
} else {
- reachableTime := int64(float32(s.config.BaseReachableTime) * randomFactor)
- s.reachableTime = time.Duration(reachableTime)
+ reachableTime := int64(float32(s.mu.config.BaseReachableTime) * randomFactor)
+ s.mu.reachableTime = time.Duration(reachableTime)
}
- s.expiration = time.Now().Add(2 * time.Hour)
+ s.mu.expiration = time.Now().Add(2 * time.Hour)
}
diff --git a/pkg/tcpip/stack/nud_test.go b/pkg/tcpip/stack/nud_test.go
index 6ba97d626..bfce2fe16 100644
--- a/pkg/tcpip/stack/nud_test.go
+++ b/pkg/tcpip/stack/nud_test.go
@@ -16,6 +16,7 @@ package stack_test
import (
"math"
+ "math/rand"
"testing"
"time"
@@ -46,12 +47,14 @@ type fakeRand struct {
num float32
}
-var _ stack.Rand = (*fakeRand)(nil)
+var _ rand.Source = (*fakeRand)(nil)
-func (f *fakeRand) Float32() float32 {
- return f.num
+func (f *fakeRand) Int63() int64 {
+ return int64(f.num * float32(1<<63))
}
+func (*fakeRand) Seed(int64) {}
+
func TestNUDFunctions(t *testing.T) {
const nicID = 1
@@ -167,7 +170,7 @@ func TestNUDFunctions(t *testing.T) {
t.Errorf("s.Neigbors(%d, %d) error mismatch (-want +got):\n%s", test.nicID, ipv6.ProtocolNumber, diff)
} else if test.expectedErr == nil {
if diff := cmp.Diff(
- []stack.NeighborEntry{{Addr: llAddr2, LinkAddr: linkAddr1, State: stack.Static, UpdatedAtNanos: clock.NowNanoseconds()}},
+ []stack.NeighborEntry{{Addr: llAddr2, LinkAddr: linkAddr1, State: stack.Static, UpdatedAt: clock.Now()}},
neighbors,
); diff != "" {
t.Errorf("neighbors mismatch (-want +got):\n%s", diff)
@@ -708,7 +711,7 @@ func TestNUDStateReachableTime(t *testing.T) {
rng := fakeRand{
num: defaultFakeRandomNum,
}
- s := stack.NewNUDState(c, &rng)
+ s := stack.NewNUDState(c, rand.New(&rng))
if got, want := s.ReachableTime(), test.want; got != want {
t.Errorf("got ReachableTime = %q, want = %q", got, want)
}
@@ -780,7 +783,7 @@ func TestNUDStateRecomputeReachableTime(t *testing.T) {
rng := fakeRand{
num: defaultFakeRandomNum,
}
- s := stack.NewNUDState(c, &rng)
+ s := stack.NewNUDState(c, rand.New(&rng))
old := s.ReachableTime()
if got, want := s.ReachableTime(), old; got != want {
diff --git a/pkg/tcpip/stack/stack_test.go b/pkg/tcpip/stack/stack_test.go
index 73e0f0d58..9c61dd939 100644
--- a/pkg/tcpip/stack/stack_test.go
+++ b/pkg/tcpip/stack/stack_test.go
@@ -4427,7 +4427,7 @@ func TestClearNeighborCacheOnNICDisable(t *testing.T) {
if neighbors, err := s.Neighbors(nicID, addr.proto); err != nil {
t.Fatalf("s.Neighbors(%d, %d): %s", nicID, addr.proto, err)
} else if diff := cmp.Diff(
- []stack.NeighborEntry{{Addr: addr.addr, LinkAddr: linkAddr, State: stack.Static, UpdatedAtNanos: clock.NowNanoseconds()}},
+ []stack.NeighborEntry{{Addr: addr.addr, LinkAddr: linkAddr, State: stack.Static, UpdatedAt: clock.Now()}},
neighbors,
); diff != "" {
t.Fatalf("proto=%d neighbors mismatch (-want +got):\n%s", addr.proto, diff)