public inbox for passt-dev@passt.top
 help / color / mirror / code / Atom feed
blob cb1bab9b0ae1ed7bf7108f67b060a9763976d366 38971 bytes (raw)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
 
From 3aa86f0fd0d420c11d328c673e8162300172925a Mon Sep 17 00:00:00 2001
From: Stefano Brivio <sbrivio@redhat.com>
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 <sbrivio@redhat.com>
---
SPDX-FileCopyrightText: 2021-2022 Red Hat GmbH <sbrivio@redhat.com>
SPDX-License-Identifier: Apache-2.0

 docs/source/markdown/podman-create.1.md     |  48 ++++++++-
 docs/source/markdown/podman-pod-create.1.md |  44 ++++++++
 docs/source/markdown/podman-run.1.md        |  49 ++++++++-
 docs/source/markdown/podman.1.md            |   6 +-
 libpod/networking_linux.go                  |   6 +-
 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 +-
 11 files changed, 286 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 67bb573e2..3b96de4d7 100644
--- a/docs/source/markdown/podman-create.1.md
+++ b/docs/source/markdown/podman-create.1.md
@@ -717,10 +717,15 @@ Valid _mode_ values are:
   - **interface_name**: Specify a name for the created network interface inside the container.
 
   For example to set a static ipv4 address and a static mac address, use `--network bridge:ip=10.88.0.10,mac=44:33:22:11:00:99`.
+
 - \<network name or ID\>[:OPTIONS,...]: Connect to a user-defined network; this is the network name or ID from a network created by **[podman network create](podman-network-create.1.md)**. Using the network name implies the bridge network mode. It is possible to specify the same options described under the bridge mode above. You can use the **--network** option multiple times to specify additional networks.
+
 - **none**: Create a network namespace for the container but do not configure 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 host's network. Note: The host mode gives the container full access to local 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 user network stack. This is the default for rootless containers. It is possible to specify these additional options, they can also be set with `network_cmd_options` in containers.conf:
@@ -736,6 +741,40 @@ 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 the slirp4netns port handler. The rootlesskit port handler is also used for rootless containers when connected to user-defined networks.
   - **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.
 
+- **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. 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** and
+**-u none** are passed if, respectively, no TCP or UDP port forwarding from 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 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 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.2,--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 forwarding
+    based on observed bound ports from both host and container sides
+  - **pasta:-T,5201**: enable forwarding of TCP port 5201 from container to
+    host, using the loopback interface instead of the tap interface for improved
+    performance
+
 #### **--network-alias**=*alias*
 
 Add a network-scoped alias for the container, setting the alias for all networks that the container joins. To set a name only for a specific network, use the alias option as described under the **--network** option.
@@ -1592,8 +1631,9 @@ In order for users to run rootless, there must be an entry for their username in
 
 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 perform well. slirp4netns is
-required for VPN, without it containers need to be run with the --network=host flag.
+the vfs storage driver, which is diskspace expensive and does not perform well.
+slirp4netns or pasta are required for VPN, without it containers need to be run
+with the --network=host flag.
 
 ## ENVIRONMENT
 
@@ -1642,7 +1682,9 @@ page.
 NOTE: Use the environment variable `TMPDIR` to change the temporary storage location of downloaded container images. Podman defaults to use `/var/tmp`.
 
 ## 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-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)**
+**[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)**
 
 ## HISTORY
 October 2017, converted from Docker documentation to Podman by Dan Walsh for Podman `<dwalsh@redhat.com>`
diff --git a/docs/source/markdown/podman-pod-create.1.md b/docs/source/markdown/podman-pod-create.1.md
index de9a34bfa..e711d6823 100644
--- a/docs/source/markdown/podman-pod-create.1.md
+++ b/docs/source/markdown/podman-pod-create.1.md
@@ -193,10 +193,15 @@ Valid _mode_ values are:
   - **interface_name**: Specify a name for the created network interface inside the container.
 
   For example to set a static ipv4 address and a static mac address, use `--network bridge:ip=10.88.0.10,mac=44:33:22:11:00:99`.
+
 - \<network name or ID\>[:OPTIONS,...]: Connect to a user-defined network; this is the network name or ID from a network created by **[podman network create](podman-network-create.1.md)**. Using the network name implies the bridge network mode. It is possible to specify the same options described under the bridge mode above. You can use the **--network** option multiple times to specify additional networks.
+
 - **none**: Create a network namespace for the container but do not configure 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 host's network. Note: The host mode gives the container full access to local 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 user network stack. This is the default for rootless containers. It is possible to specify these additional options, they can also be set with `network_cmd_options` in containers.conf:
