diff --git a/pkg/tcpip/stack/nic.go b/pkg/tcpip/stack/nic.go index ef5282dfe..6af2af9a1 100644 --- a/pkg/tcpip/stack/nic.go +++ b/pkg/tcpip/stack/nic.go @@ -316,9 +316,13 @@ func (n *nic) remove() tcpip.Error { ep.Close() } + // drain and drop any packets pending link resolution. + n.linkResQueue.cancel() + // Prevent packets from going down to the link before shutting the link down. n.qDisc.Close() n.NetworkLinkEndpoint.Attach(nil) + return nil } diff --git a/pkg/tcpip/stack/pending_packets.go b/pkg/tcpip/stack/pending_packets.go index 434355d00..3584da448 100644 --- a/pkg/tcpip/stack/pending_packets.go +++ b/pkg/tcpip/stack/pending_packets.go @@ -70,6 +70,20 @@ func (f *packetsPendingLinkResolution) init(nic *nic) { f.mu.packets = make(map[<-chan struct{}][]pendingPacket) } +// cancel drains all pending packet queues and release all packet +// references. +func (f *packetsPendingLinkResolution) cancel() { + f.mu.Lock() + defer f.mu.Unlock() + for ch, pendingPackets := range f.mu.packets { + for _, p := range pendingPackets { + p.pkt.DecRef() + } + delete(f.mu.packets, ch) + } + f.mu.cancelChans = nil +} + // dequeue any pending packets associated with ch. // // If err is nil, packets will be written and sent to the given remote link