Skip to content

Commit aa47e05

Browse files
committed
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 - sandboxing and seccomp(2) policies cannot be disabled - only rootless mode is supported. See https://passt.top for more details about pasta. Also add a link to the maintained build of pasta(1) manual as valid in the man page cross-reference checks: that's where the man page for the latest build actually is -- it's not on Github and it doesn't match any existing pattern, so add it explicitly. Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
1 parent ec03579 commit aa47e05

24 files changed

+258
-28
lines changed

Diff for: cmd/podman/common/netflags.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ func DefineNetFlags(cmd *cobra.Command) {
9595
}
9696

9797
// NetFlagsToNetOptions parses the network flags for the given cmd.
98-
func NetFlagsToNetOptions(opts *entities.NetOptions, flags pflag.FlagSet) (*entities.NetOptions, error) {
98+
func NetFlagsToNetOptions(opts *entities.NetOptions, flags pflag.FlagSet, pastaNetworkNameExists bool) (*entities.NetOptions, error) {
9999
var (
100100
err error
101101
)
@@ -192,7 +192,7 @@ func NetFlagsToNetOptions(opts *entities.NetOptions, flags pflag.FlagSet) (*enti
192192
return nil, err
193193
}
194194

195-
ns, networks, options, err := specgen.ParseNetworkFlag(network)
195+
ns, networks, options, err := specgen.ParseNetworkFlag(network, pastaNetworkNameExists)
196196
if err != nil {
197197
return nil, err
198198
}

Diff for: cmd/podman/containers/create.go

+8-1
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,15 @@ func init() {
105105

106106
func commonFlags(cmd *cobra.Command) error {
107107
var err error
108+
109+
report, err := registry.ContainerEngine().NetworkExists(registry.Context(), "pasta")
110+
if err != nil {
111+
return err
112+
}
113+
pastaNetworkNameExists := report.Value
114+
108115
flags := cmd.Flags()
109-
cliVals.Net, err = common.NetFlagsToNetOptions(nil, *flags)
116+
cliVals.Net, err = common.NetFlagsToNetOptions(nil, *flags, pastaNetworkNameExists)
110117
if err != nil {
111118
return err
112119
}

Diff for: cmd/podman/pods/create.go

+8-2
Original file line numberDiff line numberDiff line change
@@ -130,12 +130,18 @@ func create(cmd *cobra.Command, args []string) error {
130130
createOptions.Infra = false
131131
}
132132

133+
report, err := registry.ContainerEngine().NetworkExists(registry.Context(), "pasta")
134+
if err != nil {
135+
return err
136+
}
137+
pastaNetworkNameExists := report.Value
138+
133139
if !createOptions.Infra {
134140
if cmd.Flag("no-hosts").Changed {
135141
return fmt.Errorf("cannot specify --no-hosts without an infra container")
136142
}
137143
flags := cmd.Flags()
138-
createOptions.Net, err = common.NetFlagsToNetOptions(nil, *flags)
144+
createOptions.Net, err = common.NetFlagsToNetOptions(nil, *flags, pastaNetworkNameExists)
139145
if err != nil {
140146
return err
141147
}
@@ -152,7 +158,7 @@ func create(cmd *cobra.Command, args []string) error {
152158
} else {
153159
// reassign certain options for lbpod api, these need to be populated in spec
154160
flags := cmd.Flags()
155-
infraOptions.Net, err = common.NetFlagsToNetOptions(nil, *flags)
161+
infraOptions.Net, err = common.NetFlagsToNetOptions(nil, *flags, pastaNetworkNameExists)
156162
if err != nil {
157163
return err
158164
}

Diff for: docs/source/markdown/options/network.md

+39
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,42 @@ Valid _mode_ values are:
3535
- **port_handler=rootlesskit**: Use rootlesskit for port forwarding. Default.
3636
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 the slirp4netns port handler. The rootlesskit port handler is also used for rootless containers when connected to user-defined networks.
3737
- **port_handler=slirp4netns**: 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.
38+
39+
- **pasta[:OPTIONS,...]**: use **pasta**(1) to create a user-mode networking
40+
stack. \
41+
This is only supported in rootless mode. \
42+
By default, IPv4 and IPv6 addresses and routes, as well as the pod interface
43+
name, are copied from the host. If port forwarding isn't configured, ports
44+
will be forwarded dynamically as services are bound on either side (init
45+
namespace or container namespace). Port forwarding preserves the original
46+
source IP address. Options described in pasta(1) can be specified as
47+
comma-separated arguments. \
48+
In terms of pasta(1) options, **--config-net** is given by default, in
49+
order to configure networking when the container is started, and
50+
**--no-map-gw** is also assumed by default, to avoid direct access from
51+
container to host using the gateway address. The latter can be overridden
52+
by passing **--map-gw** in the pasta-specific options (despite not being an
53+
actual pasta(1) option). \
54+
Also, **-t none** and **-u none** are passed if, respectively, no TCP or
55+
UDP port forwarding from host to container is configured, to disable
56+
automatic port forwarding based on bound ports. Similarly, **-T none** and
57+
**-U none** are given to disable the same functionality from container to
58+
host. \
59+
Some examples:
60+
- **pasta:--map-gw**: Allow the container to directly reach the host using the
61+
gateway address.
62+
- **pasta:--mtu,1500**: Specify a 1500 bytes MTU for the _tap_ interface in
63+
the container.
64+
- **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**,
65+
equivalent to default slirp4netns(1) options: disable IPv6, assign
66+
`10.0.2.0/24` to the `tap0` interface in the container, with gateway
67+
`10.0.2.3`, enable DNS forwarder reachable at `10.0.2.3`, set MTU to 1500
68+
bytes, disable NDP, DHCPv6 and DHCP support.
69+
- **pasta:-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**,
70+
equivalent to default slirp4netns(1) options with Podman overrides: same as
71+
above, but leave the MTU to 65520 bytes
72+
- **pasta:-t,auto,-u,auto,-T,auto,-U,auto**: enable automatic port forwarding
73+
based on observed bound ports from both host and container sides
74+
- **pasta:-T,5201**: enable forwarding of TCP port 5201 from container to
75+
host, using the loopback interface instead of the tap interface for improved
76+
performance

Diff for: docs/source/markdown/podman-create.1.md.in

+6-3
Original file line numberDiff line numberDiff line change
@@ -491,8 +491,11 @@ In order for users to run rootless, there must be an entry for their username in
491491

492492
Rootless Podman works better if the fuse-overlayfs and slirp4netns packages are installed.
493493
The fuse-overlayfs package provides a userspace overlay storage driver, otherwise users need to use
494-
the vfs storage driver, which is diskspace expensive and does not perform well. slirp4netns is
495-
required for VPN, without it containers need to be run with the --network=host flag.
494+
the vfs storage driver, which can be disk space expensive and less performant
495+
than other drivers.
496+
497+
To enable VPN on the container, slirp4netns or pasta needs to be specified;
498+
without either, containers need to be run with the --network=host flag.
496499

497500
## ENVIRONMENT
498501

@@ -541,7 +544,7 @@ page.
541544
NOTE: Use the environment variable `TMPDIR` to change the temporary storage location of downloaded container images. Podman defaults to use `/var/tmp`.
542545

543546
## SEE ALSO
544-
**[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-kill(1)](podman-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)](https://github.com/containers/common/blob/main/docs/containers.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/rootless-containers/slirp4netns/blob/master/slirp4netns.1.md)**, **[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)**
547+
**[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-kill(1)](podman-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)](https://github.com/containers/common/blob/main/docs/containers.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/rootless-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)**
545548

546549
## HISTORY
547550
October 2017, converted from Docker documentation to Podman by Dan Walsh for Podman `<dwalsh@redhat.com>`

Diff for: docs/source/markdown/podman-pod-create.1.md.in

+2
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,8 @@ $ podman pod create --network slirp4netns:outbound_addr=127.0.0.1,allow_host_loo
219219

220220
$ podman pod create --network slirp4netns:cidr=192.168.0.0/24
221221

222+
$ podman pod create --network pasta
223+
222224
$ podman pod create --network net1:ip=10.89.1.5 --network net2:ip=10.89.10.10
223225
```
224226

Diff for: docs/source/markdown/podman-run.1.md.in

+6-3
Original file line numberDiff line numberDiff line change
@@ -837,8 +837,11 @@ In order for users to run rootless, there must be an entry for their username in
837837

838838
Rootless Podman works better if the fuse-overlayfs and slirp4netns packages are installed.
839839
The **fuse-overlayfs** package provides a userspace overlay storage driver, otherwise users need to use
840-
the **vfs** storage driver, which is diskspace expensive and does not perform well. slirp4netns is
841-
required for VPN, without it containers need to be run with the **--network=host** flag.
840+
the **vfs** storage driver, which can be disk space expensive and less
841+
performant than other drivers.
842+
843+
To enable VPN on the container, slirp4netns or pasta needs to be specified;
844+
without either, containers need to be run with the --network=host flag.
842845

843846
## ENVIRONMENT
844847

@@ -885,7 +888,7 @@ page.
885888
NOTE: Use the environment variable `TMPDIR` to change the temporary storage location of downloaded container images. Podman defaults to use `/var/tmp`.
886889

887890
## SEE ALSO
888-
**[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-kill(1)](podman-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)](https://github.com/containers/common/blob/main/docs/containers.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/rootless-containers/slirp4netns/blob/master/slirp4netns.1.md)**, **[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)**
891+
**[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-kill(1)](podman-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)](https://github.com/containers/common/blob/main/docs/containers.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/rootless-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)**
889892

890893
## HISTORY
891894
September 2018, updated by Kunal Kushwaha `<kushwaha_kunal_v7@lab.ntt.co.jp>`

Diff for: docs/source/markdown/podman.1.md

+5-3
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ Set libpod namespace. Namespaces are used to separate groups of containers and p
8888
When namespace is set, created containers and pods will join the given namespace, and only containers and pods in the given namespace will be visible to Podman.
8989

9090
#### **--network-cmd-path**=*path*
91-
Path to the command binary to use for setting up a network. It is currently only used for setting up a slirp4netns network. If "" is used then the binary is looked up using the $PATH environment variable.
91+
Path to the command binary to use for setting up a network. It is currently 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.
9292

9393
#### **--network-config-dir**=*directory*
9494

@@ -422,7 +422,9 @@ See the `subuid(5)` and `subgid(5)` man pages for more information.
422422

423423
Images are pulled under `XDG_DATA_HOME` when specified, otherwise in the home directory of the user under `.local/share/containers/storage`.
424424

425-
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.
425+
Currently slirp4netns or pasta is required to be installed to create a network
426+
device, otherwise rootless containers need to run in the network namespace of
427+
the host.
426428

427429
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 with 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 files. This option tells Podman when pulling an image to ignore chown errors when 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 could cause issues when running the container.
428430

@@ -435,7 +437,7 @@ The Network File System (NFS) and other distributed file systems (for example: L
435437
For more information, please refer to the [Podman Troubleshooting Page](https://github.com/containers/podman/blob/main/troubleshooting.md).
436438

437439
## SEE ALSO
438-
**[containers-mounts.conf(5)](https://github.com/containers/common/blob/main/docs/containers-mounts.conf.5.md)**, **[containers.conf(5)](https://github.com/containers/common/blob/main/docs/containers.conf.5.md)**, **[containers-registries.conf(5)](https://github.com/containers/image/blob/main/docs/containers-registries.conf.5.md)**, **[containers-storage.conf(5)](https://github.com/containers/storage/blob/main/docs/containers-storage.conf.5.md)**, **[buildah(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://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.8.md)**
440+
**[containers-mounts.conf(5)](https://github.com/containers/common/blob/main/docs/containers-mounts.conf.5.md)**, **[containers.conf(5)](https://github.com/containers/common/blob/main/docs/containers.conf.5.md)**, **[containers-registries.conf(5)](https://github.com/containers/image/blob/main/docs/containers-registries.conf.5.md)**, **[containers-storage.conf(5)](https://github.com/containers/storage/blob/main/docs/containers-storage.conf.5.md)**, **[buildah(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://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)**, **[conmon(8)](https://github.com/containers/conmon/blob/main/docs/conmon.8.md)**
439441

440442
## HISTORY
441443
Dec 2016, Originally compiled by Dan Walsh <dwalsh@redhat.com>

Diff for: hack/xref-helpmsgs-manpages

+2
Original file line numberDiff line numberDiff line change
@@ -619,6 +619,8 @@ sub _is_valid_external_link {
619619
return 1 if $link eq "https://www.freedesktop.org/software/systemd/man/$base.html";
620620
}
621621

622+
return 1 if $link eq "https://passt.top/builds/latest/web/passt.1.html";
623+
622624
return;
623625
}
624626

Diff for: libpod/networking_common.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,8 @@ func (r *Runtime) teardownCNI(ctr *Container) error {
133133
return err
134134
}
135135

136-
if !ctr.config.NetMode.IsSlirp4netns() && len(networks) > 0 {
136+
if !ctr.config.NetMode.IsSlirp4netns() &&
137+
!ctr.config.NetMode.IsPasta() && len(networks) > 0 {
137138
netOpts := ctr.getNetworkOptions(networks)
138139
return r.teardownNetwork(ctr.state.NetNS.Path(), netOpts)
139140
}

Diff for: libpod/networking_linux.go

+3
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,9 @@ func (r *Runtime) configureNetNS(ctr *Container, ctrNS ns.NetNS) (status map[str
563563
if ctr.config.NetMode.IsSlirp4netns() {
564564
return nil, r.setupSlirp4netns(ctr, ctrNS)
565565
}
566+
if ctr.config.NetMode.IsPasta() {
567+
return nil, r.setupPasta(ctr, ctrNS)
568+
}
566569
networks, err := ctr.networks()
567570
if err != nil {
568571
return nil, err

0 commit comments

Comments
 (0)