From mboxrd@z Thu Jan 1 00:00:00 1970 From: Stefano Brivio To: passt-dev@passt.top Subject: [PATCH 17/18] contrib: Add patch for Podman integration Date: Tue, 22 Feb 2022 02:34:33 +0100 Message-ID: <20220222013434.4116044-18-sbrivio@redhat.com> In-Reply-To: <20220222013434.4116044-1-sbrivio@redhat.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============4413460242876116695==" --===============4413460242876116695== Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable The patch introduces a "pasta" networking mode for rootless container, similar to the existing slirp4netns mode. Notable differences are described in the commit message. Signed-off-by: Stefano Brivio --- ...001-libpod-Add-pasta-networking-mode.patch | 542 ++++++++++++++++++ 1 file changed, 542 insertions(+) create mode 100644 contrib/podman/0001-libpod-Add-pasta-networking-mode.patch diff --git a/contrib/podman/0001-libpod-Add-pasta-networking-mode.patch b/con= trib/podman/0001-libpod-Add-pasta-networking-mode.patch new file mode 100644 index 0000000..98cb48b --- /dev/null +++ b/contrib/podman/0001-libpod-Add-pasta-networking-mode.patch @@ -0,0 +1,542 @@ +From bcfd618a316097e5d2e1a20703b11beeb21b6899 Mon Sep 17 00:00:00 2001 +From: Stefano Brivio +Date: Sat, 19 Feb 2022 04:54:09 +0100 +Subject: [PATCH] libpod: Add pasta networking mode + +Conceptually equivalent to networking by means of slirp4netns(1), +with a few practical differences: + +- pasta(1) forks to background once networking is configured in the + namespace and quits on its own once the namespace is deleted: + file descriptor synchronisation and PID tracking are not needed + +- port forwarding is configured via command line options at start-up, + instead of an API socket: this is taken care of right away as we're + about to start pasta + +- there's no need for further selection of port forwarding modes: + pasta behaves similarly to containers-rootlessport for local binds + (splice() instead of read()/write() pairs, without L2-L4 + translation), and keeps the original source address for non-local + connections like slirp4netns does + +- IPv6 is enabled by default, it's not an experimental feature. It + can be disabled using additional options as documented + +- by default, addresses and routes are copied from the host, that is, + container users will see the same IP address and routes as if they + were in the init namespace context. The interface name is also + sourced from the host upstream interface with the first default + route in the routing table. This is also configurable as documented + +- by default, the host is reachable using the gateway address from + the container, unless the --no-map-gw option is passed + +- sandboxing and seccomp(2) policies cannot be disabled + +See https://passt.top for more details about pasta. + +Signed-off-by: Stefano Brivio +--- +SPDX-FileCopyrightText: 2021-2022 Red Hat GmbH +SPDX-License-Identifier: Apache-2.0 + + docs/source/markdown/podman-create.1.md | 40 ++++++++++++- + docs/source/markdown/podman-pod-create.1.md | 33 +++++++++++ + docs/source/markdown/podman-run.1.md | 38 +++++++++++- + docs/source/markdown/podman.1.md | 6 +- + libpod/networking_linux.go | 6 +- + libpod/networking_pasta.go | 64 +++++++++++++++++++++ + pkg/namespaces/namespaces.go | 6 ++ + pkg/specgen/generate/namespaces.go | 10 ++++ + pkg/specgen/generate/pod_create.go | 6 ++ + pkg/specgen/namespaces.go | 18 +++++- + pkg/specgen/podspecgen.go | 2 +- + 11 files changed, 215 insertions(+), 14 deletions(-) + create mode 100644 libpod/networking_pasta.go + +diff --git a/docs/source/markdown/podman-create.1.md b/docs/source/markdown/= podman-create.1.md +index 2a0f3b738..5cc03bff3 100644 +--- a/docs/source/markdown/podman-create.1.md ++++ b/docs/source/markdown/podman-create.1.md +@@ -699,12 +699,19 @@ Valid _mode_ values are: + - **interface_name**: Specify a name for the created network interface in= side the container. +=20 + For example to set a static ipv4 address and a static mac address, use `-= -network bridge:ip=3D10.88.0.10,mac=3D44:33:22:11:00:99`. ++ + - \[:OPTIONS,...]: Connect to a user-defined network; = this is the network name or ID from a network created by **[podman network cr= eate](podman-network-create.1.md)**. Using the network name implies the bridg= e network mode. It is possible to specify the same options described under th= e bridge mode above. You can use the **--network** option multiple times to s= pecify additional networks. ++ + - **none**: Create a network namespace for the container but do not configu= re network interfaces for it, thus the container has no network connectivity. ++ + - **container:**_id_: Reuse another container's network stack. ++ + - **host**: Do not create a network namespace, the container will use the h= ost's network. Note: The host mode gives the container full access to local s= ystem services such as D-bus and is therefore considered insecure. ++ + - **ns:**_path_: Path to a network namespace to join. ++ + - **private**: Create a new namespace for the container. This will use the = **bridge** mode for rootfull containers and **slirp4netns** for rootless ones. ++ + - **slirp4netns[:OPTIONS,...]**: use **slirp4netns**(1) to create a user ne= twork stack. This is the default for rootless containers. It is possible to s= pecify these additional options: + - **allow_host_loopback=3Dtrue|false**: Allow the slirp4netns to reach th= e host loopback IP (`10.0.2.2`, which is added to `/etc/hosts` as `host.conta= iners.internal` for your convenience). Default is false. + - **mtu=3DMTU**: Specify the MTU to use for this network. (Default is `65= 520`). +@@ -718,6 +725,30 @@ Valid _mode_ values are: + Note: Rootlesskit changes the source IP address of incoming packets to an= IP address in the container network namespace, usually `10.0.2.100`. If your= application requires the real source IP address, e.g. web server logs, use t= he slirp4netns port handler. The rootlesskit port handler is also used for ro= otless containers when connected to user-defined networks. + - **port_handler=3Dslirp4netns**: Use the slirp4netns port forwarding, it= is slower than rootlesskit but preserves the correct source IP address. This= port handler cannot be used for user-defined networks. +=20 ++- **pasta[:OPTIONS,...]**: use **pasta**(1) to create a user-mode networking ++stack. By default, IPv4 and IPv6 addresses and routes, as well as the pod ++interface name, are copied from the host. If port forwarding isn't configur= ed, ++ports will be forwarded dynamically as services are bound on either side (i= nit ++namespace or container namespace). Port forwarding preserves the original s= ource ++IP address. Options described in pasta(1) can be specified as comma-separat= ed ++arguments. In terms of pasta(1) options, only **--config-net** is given by ++default, in order to configure networking when the container is started. So= me ++examples: ++ - **pasta:--no-map-gw**: Don't allow the container to directly reach the = host ++ using the gateway address, which would normally be mapped to a loopback= or ++ link-local address. ++ - **pasta:--mtu,1500**: Specify a 1500 bytes MTU for the _tap_ interface = in ++ the container. ++ - **pasta:--ipv4-only,-a,10.0.2.0,-n,24,-g,10.0.2.2,--dns-forward,10.0.2.= 3,-m,1500,--no-ndp,--no-dhcpv6,--no-dhcp**, ++ equivalent to default slirp4netns(1) options: disable IPv6, assign ++ `10.0.2.0/24` to the `tap0` interface in the container, with gateway ++ `10.0.2.3`, enable DNS forwarder reachable at `10.0.2.3`, set MTU to 15= 00 ++ bytes, disable NDP, DHCPv6 and DHCP support. ++ - **pasta:--no-map-gw,-I,tap0,--ipv4-only,-a,10.0.2.0,-n,24,-g,10.0.2.2,-= -dns-forward,10.0.2.3,--no-ndp,--no-dhcpv6,--no-dhcp**, ++ equivalent to default slirp4netns(1) options with Podman overrides: sam= e as ++ above, but leave the MTU to 65520 bytes, and don't map the gateway addr= ess ++ from the container to a local address. ++ + #### **--network-alias**=3D*alias* +=20 + Add a network-scoped alias for the container, setting the alias for all net= works that the container joins. To set a name only for a specific network, us= e the alias option as described under the **--network** option. +@@ -1551,8 +1582,9 @@ In order for users to run rootless, there must be an e= ntry for their username in +=20 + Rootless Podman works better if the fuse-overlayfs and slirp4netns packages= are installed. + The fuse-overlayfs package provides a userspace overlay storage driver, oth= erwise users need to use +-the vfs storage driver, which is diskspace expensive and does not perform w= ell. slirp4netns is +-required for VPN, without it containers need to be run with the --network= =3Dhost flag. ++the vfs storage driver, which is diskspace expensive and does not perform w= ell. ++slirp4netns or pasta are required for VPN, without it containers need to be= run ++with the --network=3Dhost flag. +=20 + ## ENVIRONMENT +=20 +@@ -1601,7 +1633,9 @@ page. + NOTE: Use the environment variable `TMPDIR` to change the temporary storage= location of downloaded container images. Podman defaults to use `/var/tmp`. +=20 + ## SEE ALSO +-**[podman(1)](podman.1.md)**, **[podman-save(1)](podman-save.1.md)**, **[po= dman-ps(1)](podman-ps.1.md)**, **[podman-attach(1)](podman-attach.1.md)**, **= [podman-pod-create(1)](podman-pod-create.1.md)**, **[podman-port(1)](podman-p= ort.1.md)**, **[podman-start(1)](podman-start.1.md)**, **[podman-kill(1)](pod= man-kill.1.md)**, **[podman-stop(1)](podman-stop.1.md)**, **[podman-generate-= systemd(1)](podman-generate-systemd.1.md)**, **[podman-rm(1)](podman-rm.1.md)= **, **[subgid(5)](https://www.unix.com/man-page/linux/5/subgid)**, **[subuid(= 5)](https://www.unix.com/man-page/linux/5/subuid)**, **[containers.conf(5)](h= ttps://github.com/containers/common/blob/main/docs/containers.conf.5.md)**, *= *[systemd.unit(5)](https://www.freedesktop.org/software/systemd/man/systemd.u= nit.html)**, **[setsebool(8)](https://man7.org/linux/man-pages/man8/setsebool= .8.html)**, **[slirp4netns(1)](https://github.com/rootless-containers/slirp4n= etns/blob/master/slirp4netns.1.md)**, **[fuse-overlayfs(1)](https://github.co= m/containers/fuse-overlayfs/blob/main/fuse-overlayfs.1.md)**, **proc(5)**, **= [conmon(8)](https://github.com/containers/conmon/blob/main/docs/conmon.8.md)*= *, **personality(2)** ++**[podman(1)](podman.1.md)**, **[podman-save(1)](podman-save.1.md)**, **[po= dman-ps(1)](podman-ps.1.md)**, **[podman-attach(1)](podman-attach.1.md)**, **= [podman-pod-create(1)](podman-pod-create.1.md)**, **[podman-port(1)](podman-p= ort.1.md)**, **[podman-start(1)](podman-start.1.md)**, **[podman-kill(1)](pod= man-kill.1.md)**, **[podman-stop(1)](podman-stop.1.md)**, **[podman-generate-= systemd(1)](podman-generate-systemd.1.md)**, **[podman-rm(1)](podman-rm.1.md)= **, **[subgid(5)](https://www.unix.com/man-page/linux/5/subgid)**, **[subuid(= 5)](https://www.unix.com/man-page/linux/5/subuid)**, **[containers.conf(5)](h= ttps://github.com/containers/common/blob/main/docs/containers.conf.5.md)**, *= *[systemd.unit(5)](https://www.freedesktop.org/software/systemd/man/systemd.u= nit.html)**, **[setsebool(8)](https://man7.org/linux/man-pages/man8/setsebool= .8.html)**, **[slirp4netns(1)](https://github.com/rootless-containers/slirp4n= etns/blob/master/slirp4netns.1.md)**, ++**[pasta(1)](https://passt.top/builds/latest/web/passt.1.html)**, ++**[fuse-overlayfs(1)](https://github.com/containers/fuse-overlayfs/blob/mai= n/fuse-overlayfs.1.md)**, **proc(5)**, **[conmon(8)](https://github.com/conta= iners/conmon/blob/main/docs/conmon.8.md)**, **personality(2)** +=20 + ## HISTORY + October 2017, converted from Docker documentation to Podman by Dan Walsh fo= r Podman `` +diff --git a/docs/source/markdown/podman-pod-create.1.md b/docs/source/markd= own/podman-pod-create.1.md +index 8088e1d62..c94ac6061 100644 +--- a/docs/source/markdown/podman-pod-create.1.md ++++ b/docs/source/markdown/podman-pod-create.1.md +@@ -175,12 +175,19 @@ Valid _mode_ values are: + - **interface_name**: Specify a name for the created network interface in= side the container. +=20 + For example to set a static ipv4 address and a static mac address, use `-= -network bridge:ip=3D10.88.0.10,mac=3D44:33:22:11:00:99`. ++ + - \[:OPTIONS,...]: Connect to a user-defined network; = this is the network name or ID from a network created by **[podman network cr= eate](podman-network-create.1.md)**. Using the network name implies the bridg= e network mode. It is possible to specify the same options described under th= e bridge mode above. You can use the **--network** option multiple times to s= pecify additional networks. ++ + - **none**: Create a network namespace for the container but do not configu= re network interfaces for it, thus the container has no network connectivity. ++ + - **container:**_id_: Reuse another container's network stack. ++ + - **host**: Do not create a network namespace, the container will use the h= ost's network. Note: The host mode gives the container full access to local s= ystem services such as D-bus and is therefore considered insecure. ++ + - **ns:**_path_: Path to a network namespace to join. ++ + - **private**: Create a new namespace for the container. This will use the = **bridge** mode for rootfull containers and **slirp4netns** for rootless ones. ++ + - **slirp4netns[:OPTIONS,...]**: use **slirp4netns**(1) to create a user ne= twork stack. This is the default for rootless containers. It is possible to s= pecify these additional options: + - **allow_host_loopback=3Dtrue|false**: Allow the slirp4netns to reach th= e host loopback IP (`10.0.2.2`, which is added to `/etc/hosts` as `host.conta= iners.internal` for your convenience). Default is false. + - **mtu=3DMTU**: Specify the MTU to use for this network. (Default is `65= 520`). +@@ -194,6 +201,30 @@ Valid _mode_ values are: + Note: Rootlesskit changes the source IP address of incoming packets to an= IP address in the container network namespace, usually `10.0.2.100`. If your= application requires the real source IP address, e.g. web server logs, use t= he slirp4netns port handler. The rootlesskit port handler is also used for ro= otless containers when connected to user-defined networks. + - **port_handler=3Dslirp4netns**: Use the slirp4netns port forwarding, it= is slower than rootlesskit but preserves the correct source IP address. This= port handler cannot be used for user-defined networks. +=20 ++- **pasta[:OPTIONS,...]**: use **pasta**(1) to create a user-mode networking ++stack. By default, IPv4 and IPv6 addresses and routes, as well as the pod ++interface name, are copied from the host. If port forwarding isn't configur= ed, ++ports will be forwarded dynamically as services are bound on either side (i= nit ++namespace or container namespace). Port forwarding preserves the original s= ource ++IP address. Options described in pasta(1) can be specified as comma-separat= ed ++arguments. In terms of pasta(1) options, only **--config-net** is given by ++default, in order to configure networking when the container is started. So= me ++examples: ++ - **pasta:--no-map-gw**: Don't allow the container to directly reach the = host ++ using the gateway address, which would normally be mapped to a loopback= or ++ link-local address. ++ - **pasta:--mtu,1500**: Specify a 1500 bytes MTU for the _tap_ interface = in ++ the container. ++ - **pasta:--ipv4-only,-a,10.0.2.0,-n,24,-g,10.0.2.2,--dns-forward,10.0.2.= 3,-m,1500,--no-ndp,--no-dhcpv6,--no-dhcp**, ++ equivalent to default slirp4netns(1) options: disable IPv6, assign ++ `10.0.2.0/24` to the `tap0` interface in the container, with gateway ++ `10.0.2.3`, enable DNS forwarder reachable at `10.0.2.3`, set MTU to 15= 00 ++ bytes, disable NDP, DHCPv6 and DHCP support. ++ - **pasta:--no-map-gw,-I,tap0,--ipv4-only,-a,10.0.2.0,-n,24,-g,10.0.2.2,-= -dns-forward,10.0.2.3,--no-ndp,--no-dhcpv6,--no-dhcp**, ++ equivalent to default slirp4netns(1) options with Podman overrides: sam= e as ++ above, but leave the MTU to 65520 bytes, and don't map the gateway addr= ess ++ from the container to a local address. ++ + #### **--network-alias**=3D*alias* +=20 + Add a network-scoped alias for the pod, setting the alias for all networks = that the pod joins. To set a name only for a specific network, use the alias = option as described under the **--network** option. +@@ -527,6 +558,8 @@ $ podman pod create --network slirp4netns:outbound_addr= =3D127.0.0.1,allow_host_loo +=20 + $ podman pod create --network slirp4netns:cidr=3D192.168.0.0/24 +=20 ++$ podman pod create --network pasta ++ + $ podman pod create --network net1:ip=3D10.89.1.5 --network net2:ip=3D10.89= .10.10 + ``` +=20 +diff --git a/docs/source/markdown/podman-run.1.md b/docs/source/markdown/pod= man-run.1.md +index 239cf3b83..7c12f5e88 100644 +--- a/docs/source/markdown/podman-run.1.md ++++ b/docs/source/markdown/podman-run.1.md +@@ -726,12 +726,19 @@ Valid _mode_ values are: + - **interface_name**: Specify a name for the created network interface in= side the container. +=20 + For example to set a static ipv4 address and a static mac address, use `-= -network bridge:ip=3D10.88.0.10,mac=3D44:33:22:11:00:99`. ++ + - \[:OPTIONS,...]: Connect to a user-defined network; = this is the network name or ID from a network created by **[podman network cr= eate](podman-network-create.1.md)**. Using the network name implies the bridg= e network mode. It is possible to specify the same options described under th= e bridge mode above. You can use the **--network** option multiple times to s= pecify additional networks. ++ + - **none**: Create a network namespace for the container but do not configu= re network interfaces for it, thus the container has no network connectivity. ++ + - **container:**_id_: Reuse another container's network stack. ++ + - **host**: Do not create a network namespace, the container will use the h= ost's network. Note: The host mode gives the container full access to local s= ystem services such as D-bus and is therefore considered insecure. ++ + - **ns:**_path_: Path to a network namespace to join. ++ + - **private**: Create a new namespace for the container. This will use the = **bridge** mode for rootfull containers and **slirp4netns** for rootless ones. ++ + - **slirp4netns[:OPTIONS,...]**: use **slirp4netns**(1) to create a user ne= twork stack. This is the default for rootless containers. It is possible to s= pecify these additional options: + - **allow_host_loopback=3Dtrue|false**: Allow the slirp4netns to reach th= e host loopback IP (`10.0.2.2`, which is added to `/etc/hosts` as `host.conta= iners.internal` for your convenience). Default is false. + - **mtu=3DMTU**: Specify the MTU to use for this network. (Default is `65= 520`). +@@ -745,6 +752,30 @@ Valid _mode_ values are: + Note: Rootlesskit changes the source IP address of incoming packets to an= IP address in the container network namespace, usually `10.0.2.100`. If your= application requires the real source IP address, e.g. web server logs, use t= he slirp4netns port handler. The rootlesskit port handler is also used for ro= otless containers when connected to user-defined networks. + - **port_handler=3Dslirp4netns**: Use the slirp4netns port forwarding, it= is slower than rootlesskit but preserves the correct source IP address. This= port handler cannot be used for user-defined networks. +=20 ++- **pasta[:OPTIONS,...]**: use **pasta**(1) to create a user-mode networking ++stack. By default, IPv4 and IPv6 addresses and routes, as well as the pod ++interface name, are copied from the host. If port forwarding isn't configur= ed, ++ports will be forwarded dynamically as services are bound on either side (i= nit ++namespace or container namespace). Port forwarding preserves the original s= ource ++IP address. Options described in pasta(1) can be specified as comma-separat= ed ++arguments. In terms of pasta(1) options, only **--config-net** is given by ++default, in order to configure networking when the container is started. So= me ++examples: ++ - **pasta:--no-map-gw**: Don't allow the container to directly reach the = host ++ using the gateway address, which would normally be mapped to a loopback= or ++ link-local address. ++ - **pasta:--mtu,1500**: Specify a 1500 bytes MTU for the _tap_ interface = in ++ the container. ++ - **pasta:--ipv4-only,-a,10.0.2.0,-n,24,-g,10.0.2.2,--dns-forward,10.0.2.= 3,-m,1500,--no-ndp,--no-dhcpv6,--no-dhcp**, ++ equivalent to default slirp4netns(1) options: disable IPv6, assign ++ `10.0.2.0/24` to the `tap0` interface in the container, with gateway ++ `10.0.2.3`, enable DNS forwarder reachable at `10.0.2.3`, set MTU to 15= 00 ++ bytes, disable NDP, DHCPv6 and DHCP support. ++ - **pasta:--no-map-gw,-I,tap0,--ipv4-only,-a,10.0.2.0,-n,24,-g,10.0.2.2,-= -dns-forward,10.0.2.3,--no-ndp,--no-dhcpv6,--no-dhcp**, ++ equivalent to default slirp4netns(1) options with Podman overrides: sam= e as ++ above, but leave the MTU to 65520 bytes, and don't map the gateway addr= ess ++ from the container to a local address. ++ + #### **--network-alias**=3D*alias* +=20 + Add a network-scoped alias for the container, setting the alias for all net= works that the container joins. To set a name only for a specific network, us= e the alias option as described under the **--network** option. +@@ -1935,8 +1966,9 @@ In order for users to run rootless, there must be an e= ntry for their username in +=20 + Rootless Podman works better if the fuse-overlayfs and slirp4netns packages= are installed. + The **fuse-overlayfs** package provides a userspace overlay storage driver,= otherwise users need to use +-the **vfs** storage driver, which is diskspace expensive and does not perfo= rm well. slirp4netns is +-required for VPN, without it containers need to be run with the **--network= =3Dhost** flag. ++the **vfs** storage driver, which is diskspace expensive and does not perfo= rm ++well. slirp4netns or pasta are required for VPN, without it containers need= to ++be run with the **--network=3Dhost** flag. +=20 + ## ENVIRONMENT +=20 +@@ -1983,7 +2015,7 @@ page. + NOTE: Use the environment variable `TMPDIR` to change the temporary storage= location of downloaded container images. Podman defaults to use `/var/tmp`. +=20 + ## SEE ALSO +-**[podman(1)](podman.1.md)**, **[podman-save(1)](podman-save.1.md)**, **[po= dman-ps(1)](podman-ps.1.md)**, **[podman-attach(1)](podman-attach.1.md)**, **= [podman-pod-create(1)](podman-pod-create.1.md)**, **[podman-port(1)](podman-p= ort.1.md)**, **[podman-start(1)](podman-start.1.md)**, **[podman-kill(1)](pod= man-kill.1.md)**, **[podman-stop(1)](podman-stop.1.md)**, **[podman-generate-= systemd(1)](podman-generate-systemd.1.md)**, **[podman-rm(1)](podman-rm.1.md)= **, **[subgid(5)](https://www.unix.com/man-page/linux/5/subgid)**, **[subuid(= 5)](https://www.unix.com/man-page/linux/5/subuid)**, **[containers.conf(5)](h= ttps://github.com/containers/common/blob/main/docs/containers.conf.5.md)**, *= *[systemd.unit(5)](https://www.freedesktop.org/software/systemd/man/systemd.u= nit.html)**, **[setsebool(8)](https://man7.org/linux/man-pages/man8/setsebool= .8.html)**, **[slirp4netns(1)](https://github.com/rootless-containers/slirp4n= etns/blob/master/slirp4netns.1.md)**, **[fuse-overlayfs(1)](https://github.co= m/containers/fuse-overlayfs/blob/main/fuse-overlayfs.1.md)**, **proc(5)**, **= [conmon(8)](https://github.com/containers/conmon/blob/main/docs/conmon.8.md)*= *, **personality(2)** ++**[podman(1)](podman.1.md)**, **[podman-save(1)](podman-save.1.md)**, **[po= dman-ps(1)](podman-ps.1.md)**, **[podman-attach(1)](podman-attach.1.md)**, **= [podman-pod-create(1)](podman-pod-create.1.md)**, **[podman-port(1)](podman-p= ort.1.md)**, **[podman-start(1)](podman-start.1.md)**, **[podman-kill(1)](pod= man-kill.1.md)**, **[podman-stop(1)](podman-stop.1.md)**, **[podman-generate-= systemd(1)](podman-generate-systemd.1.md)**, **[podman-rm(1)](podman-rm.1.md)= **, **[subgid(5)](https://www.unix.com/man-page/linux/5/subgid)**, **[subuid(= 5)](https://www.unix.com/man-page/linux/5/subuid)**, **[containers.conf(5)](h= ttps://github.com/containers/common/blob/main/docs/containers.conf.5.md)**, *= *[systemd.unit(5)](https://www.freedesktop.org/software/systemd/man/systemd.u= nit.html)**, **[setsebool(8)](https://man7.org/linux/man-pages/man8/setsebool= .8.html)**, **[slirp4netns(1)](https://github.com/rootless-containers/slirp4n= etns/blob/master/slirp4netns.1.md)**, **[pasta(1)](https://passt.top/builds/l= atest/web/passt.1.html)**, **[fuse-overlayfs(1)](https://github.com/container= s/fuse-overlayfs/blob/main/fuse-overlayfs.1.md)**, **proc(5)**, **[conmon(8)]= (https://github.com/containers/conmon/blob/main/docs/conmon.8.md)**, **person= ality(2)** +=20 + ## HISTORY + September 2018, updated by Kunal Kushwaha `` +diff --git a/docs/source/markdown/podman.1.md b/docs/source/markdown/podman.= 1.md +index b318001e4..1ad808cba 100644 +--- a/docs/source/markdown/podman.1.md ++++ b/docs/source/markdown/podman.1.md +@@ -95,7 +95,7 @@ Set libpod namespace. Namespaces are used to separate grou= ps of containers and p + When namespace is set, created containers and pods will join the given name= space, and only containers and pods in the given namespace will be visible to= Podman. +=20 + #### **--network-cmd-path**=3D*path* +-Path to the command binary to use for setting up a network. It is currentl= y only used for setting up a slirp4netns network. If "" is used then the bin= ary is looked up using the $PATH environment variable. ++Path to the command binary to use for setting up a network. It is currentl= y only used for setting up a slirp4netns(1) or pasta(1) network. If "" is us= ed then the binary is looked up using the $PATH environment variable. +=20 + #### **--noout** +=20 +@@ -409,7 +409,7 @@ See the `subuid(5)` and `subgid(5)` man pages for more i= nformation. +=20 + Images are pulled under `XDG_DATA_HOME` when specified, otherwise in the ho= me directory of the user under `.local/share/containers/storage`. +=20 +-Currently the slirp4netns package is required to be installed to create a n= etwork device, otherwise rootless containers need to run in the network names= pace of the host. ++Currently either slirp4netns or pasta are required to be installed to creat= e a network device, otherwise rootless containers need to run in the network = namespace of the host. +=20 + In certain environments like HPC (High Performance Computing), users cannot= take advantage of the additional UIDs and GIDs from the /etc/subuid and /etc= /subgid systems. However, in this environment, rootless Podman can operate w= ith a single UID. To make this work, set the `ignore_chown_errors` option in= the /etc/containers/storage.conf or in ~/.config/containers/storage.conf fil= es. This option tells Podman when pulling an image to ignore chown errors whe= n attempting to change a file in a container image to match the non-root UID = in the image. This means all files get saved as the user's UID. Note this cou= ld cause issues when running the container. +=20 +@@ -422,7 +422,7 @@ The Network File System (NFS) and other distributed file= systems (for example: L + For more information, please refer to the [Podman Troubleshooting Page](htt= ps://github.com/containers/podman/blob/main/troubleshooting.md). +=20 + ## SEE ALSO +-**[containers-mounts.conf(5)](https://github.com/containers/common/blob/mai= n/docs/containers-mounts.conf.5.md)**, **[containers.conf(5)](https://github.= com/containers/common/blob/main/docs/containers.conf.5.md)**, **[containers-r= egistries.conf(5)](https://github.com/containers/image/blob/main/docs/contain= ers-registries.conf.5.md)**, **[containers-storage.conf(5)](https://github.co= m/containers/storage/blob/main/docs/containers-storage.conf.5.md)**, **[build= ah(1)](https://github.com/containers/buildah/blob/main/docs/buildah.1.md)**, = **oci-hooks(5)**, **[containers-policy.json(5)](https://github.com/containers= /image/blob/main/docs/containers-policy.json.5.md)**, **[crun(1)](https://git= hub.com/containers/crun/blob/main/crun.1.md)**, **[runc(8)](https://github.co= m/opencontainers/runc/blob/master/man/runc.8.md)**, **[subuid(5)](https://www= .unix.com/man-page/linux/5/subuid)**, **[subgid(5)](https://www.unix.com/man-= page/linux/5/subgid)**, **[slirp4netns(1)](https://github.com/rootless-contai= ners/slirp4netns/blob/master/slirp4netns.1.md)**, **[conmon(8)](https://githu= b.com/containers/conmon/blob/main/docs/conmon.8.md)** ++**[containers-mounts.conf(5)](https://github.com/containers/common/blob/mai= n/docs/containers-mounts.conf.5.md)**, **[containers.conf(5)](https://github.= com/containers/common/blob/main/docs/containers.conf.5.md)**, **[containers-r= egistries.conf(5)](https://github.com/containers/image/blob/main/docs/contain= ers-registries.conf.5.md)**, **[containers-storage.conf(5)](https://github.co= m/containers/storage/blob/main/docs/containers-storage.conf.5.md)**, **[build= ah(1)](https://github.com/containers/buildah/blob/main/docs/buildah.1.md)**, = **oci-hooks(5)**, **[containers-policy.json(5)](https://github.com/containers= /image/blob/main/docs/containers-policy.json.5.md)**, **[crun(1)](https://git= hub.com/containers/crun/blob/main/crun.1.md)**, **[runc(8)](https://github.co= m/opencontainers/runc/blob/master/man/runc.8.md)**, **[subuid(5)](https://www= .unix.com/man-page/linux/5/subuid)**, **[subgid(5)](https://www.unix.com/man-= page/linux/5/subgid)**, **[slirp4netns(1)](https://github.com/rootless-contai= ners/slirp4netns/blob/master/slirp4netns.1.md)**, **[pasta(1)](https://passt.= top/builds/latest/web/passt.1.html)**, **[conmon(8)](https://github.com/conta= iners/conmon/blob/main/docs/conmon.8.md)** +=20 + ## HISTORY + Dec 2016, Originally compiled by Dan Walsh +diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go +index 19d5c7f76..183f815ba 100644 +--- a/libpod/networking_linux.go ++++ b/libpod/networking_linux.go +@@ -636,6 +636,9 @@ func (r *Runtime) configureNetNS(ctr *Container, ctrNS n= s.NetNS) (status map[str + if ctr.config.NetMode.IsSlirp4netns() { + return nil, r.setupSlirp4netns(ctr, ctrNS) + } ++ if ctr.config.NetMode.IsPasta() { ++ return nil, r.setupPasta(ctr, ctrNS) ++ } + networks, err :=3D ctr.networks() + if err !=3D nil { + return nil, err +@@ -806,7 +809,8 @@ func (r *Runtime) teardownCNI(ctr *Container) error { + return err + } +=20 +- if !ctr.config.NetMode.IsSlirp4netns() && len(networks) > 0 { ++ if !ctr.config.NetMode.IsSlirp4netns() && ++ !ctr.config.NetMode.IsPasta() && len(networks) > 0 { + netOpts, err :=3D ctr.getNetworkOptions(networks) + if err !=3D nil { + return err +diff --git a/libpod/networking_pasta.go b/libpod/networking_pasta.go +new file mode 100644 +index 000000000..71595c87c +--- /dev/null ++++ b/libpod/networking_pasta.go +@@ -0,0 +1,64 @@ ++// SPDX-License-Identifier: Apache-2.0 ++// ++// networking_pasta.go - Start pasta(1) to provide connectivity to the cont= ainer ++// ++// Copyright (c) 2022 Red Hat GmbH ++// Author: Stefano Brivio ++// ++// +build linux ++ ++package libpod ++ ++import ( ++ "os/exec" ++ "fmt" ++ "strings" ++ ++ "github.com/containernetworking/plugins/pkg/ns" ++ "github.com/pkg/errors" ++ "github.com/sirupsen/logrus" ++) ++ ++func (r *Runtime) setupPasta(ctr *Container, netns ns.NetNS) error { ++ path :=3D r.config.Engine.NetworkCmdPath ++ if path =3D=3D "" { ++ var err error ++ path, err =3D exec.LookPath("pasta") ++ if err !=3D nil { ++ logrus.Errorf("Could not find pasta, the network namespace won't be conf= igured: %v", err) ++ return nil ++ } ++ } ++ ++ cmdArgs :=3D []string{} ++ cmdArgs =3D append(cmdArgs, "--config-net") ++ ++ for _, i :=3D range ctr.convertPortMappings() { ++ if i.Protocol =3D=3D "tcp" { ++ cmdArgs =3D append(cmdArgs, "-t") ++ } else if i.Protocol =3D=3D "udp" { ++ cmdArgs =3D append(cmdArgs, "-u") ++ } else { ++ logrus.Errorf("can't forward protocol: %s", i.Protocol) ++ return nil ++ } ++ ++ arg :=3D fmt.Sprintf("%d:%d", i.HostPort, i.ContainerPort) ++ cmdArgs =3D append(cmdArgs, arg) ++ } ++ ++ cmdArgs =3D append(cmdArgs, ctr.config.NetworkOptions["pasta"]...) ++ ++ cmdArgs =3D append(cmdArgs, netns.Path()) ++ ++ logrus.Debugf("pasta arguments: %s", strings.Join(cmdArgs, " ")) ++ ++ // pasta forks once ready, and quits once we delete the target namespace ++ _, err :=3D exec.Command(path, cmdArgs...).Output() ++ if err !=3D nil { ++ return errors.Wrapf(err, "failed to start pasta: %s", ++ err.(*exec.ExitError).Stderr) ++ } ++ ++ return nil ++} +diff --git a/pkg/namespaces/namespaces.go b/pkg/namespaces/namespaces.go +index a7736aee0..0b2cb2b0b 100644 +--- a/pkg/namespaces/namespaces.go ++++ b/pkg/namespaces/namespaces.go +@@ -19,6 +19,7 @@ const ( + privateType =3D "private" + shareableType =3D "shareable" + slirpType =3D "slirp4netns" ++ pastaType =3D "pasta" + ) +=20 + // CgroupMode represents cgroup mode in the container. +@@ -388,6 +389,11 @@ func (n NetworkMode) IsSlirp4netns() bool { + return n =3D=3D slirpType || strings.HasPrefix(string(n), slirpType+":") + } +=20 ++// IsPasta indicates if we are running a rootless network stack using pasta ++func (n NetworkMode) IsPasta() bool { ++ return n =3D=3D pastaType || strings.HasPrefix(string(n), pastaType + ":") ++} ++ + // IsNS indicates a network namespace passed in by path (ns:) + func (n NetworkMode) IsNS() bool { + return strings.HasPrefix(string(n), nsType) +diff --git a/pkg/specgen/generate/namespaces.go b/pkg/specgen/generate/names= paces.go +index 3f77cbe76..a72be1731 100644 +--- a/pkg/specgen/generate/namespaces.go ++++ b/pkg/specgen/generate/namespaces.go +@@ -258,6 +258,16 @@ func namespaceOptions(ctx context.Context, s *specgen.S= pecGenerator, rt *libpod. + val =3D fmt.Sprintf("slirp4netns:%s", s.NetNS.Value) + } + toReturn =3D append(toReturn, libpod.WithNetNS(portMappings, expose, post= ConfigureNetNS, val, nil)) ++ case specgen.Pasta: ++ portMappings, expose, err :=3D createPortMappings(ctx, s, imageData) ++ if err !=3D nil { ++ return nil, err ++ } ++ val :=3D "pasta" ++ if s.NetNS.Value !=3D "" { ++ val =3D fmt.Sprintf("pasta:%s", s.NetNS.Value) ++ } ++ toReturn =3D append(toReturn, libpod.WithNetNS(portMappings, expose, post= ConfigureNetNS, val, nil)) + case specgen.Private: + fallthrough + case specgen.Bridge: +diff --git a/pkg/specgen/generate/pod_create.go b/pkg/specgen/generate/pod_c= reate.go +index 68fda3ad7..0d64027a3 100644 +--- a/pkg/specgen/generate/pod_create.go ++++ b/pkg/specgen/generate/pod_create.go +@@ -232,6 +232,12 @@ func MapSpec(p *specgen.PodSpecGenerator) (*specgen.Spe= cGenerator, error) { + p.InfraContainerSpec.NetworkOptions =3D p.NetworkOptions + p.InfraContainerSpec.NetNS.NSMode =3D specgen.NamespaceMode("slirp4netns= ") + } ++ case specgen.Pasta: ++ logrus.Debugf("Pod will use pasta") ++ if p.InfraContainerSpec.NetNS.NSMode !=3D "host" { ++ p.InfraContainerSpec.NetworkOptions =3D p.NetworkOptions ++ p.InfraContainerSpec.NetNS.NSMode =3D specgen.NamespaceMode("pasta") ++ } + case specgen.NoNetwork: + logrus.Debugf("Pod will not use networking") + if len(p.InfraContainerSpec.PortMappings) > 0 || +diff --git a/pkg/specgen/namespaces.go b/pkg/specgen/namespaces.go +index e672bc65f..c7d443661 100644 +--- a/pkg/specgen/namespaces.go ++++ b/pkg/specgen/namespaces.go +@@ -47,6 +47,9 @@ const ( + // be used. + // Only used with the network namespace, invalid otherwise. + Slirp NamespaceMode =3D "slirp4netns" ++ // Pasta indicates that a pasta network stack should be used. ++ // Only used with the network namespace, invalid otherwise. ++ Pasta NamespaceMode =3D "pasta" + // KeepId indicates a user namespace to keep the owner uid inside + // of the namespace itself. + // Only used with the user namespace, invalid otherwise. +@@ -135,7 +138,7 @@ func validateNetNS(n *Namespace) error { + return nil + } + switch n.NSMode { +- case Slirp: ++ case Slirp, Pasta: + break + case "", Default, Host, Path, FromContainer, FromPod, Private, NoNetwork, = Bridge: + break +@@ -167,7 +170,7 @@ func (n *Namespace) validate() error { + switch n.NSMode { + case "", Default, Host, Path, FromContainer, FromPod, Private: + // Valid, do nothing +- case NoNetwork, Bridge, Slirp: ++ case NoNetwork, Bridge, Slirp, Pasta: + return errors.Errorf("cannot use network modes with non-network namespace= ") + default: + return errors.Errorf("invalid namespace type %s specified", n.NSMode) +@@ -281,6 +284,8 @@ func ParseNetworkNamespace(ns string, rootlessDefaultCNI= bool) (Namespace, map[s + switch { + case ns =3D=3D string(Slirp), strings.HasPrefix(ns, string(Slirp)+":"): + toReturn.NSMode =3D Slirp ++ case ns =3D=3D string(Pasta), strings.HasPrefix(ns, string(Pasta) + ":"): ++ toReturn.NSMode =3D Pasta + case ns =3D=3D string(FromPod): + toReturn.NSMode =3D FromPod + case ns =3D=3D "" || ns =3D=3D string(Default) || ns =3D=3D string(Private= ): +@@ -349,6 +354,13 @@ func ParseNetworkFlag(networks []string) (Namespace, ma= p[string]types.PerNetwork + networkOptions[parts[0]] =3D strings.Split(parts[1], ",") + } + toReturn.NSMode =3D Slirp ++ case ns =3D=3D string(Pasta), strings.HasPrefix(ns, string(Pasta) + ":"): ++ parts :=3D strings.SplitN(ns, ":", 2) ++ if len(parts) > 1 { ++ networkOptions =3D make(map[string][]string) ++ networkOptions[parts[0]] =3D strings.Split(parts[1], ",") ++ } ++ toReturn.NSMode =3D Pasta + case ns =3D=3D string(FromPod): + toReturn.NSMode =3D FromPod + case ns =3D=3D "" || ns =3D=3D string(Default) || ns =3D=3D string(Private= ): +@@ -425,7 +437,7 @@ func ParseNetworkFlag(networks []string) (Namespace, map= [string]types.PerNetwork + if parts[0] =3D=3D "" { + return toReturn, nil, nil, errors.Wrapf(define.ErrInvalidArg, "network = name cannot be empty") + } +- if util.StringInSlice(parts[0], []string{string(Bridge), string(Slirp), = string(FromPod), string(NoNetwork), ++ if util.StringInSlice(parts[0], []string{string(Bridge), string(Slirp), = string(Pasta), string(FromPod), string(NoNetwork), + string(Default), string(Private), string(Path), string(FromContainer), = string(Host)}) { + return toReturn, nil, nil, errors.Wrapf(define.ErrInvalidArg, "can only= set extra network names, selected mode %s conflicts with bridge", parts[0]) + } +diff --git a/pkg/specgen/podspecgen.go b/pkg/specgen/podspecgen.go +index 759caa0c0..f95bbffc7 100644 +--- a/pkg/specgen/podspecgen.go ++++ b/pkg/specgen/podspecgen.go +@@ -93,7 +93,7 @@ type PodNetworkConfig struct { + // PortMappings is a set of ports to map into the infra container. + // As, by default, containers share their network with the infra + // container, this will forward the ports to the entire pod. +- // Only available if NetNS is set to Bridge or Slirp. ++ // Only available if NetNS is set to Bridge, Slirp, or Pasta. + // Optional. + PortMappings []types.PortMapping `json:"portmappings,omitempty"` + // Map of networks names to ids the container should join to. +--=20 +2.28.0 + --=20 2.34.1 --===============4413460242876116695==--