From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from gandalf.ozlabs.org (mail.ozlabs.org [IPv6:2404:9400:2221:ea00::3]) by passt.top (Postfix) with ESMTPS id A22F75A0277 for ; Wed, 8 Mar 2023 23:57:20 +0100 (CET) Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4PX74C10d1z4xDh; Thu, 9 Mar 2023 09:57:15 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=201602; t=1678316235; bh=4G0jHsEeyBRqCoAeCv6J87aAqULLZGPuA1x5rYvkB7Q=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=F8sxakAh49VXYMEmrQwRkZpZ0bfP7JDTmEjVP+I5hPIdj/kJYgyqwJ+UIchBxwAyk cjqX/Of9/b53bX7eCD4lRzv+ZUlNtLIa8wEH4+iGRrA8vXBp+OcMKA3UV3s0i66Ljj 5AHuUTc4sIvXoSbwZyhQuUyhJeZAcLOEasEjSH34= Date: Thu, 9 Mar 2023 09:53:24 +1100 From: David Gibson To: Stefano Brivio Subject: Re: [PATCH] contrib: Drop Podman out-of-tree patch, integration is upstream now Message-ID: References: <20230308224957.2589844-1-sbrivio@redhat.com> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha256; protocol="application/pgp-signature"; boundary="0bsbI9gTS3qL+uju" Content-Disposition: inline In-Reply-To: <20230308224957.2589844-1-sbrivio@redhat.com> Message-ID-Hash: RPS6MF5P4ERZMO2ASLBWDCLOI4FOS47F X-Message-ID-Hash: RPS6MF5P4ERZMO2ASLBWDCLOI4FOS47F X-MailFrom: dgibson@gandalf.ozlabs.org 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: 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: --0bsbI9gTS3qL+uju Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Wed, Mar 08, 2023 at 11:49:57PM +0100, Stefano Brivio wrote: > See https://github.com/containers/podman/pull/16141, shipped in > Podman 4.4. >=20 > Signed-off-by: Stefano Brivio Reviewed-by: David Gibson > --- > ...001-libpod-Add-pasta-networking-mode.patch | 605 ------------------ > 1 file changed, 605 deletions(-) > delete mode 100644 contrib/podman/0001-libpod-Add-pasta-networking-mode.= patch >=20 > diff --git a/contrib/podman/0001-libpod-Add-pasta-networking-mode.patch b= /contrib/podman/0001-libpod-Add-pasta-networking-mode.patch > deleted file mode 100644 > index a6e832a..0000000 > --- a/contrib/podman/0001-libpod-Add-pasta-networking-mode.patch > +++ /dev/null > @@ -1,605 +0,0 @@ > -From 7294b62e15bee68f1920ea04aaab3284ce43e7ea Mon Sep 17 00:00:00 2001 > -From: Stefano Brivio > -Date: Mon, 2 May 2022 16:12:07 +0200 > -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 not an experimental feature, and enabled by default. IPv6 > - port forwarding is supported > - > -- 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.in | 48 +++++++- > - .../source/markdown/podman-pod-create.1.md.in | 44 +++++++ > - docs/source/markdown/podman-run.1.md.in | 49 +++++++- > - docs/source/markdown/podman.1.md | 6 +- > - libpod/networking_common.go | 3 +- > - libpod/networking_linux.go | 3 + > - libpod/networking_pasta.go | 107 ++++++++++++++++++ > - pkg/namespaces/namespaces.go | 6 + > - pkg/specgen/generate/namespaces.go | 10 ++ > - pkg/specgen/generate/pod_create.go | 6 + > - pkg/specgen/namespaces.go | 16 ++- > - pkg/specgen/podspecgen.go | 2 +- > - 12 files changed, 286 insertions(+), 14 deletions(-) > - create mode 100644 libpod/networking_pasta.go > - > -diff --git a/docs/source/markdown/podman-create.1.md.in b/docs/source/ma= rkdown/podman-create.1.md.in > -index 742a32b5a..79fb3a3e1 100644 > ---- a/docs/source/markdown/podman-create.1.md.in > -+++ b/docs/source/markdown/podman-create.1.md.in > -@@ -277,10 +277,15 @@ Valid _mode_ values are: > - - **interface_name**: Specify a name for the created network interfac= e inside the container. > -=20 > - For example to set a static ipv4 address and a static mac address, us= e `--network bridge:ip=3D10.88.0.10,mac=3D44:33:22:11:00:99`. > -+ > - - \[:OPTIONS,...]: Connect to a user-defined netwo= rk; this is the network name or ID from a network created by **[podman netw= ork create](podman-network-create.1.md)**. Using the network name implies t= he bridge network mode. It is possible to specify the same options describe= d under the bridge mode above. You can use the **--network** option multipl= e times to specify additional networks. > -+ > - - **none**: Create a network namespace for the container but do not con= figure network interfaces for it, thus the container has no network connect= ivity. > -+ > - - **container:**_id_: Reuse another container's network stack. > -+ > - - **host**: Do not create a network namespace, the container will use t= he host's network. Note: The host mode gives the container full access to l= ocal system 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 rootful containers and **slirp4netns** for rootless= ones. > - - **slirp4netns[:OPTIONS,...]**: use **slirp4netns**(1) to create a use= r network stack. This is the default for rootless containers. It is possibl= e to specify these additional options, they can also be set with `network_c= md_options` in containers.conf: > -@@ -296,6 +301,40 @@ Valid _mode_ values are: > - Note: Rootlesskit changes the source IP address of incoming packets t= o an IP address in the container network namespace, usually `10.0.2.100`. I= f your application requires the real source IP address, e.g. web server log= s, use the slirp4netns port handler. The rootlesskit port handler is also u= sed for rootless 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= =2E This port handler cannot be used for user-defined networks. > -=20 > -+- **pasta[:OPTIONS,...]**: use **pasta**(1) to create a user-mode netwo= rking > -+stack. By default, IPv4 and IPv6 addresses and routes, as well as the p= od > -+interface name, are copied from the host. Port forwarding preserves the= original > -+source IP address. Options described in pasta(1) can be specified as > -+comma-separated arguments. > -+ > -+In terms of pasta(1) options, **--config-net** is given by default, in = order to > -+configure networking when the container is started. Also, **-t none** a= nd > -+**-u none** are passed if, respectively, no TCP or UDP port forwarding = =66rom host > -+to container is configured, to disable automatic port forwarding based = on bound > -+ports. Similarly, **-T none** and **-U none** are also given to disable= the same > -+functionality from container to host. > -+ > -+Some 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 loop= back or > -+ link-local address. > -+ - **pasta:--mtu,1500**: Specify a 1500 bytes MTU for the _tap_ interf= ace 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 t= o 1500 > -+ 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= =2E2,--dns-forward,10.0.2.3,--no-ndp,--no-dhcpv6,--no-dhcp**, > -+ equivalent to default slirp4netns(1) options with Podman overrides:= same as > -+ above, but leave the MTU to 65520 bytes, and don't map the gateway = address > -+ from the container to a local address. > -+ - **pasta:-t,auto,-u,auto,-T,auto,-U,auto**: enable automatic port fo= rwarding > -+ based on observed bound ports from both host and container sides > -+ - **pasta:-T,5201**: enable forwarding of TCP port 5201 from containe= r to > -+ host, using the loopback interface instead of the tap interface for= improved > -+ performance > -+ > - @@option network-alias > -=20 > - @@option no-healthcheck > -@@ -550,8 +589,9 @@ In order for users to run rootless, there must be an= entry for their username in > -=20 > - Rootless Podman works better if the fuse-overlayfs and slirp4netns pack= ages 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 --netwo= rk=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 t= o be run > -+with the --network=3Dhost flag. > -=20 > - ## ENVIRONMENT > -=20 > -@@ -600,7 +640,9 @@ page. > - NOTE: Use the environment variable `TMPDIR` to change the temporary sto= rage 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)**, *= *[podman-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-port.1.md)**, **[podman-start(1)](podman-start.1.md)**, **[podman-ki= ll(1)](podman-kill.1.md)**, **[podman-stop(1)](podman-stop.1.md)**, **[podm= an-generate-systemd(1)](podman-generate-systemd.1.md)**, **[podman-rm(1)](p= odman-rm.1.md)**, **[subgid(5)](https://www.unix.com/man-page/linux/5/subgi= d)**, **[subuid(5)](https://www.unix.com/man-page/linux/5/subuid)**, **[con= tainers.conf(5)](https://github.com/containers/common/blob/main/docs/contai= ners.conf.5.md)**, **[systemd.unit(5)](https://www.freedesktop.org/software= /systemd/man/systemd.unit.html)**, **[setsebool(8)](https://man7.org/linux/= man-pages/man8/setsebool.8.html)**, **[slirp4netns(1)](https://github.com/r= ootless-containers/slirp4netns/blob/master/slirp4netns.1.md)**, **[fuse-ove= rlayfs(1)](https://github.com/containers/fuse-overlayfs/blob/main/fuse-over= layfs.1.md)**, **proc(5)**, **[conmon(8)](https://github.com/containers/con= mon/blob/main/docs/conmon.8.md)**, **personality(2)** > -+**[podman(1)](podman.1.md)**, **[podman-save(1)](podman-save.1.md)**, *= *[podman-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-port.1.md)**, **[podman-start(1)](podman-start.1.md)**, **[podman-ki= ll(1)](podman-kill.1.md)**, **[podman-stop(1)](podman-stop.1.md)**, **[podm= an-generate-systemd(1)](podman-generate-systemd.1.md)**, **[podman-rm(1)](p= odman-rm.1.md)**, **[subgid(5)](https://www.unix.com/man-page/linux/5/subgi= d)**, **[subuid(5)](https://www.unix.com/man-page/linux/5/subuid)**, **[con= tainers.conf(5)](https://github.com/containers/common/blob/main/docs/contai= ners.conf.5.md)**, **[systemd.unit(5)](https://www.freedesktop.org/software= /systemd/man/systemd.unit.html)**, **[setsebool(8)](https://man7.org/linux/= man-pages/man8/setsebool.8.html)**, **[slirp4netns(1)](https://github.com/r= ootless-containers/slirp4netns/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= /main/fuse-overlayfs.1.md)**, **proc(5)**, **[conmon(8)](https://github.com= /containers/conmon/blob/main/docs/conmon.8.md)**, **personality(2)** > -=20 > - ## HISTORY > - October 2017, converted from Docker documentation to Podman by Dan Wals= h for Podman `` > -diff --git a/docs/source/markdown/podman-pod-create.1.md.in b/docs/sourc= e/markdown/podman-pod-create.1.md.in > -index fdae1d249..104ad460b 100644 > ---- a/docs/source/markdown/podman-pod-create.1.md.in > -+++ b/docs/source/markdown/podman-pod-create.1.md.in > -@@ -131,10 +131,15 @@ Valid _mode_ values are: > - - **interface_name**: Specify a name for the created network interfac= e inside the container. > -=20 > - For example to set a static ipv4 address and a static mac address, us= e `--network bridge:ip=3D10.88.0.10,mac=3D44:33:22:11:00:99`. > -+ > - - \[:OPTIONS,...]: Connect to a user-defined netwo= rk; this is the network name or ID from a network created by **[podman netw= ork create](podman-network-create.1.md)**. Using the network name implies t= he bridge network mode. It is possible to specify the same options describe= d under the bridge mode above. You can use the **--network** option multipl= e times to specify additional networks. > -+ > - - **none**: Create a network namespace for the container but do not con= figure network interfaces for it, thus the container has no network connect= ivity. > -+ > - - **container:**_id_: Reuse another container's network stack. > -+ > - - **host**: Do not create a network namespace, the container will use t= he host's network. Note: The host mode gives the container full access to l= ocal system 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 rootful containers and **slirp4netns** for rootless= ones. > - - **slirp4netns[:OPTIONS,...]**: use **slirp4netns**(1) to create a use= r network stack. This is the default for rootless containers. It is possibl= e to specify these additional options, they can also be set with `network_c= md_options` in containers.conf: > -@@ -150,6 +155,43 @@ Valid _mode_ values are: > - Note: Rootlesskit changes the source IP address of incoming packets t= o an IP address in the container network namespace, usually `10.0.2.100`. I= f your application requires the real source IP address, e.g. web server log= s, use the slirp4netns port handler. The rootlesskit port handler is also u= sed for rootless 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= =2E This port handler cannot be used for user-defined networks. > -=20 > -+- **pasta[:OPTIONS,...]**: use **pasta**(1) to create a user-mode netwo= rking > -+stack. By default, IPv4 and IPv6 addresses and routes, as well as the p= od > -+interface name, are copied from the host. If port forwarding isn't conf= igured, > -+ports will be forwarded dynamically as services are bound on either sid= e (init > -+namespace or container namespace). Port forwarding preserves the origin= al source > -+IP address. Options described in pasta(1) can be specified as comma-sep= arated > -+arguments. > -+ > -+ > -+In terms of pasta(1) options, **--config-net** is given by default, in = order to > -+configure networking when the container is started. Also, **-t none** a= nd > -+**-u none** are passed if, respectively, no TCP or UDP port forwarding = =66rom host > -+to container is configured, to disable automatic port forwarding based = on bound > -+ports. Similarly, **-T none** and **-U none** are also given to disable= the same > -+functionality from container to host. > -+ > -+Some 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 loop= back or > -+ link-local address. > -+ - **pasta:--mtu,1500**: Specify a 1500 bytes MTU for the _tap_ interf= ace 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 t= o 1500 > -+ 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= =2E2,--dns-forward,10.0.2.3,--no-ndp,--no-dhcpv6,--no-dhcp**, > -+ equivalent to default slirp4netns(1) options with Podman overrides:= same as > -+ above, but leave the MTU to 65520 bytes, and don't map the gateway = address > -+ from the container to a local address. > -+ - **pasta:-t,auto,-u,auto,-T,auto,-U,auto**: enable automatic port fo= rwarding > -+ based on observed bound ports from both host and container sides > -+ - **pasta:-T,5201**: enable forwarding of TCP port 5201 from containe= r to > -+ host, using the loopback interface instead of the tap interface for= improved > -+ performance > -+ > - @@option network-alias > -=20 > - @@option no-hosts > -@@ -248,6 +290,8 @@ $ podman pod create --network slirp4netns:outbound_a= ddr=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=3D1= 0.89.10.10 > - ``` > -=20 > -diff --git a/docs/source/markdown/podman-run.1.md.in b/docs/source/markd= own/podman-run.1.md.in > -index 2109a0e33..a9b212e81 100644 > ---- a/docs/source/markdown/podman-run.1.md.in > -+++ b/docs/source/markdown/podman-run.1.md.in > -@@ -298,10 +298,15 @@ Valid _mode_ values are: > - - **interface_name**: Specify a name for the created network interfac= e inside the container. > -=20 > - For example to set a static ipv4 address and a static mac address, us= e `--network bridge:ip=3D10.88.0.10,mac=3D44:33:22:11:00:99`. > -+ > - - \[:OPTIONS,...]: Connect to a user-defined netwo= rk; this is the network name or ID from a network created by **[podman netw= ork create](podman-network-create.1.md)**. Using the network name implies t= he bridge network mode. It is possible to specify the same options describe= d under the bridge mode above. You can use the **--network** option multipl= e times to specify additional networks. > -+ > - - **none**: Create a network namespace for the container but do not con= figure network interfaces for it, thus the container has no network connect= ivity. > -+ > - - **container:**_id_: Reuse another container's network stack. > -+ > - - **host**: Do not create a network namespace, the container will use t= he host's network. Note: The host mode gives the container full access to l= ocal system 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 rootful containers and **slirp4netns** for rootless= ones. > - - **slirp4netns[:OPTIONS,...]**: use **slirp4netns**(1) to create a use= r network stack. This is the default for rootless containers. It is possibl= e to specify these additional options, they can also be set with `network_c= md_options` in containers.conf: > -@@ -317,6 +322,43 @@ Valid _mode_ values are: > - Note: Rootlesskit changes the source IP address of incoming packets t= o an IP address in the container network namespace, usually `10.0.2.100`. I= f your application requires the real source IP address, e.g. web server log= s, use the slirp4netns port handler. The rootlesskit port handler is also u= sed for rootless 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= =2E This port handler cannot be used for user-defined networks. > -=20 > -+- **pasta[:OPTIONS,...]**: use **pasta**(1) to create a user-mode netwo= rking > -+stack. By default, IPv4 and IPv6 addresses and routes, as well as the p= od > -+interface name, are copied from the host. If port forwarding isn't conf= igured, > -+ports will be forwarded dynamically as services are bound on either sid= e (init > -+namespace or container namespace). Port forwarding preserves the origin= al source > -+IP address. Options described in pasta(1) can be specified as comma-sep= arated > -+arguments. > -+ > -+ > -+In terms of pasta(1) options, **--config-net** is given by default, in = order to > -+configure networking when the container is started. Also, **-t none** a= nd > -+**-u none** are passed if, respectively, no TCP or UDP port forwarding = =66rom host > -+to container is configured, to disable automatic port forwarding based = on bound > -+ports. Similarly, **-T none** and **-U none** are also given to disable= the same > -+functionality from container to host. > -+ > -+Some 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 loop= back or > -+ link-local address. > -+ - **pasta:--mtu,1500**: Specify a 1500 bytes MTU for the _tap_ interf= ace 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 t= o 1500 > -+ 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= =2E2,--dns-forward,10.0.2.3,--no-ndp,--no-dhcpv6,--no-dhcp**, > -+ equivalent to default slirp4netns(1) options with Podman overrides:= same as > -+ above, but leave the MTU to 65520 bytes, and don't map the gateway = address > -+ from the container to a local address. > -+ - **pasta:-t,auto,-u,auto,-T,auto,-U,auto**: enable automatic port fo= rwarding > -+ based on observed bound ports from both host and container sides > -+ - **pasta:-T,5201**: enable forwarding of TCP port 5201 from containe= r to > -+ host, using the loopback interface instead of the tap interface for= improved > -+ performance > -+ > - @@option network-alias > -=20 > - @@option no-healthcheck > -@@ -900,8 +942,9 @@ In order for users to run rootless, there must be an= entry for their username in > -=20 > - Rootless Podman works better if the fuse-overlayfs and slirp4netns pack= ages are installed. > - The **fuse-overlayfs** package provides a userspace overlay storage dri= ver, otherwise users need to use > --the **vfs** storage driver, which is diskspace expensive and does not p= erform well. slirp4netns is > --required for VPN, without it containers need to be run with the **--net= work=3Dhost** flag. > -+the **vfs** storage driver, which is diskspace expensive and does not p= erform > -+well. slirp4netns or pasta are required for VPN, without it containers = need to > -+be run with the **--network=3Dhost** flag. > -=20 > - ## ENVIRONMENT > -=20 > -@@ -948,7 +991,7 @@ page. > - NOTE: Use the environment variable `TMPDIR` to change the temporary sto= rage 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)**, *= *[podman-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-port.1.md)**, **[podman-start(1)](podman-start.1.md)**, **[podman-ki= ll(1)](podman-kill.1.md)**, **[podman-stop(1)](podman-stop.1.md)**, **[podm= an-generate-systemd(1)](podman-generate-systemd.1.md)**, **[podman-rm(1)](p= odman-rm.1.md)**, **[subgid(5)](https://www.unix.com/man-page/linux/5/subgi= d)**, **[subuid(5)](https://www.unix.com/man-page/linux/5/subuid)**, **[con= tainers.conf(5)](https://github.com/containers/common/blob/main/docs/contai= ners.conf.5.md)**, **[systemd.unit(5)](https://www.freedesktop.org/software= /systemd/man/systemd.unit.html)**, **[setsebool(8)](https://man7.org/linux/= man-pages/man8/setsebool.8.html)**, **[slirp4netns(1)](https://github.com/r= ootless-containers/slirp4netns/blob/master/slirp4netns.1.md)**, **[fuse-ove= rlayfs(1)](https://github.com/containers/fuse-overlayfs/blob/main/fuse-over= layfs.1.md)**, **proc(5)**, **[conmon(8)](https://github.com/containers/con= mon/blob/main/docs/conmon.8.md)**, **personality(2)** > -+**[podman(1)](podman.1.md)**, **[podman-save(1)](podman-save.1.md)**, *= *[podman-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-port.1.md)**, **[podman-start(1)](podman-start.1.md)**, **[podman-ki= ll(1)](podman-kill.1.md)**, **[podman-stop(1)](podman-stop.1.md)**, **[podm= an-generate-systemd(1)](podman-generate-systemd.1.md)**, **[podman-rm(1)](p= odman-rm.1.md)**, **[subgid(5)](https://www.unix.com/man-page/linux/5/subgi= d)**, **[subuid(5)](https://www.unix.com/man-page/linux/5/subuid)**, **[con= tainers.conf(5)](https://github.com/containers/common/blob/main/docs/contai= ners.conf.5.md)**, **[systemd.unit(5)](https://www.freedesktop.org/software= /systemd/man/systemd.unit.html)**, **[setsebool(8)](https://man7.org/linux/= man-pages/man8/setsebool.8.html)**, **[slirp4netns(1)](https://github.com/r= ootless-containers/slirp4netns/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/main/fuse-overlayfs.1.m= d)**, **proc(5)**, **[conmon(8)](https://github.com/containers/conmon/blob/= main/docs/conmon.8.md)**, **personality(2)** > -=20 > - ## HISTORY > - September 2018, updated by Kunal Kushwaha `` > -diff --git a/docs/source/markdown/podman.1.md b/docs/source/markdown/pod= man.1.md > -index 7a8dd7043..a54288bb0 100644 > ---- a/docs/source/markdown/podman.1.md > -+++ b/docs/source/markdown/podman.1.md > -@@ -88,7 +88,7 @@ Set libpod namespace. Namespaces are used to separate = groups of containers and p > - When namespace is set, created containers and pods will join the given = namespace, and only containers and pods in the given namespace will be visi= ble to Podman. > -=20 > - #### **--network-cmd-path**=3D*path* > --Path to the command binary to use for setting up a network. It is curr= ently only used for setting up a slirp4netns network. If "" is used then t= he binary is looked up using the $PATH environment variable. > -+Path to the command binary to use for setting up a network. It is curr= ently only used for setting up a slirp4netns(1) or pasta(1) network. If ""= is used then the binary is looked up using the $PATH environment variable. > -=20 > - #### **--network-config-dir**=3D*directory* > -=20 > -@@ -422,7 +422,7 @@ See the `subuid(5)` and `subgid(5)` man pages for mo= re information. > -=20 > - Images are pulled under `XDG_DATA_HOME` when specified, otherwise in th= e home directory of the user under `.local/share/containers/storage`. > -=20 > --Currently the slirp4netns package is required to be installed to create= a network device, otherwise rootless containers need to run in the network= namespace of the host. > -+Currently either slirp4netns or pasta are required to be installed to c= reate a network device, otherwise rootless containers need to run in the ne= twork namespace of the host. > -=20 > - In certain environments like HPC (High Performance Computing), users ca= nnot take advantage of the additional UIDs and GIDs from the /etc/subuid an= d /etc/subgid systems. However, in this environment, rootless Podman can o= perate with a single UID. To make this work, set the `ignore_chown_errors`= option in the /etc/containers/storage.conf or in ~/.config/containers/stor= age.conf files. This option tells Podman when pulling an image to ignore ch= own errors when attempting to change a file in a container image to match t= he non-root UID in the image. This means all files get saved as the user's = UID. Note this could cause issues when running the container. > -=20 > -@@ -435,7 +435,7 @@ The Network File System (NFS) and other distributed = file systems (for example: L > - For more information, please refer to the [Podman Troubleshooting Page]= (https://github.com/containers/podman/blob/main/troubleshooting.md). > -=20 > - ## SEE ALSO > --**[containers-mounts.conf(5)](https://github.com/containers/common/blob= /main/docs/containers-mounts.conf.5.md)**, **[containers.conf(5)](https://g= ithub.com/containers/common/blob/main/docs/containers.conf.5.md)**, **[cont= ainers-registries.conf(5)](https://github.com/containers/image/blob/main/do= cs/containers-registries.conf.5.md)**, **[containers-storage.conf(5)](https= ://github.com/containers/storage/blob/main/docs/containers-storage.conf.5.m= d)**, **[buildah(1)](https://github.com/containers/buildah/blob/main/docs/b= uildah.1.md)**, **oci-hooks(5)**, **[containers-policy.json(5)](https://git= hub.com/containers/image/blob/main/docs/containers-policy.json.5.md)**, **[= crun(1)](https://github.com/containers/crun/blob/main/crun.1.md)**, **[runc= (8)](https://github.com/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-containers/slirp4netns/blob/master/slirp4netns.1.md)*= *, **[conmon(8)](https://github.com/containers/conmon/blob/main/docs/conmon= =2E8.md)** > -+**[containers-mounts.conf(5)](https://github.com/containers/common/blob= /main/docs/containers-mounts.conf.5.md)**, **[containers.conf(5)](https://g= ithub.com/containers/common/blob/main/docs/containers.conf.5.md)**, **[cont= ainers-registries.conf(5)](https://github.com/containers/image/blob/main/do= cs/containers-registries.conf.5.md)**, **[containers-storage.conf(5)](https= ://github.com/containers/storage/blob/main/docs/containers-storage.conf.5.m= d)**, **[buildah(1)](https://github.com/containers/buildah/blob/main/docs/b= uildah.1.md)**, **oci-hooks(5)**, **[containers-policy.json(5)](https://git= hub.com/containers/image/blob/main/docs/containers-policy.json.5.md)**, **[= crun(1)](https://github.com/containers/crun/blob/main/crun.1.md)**, **[runc= (8)](https://github.com/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-containers/slirp4netns/blob/master/slirp4netns.1.md)*= *, **[pasta(1)](https://passt.top/builds/latest/web/passt.1.html)**, **[con= mon(8)](https://github.com/containers/conmon/blob/main/docs/conmon.8.md)** > -=20 > - ## HISTORY > - Dec 2016, Originally compiled by Dan Walsh > -diff --git a/libpod/networking_common.go b/libpod/networking_common.go > -index fa444e26a..2590a4477 100644 > ---- a/libpod/networking_common.go > -+++ b/libpod/networking_common.go > -@@ -133,7 +133,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 :=3D ctr.getNetworkOptions(networks) > - return r.teardownNetwork(ctr.state.NetNS.Path(), netOpts) > - } > -diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go > -index 6ea56ade5..822004a7c 100644 > ---- a/libpod/networking_linux.go > -+++ b/libpod/networking_linux.go > -@@ -563,6 +563,9 @@ func (r *Runtime) configureNetNS(ctr *Container, ctr= NS ns.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 > -diff --git a/libpod/networking_pasta.go b/libpod/networking_pasta.go > -new file mode 100644 > -index 000000000..f179c803a > ---- /dev/null > -+++ b/libpod/networking_pasta.go > -@@ -0,0 +1,107 @@ > -+// SPDX-License-Identifier: Apache-2.0 > -+// > -+// networking_pasta.go - Start pasta(1) to provide connectivity to the = container > -+// > -+// 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 { > -+ var NoTCPInitPorts =3D true > -+ var NoUDPInitPorts =3D true > -+ var NoTCPNamespacePorts =3D true > -+ var NoUDPNamespacePorts =3D true > -+ > -+ path :=3D r.config.Engine.NetworkCmdPath > -+ if path =3D=3D "" { > -+ var err error > -+ path, err =3D exec.LookPath("pasta") > -+ if err !=3D nil { > -+ return fmt.Errorf("could not find pasta, the network namespace can't= be configured: %w", err) > -+ } > -+ } > -+ > -+ cmdArgs :=3D []string{} > -+ cmdArgs =3D append(cmdArgs, "--config-net") > -+ > -+ for _, i :=3D range ctr.convertPortMappings() { > -+ protocols :=3D strings.Split(i.Protocol, ",") > -+ for _, protocol :=3D range protocols { > -+ var addr string > -+ > -+ if (i.HostIP !=3D "") { > -+ addr =3D fmt.Sprintf("%s/", i.HostIP) > -+ } else { > -+ addr =3D "" > -+ } > -+ > -+ if protocol =3D=3D "tcp" { > -+ cmdArgs =3D append(cmdArgs, "-t") > -+ } else if protocol =3D=3D "udp" { > -+ cmdArgs =3D append(cmdArgs, "-u") > -+ } else { > -+ return fmt.Errorf("can't forward protocol: %s", protocol) > -+ } > -+ > -+ arg :=3D fmt.Sprintf("%s%d-%d:%d-%d", addr, > -+ i.HostPort, > -+ i.HostPort + i.Range - 1, > -+ i.ContainerPort, > -+ i.ContainerPort + i.Range - 1) > -+ cmdArgs =3D append(cmdArgs, arg) > -+ } > -+ } > -+ > -+ cmdArgs =3D append(cmdArgs, ctr.config.NetworkOptions["pasta"]...) > -+ > -+ for _, i :=3D range cmdArgs { > -+ if (i =3D=3D "-t" || i =3D=3D "--tcp-ports") { > -+ NoTCPInitPorts =3D false > -+ } else if (i =3D=3D "-u" || i =3D=3D "--udp-ports") { > -+ NoUDPInitPorts =3D false > -+ } else if (i =3D=3D "-T" || i =3D=3D "--tcp-ns") { > -+ NoTCPNamespacePorts =3D false > -+ } else if (i =3D=3D "-U" || i =3D=3D "--udp-ns") { > -+ NoUDPNamespacePorts =3D false > -+ } > -+ } > -+ > -+ if (NoTCPInitPorts) { > -+ cmdArgs =3D append(cmdArgs, "-t", "none") > -+ } > -+ if (NoUDPInitPorts) { > -+ cmdArgs =3D append(cmdArgs, "-u", "none") > -+ } > -+ if (NoTCPNamespacePorts) { > -+ cmdArgs =3D append(cmdArgs, "-T", "none") > -+ } > -+ if (NoUDPNamespacePorts) { > -+ cmdArgs =3D append(cmdArgs, "-U", "none") > -+ } > -+ > -+ cmdArgs =3D append(cmdArgs, "--netns", netns.Path()) > -+ > -+ logrus.Debugf("pasta arguments: %s", strings.Join(cmdArgs, " ")) > -+ > -+ // pasta forks once ready, and quits once we delete the target namespa= ce > -+ _, 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 6dd576ea5..85903e7a9 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 > - // KeepIDUserNsOptions defines how to keepIDmatically create a user nam= espace. > -@@ -440,6 +441,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 p= asta > -+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/n= amespaces.go > -index 9497894f3..11a30e545 100644 > ---- a/pkg/specgen/generate/namespaces.go > -+++ b/pkg/specgen/generate/namespaces.go > -@@ -300,6 +300,16 @@ func namespaceOptions(s *specgen.SpecGenerator, rt = *libpod.Runtime, pod *libpod. > - val =3D fmt.Sprintf("slirp4netns:%s", s.NetNS.Value) > - } > - toReturn =3D append(toReturn, libpod.WithNetNS(portMappings, expose, = postConfigureNetNS, val, nil)) > -+ case specgen.Pasta: > -+ portMappings, expose, err :=3D createPortMappings(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, = postConfigureNetNS, val, nil)) > - case specgen.Bridge, specgen.Private, specgen.Default: > - portMappings, expose, err :=3D createPortMappings(s, imageData) > - if err !=3D nil { > -diff --git a/pkg/specgen/generate/pod_create.go b/pkg/specgen/generate/p= od_create.go > -index 14d390e49..ad91353cb 100644 > ---- a/pkg/specgen/generate/pod_create.go > -+++ b/pkg/specgen/generate/pod_create.go > -@@ -195,6 +195,12 @@ func MapSpec(p *specgen.PodSpecGenerator) (*specgen= =2ESpecGenerator, error) { > - p.InfraContainerSpec.NetworkOptions =3D p.NetworkOptions > - p.InfraContainerSpec.NetNS.NSMode =3D specgen.Slirp > - } > -+ 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 b6bbee868..5c4cb97c2 100644 > ---- a/pkg/specgen/namespaces.go > -+++ b/pkg/specgen/namespaces.go > -@@ -52,6 +52,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. > -@@ -154,7 +157,7 @@ func validateNetNS(n *Namespace) error { > - return nil > - } > - switch n.NSMode { > -- case Slirp: > -+ case Slirp, Pasta: > - break > - case "", Default, Host, Path, FromContainer, FromPod, Private, NoNetwo= rk, Bridge: > - break > -@@ -197,7 +200,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.New("cannot use network modes with non-network namespac= e") > - default: > - return fmt.Errorf("invalid namespace type %s specified", n.NSMode) > -@@ -349,6 +352,13 @@ func ParseNetworkFlag(networks []string) (Namespace= , map[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(Pri= vate): > -@@ -419,7 +429,7 @@ func ParseNetworkFlag(networks []string) (Namespace,= map[string]types.PerNetwork > - if parts[0] =3D=3D "" { > - return toReturn, nil, nil, fmt.Errorf("network name cannot be empty= : %w", define.ErrInvalidArg) > - } > -- if cutil.StringInSlice(parts[0], []string{string(Bridge), string(Sli= rp), string(FromPod), string(NoNetwork), > -+ if cutil.StringInSlice(parts[0], []string{string(Bridge), string(Sli= rp), string(Pasta), string(FromPod), string(NoNetwork), > - string(Default), string(Private), string(Path), string(FromContaine= r), string(Host)}) { > - return toReturn, nil, nil, fmt.Errorf("can only set extra network n= ames, selected mode %s conflicts with bridge: %w", parts[0], define.ErrInva= lidArg) > - } > -diff --git a/pkg/specgen/podspecgen.go b/pkg/specgen/podspecgen.go > -index 64a79f4ee..faeeb2ed6 100644 > ---- a/pkg/specgen/podspecgen.go > -+++ b/pkg/specgen/podspecgen.go > -@@ -98,7 +98,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.35.1 > - --=20 David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson --0bsbI9gTS3qL+uju Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQIzBAEBCAAdFiEEO+dNsU4E3yXUXRK2zQJF27ox2GcFAmQJEd4ACgkQzQJF27ox 2GfJWQ/9FV5l62CebfTfabsZLaIFCM/oEs7vPcWK2lHcnFt1UT73HpvJyWQaA/1U tKlS7KXaSnM4t7jb3dcvjxZUZ3wVCxXisGktG9IM3RNnT9MytiX9ILnS8PRgmq/0 GnRENGSPXLn/sjTrrxGjoAYPA8sU9sse3xFUc3P99FidJXxdt0m3DFXHp0CwgXRJ fxJx104Oxph/sJSOAjdSUxRJ/JiDoogBK+rsF5vEXBT35rm2gIRdXM5y8nGscJ9Y 6jJEoFYId8PDza6TzAqAgOyBtTrROAHOy5yo284A7+TdEj2g8qVL5zlofwevp/wh ed1O33EN4dnWNfvfBsrzJHv6B9dLr0L0nNS0XwwVqQr5Wx7+19b7hZ9Xayt6dqqG Fb+0fffeP8f7HOU6IGUFFi/j8pKO+ju3q7xMokZthmDQEV3E71I0N1u4CzcRSPb4 pRGkzDclGmTSNRRKYgam6E9r9irWuDpqxqO9L+ObFj9nr57bkXHT/XGhtMjljW0K BVUNcEtapL3BYDNLrRxnntfC2vWQvmt6ij8a1usp0ju7BQDs5sf5nea7PboovBh5 guFxN/bL9BXCgW6BW8cgMlhmVeX9u9NFpH+9v3EHGZLR2mZsgQdO9SH3YQWfL/9B JZ8temobKiuAILVtpPDHpNHrnKvf99/XWLDRuDB7re905ZpFkIQ= =MB0s -----END PGP SIGNATURE----- --0bsbI9gTS3qL+uju--