Pass NeighborEntry in NUD callbacks

...instead of passing its fields piecemeal.

PiperOrigin-RevId: 339345899
This commit is contained in:
Tamir Duberstein 2020-10-27 15:43:08 -07:00 committed by gVisor bot
parent 6d50185e7c
commit 4d9066d1d7
7 changed files with 870 additions and 563 deletions

View File

@ -30,5 +30,6 @@ go_test(
"//pkg/tcpip/stack",
"//pkg/tcpip/transport/icmp",
"@com_github_google_go_cmp//cmp:go_default_library",
"@com_github_google_go_cmp//cmp/cmpopts:go_default_library",
],
)

View File

@ -22,6 +22,7 @@ import (
"time"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"gvisor.dev/gvisor/pkg/tcpip"
"gvisor.dev/gvisor/pkg/tcpip/buffer"
"gvisor.dev/gvisor/pkg/tcpip/header"
@ -78,13 +79,11 @@ func (t eventType) String() string {
type eventInfo struct {
eventType eventType
nicID tcpip.NICID
addr tcpip.Address
linkAddr tcpip.LinkAddress
state stack.NeighborState
entry stack.NeighborEntry
}
func (e eventInfo) String() string {
return fmt.Sprintf("%s event for NIC #%d, addr=%q, linkAddr=%q, state=%q", e.eventType, e.nicID, e.addr, e.linkAddr, e.state)
return fmt.Sprintf("%s event for NIC #%d, %#v", e.eventType, e.nicID, e.entry)
}
// arpDispatcher implements NUDDispatcher to validate the dispatching of
@ -96,35 +95,29 @@ type arpDispatcher struct {
var _ stack.NUDDispatcher = (*arpDispatcher)(nil)
func (d *arpDispatcher) OnNeighborAdded(nicID tcpip.NICID, addr tcpip.Address, linkAddr tcpip.LinkAddress, state stack.NeighborState, updatedAt time.Time) {
func (d *arpDispatcher) OnNeighborAdded(nicID tcpip.NICID, entry stack.NeighborEntry) {
e := eventInfo{
eventType: entryAdded,
nicID: nicID,
addr: addr,
linkAddr: linkAddr,
state: state,
entry: entry,
}
d.C <- e
}
func (d *arpDispatcher) OnNeighborChanged(nicID tcpip.NICID, addr tcpip.Address, linkAddr tcpip.LinkAddress, state stack.NeighborState, updatedAt time.Time) {
func (d *arpDispatcher) OnNeighborChanged(nicID tcpip.NICID, entry stack.NeighborEntry) {
e := eventInfo{
eventType: entryChanged,
nicID: nicID,
addr: addr,
linkAddr: linkAddr,
state: state,
entry: entry,
}
d.C <- e
}
func (d *arpDispatcher) OnNeighborRemoved(nicID tcpip.NICID, addr tcpip.Address, linkAddr tcpip.LinkAddress, state stack.NeighborState, updatedAt time.Time) {
func (d *arpDispatcher) OnNeighborRemoved(nicID tcpip.NICID, entry stack.NeighborEntry) {
e := eventInfo{
eventType: entryRemoved,
nicID: nicID,
addr: addr,
linkAddr: linkAddr,
state: state,
entry: entry,
}
d.C <- e
}
@ -132,7 +125,7 @@ func (d *arpDispatcher) OnNeighborRemoved(nicID tcpip.NICID, addr tcpip.Address,
func (d *arpDispatcher) waitForEvent(ctx context.Context, want eventInfo) error {
select {
case got := <-d.C:
if diff := cmp.Diff(got, want, cmp.AllowUnexported(got)); diff != "" {
if diff := cmp.Diff(got, want, cmp.AllowUnexported(got), cmpopts.IgnoreFields(stack.NeighborEntry{}, "UpdatedAt")); diff != "" {
return fmt.Errorf("got invalid event (-got +want):\n%s", diff)
}
case <-ctx.Done():
@ -373,9 +366,11 @@ func TestDirectRequestWithNeighborCache(t *testing.T) {
wantEvent := eventInfo{
eventType: entryAdded,
nicID: nicID,
addr: test.senderAddr,
linkAddr: tcpip.LinkAddress(test.senderLinkAddr),
state: stack.Stale,
entry: stack.NeighborEntry{
Addr: test.senderAddr,
LinkAddr: tcpip.LinkAddress(test.senderLinkAddr),
State: stack.Stale,
},
}
if err := c.nudDisp.waitForEventWithTimeout(wantEvent, time.Second); err != nil {
t.Fatal(err)

View File

@ -210,7 +210,7 @@ func (n *neighborCache) addStaticEntry(addr tcpip.Address, linkAddr tcpip.LinkAd
} else {
// Static entry found with the same address but different link address.
entry.neigh.LinkAddr = linkAddr
entry.dispatchChangeEventLocked(entry.neigh.State)
entry.dispatchChangeEventLocked()
entry.mu.Unlock()
return
}
@ -223,8 +223,7 @@ func (n *neighborCache) addStaticEntry(addr tcpip.Address, linkAddr tcpip.LinkAd
entry.mu.Unlock()
}
entry := newStaticNeighborEntry(n.nic, addr, linkAddr, n.state)
n.cache[addr] = entry
n.cache[addr] = newStaticNeighborEntry(n.nic, addr, linkAddr, n.state)
}
// removeEntryLocked removes the specified entry from the neighbor cache.

View File

@ -303,15 +303,19 @@ func TestNeighborCacheEntry(t *testing.T) {
{
EventType: entryTestAdded,
NICID: 1,
Addr: entry.Addr,
State: Incomplete,
Entry: NeighborEntry{
Addr: entry.Addr,
State: Incomplete,
},
},
{
EventType: entryTestChanged,
NICID: 1,
Addr: entry.Addr,
LinkAddr: entry.LinkAddr,
State: Reachable,
Entry: NeighborEntry{
Addr: entry.Addr,
LinkAddr: entry.LinkAddr,
State: Reachable,
},
},
}
nudDisp.mu.Lock()
@ -363,15 +367,19 @@ func TestNeighborCacheRemoveEntry(t *testing.T) {
{
EventType: entryTestAdded,
NICID: 1,
Addr: entry.Addr,
State: Incomplete,
Entry: NeighborEntry{
Addr: entry.Addr,
State: Incomplete,
},
},
{
EventType: entryTestChanged,
NICID: 1,
Addr: entry.Addr,
LinkAddr: entry.LinkAddr,
State: Reachable,
Entry: NeighborEntry{
Addr: entry.Addr,
LinkAddr: entry.LinkAddr,
State: Reachable,
},
},
}
nudDisp.mu.Lock()
@ -389,9 +397,11 @@ func TestNeighborCacheRemoveEntry(t *testing.T) {
{
EventType: entryTestRemoved,
NICID: 1,
Addr: entry.Addr,
LinkAddr: entry.LinkAddr,
State: Reachable,
Entry: NeighborEntry{
Addr: entry.Addr,
LinkAddr: entry.LinkAddr,
State: Reachable,
},
},
}
nudDisp.mu.Lock()
@ -468,23 +478,29 @@ func (c *testContext) overflowCache(opts overflowOptions) error {
wantEvents = append(wantEvents, testEntryEventInfo{
EventType: entryTestRemoved,
NICID: 1,
Addr: removedEntry.Addr,
LinkAddr: removedEntry.LinkAddr,
State: Reachable,
Entry: NeighborEntry{
Addr: removedEntry.Addr,
LinkAddr: removedEntry.LinkAddr,
State: Reachable,
},
})
}
wantEvents = append(wantEvents, testEntryEventInfo{
EventType: entryTestAdded,
NICID: 1,
Addr: entry.Addr,
State: Incomplete,
Entry: NeighborEntry{
Addr: entry.Addr,
State: Incomplete,
},
}, testEntryEventInfo{
EventType: entryTestChanged,
NICID: 1,
Addr: entry.Addr,
LinkAddr: entry.LinkAddr,
State: Reachable,
Entry: NeighborEntry{
Addr: entry.Addr,
LinkAddr: entry.LinkAddr,
State: Reachable,
},
})
c.nudDisp.mu.Lock()
@ -569,15 +585,19 @@ func TestNeighborCacheRemoveEntryThenOverflow(t *testing.T) {
{
EventType: entryTestAdded,
NICID: 1,
Addr: entry.Addr,
State: Incomplete,
Entry: NeighborEntry{
Addr: entry.Addr,
State: Incomplete,
},
},
{
EventType: entryTestChanged,
NICID: 1,
Addr: entry.Addr,
LinkAddr: entry.LinkAddr,
State: Reachable,
Entry: NeighborEntry{
Addr: entry.Addr,
LinkAddr: entry.LinkAddr,
State: Reachable,
},
},
}
c.nudDisp.mu.Lock()
@ -596,9 +616,11 @@ func TestNeighborCacheRemoveEntryThenOverflow(t *testing.T) {
{
EventType: entryTestRemoved,
NICID: 1,
Addr: entry.Addr,
LinkAddr: entry.LinkAddr,
State: Reachable,
Entry: NeighborEntry{
Addr: entry.Addr,
LinkAddr: entry.LinkAddr,
State: Reachable,
},
},
}
c.nudDisp.mu.Lock()
@ -636,9 +658,11 @@ func TestNeighborCacheDuplicateStaticEntryWithSameLinkAddress(t *testing.T) {
{
EventType: entryTestAdded,
NICID: 1,
Addr: entry.Addr,
LinkAddr: staticLinkAddr,
State: Static,
Entry: NeighborEntry{
Addr: entry.Addr,
LinkAddr: staticLinkAddr,
State: Static,
},
},
}
c.nudDisp.mu.Lock()
@ -678,9 +702,11 @@ func TestNeighborCacheDuplicateStaticEntryWithDifferentLinkAddress(t *testing.T)
{
EventType: entryTestAdded,
NICID: 1,
Addr: entry.Addr,
LinkAddr: staticLinkAddr,
State: Static,
Entry: NeighborEntry{
Addr: entry.Addr,
LinkAddr: staticLinkAddr,
State: Static,
},
},
}
c.nudDisp.mu.Lock()
@ -699,9 +725,11 @@ func TestNeighborCacheDuplicateStaticEntryWithDifferentLinkAddress(t *testing.T)
{
EventType: entryTestChanged,
NICID: 1,
Addr: entry.Addr,
LinkAddr: staticLinkAddr,
State: Static,
Entry: NeighborEntry{
Addr: entry.Addr,
LinkAddr: staticLinkAddr,
State: Static,
},
},
}
c.nudDisp.mu.Lock()
@ -736,9 +764,11 @@ func TestNeighborCacheRemoveStaticEntryThenOverflow(t *testing.T) {
{
EventType: entryTestAdded,
NICID: 1,
Addr: entry.Addr,
LinkAddr: staticLinkAddr,
State: Static,
Entry: NeighborEntry{
Addr: entry.Addr,
LinkAddr: staticLinkAddr,
State: Static,
},
},
}
c.nudDisp.mu.Lock()
@ -756,9 +786,11 @@ func TestNeighborCacheRemoveStaticEntryThenOverflow(t *testing.T) {
{
EventType: entryTestRemoved,
NICID: 1,
Addr: entry.Addr,
LinkAddr: staticLinkAddr,
State: Static,
Entry: NeighborEntry{
Addr: entry.Addr,
LinkAddr: staticLinkAddr,
State: Static,
},
},
}
c.nudDisp.mu.Lock()
@ -804,15 +836,19 @@ func TestNeighborCacheOverwriteWithStaticEntryThenOverflow(t *testing.T) {
{
EventType: entryTestAdded,
NICID: 1,
Addr: entry.Addr,
State: Incomplete,
Entry: NeighborEntry{
Addr: entry.Addr,
State: Incomplete,
},
},
{
EventType: entryTestChanged,
NICID: 1,
Addr: entry.Addr,
LinkAddr: entry.LinkAddr,
State: Reachable,
Entry: NeighborEntry{
Addr: entry.Addr,
LinkAddr: entry.LinkAddr,
State: Reachable,
},
},
}
c.nudDisp.mu.Lock()
@ -831,16 +867,20 @@ func TestNeighborCacheOverwriteWithStaticEntryThenOverflow(t *testing.T) {
{
EventType: entryTestRemoved,
NICID: 1,
Addr: entry.Addr,
LinkAddr: entry.LinkAddr,
State: Reachable,
Entry: NeighborEntry{
Addr: entry.Addr,
LinkAddr: entry.LinkAddr,
State: Reachable,
},
},
{
EventType: entryTestAdded,
NICID: 1,
Addr: entry.Addr,
LinkAddr: staticLinkAddr,
State: Static,
Entry: NeighborEntry{
Addr: entry.Addr,
LinkAddr: staticLinkAddr,
State: Static,
},
},
}
c.nudDisp.mu.Lock()
@ -917,15 +957,19 @@ func TestNeighborCacheNotifiesWaker(t *testing.T) {
{
EventType: entryTestAdded,
NICID: 1,
Addr: entry.Addr,
State: Incomplete,
Entry: NeighborEntry{
Addr: entry.Addr,
State: Incomplete,
},
},
{
EventType: entryTestChanged,
NICID: 1,
Addr: entry.Addr,
LinkAddr: entry.LinkAddr,
State: Reachable,
Entry: NeighborEntry{
Addr: entry.Addr,
LinkAddr: entry.LinkAddr,
State: Reachable,
},
},
}
nudDisp.mu.Lock()
@ -985,15 +1029,19 @@ func TestNeighborCacheRemoveWaker(t *testing.T) {
{
EventType: entryTestAdded,
NICID: 1,
Addr: entry.Addr,
State: Incomplete,
Entry: NeighborEntry{
Addr: entry.Addr,
State: Incomplete,
},
},
{
EventType: entryTestChanged,
NICID: 1,
Addr: entry.Addr,
LinkAddr: entry.LinkAddr,
State: Reachable,
Entry: NeighborEntry{
Addr: entry.Addr,
LinkAddr: entry.LinkAddr,
State: Reachable,
},
},
}
nudDisp.mu.Lock()
@ -1034,9 +1082,11 @@ func TestNeighborCacheAddStaticEntryThenOverflow(t *testing.T) {
{
EventType: entryTestAdded,
NICID: 1,
Addr: entry.Addr,
LinkAddr: entry.LinkAddr,
State: Static,
Entry: NeighborEntry{
Addr: entry.Addr,
LinkAddr: entry.LinkAddr,
State: Static,
},
},
}
c.nudDisp.mu.Lock()
@ -1090,15 +1140,19 @@ func TestNeighborCacheClear(t *testing.T) {
{
EventType: entryTestAdded,
NICID: 1,
Addr: entry.Addr,
State: Incomplete,
Entry: NeighborEntry{
Addr: entry.Addr,
State: Incomplete,
},
},
{
EventType: entryTestChanged,
NICID: 1,
Addr: entry.Addr,
LinkAddr: entry.LinkAddr,
State: Reachable,
Entry: NeighborEntry{
Addr: entry.Addr,
LinkAddr: entry.LinkAddr,
State: Reachable,
},
},
}
nudDisp.mu.Lock()
@ -1117,9 +1171,11 @@ func TestNeighborCacheClear(t *testing.T) {
{
EventType: entryTestAdded,
NICID: 1,
Addr: entryTestAddr1,
LinkAddr: entryTestLinkAddr1,
State: Static,
Entry: NeighborEntry{
Addr: entryTestAddr1,
LinkAddr: entryTestLinkAddr1,
State: Static,
},
},
}
nudDisp.mu.Lock()
@ -1140,16 +1196,20 @@ func TestNeighborCacheClear(t *testing.T) {
{
EventType: entryTestRemoved,
NICID: 1,
Addr: entry.Addr,
LinkAddr: entry.LinkAddr,
State: Reachable,
Entry: NeighborEntry{
Addr: entry.Addr,
LinkAddr: entry.LinkAddr,
State: Reachable,
},
},
{
EventType: entryTestRemoved,
NICID: 1,
Addr: entryTestAddr1,
LinkAddr: entryTestLinkAddr1,
State: Static,
Entry: NeighborEntry{
Addr: entryTestAddr1,
LinkAddr: entryTestLinkAddr1,
State: Static,
},
},
}
nudDisp.mu.Lock()
@ -1184,15 +1244,19 @@ func TestNeighborCacheClearThenOverflow(t *testing.T) {
{
EventType: entryTestAdded,
NICID: 1,
Addr: entry.Addr,
State: Incomplete,
Entry: NeighborEntry{
Addr: entry.Addr,
State: Incomplete,
},
},
{
EventType: entryTestChanged,
NICID: 1,
Addr: entry.Addr,
LinkAddr: entry.LinkAddr,
State: Reachable,
Entry: NeighborEntry{
Addr: entry.Addr,
LinkAddr: entry.LinkAddr,
State: Reachable,
},
},
}
c.nudDisp.mu.Lock()
@ -1210,9 +1274,11 @@ func TestNeighborCacheClearThenOverflow(t *testing.T) {
{
EventType: entryTestRemoved,
NICID: 1,
Addr: entry.Addr,
LinkAddr: entry.LinkAddr,
State: Reachable,
Entry: NeighborEntry{
Addr: entry.Addr,
LinkAddr: entry.LinkAddr,
State: Reachable,
},
},
}
c.nudDisp.mu.Lock()
@ -1278,15 +1344,19 @@ func TestNeighborCacheKeepFrequentlyUsed(t *testing.T) {
{
EventType: entryTestAdded,
NICID: 1,
Addr: entry.Addr,
State: Incomplete,
Entry: NeighborEntry{
Addr: entry.Addr,
State: Incomplete,
},
},
{
EventType: entryTestChanged,
NICID: 1,
Addr: entry.Addr,
LinkAddr: entry.LinkAddr,
State: Reachable,
Entry: NeighborEntry{
Addr: entry.Addr,
LinkAddr: entry.LinkAddr,
State: Reachable,
},
},
}
nudDisp.mu.Lock()
@ -1331,22 +1401,28 @@ func TestNeighborCacheKeepFrequentlyUsed(t *testing.T) {
{
EventType: entryTestRemoved,
NICID: 1,
Addr: removedEntry.Addr,
LinkAddr: removedEntry.LinkAddr,
State: Reachable,
Entry: NeighborEntry{
Addr: removedEntry.Addr,
LinkAddr: removedEntry.LinkAddr,
State: Reachable,
},
},
{
EventType: entryTestAdded,
NICID: 1,
Addr: entry.Addr,
State: Incomplete,
Entry: NeighborEntry{
Addr: entry.Addr,
State: Incomplete,
},
},
{
EventType: entryTestChanged,
NICID: 1,
Addr: entry.Addr,
LinkAddr: entry.LinkAddr,
State: Reachable,
Entry: NeighborEntry{
Addr: entry.Addr,
LinkAddr: entry.LinkAddr,
State: Reachable,
},
},
}
nudDisp.mu.Lock()

View File

@ -117,22 +117,23 @@ func newNeighborEntry(nic *NIC, remoteAddr tcpip.Address, nudState *NUDState, li
}
}
// newStaticNeighborEntry creates a neighbor cache entry starting at the Static
// state. The entry can only transition out of Static by directly calling
// `setStateLocked`.
// newStaticNeighborEntry creates a neighbor cache entry starting at the
// Static state. The entry can only transition out of Static by directly
// calling `setStateLocked`.
func newStaticNeighborEntry(nic *NIC, addr tcpip.Address, linkAddr tcpip.LinkAddress, state *NUDState) *neighborEntry {
entry := NeighborEntry{
Addr: addr,
LinkAddr: linkAddr,
State: Static,
UpdatedAt: time.Now(),
}
if nic.stack.nudDisp != nil {
nic.stack.nudDisp.OnNeighborAdded(nic.id, addr, linkAddr, Static, time.Now())
nic.stack.nudDisp.OnNeighborAdded(nic.id, entry)
}
return &neighborEntry{
nic: nic,
nudState: state,
neigh: NeighborEntry{
Addr: addr,
LinkAddr: linkAddr,
State: Static,
UpdatedAt: time.Now(),
},
neigh: entry,
}
}
@ -163,17 +164,17 @@ func (e *neighborEntry) notifyWakersLocked() {
// dispatchAddEventLocked signals to stack's NUD Dispatcher that the entry has
// been added.
func (e *neighborEntry) dispatchAddEventLocked(nextState NeighborState) {
func (e *neighborEntry) dispatchAddEventLocked() {
if nudDisp := e.nic.stack.nudDisp; nudDisp != nil {
nudDisp.OnNeighborAdded(e.nic.id, e.neigh.Addr, e.neigh.LinkAddr, nextState, time.Now())
nudDisp.OnNeighborAdded(e.nic.id, e.neigh)
}
}
// dispatchChangeEventLocked signals to stack's NUD Dispatcher that the entry
// has changed state or link-layer address.
func (e *neighborEntry) dispatchChangeEventLocked(nextState NeighborState) {
func (e *neighborEntry) dispatchChangeEventLocked() {
if nudDisp := e.nic.stack.nudDisp; nudDisp != nil {
nudDisp.OnNeighborChanged(e.nic.id, e.neigh.Addr, e.neigh.LinkAddr, nextState, time.Now())
nudDisp.OnNeighborChanged(e.nic.id, e.neigh)
}
}
@ -181,7 +182,7 @@ func (e *neighborEntry) dispatchChangeEventLocked(nextState NeighborState) {
// has been removed.
func (e *neighborEntry) dispatchRemoveEventLocked() {
if nudDisp := e.nic.stack.nudDisp; nudDisp != nil {
nudDisp.OnNeighborRemoved(e.nic.id, e.neigh.Addr, e.neigh.LinkAddr, e.neigh.State, time.Now())
nudDisp.OnNeighborRemoved(e.nic.id, e.neigh)
}
}
@ -208,15 +209,15 @@ func (e *neighborEntry) setStateLocked(next NeighborState) {
case Reachable:
e.job = e.nic.stack.newJob(&e.mu, func() {
e.dispatchChangeEventLocked(Stale)
e.setStateLocked(Stale)
e.dispatchChangeEventLocked()
})
e.job.Schedule(e.nudState.ReachableTime())
case Delay:
e.job = e.nic.stack.newJob(&e.mu, func() {
e.dispatchChangeEventLocked(Probe)
e.setStateLocked(Probe)
e.dispatchChangeEventLocked()
})
e.job.Schedule(config.DelayFirstProbeTime)
@ -266,10 +267,11 @@ func (e *neighborEntry) setStateLocked(next NeighborState) {
func (e *neighborEntry) handlePacketQueuedLocked(localAddr tcpip.Address) {
switch e.neigh.State {
case Unknown:
e.dispatchAddEventLocked(Incomplete)
e.neigh.State = Incomplete
e.neigh.UpdatedAt = time.Now()
e.dispatchAddEventLocked()
config := e.nudState.Config()
var retryCounter uint32
@ -326,8 +328,8 @@ func (e *neighborEntry) handlePacketQueuedLocked(localAddr tcpip.Address) {
sendMulticastProbe()
case Stale:
e.dispatchChangeEventLocked(Delay)
e.setStateLocked(Delay)
e.dispatchChangeEventLocked()
case Incomplete, Reachable, Delay, Probe, Static, Failed:
// Do nothing
@ -349,21 +351,21 @@ func (e *neighborEntry) handleProbeLocked(remoteLinkAddr tcpip.LinkAddress) {
switch e.neigh.State {
case Unknown, Incomplete, Failed:
e.neigh.LinkAddr = remoteLinkAddr
e.dispatchAddEventLocked(Stale)
e.setStateLocked(Stale)
e.notifyWakersLocked()
e.dispatchAddEventLocked()
case Reachable, Delay, Probe:
if e.neigh.LinkAddr != remoteLinkAddr {
e.neigh.LinkAddr = remoteLinkAddr
e.dispatchChangeEventLocked(Stale)
e.setStateLocked(Stale)
e.dispatchChangeEventLocked()
}
case Stale:
if e.neigh.LinkAddr != remoteLinkAddr {
e.neigh.LinkAddr = remoteLinkAddr
e.dispatchChangeEventLocked(Stale)
e.dispatchChangeEventLocked()
}
case Static:
@ -397,12 +399,11 @@ func (e *neighborEntry) handleConfirmationLocked(linkAddr tcpip.LinkAddress, fla
e.neigh.LinkAddr = linkAddr
if flags.Solicited {
e.dispatchChangeEventLocked(Reachable)
e.setStateLocked(Reachable)
} else {
e.dispatchChangeEventLocked(Stale)
e.setStateLocked(Stale)
}
e.dispatchChangeEventLocked()
e.isRouter = flags.IsRouter
e.notifyWakersLocked()
@ -415,8 +416,8 @@ func (e *neighborEntry) handleConfirmationLocked(linkAddr tcpip.LinkAddress, fla
if isLinkAddrDifferent {
if !flags.Override {
if e.neigh.State == Reachable {
e.dispatchChangeEventLocked(Stale)
e.setStateLocked(Stale)
e.dispatchChangeEventLocked()
}
break
}
@ -425,23 +426,24 @@ func (e *neighborEntry) handleConfirmationLocked(linkAddr tcpip.LinkAddress, fla
if !flags.Solicited {
if e.neigh.State != Stale {
e.dispatchChangeEventLocked(Stale)
e.setStateLocked(Stale)
e.dispatchChangeEventLocked()
} else {
// Notify the LinkAddr change, even though NUD state hasn't changed.
e.dispatchChangeEventLocked(e.neigh.State)
e.dispatchChangeEventLocked()
}
break
}
}
if flags.Solicited && (flags.Override || !isLinkAddrDifferent) {
if e.neigh.State != Reachable {
e.dispatchChangeEventLocked(Reachable)
}
wasReachable := e.neigh.State == Reachable
// Set state to Reachable again to refresh timers.
e.setStateLocked(Reachable)
e.notifyWakersLocked()
if !wasReachable {
e.dispatchChangeEventLocked()
}
}
if e.isRouter && !flags.IsRouter && header.IsV6UnicastAddress(e.neigh.Addr) {
@ -479,11 +481,12 @@ func (e *neighborEntry) handleConfirmationLocked(linkAddr tcpip.LinkAddress, fla
func (e *neighborEntry) handleUpperLevelConfirmationLocked() {
switch e.neigh.State {
case Reachable, Stale, Delay, Probe:
if e.neigh.State != Reachable {
e.dispatchChangeEventLocked(Reachable)
// Set state to Reachable again to refresh timers.
}
wasReachable := e.neigh.State == Reachable
// Set state to Reachable again to refresh timers.
e.setStateLocked(Reachable)
if !wasReachable {
e.dispatchChangeEventLocked()
}
case Unknown, Incomplete, Failed, Static:
// Do nothing

File diff suppressed because it is too large Load Diff

View File

@ -129,7 +129,7 @@ type NUDDispatcher interface {
// the stack's operation.
//
// May be called concurrently.
OnNeighborAdded(nicID tcpip.NICID, ipAddr tcpip.Address, linkAddr tcpip.LinkAddress, state NeighborState, updatedAt time.Time)
OnNeighborAdded(tcpip.NICID, NeighborEntry)
// OnNeighborChanged will be called when an entry in a NIC's (with ID nicID)
// neighbor table changes state and/or link address.
@ -138,7 +138,7 @@ type NUDDispatcher interface {
// the stack's operation.
//
// May be called concurrently.
OnNeighborChanged(nicID tcpip.NICID, ipAddr tcpip.Address, linkAddr tcpip.LinkAddress, state NeighborState, updatedAt time.Time)
OnNeighborChanged(tcpip.NICID, NeighborEntry)
// OnNeighborRemoved will be called when an entry is removed from a NIC's
// (with ID nicID) neighbor table.
@ -147,7 +147,7 @@ type NUDDispatcher interface {
// the stack's operation.
//
// May be called concurrently.
OnNeighborRemoved(nicID tcpip.NICID, ipAddr tcpip.Address, linkAddr tcpip.LinkAddress, state NeighborState, updatedAt time.Time)
OnNeighborRemoved(tcpip.NICID, NeighborEntry)
}
// ReachabilityConfirmationFlags describes the flags used within a reachability