summaryrefslogtreecommitdiff
path: root/libpod/networking_slirp4netns.go
diff options
context:
space:
mode:
Diffstat (limited to 'libpod/networking_slirp4netns.go')
-rw-r--r--libpod/networking_slirp4netns.go53
1 files changed, 48 insertions, 5 deletions
diff --git a/libpod/networking_slirp4netns.go b/libpod/networking_slirp4netns.go
index 46cda89a9..760427f22 100644
--- a/libpod/networking_slirp4netns.go
+++ b/libpod/networking_slirp4netns.go
@@ -16,6 +16,7 @@ import (
"syscall"
"time"
+ "github.com/containernetworking/plugins/pkg/ns"
"github.com/containers/podman/v3/pkg/errorhandling"
"github.com/containers/podman/v3/pkg/rootless"
"github.com/containers/podman/v3/pkg/rootlessport"
@@ -37,9 +38,9 @@ type slirpFeatures struct {
type slirp4netnsCmdArg struct {
Proto string `json:"proto,omitempty"`
HostAddr string `json:"host_addr"`
- HostPort int32 `json:"host_port"`
+ HostPort uint16 `json:"host_port"`
GuestAddr string `json:"guest_addr"`
- GuestPort int32 `json:"guest_port"`
+ GuestPort uint16 `json:"guest_port"`
}
type slirp4netnsCmd struct {
@@ -58,6 +59,8 @@ type slirp4netnsNetworkOptions struct {
outboundAddr6 string
}
+const ipv6ConfDefaultAcceptDadSysctl = "/proc/sys/net/ipv6/conf/default/accept_dad"
+
func checkSlirpFlags(path string) (*slirpFeatures, error) {
cmd := exec.Command(path, "--help")
out, err := cmd.CombinedOutput()
@@ -297,6 +300,39 @@ func (r *Runtime) setupSlirp4netns(ctr *Container) error {
}
cmd.Stdout = logFile
cmd.Stderr = logFile
+
+ var slirpReadyChan (chan struct{})
+
+ if netOptions.enableIPv6 {
+ slirpReadyChan = make(chan struct{})
+ defer close(slirpReadyChan)
+ go func() {
+ err := ns.WithNetNSPath(netnsPath, func(_ ns.NetNS) error {
+ // Duplicate Address Detection slows the ipv6 setup down for 1-2 seconds.
+ // Since slirp4netns is run it is own namespace and not directly routed
+ // we can skip this to make the ipv6 address immediately available.
+ // We change the default to make sure the slirp tap interface gets the
+ // correct value assigned so DAD is disabled for it
+ // Also make sure to change this value back to the original after slirp4netns
+ // is ready in case users rely on this sysctl.
+ orgValue, err := ioutil.ReadFile(ipv6ConfDefaultAcceptDadSysctl)
+ if err != nil {
+ return err
+ }
+ err = ioutil.WriteFile(ipv6ConfDefaultAcceptDadSysctl, []byte("0"), 0644)
+ if err != nil {
+ return err
+ }
+ // wait for slirp to finish setup
+ <-slirpReadyChan
+ return ioutil.WriteFile(ipv6ConfDefaultAcceptDadSysctl, orgValue, 0644)
+ })
+ if err != nil {
+ logrus.Warnf("failed to set net.ipv6.conf.default.accept_dad sysctl: %v", err)
+ }
+ }()
+ }
+
if err := cmd.Start(); err != nil {
return errors.Wrapf(err, "failed to start slirp4netns process")
}
@@ -310,6 +346,9 @@ func (r *Runtime) setupSlirp4netns(ctr *Container) error {
if err := waitForSync(syncR, cmd, logFile, 1*time.Second); err != nil {
return err
}
+ if slirpReadyChan != nil {
+ slirpReadyChan <- struct{}{}
+ }
// Set a default slirp subnet. Parsing a string with the net helper is easier than building the struct myself
_, ctr.slirp4netnsSubnet, _ = net.ParseCIDR(defaultSlirp4netnsSubnet)
@@ -484,10 +523,14 @@ func (r *Runtime) setupRootlessPortMappingViaRLK(ctr *Container, netnsPath strin
}
cfgR := bytes.NewReader(cfgJSON)
var stdout bytes.Buffer
- cmd := exec.Command(fmt.Sprintf("/proc/%d/exe", os.Getpid()))
- cmd.Args = []string{rootlessport.ReexecKey}
- // Leak one end of the pipe in rootlessport process, the other will be sent to conmon
+ path, err := r.config.FindHelperBinary(rootlessport.BinaryName, false)
+ if err != nil {
+ return err
+ }
+ cmd := exec.Command(path)
+ cmd.Args = []string{rootlessport.BinaryName}
+ // Leak one end of the pipe in rootlessport process, the other will be sent to conmon
if ctr.rootlessPortSyncR != nil {
defer errorhandling.CloseQuiet(ctr.rootlessPortSyncR)
}