From 2fafeba22fc07ea7f953a709100c7fb86287bd0b Mon Sep 17 00:00:00 2001 From: Stefano Brivio Date: Fri, 16 Aug 2024 09:58:51 +0000 Subject: [PATCH] child, pasta: Allow drivers to configure their own interface, let pasta do that As reported in https://github.com/moby/moby/issues/48257, when Docker rootless uses pasta through rootlesskit for user-mode connectivity, IPv6 can't be used for outbound connections because no addresses and no routes are configured in the container. The reason is that rootlesskit won't configure IPv6 addresses on the interface, and at the same time it doesn't ask pasta to do so using the --config-net option. Add a ConfigureNet attribute in struct Opt signalling that the driver will configure the address by itself, so there's no reason to call activateDev() from setupNet() in that case, and set it for pasta. In the pasta driver, skip the call to PrepareTap(), because pasta can take care of that as well. At the same time, ask pasta to do all that: set up the tap device, and configure IPv4 and IPv6, using --config-net. While at it, drop options --no-ra and --no-dhcp, as the container might want to send router solicitations and DHCP requests even if we permanently configure IPv4 and IPv6 addresses and routes, and there's no reason to ignore those requests. Drop --stderr as well: it doesn't do anything anymore, and it has been obsoleted in pasta for a while (it will always print to stderr when starting in foreground anyway). Link: https://github.com/moby/moby/issues/48257 Signed-off-by: Stefano Brivio --- cmd/rootlesskit/main.go | 2 ++ pkg/child/child.go | 16 +++++++++++----- pkg/network/pasta/pasta.go | 7 +------ 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/cmd/rootlesskit/main.go b/cmd/rootlesskit/main.go index be7d7f29..ba9dde00 100644 --- a/cmd/rootlesskit/main.go +++ b/cmd/rootlesskit/main.go @@ -604,6 +604,7 @@ func createChildOpt(clicontext *cli.Context) (child.Opt, error) { DetachNetNS: detachNetNS, Propagation: clicontext.String("propagation"), EvacuateCgroup2: clicontext.String("evacuate-cgroup2") != "", + ConfigureNet: false, } switch reaperStr := clicontext.String("reaper"); reaperStr { case "auto": @@ -625,6 +626,7 @@ func createChildOpt(clicontext *cli.Context) (child.Opt, error) { // NOP case "pasta": opt.NetworkDriver = pasta.NewChildDriver() + opt.ConfigureNet = true case "slirp4netns": opt.NetworkDriver = slirp4netns.NewChildDriver() case "vpnkit": diff --git a/pkg/child/child.go b/pkg/child/child.go index b4d14787..db1e5f38 100644 --- a/pkg/child/child.go +++ b/pkg/child/child.go @@ -187,7 +187,7 @@ func setupCopyDir(driver copyup.ChildDriver, dirs []string) (bool, error) { // setupNet sets up the network driver. // // NOTE: msg is altered during calling driver.ConfigureNetworkChild -func setupNet(stateDir string, msg *messages.ParentInitNetworkDriverCompleted, etcWasCopied bool, driver network.ChildDriver, detachedNetNSPath string) error { +func setupNet(stateDir string, msg *messages.ParentInitNetworkDriverCompleted, etcWasCopied bool, driver network.ChildDriver, driverConfiguresNet bool, detachedNetNSPath string) error { // HostNetwork if driver == nil { return nil @@ -215,8 +215,10 @@ func setupNet(stateDir string, msg *messages.ParentInitNetworkDriverCompleted, e if err := os.WriteFile(stateDirResolvConf, generateResolvConf(msg.DNS), 0644); err != nil { return fmt.Errorf("writing %s: %w", stateDirResolvConf, err) } - if err := activateDev(dev, msg.IP, msg.Netmask, msg.Gateway, msg.MTU); err != nil { - return err + if !driverConfiguresNet { + if err := activateDev(dev, msg.IP, msg.Netmask, msg.Gateway, msg.MTU); err != nil { + return err + } } if etcWasCopied { // remove copied-up link @@ -255,7 +257,10 @@ func setupNet(stateDir string, msg *messages.ParentInitNetworkDriverCompleted, e return fmt.Errorf("writing %s: %w", stateDirResolvConf, err) } if err := ns.WithNetNSPath(detachedNetNSPath, func(_ ns.NetNS) error { - return activateDev(dev, msg.IP, msg.Netmask, msg.Gateway, msg.MTU) + if !driverConfiguresNet { + return activateDev(dev, msg.IP, msg.Netmask, msg.Gateway, msg.MTU) + } + return nil }); err != nil { return err } @@ -278,6 +283,7 @@ type Opt struct { Propagation string // mount propagation type Reaper bool EvacuateCgroup2 bool // needs to correspond to parent.Opt.EvacuateCgroup2 is set + ConfigureNet bool // driver configures network interface by itself } // statPIDNS is from https://github.com/containerd/containerd/blob/v1.7.2/services/introspection/pidns_linux.go#L25-L36 @@ -458,7 +464,7 @@ func Child(opt Opt) error { return err } } - if err := setupNet(stateDir, netMsg, etcWasCopied, opt.NetworkDriver, detachedNetNSPath); err != nil { + if err := setupNet(stateDir, netMsg, etcWasCopied, opt.NetworkDriver, opt.ConfigureNet, detachedNetNSPath); err != nil { return err } portQuitCh := make(chan struct{}) diff --git a/pkg/network/pasta/pasta.go b/pkg/network/pasta/pasta.go index 6a2520fa..b9b9a2a6 100644 --- a/pkg/network/pasta/pasta.go +++ b/pkg/network/pasta/pasta.go @@ -17,7 +17,6 @@ import ( "github.com/rootless-containers/rootlesskit/v2/pkg/messages" "github.com/rootless-containers/rootlesskit/v2/pkg/network" "github.com/rootless-containers/rootlesskit/v2/pkg/network/iputils" - "github.com/rootless-containers/rootlesskit/v2/pkg/network/parentutils" ) // NewParentDriver instantiates new parent driver. @@ -92,9 +91,6 @@ func (d *parentDriver) MTU() int { func (d *parentDriver) ConfigureNetwork(childPID int, stateDir, detachedNetNSPath string) (*messages.ParentInitNetworkDriverCompleted, func() error, error) { tap := d.ifname var cleanups []func() error - if err := parentutils.PrepareTap(childPID, detachedNetNSPath, tap); err != nil { - return nil, common.Seq(cleanups), fmt.Errorf("setting up tap %s: %w", tap, err) - } address, err := iputils.AddIPInt(d.ipnet.IP, 100) if err != nil { @@ -114,8 +110,7 @@ func (d *parentDriver) ConfigureNetwork(childPID int, stateDir, detachedNetNSPat "--stderr", "--ns-ifname=" + d.ifname, "--mtu=" + strconv.Itoa(d.mtu), - "--no-dhcp", - "--no-ra", + "--config-net", "--address=" + address.String(), "--netmask=" + strconv.Itoa(netmask), "--gateway=" + gateway.String(),