@@ -212,6 +217,43 @@ 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 the slirp4netns port handler. The rootlesskit port handler is also used for rootless containers when connected to user-defined networks.
   - **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.
 
+- **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 configured,
+ports will be forwarded dynamically as services are bound on either side (init
+namespace or container namespace). 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** and
+**-u none** are passed if, respectively, no TCP or UDP port forwarding from 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 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 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.2,--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 forwarding
+    based on observed bound ports from both host and container sides
+  - **pasta:-T,5201**: enable forwarding of TCP port 5201 from container to
+    host, using the loopback interface instead of the tap interface for improved
+    performance
+
 #### **--network-alias**=*alias*
 
 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.
@@ -599,6 +641,8 @@ $ podman pod create --network slirp4netns:outbound_addr=127.0.0.1,allow_host_loo
 
 $ podman pod create --network slirp4netns:cidr=192.168.0.0/24
 
+$ podman pod create --network pasta
+
 $ podman pod create --network net1:ip=10.89.1.5 --network net2:ip=10.89.10.10
 ```
 
diff --git a/docs/source/markdown/podman-run.1.md b/docs/source/markdown/podman-run.1.md
index 4566a73d0..8f8b5b4c1 100644
--- a/docs/source/markdown/podman-run.1.md
+++ b/docs/source/markdown/podman-run.1.md
@@ -734,10 +734,15 @@ Valid _mode_ values are:
   - **interface_name**: Specify a name for the created network interface inside the container.
 
   For example to set a static ipv4 address and a static mac address, use `--network bridge:ip=10.88.0.10,mac=44:33:22:11:00:99`.
+
 - \<network name or ID\>[:OPTIONS,...]: Connect to a user-defined network; this is the network name or ID from a network created by **[podman network create](podman-network-create.1.md)**. Using the network name implies the bridge network mode. It is possible to specify the same options described under the bridge mode above. You can use the **--network** option multiple times to specify additional networks.
+
 - **none**: Create a network namespace for the container but do not configure 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 host's network. Note: The host mode gives the container full access to local 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 user network stack. This is the default for rootless containers. It is possible to specify these additional options, they can also be set with `network_cmd_options` in containers.conf:
@@ -753,6 +758,43 @@ 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 the slirp4netns port handler. The rootlesskit port handler is also used for rootless containers when connected to user-defined networks.
   - **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.
 
+- **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 configured,
+ports will be forwarded dynamically as services are bound on either side (init
+namespace or container namespace). 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** and
+**-u none** are passed if, respectively, no TCP or UDP port forwarding from 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 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 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.2,--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 forwarding
+    based on observed bound ports from both host and container sides
+  - **pasta:-T,5201**: enable forwarding of TCP port 5201 from container to
+    host, using the loopback interface instead of the tap interface for improved
+    performance
+
 #### **--network-alias**=*alias*
 
 Add a network-scoped alias for the container, setting the alias for all networks that the container joins. To set a name only for a specific network, use the alias option as described under the **--network** option.
@@ -1964,8 +2006,9 @@ In order for users to run rootless, there must be an entry for their username in
 
 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 perform well. slirp4netns is
-required for VPN, without it containers need to be run with the **--network=host** flag.
+the **vfs** storage driver, which is diskspace expensive and does not perform
+well. slirp4netns or pasta are required for VPN, without it containers need to
+be run with the **--network=host** flag.
 
 ## ENVIRONMENT
 
@@ -2012,7 +2055,7 @@ page.
 NOTE: Use the environment variable `TMPDIR` to change the temporary storage location of downloaded container images. Podman defaults to use `/var/tmp`.
 
 ## 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-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)**
+**[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)**
 
 ## HISTORY
 September 2018, updated by Kunal Kushwaha `<kushwaha_kunal_v7@lab.ntt.co.jp>`
diff --git a/docs/source/markdown/podman.1.md b/docs/source/markdown/podman.1.md
index 4c019ae97..4c09d4bee 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 visible to Podman.
 
 #### **--network-cmd-path**=*path*
-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.
+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.
 
 #### **--network-config-dir**=*directory*
 
@@ -415,7 +415,7 @@ See the `subuid(5)` and `subgid(5)` man pages for more information.
 
 Images are pulled under `XDG_DATA_HOME` when specified, otherwise in the home directory of the user under `.local/share/containers/storage`.
 
-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 create a network device, otherwise rootless containers need to run in the network namespace of the host.
 
 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.
 
@@ -428,7 +428,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).
 
 ## SEE ALSO
-**[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)**
+**[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)**
 
 ## HISTORY
 Dec 2016, Originally compiled by Dan Walsh <dwalsh@redhat.com>
diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go
index c05796768..5c1f0ea35 100644
--- a/libpod/networking_linux.go
+++ b/libpod/networking_linux.go
@@ -640,6 +640,9 @@ func (r *Runtime) configureNetNS(ctr *Container, ctrNS 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 := ctr.networks()
 	if err != nil {
 		return nil, err
@@ -809,7 +812,8 @@ func (r *Runtime) teardownCNI(ctr *Container) error {
 		return err
 	}
 
-	if !ctr.config.NetMode.IsSlirp4netns() && len(networks) > 0 {
+	if !ctr.config.NetMode.IsSlirp4netns() &&
+	   !ctr.config.NetMode.IsPasta() && len(networks) > 0 {
 		netOpts := ctr.getNetworkOptions(networks)
 		return r.teardownNetwork(ctr.state.NetNS.Path(), netOpts)
 	}
diff --git a/libpod/networking_pasta.go b/libpod/networking_pasta.go
new file mode 100644
index 000000000..66f81cbfc
--- /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 <sbrivio@redhat.com>
+//
+// +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 = true
+	var NoUDPInitPorts = true
+	var NoTCPNamespacePorts = true
+	var NoUDPNamespacePorts = true
+
+	path := r.config.Engine.NetworkCmdPath
+	if path == "" {
+		var err error
+		path, err = exec.LookPath("pasta")
+		if err != nil {
+			return fmt.Errorf("could not find pasta, the network namespace can't be configured: %w", err)
+		}
+	}
+
+	cmdArgs := []string{}
+	cmdArgs = append(cmdArgs, "--config-net")
+
+	for _, i := range ctr.convertPortMappings() {
+		protocols := strings.Split(i.Protocol, ",")
+		for _, protocol := range protocols {
+			var addr string
+
+			if (i.HostIP != "") {
+				addr = fmt.Sprintf("%s/", i.HostIP)
+			} else {
+				addr = ""
+			}
+
+			if protocol == "tcp" {
+				cmdArgs = append(cmdArgs, "-t")
+			} else if protocol == "udp" {
+				cmdArgs = append(cmdArgs, "-u")
+			} else {
+				return fmt.Errorf("can't forward protocol: %s", protocol)
+			}
+
+			arg := fmt.Sprintf("%s%d-%d:%d-%d", addr,
+					   i.HostPort,
+					   i.HostPort + i.Range - 1,
+					   i.ContainerPort,
+					   i.ContainerPort + i.Range - 1)
+			cmdArgs = append(cmdArgs, arg)
+		}
+	}
+
+	cmdArgs = append(cmdArgs, ctr.config.NetworkOptions["pasta"]...)
+
+	for _, i := range cmdArgs {
+		if (i == "-t" || i == "--tcp-ports") {
+			NoTCPInitPorts = false
+		} else if (i == "-u" || i == "--udp-ports") {
+			NoUDPInitPorts = false
+		} else if (i == "-T" || i == "--tcp-ns") {
+			NoTCPNamespacePorts = false
+		} else if (i == "-U" || i == "--udp-ns") {
+			NoUDPNamespacePorts = false
+		}
+	}
+
+	if (NoTCPInitPorts) {
+		cmdArgs = append(cmdArgs, "-t", "none")
+	}
+	if (NoUDPInitPorts) {
+		cmdArgs = append(cmdArgs, "-u", "none")
+	}
+	if (NoTCPNamespacePorts) {
+		cmdArgs = append(cmdArgs, "-T", "none")
+	}
+	if (NoUDPNamespacePorts) {
+		cmdArgs = append(cmdArgs, "-U", "none")
+	}
+
+	cmdArgs = 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 := exec.Command(path, cmdArgs...).Output()
+	if err != 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 8eacb8da7..49a6d3786 100644
--- a/pkg/namespaces/namespaces.go
+++ b/pkg/namespaces/namespaces.go
@@ -19,6 +19,7 @@ const (
 	privateType   = "private"
 	shareableType = "shareable"
 	slirpType     = "slirp4netns"
+	pastaType     = "pasta"
 )
 
 // CgroupMode represents cgroup mode in the container.
@@ -393,6 +394,11 @@ func (n NetworkMode) IsSlirp4netns() bool {
 	return n == slirpType || strings.HasPrefix(string(n), slirpType+":")
 }
 
+// IsPasta indicates if we are running a rootless network stack using pasta
+func (n NetworkMode) IsPasta() bool {
+	return n == pastaType || strings.HasPrefix(string(n), pastaType + ":")
+}
+
 // IsNS indicates a network namespace passed in by path (ns:<path>)
 func (n NetworkMode) IsNS() bool {
 	return strings.HasPrefix(string(n), nsType)
diff --git a/pkg/specgen/generate/namespaces.go b/pkg/specgen/generate/namespaces.go
index f0d4e9153..2c4b40509 100644
--- a/pkg/specgen/generate/namespaces.go
+++ b/pkg/specgen/generate/namespaces.go
@@ -295,6 +295,16 @@ func namespaceOptions(s *specgen.SpecGenerator, rt *libpod.Runtime, pod *libpod.
 			val = fmt.Sprintf("slirp4netns:%s", s.NetNS.Value)
 		}
 		toReturn = append(toReturn, libpod.WithNetNS(portMappings, expose, postConfigureNetNS, val, nil))
+	case specgen.Pasta:
+		portMappings, expose, err := createPortMappings(s, imageData)
+		if err != nil {
+			return nil, err
+		}
+		val := "pasta"
+		if s.NetNS.Value != "" {
+			val = fmt.Sprintf("pasta:%s", s.NetNS.Value)
+		}
+		toReturn = append(toReturn, libpod.WithNetNS(portMappings, expose, postConfigureNetNS, val, nil))
 	case specgen.Bridge, specgen.Private, specgen.Default:
 		portMappings, expose, err := createPortMappings(s, imageData)
 		if err != nil {
diff --git a/pkg/specgen/generate/pod_create.go b/pkg/specgen/generate/pod_create.go
index 212d613fe..b50fe3586 100644
--- a/pkg/specgen/generate/pod_create.go
+++ b/pkg/specgen/generate/pod_create.go
@@ -163,6 +163,12 @@ func MapSpec(p *specgen.PodSpecGenerator) (*specgen.SpecGenerator, error) {
 			p.InfraContainerSpec.NetworkOptions = p.NetworkOptions
 			p.InfraContainerSpec.NetNS.NSMode = specgen.Slirp
 		}
+	case specgen.Pasta:
+		logrus.Debugf("Pod will use pasta")
+		if p.InfraContainerSpec.NetNS.NSMode != "host" {
+			p.InfraContainerSpec.NetworkOptions = p.NetworkOptions
+			p.InfraContainerSpec.NetNS.NSMode = 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 03a2049f6..baa113570 100644
--- a/pkg/specgen/namespaces.go
+++ b/pkg/specgen/namespaces.go
@@ -51,6 +51,9 @@ const (
 	// be used.
 	// Only used with the network namespace, invalid otherwise.
 	Slirp NamespaceMode = "slirp4netns"
+	// Pasta indicates that a pasta network stack should be used.
+	// Only used with the network namespace, invalid otherwise.
+	Pasta NamespaceMode = "pasta"
 	// KeepId indicates a user namespace to keep the owner uid inside
 	// of the namespace itself.
 	// Only used with the user namespace, invalid otherwise.
@@ -153,7 +156,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
@@ -196,7 +199,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 namespace")
 	default:
 		return fmt.Errorf("invalid namespace type %s specified", n.NSMode)
@@ -340,6 +343,13 @@ func ParseNetworkFlag(networks []string) (Namespace, map[string]types.PerNetwork
 			networkOptions[parts[0]] = strings.Split(parts[1], ",")
 		}
 		toReturn.NSMode = Slirp
+	case ns == string(Pasta), strings.HasPrefix(ns, string(Pasta) + ":"):
+		parts := strings.SplitN(ns, ":", 2)
+		if len(parts) > 1 {
+			networkOptions = make(map[string][]string)
+			networkOptions[parts[0]] = strings.Split(parts[1], ",")
+		}
+		toReturn.NSMode = Pasta
 	case ns == string(FromPod):
 		toReturn.NSMode = FromPod
 	case ns == "" || ns == string(Default) || ns == string(Private):
@@ -410,7 +420,7 @@ func ParseNetworkFlag(networks []string) (Namespace, map[string]types.PerNetwork
 			if parts[0] == "" {
 				return toReturn, nil, nil, fmt.Errorf("network name cannot be empty: %w", define.ErrInvalidArg)
 			}
-			if cutil.StringInSlice(parts[0], []string{string(Bridge), string(Slirp), string(FromPod), string(NoNetwork),
+			if cutil.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, fmt.Errorf("can only set extra network names, selected mode %s conflicts with bridge: %w", parts[0], define.ErrInvalidArg)
 			}
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.
-- 
2.35.1


debug log:

solving cb1bab9 ...
found cb1bab9 in https://passt.top/passt

Code repositories for project(s) associated with this public inbox

	https://passt.top/passt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for IMAP folder(s).