On Tue, 13 Jan 2026 17:57:11 +0800
Yumei Huang
On Sun, Jan 11, 2026 at 2:12 AM Stefano Brivio
wrote: On Mon, 5 Jan 2026 16:53:49 +0800 Yumei Huang
wrote: On Mon, Jan 5, 2026 at 12:18 PM David Gibson
wrote: On Mon, Dec 29, 2025 at 05:55:58PM +0800, Yumei Huang wrote:
This patch introduces a mode where we only forward loopback connections and traffic between two namespaces (via the loopback interface, 'lo'), without a tap device.
With this, podman can support forwarding ::1 in custom networks when using rootlesskit for forwarding ports.
In --no-tap mode, --host-lo-to-ns-lo, --no-icmp and --no-ra is automatically enabled. Options requiring a tap device (--ns-ifname, --ns-mac-addr, --config-net, --outbound-if4/6) are rejected.
Link: https://bugs.passt.top/show_bug.cgi?id=149 Signed-off-by: Yumei Huang
Nice work. There are some things that need polish, but overall this looks pretty good to me. Like Stefano, I'm pleasantly surprised at how simple it turned out to be.
--- conf.c | 56 +++++++++++++++++++++++++++++++++++++++++--------------- fwd.c | 3 +++ passt.1 | 5 +++++ passt.h | 2 ++ pasta.c | 3 +++ tap.c | 11 +++++++---- 6 files changed, 61 insertions(+), 19 deletions(-)
diff --git a/conf.c b/conf.c index 84ae12b..353d0a5 100644 --- a/conf.c +++ b/conf.c @@ -1049,7 +1049,8 @@ pasta_opts: " --no-copy-addrs DEPRECATED:\n" " Don't copy all addresses to namespace\n" " --ns-mac-addr ADDR Set MAC address on tap interface\n" - " --no-splice Disable inbound socket splicing\n"); + " --no-splice Disable inbound socket splicing\n" + " --no-tap Don't create tap device\n");
I feel like this description can be improved, but I'm not exactly sure how, yet.
A few possible alternatives:
- "Only enable loopback forwarding"
Thanks, I will go with this and --splice-only.
- "Loopback only from/to namespace"
- call it --splice-only, and use one of the descriptions above
- call it --loopback-only, and use one of the descriptions above
passt_exit(status); } @@ -1451,6 +1452,7 @@ void conf(struct ctx *c, int argc, char **argv) {"no-ndp", no_argument, &c->no_ndp, 1 }, {"no-ra", no_argument, &c->no_ra, 1 }, {"no-splice", no_argument, &c->no_splice, 1 }, + {"no-tap", no_argument, &c->no_tap, 1 }, {"freebind", no_argument, &c->freebind, 1 }, {"no-map-gw", no_argument, &no_map_gw, 1 }, {"ipv4-only", no_argument, NULL, '4' }, @@ -1947,8 +1949,11 @@ void conf(struct ctx *c, int argc, char **argv) } } while (name != -1);
- if (c->mode != MODE_PASTA) + if (c->mode != MODE_PASTA) { c->no_splice = 1; + if (c->no_tap) + die("--no-tap is for pasta mode only"); + }
if (c->mode == MODE_PASTA && !c->pasta_conf_ns) { if (copy_routes_opt) @@ -1957,6 +1962,25 @@ void conf(struct ctx *c, int argc, char **argv) die("--no-copy-addrs needs --config-net"); }
+ if (c->mode == MODE_PASTA && c->no_tap) { + if (c->no_splice) + die("--no-tap is incompatible with --no-splice"); + if (*c->ip4.ifname_out || *c->ip6.ifname_out) + die("--no-tap is incompatible with --outbound-if4/6"); + if (*c->pasta_ifn) + die("--no-tap is incompatible with --ns-ifname"); + if (*c->guest_mac) + die("--no-tap is incompatible with --ns-mac-addr");
These all make sense. It might also make sense to exclude the -i option - setting a template interface also makes no sense in --no-tap mode.
Sure, I can add an if condition with if4 (as if4=if6 in that case).
+ if (c->pasta_conf_ns) + die("--no-tap is incompatible with --config-net");
I don't think this is right. We still can and should bring up 'lo' in the --no-tap case.
I see your point, but seems c->pasta_conf_ns is only used for tap as https://passt.top/passt/tree/pasta.c#n328, 'lo' is configured before that line.
Right, and the reason is that there are basic bits of functionality (probing pipe sizes if I recall correctly, or anyway probing for some kind of capability) that need the loopback interface to be up.
On the other hand, checks we're adding here are kind of fragile because we'll add other options in the future and probably forget to check which ones are incompatible, so I would try a slightly different approach: only check the options that are *obviously* conflicting with --no-tap.
That is, the main thing "--config-net" does is to "Configure networking in the namespace", which we still do with "--no-tap".
I added that because I thought --config-net is for tap only (as lo is configured always), and there is no tap for this mode. I can remove it, it still works without it.
If it's harmless, I would just pick what's simpler for the implementation. For users it should be exactly the same: - slight advantage of allowing it: no need to edit the command line if one specified both by mistake - slight disadvantage of disallowing it: users might try to do something with it that won't really happen (but I guess it's unlikely)
Now, I see that making sure c->pasta_conf_ns is false saves you checks elsewhere in the implementation, which is, I think, a good reason to have this check here.
But in general we don't need to exclude all the possible options that make no sense with --no-tap. We don't really confuse users if we allow them (or, at least, some of them).
I see. From a tester's perspective, we used to uncover a few bugs by combining certain options in different ways.
In this case, we don't know in which category those bugs might be: - *added* by allowing conflicting options (bad) - *discovered* by allowing conflicting options (good) - *not discovered* by not allowing conflicting options (bad, but not as bad) ...maybe others?
I feel it's more user-friendly to explicitly state what is unsupported and what will be ignored, although this is not a strong preference. I can update with only excluding obvious ones.
I think it's relevant if there are subtle combinations that are not actually working but they might look like it. Other than that, it *might* be more user-friendly to leave users as much choice as possible, because: 1. you don't need to re-type things if you obviously added an option that didn't make sense (especially relevant if you use the reverse-search function in a shell) 2. some options are set in integrations (Podman, rootlesskit/moby), for example --config-net. Let's say you want to try things out with Podman and --splice-only: --config-net doesn't make sense in that case, but Podman sets it regardless. So if you let pasta start with both, you can try things out without rebuilding and reinstalling, otherwise you have to rebuild and reinstall, but there's no added value, it's just us being picky. -- Stefano