Files
podman/libpod/networking_pesto_linux.go
Jan Rodák e598657244 Add pasta-based port forwarding for rootless bridge networks
Add rootless_port_forwarder="pasta" option that uses pesto to update
pasta's forwarding table via UNIX socket, preserving source IPs that
rootlessport's userspace proxy masks.

HostIP is stripped from port mappings in the netavark wrapper when
pasta forwarding is active because pesto handles host-side binding
while pasta's splice changes the destination IP that netavark DNAT
expects. Pesto binds both 0.0.0.0 and [::] for dual-stack support.

Fixes: https://redhat.atlassian.net/browse/RUN-2214
Fixes: https://github.com/containers/podman/issues/8193
Fixes: https://redhat.atlassian.net/browse/RUN-3587

Signed-off-by: Jan Rodák <hony.com@seznam.cz>
2026-05-20 14:24:47 +02:00

53 lines
1.6 KiB
Go

//go:build !remote
// Pesto integration for rootless bridge network port forwarding.
//
// A shared pasta instance in the rootless netns (-c pasta.sock) handles
// host-side port forwarding. On container start/stop, pesto incrementally
// adds or deletes port forwarding rules for that container. Pasta forwards
// via kernel splice (localhost) or TAP (external), preserving source IPs.
// The container sees the real client's address instead of a proxy or bridge
// gateway address.
//
// Container start:
// - netavark sets up bridge + DNAT
// - pesto --add: adds this container's ports to pasta
//
// Container stop:
// - pesto --delete: removes this container's ports from pasta
// - netavark tears down bridge/DNAT
package libpod
import (
"go.podman.io/common/libnetwork/pasta"
)
func (r *Runtime) pestoSocketPath() string {
info, err := r.network.RootlessNetnsInfo()
if err != nil || info == nil {
return ""
}
return info.PestoSocketPath
}
// setupRootlessPortMappingViaPesto adds this container's port forwarding
// rules to the shared pasta instance.
func (r *Runtime) setupRootlessPortMappingViaPesto(ctr *Container) error {
ports := ctr.convertPortMappings()
if len(ports) == 0 {
return nil
}
return pasta.PestoAddPorts(r.config, r.pestoSocketPath(), ports)
}
// teardownRootlessPortMappingViaPesto removes this container's port
// forwarding rules from the shared pasta instance.
func (r *Runtime) teardownRootlessPortMappingViaPesto(ctr *Container) error {
ports := ctr.convertPortMappings()
if len(ports) == 0 {
return nil
}
return pasta.PestoDeletePorts(r.config, r.pestoSocketPath(), ports)
}