From 5ffbfd937d31d307eb10edf03ae0090edec76d4b Mon Sep 17 00:00:00 2001 From: Paul Holzinger Date: Thu, 15 Jun 2023 15:03:25 +0200 Subject: [PATCH] pasta: use code from c/common The code was moved to c/common so use that instead. Also add tests for the new pasta_options config field. However there is one outstanding problem[1]: pasta rejects most options when set more than once. Thus it is impossible to overwrite most of them on the cli. If we cannot fix this in pasta I need to make further changes in c/common to dedup the options. [1] https://archives.passt.top/passt-dev/895dae7d-3e61-4ef7-829a-87966ab0bb3a@redhat.com/ Signed-off-by: Paul Holzinger --- libpod/info_linux.go | 3 +- libpod/networking_pasta_linux.go | 106 +------------ test/system/505-networking-pasta.bats | 18 +++ .../common/libnetwork/pasta/pasta.go | 140 ++++++++++++++++++ vendor/modules.txt | 1 + 5 files changed, 168 insertions(+), 100 deletions(-) create mode 100644 vendor/github.com/containers/common/libnetwork/pasta/pasta.go diff --git a/libpod/info_linux.go b/libpod/info_linux.go index 25104fc43e..37a16b0d94 100644 --- a/libpod/info_linux.go +++ b/libpod/info_linux.go @@ -8,6 +8,7 @@ import ( "strconv" "strings" + "github.com/containers/common/libnetwork/pasta" "github.com/containers/common/pkg/apparmor" "github.com/containers/common/pkg/cgroups" "github.com/containers/common/pkg/seccomp" @@ -72,7 +73,7 @@ func (r *Runtime) setPlatformHostInfo(info *define.HostInfo) error { info.Slirp4NetNS = program } - pastaPath, _ := r.config.FindHelperBinary(pastaBinaryName, true) + pastaPath, _ := r.config.FindHelperBinary(pasta.BinaryName, true) if pastaPath != "" { version, err := util.ProgramVersion(pastaPath) if err != nil { diff --git a/libpod/networking_pasta_linux.go b/libpod/networking_pasta_linux.go index dcc924454f..288335ce94 100644 --- a/libpod/networking_pasta_linux.go +++ b/libpod/networking_pasta_linux.go @@ -7,105 +7,13 @@ package libpod -import ( - "fmt" - "os/exec" - "strings" - - "github.com/sirupsen/logrus" -) - -const ( - pastaBinaryName = "passt" -) +import "github.com/containers/common/libnetwork/pasta" func (r *Runtime) setupPasta(ctr *Container, netns string) error { - var NoTCPInitPorts = true - var NoUDPInitPorts = true - var NoTCPNamespacePorts = true - var NoUDPNamespacePorts = true - var NoMapGW = true - - path, err := r.config.FindHelperBinary("pasta", true) - 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) - } - - switch protocol { - case "tcp": - cmdArgs = append(cmdArgs, "-t") - case "udp": - cmdArgs = append(cmdArgs, "-u") - default: - 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, opt := range cmdArgs { - switch opt { - case "-t", "--tcp-ports": - NoTCPInitPorts = false - case "-u", "--udp-ports": - NoUDPInitPorts = false - case "-T", "--tcp-ns": - NoTCPNamespacePorts = false - case "-U", "--udp-ns": - NoUDPNamespacePorts = false - case "--map-gw": - NoMapGW = false - // not an actual pasta(1) option - cmdArgs = append(cmdArgs[:i], cmdArgs[i+1:]...) - } - } - - 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") - } - if NoMapGW { - cmdArgs = append(cmdArgs, "--no-map-gw") - } - - cmdArgs = append(cmdArgs, "--netns", netns) - - 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 fmt.Errorf("failed to start pasta:\n%s", - err.(*exec.ExitError).Stderr) - } - - return nil + return pasta.Setup(&pasta.SetupOptions{ + Config: r.config, + Netns: netns, + Ports: ctr.convertPortMappings(), + ExtraOptions: ctr.config.NetworkOptions[pasta.BinaryName], + }) } diff --git a/test/system/505-networking-pasta.bats b/test/system/505-networking-pasta.bats index a5cdcd8444..d5b1890641 100644 --- a/test/system/505-networking-pasta.bats +++ b/test/system/505-networking-pasta.bats @@ -689,3 +689,21 @@ function teardown() { run_podman 126 run --net=pasta -p "${port}:${port}/sctp" $IMAGE true is "$output" "Error: .*can't forward protocol: sctp" } + +@test "podman networking with pasta(1) - Use options from containers.conf" { + skip_if_remote "containers.conf must be set for the server" + + containersconf=$PODMAN_TMPDIR/containers.conf + mac="9a:dd:31:ea:92:98" + cat >$containersconf < + +// This file has been imported from the podman repository +// (libpod/networking_pasta_linux.go), for the full history see there. + +package pasta + +import ( + "errors" + "fmt" + "os/exec" + "strings" + + "github.com/containers/common/libnetwork/types" + "github.com/containers/common/pkg/config" + "github.com/sirupsen/logrus" +) + +const ( + BinaryName = "pasta" +) + +type SetupOptions struct { + // Config used to get pasta options and binary path via HelperBinariesDir + Config *config.Config + // Netns is the path to the container Netns + Netns string + // Ports that should be forwarded in the container + Ports []types.PortMapping + // ExtraOptions are pasta(1) cli options, these will be appended after the + // pasta options from containers.conf to allow some form of overwrite. + ExtraOptions []string +} + +// Setup start the pasta process for the given netns. +// The pasta binary is looked up in the HelperBinariesDir and $PATH. +// Note that there is no need any special cleanup logic, the pasta process will +// automatically exit when the netns path is deleted. +func Setup(opts *SetupOptions) error { + NoTCPInitPorts := true + NoUDPInitPorts := true + NoTCPNamespacePorts := true + NoUDPNamespacePorts := true + NoMapGW := true + + path, err := opts.Config.FindHelperBinary(BinaryName, true) + 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 opts.Ports { + protocols := strings.Split(i.Protocol, ",") + for _, protocol := range protocols { + var addr string + + if i.HostIP != "" { + addr = fmt.Sprintf("%s/", i.HostIP) + } + + switch protocol { + case "tcp": + cmdArgs = append(cmdArgs, "-t") + case "udp": + cmdArgs = append(cmdArgs, "-u") + default: + 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) + } + } + + // first append options set in the config + cmdArgs = append(cmdArgs, opts.Config.Network.PastaOptions...) + // then append the ones that were set on the cli + cmdArgs = append(cmdArgs, opts.ExtraOptions...) + + for i, opt := range cmdArgs { + switch opt { + case "-t", "--tcp-ports": + NoTCPInitPorts = false + case "-u", "--udp-ports": + NoUDPInitPorts = false + case "-T", "--tcp-ns": + NoTCPNamespacePorts = false + case "-U", "--udp-ns": + NoUDPNamespacePorts = false + case "--map-gw": + NoMapGW = false + // not an actual pasta(1) option + cmdArgs = append(cmdArgs[:i], cmdArgs[i+1:]...) + } + } + + 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") + } + if NoMapGW { + cmdArgs = append(cmdArgs, "--no-map-gw") + } + + cmdArgs = append(cmdArgs, "--netns", opts.Netns) + + 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 { + exitErr := &exec.ExitError{} + if errors.As(err, &exitErr) { + return fmt.Errorf("pasta failed with exit code %d:\n%s", + exitErr.ExitCode(), exitErr.Stderr) + } + return fmt.Errorf("failed to start pasta: %w", err) + } + + return nil +} diff --git a/vendor/modules.txt b/vendor/modules.txt index e9b86a6f81..a64e2e8cef 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -135,6 +135,7 @@ github.com/containers/common/libnetwork/etchosts github.com/containers/common/libnetwork/internal/util github.com/containers/common/libnetwork/netavark github.com/containers/common/libnetwork/network +github.com/containers/common/libnetwork/pasta github.com/containers/common/libnetwork/resolvconf github.com/containers/common/libnetwork/types github.com/containers/common/libnetwork/util