google / google/gvisor

Propagate asynchronously generated ICMP errors to local endpoints

Open
#6,005 1 comment 0 reactions 0 assignees View on GitHub
area: networking type: enhancement
Dominant language
Go
Stars
19.3k
Forks
2k
Avg merge
3d 7h
Merged PRs (30d)
275

Description

Currently, when we encounter an ICMP error condition, we return[1] an ICMP error packet to the source.

In addition to this behavior, there is a use case for propagating ICMP errors to the local transport endpoint: handling link resolution errors.

"
Link resolution errors are a special case since their errors are generated asynchronously. The transport endpoint performs a write call and is returned a success value while link resolution is performed.

Now, how do we propagate an error to the endpoint?

Here we fake an ICMP error and let the IP layer inform the transport dispatcher about the destination host unreachable error, but this assumes that the addresses in `pkt` were never modified. This is true as of today but will no longer be true once we add SNAT/DNAT targets that don't simply loop traffic back to ourselves.

Consider a Destination NAT rule that rewrites all destination addresses from 1.1.1.1 to 2.2.2.2. Now when a packet is written with source = 5.5.5.5 to destination = 1.1.1.1, the IP layer will perform iptables hooks which eventually rewrite the packet such that source = 5.5.5.5 and destination = 2.2.2.2.

Now imagine this rewritten packet will trigger link resolution and imagine link resolution fails. We would end up here with a packet with source = 5.5.5.5 and destination = 2.2.2.2. This packet gets propagated to the transport dispatcher which will look for an endpoint matching the addresses (and ports) but fail since no endpoint uses 2.2.2.2 (we use 1.1.1.1 but the packet was re-written). Obviously this is bad because endpoints will never receive ICMP errors.

An easy solution to this is to just let ICMP errors flow up the stack and let iptables un-do the rewriting that it performed on the original packet.
"

[1]: https://cs.opensource.google/fuchsia/fuchsia/+/main:third_party/golibs/vendor/gvisor.dev/gvisor/pkg/tcpip/network/ipv4/icmp.go;l=489?q=gvisor%2Fpkg%2Ftcpip%2Fnetwork%2Fipv4%2Ficm

Contributor guide

Open the contributing guide

Research direction

Start with the linked network/ipv4/icmp.go code and trace how IP-layer ICMP errors reach the transport dispatcher after link resolution fails. Investigate the iptables address-rewriting path and the local endpoint lookup. Done means asynchronously generated errors reach the original transport endpoint even when rewriting changed the packet addresses.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
networking
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.