[PATCH v2 0/8] Cleanups to auto port scanning
One of the trickiest parts of implementing the improved forwarding table is integrating it properly with automatic forwarding (-t auto etc.). Here are some preliminary cleanups to the automatic port scanning that will make the job a bit easier. v2: * Rename bitmap_andc() to bitmap_and_not() (4/8) * Fixed comment formatting error (4/8) * Updated commit message based on further information from Stefano (7,8/8) * All other patches unchanged, except for trivial rebase fixes David Gibson (8): icmp: Remove vestiges of ICMP timer tcp, udp, fwd: Run all port scanning from a single timer fwd: Consolidate scans (not rebinds) in fwd.c fwd: Move port exclusion handling from procfs_scan_listen() to callers fwd: Share port scanning logic between init and timer cases fwd: Check forwarding mode in fwd_scan_ports_*() rather than caller fwd: Update all port maps before applying exclusions tcp, udp: Don't exclude ports in {tcp,udp}_port_rebind() fwd.c | 107 ++++++++++++++++++++++++++++++++++++++------------------ fwd.h | 7 ++-- icmp.h | 2 -- passt.c | 8 ++--- tcp.c | 34 +++++++++--------- tcp.h | 3 +- udp.c | 31 ++++------------ udp.h | 4 +-- util.c | 24 +++++++++++++ util.h | 2 ++ 10 files changed, 131 insertions(+), 91 deletions(-) -- 2.51.0
fwd_scan_ports_timer(), via the things it calls, goes through all the auto
forwarding cases (tcp, udp, inbound, outbound) and for each one first scans
for listening ports, then rebinds - that is, closes or opens our own
listening ports to match.
Rearrange to do all the scans first, then all the rebinds after. This lets
us consolidate all the scans into fwd.c, and will enable further cleanups.
Signed-off-by: David Gibson
We no longer have a global ICMP timer (timers for individual flows are
handled through the flow timer). We still have an ICMP_TIMER_INTERVAL
define, though. Remove it.
Signed-off-by: David Gibson
With -t auto and similar options we need to periodically scan /proc for
listening ports. Currently we do this separately for TCP and UDP, from
tcp_timer() and udp_timer().
For upcoming changes (leading eventually to a more general forwarding
table), it's awkward to have these separate. Move them to a single common
timer. For now this just calls new tcp_scan_ports() and udp_scan_ports()
functions, but we'll consolidate more thoroughly in later patches.
Signed-off-by: David Gibson
To avoid forwarding loops, we need to exclude certain ports from being
auto-forwarded. To accomplish this, procfs_scan_listen() takes a bitmap
of exclusions. As it detects each port, it checks against that bitmap.
This is a complicated way of accomplishing what we need. We can instead
mask out the excluded ports in the callers using a new bitmap_and_not()
helper.
Signed-off-by: David Gibson
In fwd_scan_ports() we go through each of the automatic forwarding cases
(tcp, udp, inbound and outbound) in turn, scanning and calculating the
new forwarding map. However, to avoid avoid circular forwarding, some of
these maps affect each other. This has the odd effect that the ones
handled earlier are based on the previous scan of other maps, whereas
the later ones are based on the latest scan.
That's not generally harmful, but it is counter-intuitive and results in a
few odd edge cases. Avoid this by performing all the scans first, without
regard to other maps, then applying the exclusions afterwards.
One case has an extra wrinkle: for UDP we forwarded not just ports that
were listening on UDP but ones listening on TCP as well, for the benefit of
protocols like iperf3. We therefore also excluded listening ports from
both UDP and TCP from the other direction to avoid circular forwarding.
This doesn't really make sense, though. To avoid circular forwarding, we
don't care *why* the other side is listening on UDP, just that it *is*
listening. This was only needed because the reverse map might have been
one cycle out of date and therefore not included a port opened because of
the corresponding TCP port.
Now that we avoid that out of date map possibility, it's sufficient to
just mask out UDP listening ports in the other direction.
Signed-off-by: David Gibson
To avoid circular forwarding, {tcp,udp}_port_rebind() refuse to listen on
ports that we're already listening on in the reverse direction. This is
redundant, because we already remove such ports from the forward map when
we scan. This was needed previously, because our reverse maps might have
been one cycle out of date, so could be missing a newly appeared port.
We've now rearranged the port scanning code to avoid that, so we don't need
the check in tcp_port_rebind() any more.
Signed-off-by: David Gibson
fwd_scan_ports() needs to check for FWD_AUTO mode before calling each
scan function - otherwise it would clobber the forwarding bitmap which
should retain the user's fixed configuration.
Make this slightly cleaner and safer by moving the mode check into
fwd_scan_ports_{tcp,udp}().
Signed-off-by: David Gibson
When using -t auto and the like, we scan for listening ports once at
startup, then repeatedly on a timer. With previous rearrangements the
logic for each of these cases is very nearly repeated. Factor it out into
a fwd_scan_ports() function.
Signed-off-by: David Gibson
On Fri, 31 Oct 2025 15:19:22 +1100
David Gibson
One of the trickiest parts of implementing the improved forwarding table is integrating it properly with automatic forwarding (-t auto etc.). Here are some preliminary cleanups to the automatic port scanning that will make the job a bit easier.
v2: * Rename bitmap_andc() to bitmap_and_not() (4/8) * Fixed comment formatting error (4/8) * Updated commit message based on further information from Stefano (7,8/8) * All other patches unchanged, except for trivial rebase fixes
Applied. -- Stefano
participants (2)
-
David Gibson
-
Stefano Brivio