Send NUD probes in a separate gorountine
Send NUD probes in another gorountine to free the thread of execution for finishing the state transition. This is necessary to avoid deadlock where sending and processing probes are done in the same call stack, such as loopback and integration tests. Fixes #4701 PiperOrigin-RevId: 340362481
This commit is contained in:
parent
51b062f6cd
commit
c22067d3d4
|
@ -17,12 +17,19 @@ package stack
|
|||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/sleep"
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/header"
|
||||
)
|
||||
|
||||
const (
|
||||
// immediateDuration is a duration of zero for scheduling work that needs to
|
||||
// be done immediately but asynchronously to avoid deadlock.
|
||||
immediateDuration time.Duration = 0
|
||||
)
|
||||
|
||||
// NeighborEntry describes a neighboring device in the local network.
|
||||
type NeighborEntry struct {
|
||||
Addr tcpip.Address
|
||||
|
@ -242,7 +249,12 @@ func (e *neighborEntry) setStateLocked(next NeighborState) {
|
|||
e.job.Schedule(config.RetransmitTimer)
|
||||
}
|
||||
|
||||
sendUnicastProbe()
|
||||
// Send a probe in another gorountine to free this thread of execution
|
||||
// for finishing the state transition. This is necessary to avoid
|
||||
// deadlock where sending and processing probes are done synchronously,
|
||||
// such as loopback and integration tests.
|
||||
e.job = e.nic.stack.newJob(&e.mu, sendUnicastProbe)
|
||||
e.job.Schedule(immediateDuration)
|
||||
|
||||
case Failed:
|
||||
e.notifyWakersLocked()
|
||||
|
@ -324,7 +336,12 @@ func (e *neighborEntry) handlePacketQueuedLocked(localAddr tcpip.Address) {
|
|||
e.job.Schedule(config.RetransmitTimer)
|
||||
}
|
||||
|
||||
sendMulticastProbe()
|
||||
// Send a probe in another gorountine to free this thread of execution
|
||||
// for finishing the state transition. This is necessary to avoid
|
||||
// deadlock where sending and processing probes are done synchronously,
|
||||
// such as loopback and integration tests.
|
||||
e.job = e.nic.stack.newJob(&e.mu, sendMulticastProbe)
|
||||
e.job.Schedule(immediateDuration)
|
||||
|
||||
case Stale:
|
||||
e.setStateLocked(Delay)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue