Skip to content

Commit

Permalink
child, pasta: Allow drivers to configure their own interface, let pas…
Browse files Browse the repository at this point in the history
…ta do that

As reported in moby/moby#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 ChildDriverInfo() method to childDriver, returning a single
piece of information, that is, whether the driver configures the
network interface by itself, which is true only for pasta. If that's
the case, there's no reason to call activateDev() from setupNet().

Further, 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: moby/moby#48257
Signed-off-by: Stefano Brivio <[email protected]>
  • Loading branch information
sbrivio-rh committed Aug 16, 2024
1 parent ade4c86 commit 2c78671
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 9 deletions.
5 changes: 5 additions & 0 deletions pkg/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ type Info struct {
ChildPID int `json:"childPID"`
NetworkDriver *NetworkDriverInfo `json:"networkDriver,omitempty"`
PortDriver *PortDriverInfo `json:"portDriver,omitempty"`
ChildDriver *ChildDriverInfo `json:"childDriver,omitempty"`
}

// NetworkDriverInfo in Info
Expand All @@ -32,3 +33,7 @@ type PortDriverInfo struct {
Protos []string `json:"protos"`
DisallowLoopbackChildIP bool `json:"disallowLoopbackChildIP,omitempty"` // since API v1.1.1
}

type ChildDriverInfo struct {
ConfiguresInterface bool `json:"configuresInterface"`
}
13 changes: 10 additions & 3 deletions pkg/child/child.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,11 @@ 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
Info, _ := driver.ChildDriverInfo()
if !Info.ConfiguresInterface {
if err := activateDev(dev, msg.IP, msg.Netmask, msg.Gateway, msg.MTU); err != nil {
return err
}
}
if etcWasCopied {
// remove copied-up link
Expand Down Expand Up @@ -255,7 +258,11 @@ 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)
Info, _ := driver.ChildDriverInfo()
if !Info.ConfiguresInterface {
return activateDev(dev, msg.IP, msg.Netmask, msg.Gateway, msg.MTU)
}
return nil
}); err != nil {
return err
}
Expand Down
6 changes: 6 additions & 0 deletions pkg/network/lxcusernic/lxcusernic.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,12 @@ func exchangeDHCP(c *client4.Client, dev string, detachedNetNSPath string) (*dhc
return ack, nil
}

func (d *childDriver) ChildDriverInfo() (*api.ChildDriverInfo, error) {
return &api.ChildDriverInfo {
ConfiguresInterface: false,
}, nil
}

func (d *childDriver) ConfigureNetworkChild(netmsg *messages.ParentInitNetworkDriverCompleted, detachedNetNSPath string) (string, error) {
dev := netmsg.Dev
if dev == "" {
Expand Down
2 changes: 2 additions & 0 deletions pkg/network/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,6 @@ type ChildDriver interface {
// netmsg MAY be modified.
// devName is like "tap" or "eth0"
ConfigureNetworkChild(netmsg *messages.ParentInitNetworkDriverCompleted, detachedNetNSPath string) (devName string, err error)

ChildDriverInfo() (*api.ChildDriverInfo, error)
}
14 changes: 8 additions & 6 deletions pkg/network/pasta/pasta.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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 {
Expand All @@ -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(),
Expand Down Expand Up @@ -185,6 +180,13 @@ func NewChildDriver() network.ChildDriver {
}

type childDriver struct {
info func() *api.ChildDriverInfo
}

func (d *childDriver) ChildDriverInfo() (*api.ChildDriverInfo, error) {
return &api.ChildDriverInfo {
ConfiguresInterface: true,
}, nil
}

func (d *childDriver) ConfigureNetworkChild(netmsg *messages.ParentInitNetworkDriverCompleted, detachedNetNSPath string) (string, error) {
Expand Down
6 changes: 6 additions & 0 deletions pkg/network/slirp4netns/slirp4netns.go
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,12 @@ func NewChildDriver() network.ChildDriver {
type childDriver struct {
}

func (d *childDriver) ChildDriverInfo() (*api.ChildDriverInfo, error) {
return &api.ChildDriverInfo {
ConfiguresInterface: false,
}, nil
}

func (d *childDriver) ConfigureNetworkChild(netmsg *messages.ParentInitNetworkDriverCompleted, detachedNetNSPath string) (string, error) {
tap := netmsg.Dev
if tap == "" {
Expand Down
6 changes: 6 additions & 0 deletions pkg/network/vpnkit/vpnkit.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,12 @@ func NewChildDriver() network.ChildDriver {
type childDriver struct {
}

func (d *childDriver) ChildDriverInfo() (*api.ChildDriverInfo, error) {
return &api.ChildDriverInfo {
ConfiguresInterface: false,
}, nil
}

func (d *childDriver) ConfigureNetworkChild(netmsg *messages.ParentInitNetworkDriverCompleted, detachedNetNSPath string) (tap string, err error) {
tapName := netmsg.Dev
if tapName == "" {
Expand Down

0 comments on commit 2c78671

Please sign in to comment.