From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: passt.top; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: passt.top; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=XFmXXx0o; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by passt.top (Postfix) with ESMTPS id 64C175A0625 for ; Sat, 10 Jan 2026 19:12:26 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1768068745; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=U1TzRxicDmyV9O3+iyYh47jsjsSZZ4IDW4i0rLBW+jc=; b=XFmXXx0oBGfHvogOdGBK2LmQiXk6VzLnWnEuFKf8piCDngsyq1j5KsPLBxfQpz97MVtZ0D CdMA86LQl0uRvv7DJ5CyYbiCGLH+bKAGzB54HloJEVzcpeGJHFle21KKwmsdRlSBsJsa+U NlxXgh3Kdu2EyyzJG3GbJMXTN0ldcXM= Received: from mail-wm1-f71.google.com (mail-wm1-f71.google.com [209.85.128.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-261-Cg8-NkeQPKGglRXNEVod4A-1; Sat, 10 Jan 2026 13:12:23 -0500 X-MC-Unique: Cg8-NkeQPKGglRXNEVod4A-1 X-Mimecast-MFC-AGG-ID: Cg8-NkeQPKGglRXNEVod4A_1768068742 Received: by mail-wm1-f71.google.com with SMTP id 5b1f17b1804b1-477bf8c1413so34901405e9.1 for ; Sat, 10 Jan 2026 10:12:22 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768068742; x=1768673542; h=content-transfer-encoding:mime-version:organization:references :in-reply-to:message-id:subject:cc:to:from:date:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=F7Yf5raqkp6akPHu3kETNw0RwAqwt4Jc82k3ADfpSDA=; b=uo0bou3ofnE2bXa4/LF6iJcUo13h4bVdpe6BmypRqB2Thfb6YNV+ETtkuzV3lLX1LE GnOLg06Yi2ksxEZllSaG0iIIiYo7Y3pQoulzFAeqcSi1+c5HTyUUHhL1ifPE9vptGIOc NU6fkiojHeO1/rfz5LYssKdHEXsfEDIPxh0PndAo6d1SZJ4aCuRtzFhADWxbWHkQtTXA CME3Npq/wNpvslKXHFEvNnWey1FAB3YU8Q0mNdMs9LQYsAtPRsWfyEWT3GunQa21fjYa aZPCIYlbx2jl8aDVtEuUnQ1pt5AOelERT1twsxKK7Eb9bBjKDsBkjGVPed8nLvajFcEH OLZQ== X-Forwarded-Encrypted: i=1; AJvYcCUi6dHbe9V0wu8kfVLcF3J1mYjS9EftH3Y99caFxNtZscWIfsA/UL6P34vSd24TGrD7zB3H9bFw2+Q=@passt.top X-Gm-Message-State: AOJu0Yw7adZ3T1K8G/nU3qCh0d7ZwCf+0HRB7nUJl/jKrgx0UuEB5wqq cYkxWHfF7Jm/qYrfetUF5mrZwQ4mIgbA6dqvgd5Oo2/SZBBXCXdOzTVZBZn5uFM/ozhr3DzonHA Gb+YQQYCeFmHRmxtYOqopGLrgEh7gEiDKPIa80UH7mnCjHHiVNm6tig== X-Gm-Gg: AY/fxX5CnsXiHefif1HQp04Z2tO7iWowfKXLhbgUCeF4QhAg0FdNQwMbyoeNSR4eRmr pq8vQMLesY42E8z1icSGuBtVz1beIfnVf+MbSasT6M/iP4bY88LRS0XtF590BkYNm16SlmI4TZ1 hZQt9fNtCfn4ooOMrMInwxVhkpBHkj5E7GoanE2KZM4SiKvrn9M/48acRpM4HPdoOURLlPStlM+ RsyvjdK1coZSPldwX8OnEBph4QksLQbfspAZY8FdYOT9lV2v7Ie2d7yZcQdXnGBlk2W+IgBhOCO vMBVAIKlu5WfnxbU+Gg4VC+JcnObUBdnUSe2tz9/3c+tWz2DBZD9ZC7iNV+n7d1AY0zu0iCXPrM +7Pty9uLit1QKcgrjN9c24RUSRWB9Pe//JqOBCw== X-Received: by 2002:a05:600c:37c8:b0:475:de12:d3b5 with SMTP id 5b1f17b1804b1-47d84b40816mr119748795e9.34.1768068741837; Sat, 10 Jan 2026 10:12:21 -0800 (PST) X-Google-Smtp-Source: AGHT+IG1hzWS2So59mYV55gr7iRKGIUhD5SVxAQFxd5m1e4U+584lt8qGXMuAYUoUeVTjYyLhMoLyg== X-Received: by 2002:a05:600c:37c8:b0:475:de12:d3b5 with SMTP id 5b1f17b1804b1-47d84b40816mr119748645e9.34.1768068741260; Sat, 10 Jan 2026 10:12:21 -0800 (PST) Received: from maya.myfinge.rs (ifcgrfdd.trafficplex.cloud. [176.103.220.4]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-432bd5ee893sm28559397f8f.37.2026.01.10.10.12.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 10 Jan 2026 10:12:20 -0800 (PST) Date: Sat, 10 Jan 2026 19:12:19 +0100 From: Stefano Brivio To: Yumei Huang Subject: Re: [PATCH] conf, pasta: Add --no-tap option Message-ID: <20260110191219.29498050@elisabeth> In-Reply-To: References: <20251229095558.918055-1-yuhuang@redhat.com> Organization: Red Hat X-Mailer: Claws Mail 4.2.0 (GTK 3.24.49; x86_64-pc-linux-gnu) MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: 7ZMcNjpyaksg8-XZr4ET5McJjger-4eVQwCRdlS93QA_1768068742 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Message-ID-Hash: 6EUHV4QOMEMZEC2HLC6D4JZMD25DOFTH X-Message-ID-Hash: 6EUHV4QOMEMZEC2HLC6D4JZMD25DOFTH X-MailFrom: sbrivio@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: David Gibson , passt-dev@passt.top X-Mailman-Version: 3.3.8 Precedence: list List-Id: Development discussion and patches for passt Archived-At: Archived-At: List-Archive: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: On Mon, 5 Jan 2026 16:53:49 +0800 Yumei Huang wrote: > On Mon, Jan 5, 2026 at 12:18=E2=80=AFPM David Gibson > wrote: > > > > On Mon, Dec 29, 2025 at 05:55:58PM +0800, Yumei Huang wrote: =20 > > > This patch introduces a mode where we only forward loopback connectio= ns > > > 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 automa= tically > > > 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=3D149 > > > Signed-off-by: Yumei Huang =20 > > > > 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. > > =20 > > > --- > > > 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 nam= espace\n" > > > " --ns-mac-addr ADDR Set MAC address on tap interfac= e\n" > > > - " --no-splice Disable inbound socket splicing= \n"); > > > + " --no-splice Disable inbound socket splicing= \n" > > > + " --no-tap Don't create tap device\n"); = =20 > > > > I feel like this description can be improved, but I'm not exactly sure > > how, yet. A few possible alternatives: - "Only enable loopback forwarding" - "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 > > =20 > > > > > > 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 !=3D -1); > > > > > > - if (c->mode !=3D MODE_PASTA) > > > + if (c->mode !=3D MODE_PASTA) { > > > c->no_splice =3D 1; > > > + if (c->no_tap) > > > + die("--no-tap is for pasta mode only"); > > > + } > > > > > > if (c->mode =3D=3D 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 =3D=3D 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-i= f4/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-add= r"); =20 > > > > 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. =20 >=20 > Sure, I can add an if condition with if4 (as if4=3Dif6 in that case). > > =20 > > > + if (c->pasta_conf_ns) > > > + die("--no-tap is incompatible with --config-net= "); =20 > > > > I don't think this is right. We still can and should bring up 'lo' in > > the --no-tap case. =20 >=20 > 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". 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). > > > + c->host_lo_to_ns_lo =3D 1; > > > + c->no_icmp =3D 1; > > > + c->no_ra =3D 1; > > > + c->no_dns =3D 1; > > > + c->no_dns_search =3D 1; =20 > > > > The reasoning for the last two items is a bit unclear to me. IIUC, > > no_dns and no_dns_search aren't so much about "support" for DNS itself > > but for advertising DNS settings via DHCP. Since DHCP will be > > unsupported, so are these as a consequence. Is that right? =20 >=20 > Yeah, I think so. Actually I added c->no_dhcp, c->no_ndp here as well, > then removed them as they are set in later changes(conditions about > c->ifi4/c->ifi6), though they turn out to be not quite right :'\ Do we care about them, though? That code won't be reachable anyway, unless I'm missing something. Or is it to make the output of conf_print() nicer? In that case I guess it makes sense to go and disable things. > > > + } > > > + > > > if (!ifi4 && *c->ip4.ifname_out) > > > ifi4 =3D if_nametoindex(c->ip4.ifname_out); > > > > > > @@ -1980,9 +2004,9 @@ void conf(struct ctx *c, int argc, char **argv) > > > log_conf_parsed =3D true; /* Stop printing everything *= / > > > > > > nl_sock_init(c, false); > > > - if (!v6_only) > > > + if (!v6_only && !c->no_tap) > > > c->ifi4 =3D conf_ip4(ifi4, &c->ip4); > > > - if (!v4_only) > > > + if (!v4_only && !c->no_tap) > > > c->ifi6 =3D conf_ip6(ifi6, &c->ip6); > > > > > > if (c->ifi4 && c->mtu < IPV4_MIN_MTU) { > > > @@ -1998,30 +2022,32 @@ void conf(struct ctx *c, int argc, char **arg= v) > > > (*c->ip6.ifname_out && !c->ifi6)) > > > die("External interface not usable"); > > > > > > - if (!c->ifi4 && !c->ifi6 && !*c->pasta_ifn) { > > > + if (!c->ifi4 && !c->ifi6 && !*c->pasta_ifn && !c->no_tap) { > > > strncpy(c->pasta_ifn, pasta_default_ifn, > > > sizeof(c->pasta_ifn) - 1); > > > } > > > > > > if (!c->ifi4 && !v6_only) { > > > - info("IPv4: no external interface as template, use loca= l mode"); > > > - > > > - conf_ip4_local(&c->ip4); > > > + if (!c->no_tap) { > > > + info("IPv4: no external interface as template, = use local mode"); > > > + conf_ip4_local(&c->ip4); > > > + } > > > c->ifi4 =3D -1; > > > } > > > > > > if (!c->ifi6 && !v4_only) { > > > - info("IPv6: no external interface as template, use loca= l mode"); > > > - > > > - conf_ip6_local(&c->ip6); > > > + if (!c->no_tap) { > > > + info("IPv6: no external interface as template, = use local mode"); > > > + conf_ip6_local(&c->ip6); > > > + } > > > c->ifi6 =3D -1; > > > } > > > > > > - if (c->ifi4 && !no_map_gw && > > > + if (c->ifi4 > 0 && !no_map_gw && =20 > > > > This isn't quite right. ifi4 =3D=3D -1 now occurs in two cases: local > > mode, and --no-tap mode. Not setting map_host_loopback makes sense > > for --no-tap mode, but it's still needed for local mode. =20 >=20 > I'm a bit confused by map_host_loopback. I don't quite understand the > use scenario. IIUC, either in --no-tap mode or local mode, guest can > only communicate with host. That's not the case for local mode, the guest can communicate with any other host. Local mode is just about addresses and routes, and the fact that, when pasta started, there was no template interface. > Then why do we need to set map_host_loopback? What's the benefit? Example: guest has 169.254.2.1 (default in local mode), and wants to use 192.0.2.1 to refer to the host, via loopback interface. > > > IN4_IS_ADDR_UNSPECIFIED(&c->ip4.map_host_loopback)) > > > c->ip4.map_host_loopback =3D c->ip4.guest_gw; > > > > > > - if (c->ifi6 && !no_map_gw && > > > + if (c->ifi6 > 0 && !no_map_gw && =20 > > > > Same here. > > =20 > > > IN6_IS_ADDR_UNSPECIFIED(&c->ip6.map_host_loopback)) > > > c->ip6.map_host_loopback =3D c->ip6.guest_gw; > > > > > > @@ -2116,10 +2142,10 @@ void conf(struct ctx *c, int argc, char **arg= v) > > > conf_ports(c, name, optarg, &c->udp.fwd_out); > > > } while (name !=3D -1); > > > > > > - if (!c->ifi4) > > > + if (c->ifi4 <=3D 0) > > > c->no_dhcp =3D 1; > > > > > > - if (!c->ifi6) { > > > + if (c->ifi6 <=3D 0) { > > > c->no_ndp =3D 1; > > > c->no_dhcpv6 =3D 1; =20 > > > > And here. Local mode can still use NDP and DHCP, even though --no-tap > > mode can't. It might be simpler to force no_ndp, no_dhcp etc. along > > with no_ra and the rest above. =20 >=20 > Sure, I will add them. > > =20 > > > } else if (IN6_IS_ADDR_UNSPECIFIED(&c->ip6.addr)) { > > > diff --git a/fwd.c b/fwd.c > > > index 44a0e10..2f4a89a 100644 > > > --- a/fwd.c > > > +++ b/fwd.c > > > @@ -780,6 +780,9 @@ uint8_t fwd_nat_from_host(const struct ctx *c, ui= nt8_t proto, > > > return PIF_SPLICE; > > > } > > > > > > + if (c->no_tap) > > > + return PIF_NONE; > > > + > > > if (!nat_inbound(c, &ini->eaddr, &tgt->oaddr)) { > > > if (inany_v4(&ini->eaddr)) { > > > if (IN4_IS_ADDR_UNSPECIFIED(&c->ip4.our_tap_add= r)) > > > diff --git a/passt.1 b/passt.1 > > > index db0d662..2d643f7 100644 > > > --- a/passt.1 > > > +++ b/passt.1 > > > @@ -755,6 +755,11 @@ Default is to let the tap driver build a pseudor= andom hardware address. > > > Disable the bypass path for inbound, local traffic. See the section = \fBHandling > > > of local traffic in pasta\fR in the \fBNOTES\fR for more details. > > > > > > +.TP > > > +.BR \-\-no-tap > > > +Do not create a tap device in the namespace. In this mode, only loca= l loopback > > > +traffic between namespaces is forwarded using splice. =20 > > > > This probably wants some work, because I'm not sure "tap device" and > > "splice" are sufficiently clear in this context. =20 >=20 > Yeah, I will think about that. Thanks. > > > > =20 > > > + > > > .SH EXAMPLES > > > > > > .SS \fBpasta > > > diff --git a/passt.h b/passt.h > > > index 79d01dd..0c1ec4c 100644 > > > --- a/passt.h > > > +++ b/passt.h > > > @@ -200,6 +200,7 @@ struct ip6_ctx { > > > * @no_ndp: Disable NDP handler altogether > > > * @no_ra: Disable router advertisements > > > * @no_splice: Disable socket splicing for inbound tra= ffic > > > + * @no_tap: Do not create tap device > > > * @host_lo_to_ns_lo: Map host loopback addresses to ns loopb= ack addresses > > > * @freebind: Allow binding of non-local addresses fo= r forwarding > > > * @low_wmem: Low probed net.core.wmem_max > > > @@ -277,6 +278,7 @@ struct ctx { > > > int no_ndp; > > > int no_ra; > > > int no_splice; > > > + int no_tap; > > > int host_lo_to_ns_lo; > > > int freebind; > > > > > > diff --git a/pasta.c b/pasta.c > > > index 0ddd6b0..3510ec5 100644 > > > --- a/pasta.c > > > +++ b/pasta.c > > > @@ -316,6 +316,9 @@ void pasta_ns_conf(struct ctx *c) > > > die("Couldn't bring up loopback interface in namespace:= %s", > > > strerror_(-rc)); > > > > > > + if (c->no_tap) > > > + return; > > > + > > > /* Get or set MAC in target namespace */ > > > if (MAC_IS_ZERO(c->guest_mac)) > > > nl_link_get_mac(nl_sock_ns, c->pasta_ifi, c->guest_mac)= ; > > > diff --git a/tap.c b/tap.c > > > index 9d1344b..9b4eedc 100644 > > > --- a/tap.c > > > +++ b/tap.c > > > @@ -1491,13 +1491,16 @@ static int tap_ns_tun(void *arg) > > > */ > > > static void tap_sock_tun_init(struct ctx *c) > > > { > > > - NS_CALL(tap_ns_tun, c); > > > - if (c->fd_tap =3D=3D -1) > > > - die("Failed to set up tap device in namespace"); > > > + if (!c->no_tap) { > > > + NS_CALL(tap_ns_tun, c); > > > + if (c->fd_tap =3D=3D -1) > > > + die("Failed to set up tap device in namespace")= ; > > > + } > > > > > > pasta_ns_conf(c); > > > > > > - tap_start_connection(c); > > > + if (!c->no_tap) > > > + tap_start_connection(c); > > > } > > > > > > /** > > > -- > > > 2.49.0 > > > =20 > > > > -- > > David Gibson (he or they) | I'll have my music baroque, and my co= de > > david AT gibson.dropbear.id.au | minimalist, thank you, not the other = way > > | around. > > http://www.ozlabs.org/~dgibson =20 >=20 >=20 >=20 --=20 Stefano