diff options
author | Ghanan Gowripalan <ghanan@google.com> | 2020-10-08 17:32:41 -0700 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2020-10-08 17:34:28 -0700 |
commit | 07b1d7413e8b648b85fa9276a516732dd93276b4 (patch) | |
tree | 0b679c1bde1bb8df1a98e2dcdbb08c09c84ae105 /pkg/tcpip/stack/neighbor_cache.go | |
parent | 6bad4851d4a04b5f56ade1f8ba68bd9c16471533 (diff) |
Only block resolution when NUD is incomplete
When a completed entry exists for a neighbor, there is no need to block
while reachability is (re)confirmed. The stack should continue to use
the neighbor's link address while NUD is performed.
Test: stack_test.TestNeighborCacheReplace
PiperOrigin-RevId: 336199043
Diffstat (limited to 'pkg/tcpip/stack/neighbor_cache.go')
-rw-r--r-- | pkg/tcpip/stack/neighbor_cache.go | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/pkg/tcpip/stack/neighbor_cache.go b/pkg/tcpip/stack/neighbor_cache.go index 27e1feec0..4df288798 100644 --- a/pkg/tcpip/stack/neighbor_cache.go +++ b/pkg/tcpip/stack/neighbor_cache.go @@ -131,10 +131,17 @@ func (n *neighborCache) entry(remoteAddr, localAddr tcpip.Address, linkRes LinkA defer entry.mu.Unlock() switch s := entry.neigh.State; s { - case Reachable, Static: + case Stale: + entry.handlePacketQueuedLocked() + fallthrough + case Reachable, Static, Delay, Probe: + // As per RFC 4861 section 7.3.3: + // "Neighbor Unreachability Detection operates in parallel with the sending + // of packets to a neighbor. While reasserting a neighbor's reachability, + // a node continues sending packets to that neighbor using the cached + // link-layer address." return entry.neigh, nil, nil - - case Unknown, Incomplete, Stale, Delay, Probe: + case Unknown, Incomplete: entry.addWakerLocked(w) if entry.done == nil { @@ -147,10 +154,8 @@ func (n *neighborCache) entry(remoteAddr, localAddr tcpip.Address, linkRes LinkA entry.handlePacketQueuedLocked() return entry.neigh, entry.done, tcpip.ErrWouldBlock - case Failed: return entry.neigh, nil, tcpip.ErrNoLinkAddress - default: panic(fmt.Sprintf("Invalid cache entry state: %s", s)) } |