diff options
author | Ghanan Gowripalan <ghanan@google.com> | 2021-01-15 18:12:50 -0800 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2021-01-15 18:15:26 -0800 |
commit | 2814a032be7b34e4cc0c0607dba8030e74e11208 (patch) | |
tree | fc6a023766f5ad1ae5818abd710c997ba657e8bd /pkg/tcpip/link | |
parent | fd5b52c87ff8fbabf2b293fc95ec9f9f04e5621c (diff) |
Support GetLinkAddress with neighborCache
Test: integration_test.TestGetLinkAddress
PiperOrigin-RevId: 352119404
Diffstat (limited to 'pkg/tcpip/link')
-rw-r--r-- | pkg/tcpip/link/pipe/pipe.go | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/pkg/tcpip/link/pipe/pipe.go b/pkg/tcpip/link/pipe/pipe.go index 12e246e21..d6e83a414 100644 --- a/pkg/tcpip/link/pipe/pipe.go +++ b/pkg/tcpip/link/pipe/pipe.go @@ -55,7 +55,22 @@ func (e *Endpoint) WritePacket(r stack.RouteInfo, _ *stack.GSO, proto tcpip.Netw // remote address from the perspective of the other end of the pipe // (e.linked). Similarly, the remote address from the perspective of this // endpoint is the local address on the other end. - e.linked.dispatcher.DeliverNetworkPacket(r.LocalLinkAddress /* remote */, r.RemoteLinkAddress /* local */, proto, stack.NewPacketBuffer(stack.PacketBufferOptions{ + // + // Deliver the packet in a new goroutine to escape this goroutine's stack and + // avoid a deadlock when a packet triggers a response which leads the stack to + // try and take a lock it already holds. + // + // As of writing, a deadlock may occur when performing link resolution as the + // neighbor table will send a solicitation while holding a lock and the + // response advertisement will be sent in the same stack that sent the + // solictation. When the response is received, the stack attempts to take the + // same lock it already took before sending the solicitation, leading to a + // deadlock. Basically, we attempt to lock the same lock twice in the same + // call stack. + // + // TODO(gvisor.dev/issue/5289): don't use a new goroutine once we support send + // and receive queues. + go e.linked.dispatcher.DeliverNetworkPacket(r.LocalLinkAddress /* remote */, r.RemoteLinkAddress /* local */, proto, stack.NewPacketBuffer(stack.PacketBufferOptions{ Data: buffer.NewVectorisedView(pkt.Size(), pkt.Views()), })) |