Currently, when a packet hits the NAT table and does not hit any NAT targets,
its connection is assigned "no-op NAT", which basically means that the
connection will not be NATed. However, this causes a problem when, for example,
locally-generated traffic chooses a local port that has already been used by
forwarded traffic that the stack is NATing. In this case, the locally-generated
traffic will simply be dropped when the connection is finalized due to a tuple
conflict.
Instead of doing nothing, the netstack must implicitly perform SNAT for the
locally-generated traffic to remap its source port to prevent that traffic from
being dropped.
Also, when setting up NAT for a connection, the netstack checks if the
connections' reply tuple is unique to see whether it needs to rewrite the
transport-layer port/ID. This logic currently doesn't account for self-connected
sockets, where the original and reply tuples are identical and point to the same
connection; add logic handling that scenario, such that the reply tuple can be
non-unique if it refers to the same connection as the original tuple.
PiperOrigin-RevId: 612969884
... instead of depending on a flag.
In most cases the NAT table is in an all-ACCEPT default state:
```
root@5a7ce3a6c623:/# iptables -t nat -S
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P OUTPUT ACCEPT
-P POSTROUTING ACCEPT
```
In such cases we leave iptables off in the sandbox as a performance
optimization.
But when the table contains anything else, we now install those rules inside
the sandbox.
Turns out packetdrill installes a rule, so support for that rules is also added
in this CL.
PiperOrigin-RevId: 580051079
The important change here is in tcpip/tcpip.go, where tcpip.Address is defined.
The rest is updating uses of tcpip.Address.
This is preparation for netip.Addr or []byte based addresses, which should save
us a bunch of allocations. Currently, we allocate every time we want to, say,
get a tcpip.Address from a header. This is because the header is a byte slice,
but Address is a string. Strings are immutable, so Go allocates and copies.
PiperOrigin-RevId: 532284732
This is effectively a rollback of cl/450976957. The original motivation never
panned out, and it's easier to work with the lists. They also are easier to
avoid allocations with.
PiperOrigin-RevId: 531020857
Checksum capabilities are logically separate from tcpip header definitions
and operations. It makes sense to extract this logic into its own package.
This is also necessary to avoid circular dependencies with bufferv2.
PiperOrigin-RevId: 473096480
This change has significant performance implications. bufferv2 is reference
counted and pooled, which alleviates heap/GC pressure. Below are the results
from running the iperf benchmark.
HEAD:
BenchmarkIperf/operation.Upload-16 1552 ns/op 46.6GiB total allocations
BenchmarkIperf/operation.Download-16 1114 ns/op 68.6GiB total allocations
w/ change:
BenchmarkIperf/operation.Upload-16 1139 ns/op (-27%) 1.41GiB total allocations (-97%)
BenchmarkIperf/operation.Download-16 753.2 ns/op (-33%) 706MiB total allocations (-99%)
PiperOrigin-RevId: 462453185
Conntrack, like Linux, now skips bad packets entirely and lets the appropriate
layer deal with them. See net/netfilter/nf_conntrack_core.c:nf_conntrack_in.
This change shares the bad packet detection code between conntrack and TCP/UDP
so that they see the same packets as bad.
PiperOrigin-RevId: 452374626
Before this change, locally generated ICMPv4 replies would not
perform the Output hook so NAT will not be performed for locally
generated ICMPv4 replies. This change fixes that bug.
PiperOrigin-RevId: 418513563
https://github.com/google/gvisor/commit/4ab52f3cfdbe2c75c6525aa6732210a6d5d64b11
introduced a change to drop packets if we fail to insert the reply
tuple. This change did not take into consideration the case where the
original tuple ID is the same as the reply tuple ID. In this case, we
will have a "reply tuple conflict". However, since the reply tuple is
the same as the original tuple, we should not consider the conflict
as a real conflict since reply packets will map to the original tuple.
Updates #6850.
The change referenced above is cl/410368440.
PiperOrigin-RevId: 417634147