podman/libpod/networking_pasta_linux.go

108 lines
2.4 KiB
Go

// SPDX-License-Identifier: Apache-2.0
//
// networking_pasta_linux.go - Start pasta(1) for user-mode connectivity
//
// Copyright (c) 2022 Red Hat GmbH
// Author: Stefano Brivio <sbrivio@redhat.com>
package libpod
import (
"fmt"
"os/exec"
"strings"
"github.com/sirupsen/logrus"
)
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")
case "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
}