diff options
author | Ghanan Gowripalan <ghanan@google.com> | 2021-02-06 09:07:26 -0800 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2021-02-06 09:09:19 -0800 |
commit | c19e049f2c79ee9864cc273f6dc714b5caa434ca (patch) | |
tree | b36a569a4ce155548d75874b5237ada9792953f7 /pkg/tcpip/network/ipv4/icmp.go | |
parent | 83b764d9d2193e2e01f3a60792f3468c1843c5a8 (diff) |
Check local address directly through NIC
Network endpoints that wish to check addresses on another NIC-local
network endpoint may now do so through the NetworkInterface.
This fixes a lock ordering issue between NIC removal and link
resolution. Before this change:
NIC Removal takes the stack lock, neighbor cache lock then neighbor
entries' locks.
When performing IPv4 link resolution, we take the entry lock then ARP
would try check IPv4 local addresses through the stack which tries to
obtain the stack's lock.
Now that ARP can check IPv4 addreses through the NIC, we avoid the lock
ordering issue, while also removing the need for stack to lookup the
NIC.
PiperOrigin-RevId: 356034245
Diffstat (limited to 'pkg/tcpip/network/ipv4/icmp.go')
-rw-r--r-- | pkg/tcpip/network/ipv4/icmp.go | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/pkg/tcpip/network/ipv4/icmp.go b/pkg/tcpip/network/ipv4/icmp.go index 74e70e283..2b7bc0dd0 100644 --- a/pkg/tcpip/network/ipv4/icmp.go +++ b/pkg/tcpip/network/ipv4/icmp.go @@ -120,6 +120,18 @@ func (*icmpv4FragmentationNeededSockError) Kind() stack.TransportErrorKind { return stack.PacketTooBigTransportError } +func (e *endpoint) checkLocalAddress(addr tcpip.Address) bool { + if e.nic.Spoofing() { + return true + } + + if addressEndpoint := e.AcquireAssignedAddress(addr, false, stack.NeverPrimaryEndpoint); addressEndpoint != nil { + addressEndpoint.DecRef() + return true + } + return false +} + // handleControl handles the case when an ICMP error packet contains the headers // of the original packet that caused the ICMP one to be sent. This information // is used to find out which transport endpoint must be notified about the ICMP @@ -139,7 +151,7 @@ func (e *endpoint) handleControl(errInfo stack.TransportError, pkt *stack.Packet // Drop packet if it doesn't have the basic IPv4 header or if the // original source address doesn't match an address we own. srcAddr := hdr.SourceAddress() - if e.protocol.stack.CheckLocalAddress(e.nic.ID(), ProtocolNumber, srcAddr) == 0 { + if !e.checkLocalAddress(srcAddr) { return } |