Skip to content

Commit

Permalink
slirp: fix setup on ipv6 disabled systems
Browse files Browse the repository at this point in the history
When enable_ipv6=true is set for slirp4netns (default since podman v4),
we will try to set the accept sysctl. This sysctl will not exist on
systems that have ipv6 disabled. In this case we should not error and
just ignore the extra ipv6 setup.

Also the current logic to wait for the slirp4 setup was kinda broken, it
did not actually wait until the sysctl was set before starting slirp.
This should now be fixed by using two `sync.WaitGroup`s.

[NO NEW TESTS NEEDED]

Fixes containers#13388

Signed-off-by: Paul Holzinger <[email protected]>
  • Loading branch information
Luap99 authored and mheon committed Mar 30, 2022
1 parent 4a0d744 commit e424c64
Showing 1 changed file with 30 additions and 10 deletions.
40 changes: 30 additions & 10 deletions libpod/networking_slirp4netns.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"path/filepath"
"strconv"
"strings"
"sync"
"syscall"
"time"

Expand Down Expand Up @@ -302,11 +303,15 @@ func (r *Runtime) setupSlirp4netns(ctr *Container, netns ns.NetNS) error {
cmd.Stdout = logFile
cmd.Stderr = logFile

var slirpReadyChan (chan struct{})

var slirpReadyWg, netnsReadyWg *sync.WaitGroup
if netOptions.enableIPv6 {
slirpReadyChan = make(chan struct{})
defer close(slirpReadyChan)
// use two wait groups to make sure we set the sysctl before
// starting slirp and reset it only after slirp is ready
slirpReadyWg = &sync.WaitGroup{}
netnsReadyWg = &sync.WaitGroup{}
slirpReadyWg.Add(1)
netnsReadyWg.Add(1)

go func() {
err := ns.WithNetNSPath(netnsPath, func(_ ns.NetNS) error {
// Duplicate Address Detection slows the ipv6 setup down for 1-2 seconds.
Expand All @@ -318,23 +323,37 @@ func (r *Runtime) setupSlirp4netns(ctr *Container, netns ns.NetNS) error {
// is ready in case users rely on this sysctl.
orgValue, err := ioutil.ReadFile(ipv6ConfDefaultAcceptDadSysctl)
if err != nil {
netnsReadyWg.Done()
// on ipv6 disabled systems the sysctl does not exists
// so we should not error
if errors.Is(err, os.ErrNotExist) {
return nil
}
return err
}
err = ioutil.WriteFile(ipv6ConfDefaultAcceptDadSysctl, []byte("0"), 0644)
netnsReadyWg.Done()
if err != nil {
return err
}
// wait for slirp to finish setup
<-slirpReadyChan

// wait until slirp4nets is ready before reseting this value
slirpReadyWg.Wait()
return ioutil.WriteFile(ipv6ConfDefaultAcceptDadSysctl, orgValue, 0644)
})
if err != nil {
logrus.Warnf("failed to set net.ipv6.conf.default.accept_dad sysctl: %v", err)
}
}()

// wait until we set the sysctl
netnsReadyWg.Wait()
}

if err := cmd.Start(); err != nil {
if netOptions.enableIPv6 {
slirpReadyWg.Done()
}
return errors.Wrapf(err, "failed to start slirp4netns process")
}
defer func() {
Expand All @@ -344,11 +363,12 @@ func (r *Runtime) setupSlirp4netns(ctr *Container, netns ns.NetNS) error {
}
}()

if err := waitForSync(syncR, cmd, logFile, 1*time.Second); err != nil {
return err
err = waitForSync(syncR, cmd, logFile, 1*time.Second)
if netOptions.enableIPv6 {
slirpReadyWg.Done()
}
if slirpReadyChan != nil {
slirpReadyChan <- struct{}{}
if err != nil {
return err
}

// Set a default slirp subnet. Parsing a string with the net helper is easier than building the struct myself
Expand Down

0 comments on commit e424c64

Please sign in to comment.