diff --git a/pkg/child/child.go b/pkg/child/child.go index 41f880a4..a161c056 100644 --- a/pkg/child/child.go +++ b/pkg/child/child.go @@ -152,12 +152,18 @@ func activateLoopback() error { return nil } -func activateDev(dev, ip string, netmask int, gateway string, mtu int) error { +func activateDev(dev string, ips []messages.NetworkDriverIP, gateway []string, mtu int) error { cmds := [][]string{ {"ip", "link", "set", dev, "up"}, {"ip", "link", "set", "dev", dev, "mtu", strconv.Itoa(mtu)}, - {"ip", "addr", "add", ip + "/" + strconv.Itoa(netmask), "dev", dev}, - {"ip", "route", "add", "default", "via", gateway, "dev", dev}, + } + + for _, ip := range ips { + cmds = append(cmds, []string{"ip", "addr", "add", ip.IP + "/" + strconv.Itoa(ip.PrefixLen), "dev", dev}) + } + + for _, gw := range gateway { + cmds = append(cmds, []string{"ip", "route", "add", "default", "via", gw, "dev", dev}) } if err := common.Execs(os.Stderr, os.Environ(), cmds); err != nil { return fmt.Errorf("executing %v: %w", cmds, err) @@ -216,7 +222,7 @@ func setupNet(stateDir string, msg *messages.ParentInitNetworkDriverCompleted, e } Info, _ := driver.ChildDriverInfo() if !Info.ConfiguresInterface { - if err := activateDev(dev, msg.IP, msg.Netmask, msg.Gateway, msg.MTU); err != nil { + if err := activateDev(dev, msg.IPs, msg.Gateways, msg.MTU); err != nil { return err } } @@ -259,7 +265,7 @@ func setupNet(stateDir string, msg *messages.ParentInitNetworkDriverCompleted, e if err := ns.WithNetNSPath(detachedNetNSPath, func(_ ns.NetNS) error { Info, _ := driver.ChildDriverInfo() if !Info.ConfiguresInterface { - return activateDev(dev, msg.IP, msg.Netmask, msg.Gateway, msg.MTU) + return activateDev(dev, msg.IPs, msg.Gateways, msg.MTU) } return nil }); err != nil { diff --git a/pkg/messages/messages.go b/pkg/messages/messages.go index 83466be6..be7641d4 100644 --- a/pkg/messages/messages.go +++ b/pkg/messages/messages.go @@ -53,14 +53,18 @@ type ParentInitIdmapCompleted struct { type ChildInitUserNSCompleted struct { } +type NetworkDriverIP struct { + IP string + PrefixLen int +} + type ParentInitNetworkDriverCompleted struct { // Fields are empty for HostNetwork. - Dev string - IP string - Netmask int - Gateway string - DNS []string - MTU int + Dev string + IPs []NetworkDriverIP + Gateways []string + DNS []string + MTU int // NetworkDriverOpaque strings are specific to driver NetworkDriverOpaque map[string]string } diff --git a/pkg/network/lxcusernic/lxcusernic.go b/pkg/network/lxcusernic/lxcusernic.go index bf9746af..6c1262e9 100644 --- a/pkg/network/lxcusernic/lxcusernic.go +++ b/pkg/network/lxcusernic/lxcusernic.go @@ -186,10 +186,10 @@ func (d *childDriver) ConfigureNetworkChild(netmsg *messages.ParentInitNetworkDr if len(p.DNS()) == 0 { return "", errors.New("got no DNS") } - netmsg.IP = p.YourIPAddr.To4().String() + netmask, _ := p.SubnetMask().Size() - netmsg.Netmask = netmask - netmsg.Gateway = p.Router()[0].To4().String() + netmsg.IPs = []messages.NetworkDriverIP{messages.NetworkDriverIP{IP: p.YourIPAddr.To4().String(), PrefixLen: netmask}} + netmsg.Gateways = []string{p.Router()[0].To4().String()} netmsg.DNS = []string{p.DNS()[0].To4().String()} go dhcpRenewRoutine(c, dev, p.YourIPAddr.To4(), p.IPAddressLeaseTime(time.Hour), detachedNetNSPath) return dev, nil diff --git a/pkg/network/parentutils/parentutils.go b/pkg/network/parentutils/parentutils.go index 34ab6ecb..622603df 100644 --- a/pkg/network/parentutils/parentutils.go +++ b/pkg/network/parentutils/parentutils.go @@ -6,9 +6,11 @@ import ( "strconv" "github.com/rootless-containers/rootlesskit/v2/pkg/common" + "github.com/sirupsen/logrus" ) func PrepareTap(childPID int, childNetNsPath string, tap string) error { + logrus.Debugf("PrepareTap") cmds := [][]string{ nsenter(childPID, childNetNsPath, []string{"ip", "tuntap", "add", "name", tap, "mode", "tap"}), nsenter(childPID, childNetNsPath, []string{"ip", "link", "set", tap, "up"}), diff --git a/pkg/network/pasta/pasta.go b/pkg/network/pasta/pasta.go index 69cf06c3..f0cabb6c 100644 --- a/pkg/network/pasta/pasta.go +++ b/pkg/network/pasta/pasta.go @@ -208,9 +208,13 @@ func (d *parentDriver) ConfigureNetwork(childPID int, stateDir, detachedNetNSPat Dev: tap, MTU: d.mtu, } - netmsg.IP = address.String() - netmsg.Netmask = netmask - netmsg.Gateway = gateway.String() + netmsg.IPs = []messages.NetworkDriverIP{ + messages.NetworkDriverIP{ + IP: address.String(), + PrefixLen: netmask, + }, + } + netmsg.Gateways = []string{gateway.String()} netmsg.DNS = []string{dns.String()} d.infoMu.Lock() @@ -218,7 +222,7 @@ func (d *parentDriver) ConfigureNetwork(childPID int, stateDir, detachedNetNSPat return &api.NetworkDriverInfo{ Driver: DriverName, DNS: []net.IP{net.ParseIP(netmsg.DNS[0])}, - ChildIP: net.ParseIP(netmsg.IP), + ChildIP: net.ParseIP(netmsg.IPs[0].IP), DynamicChildIP: false, } } diff --git a/pkg/network/slirp4netns/slirp4netns.go b/pkg/network/slirp4netns/slirp4netns.go index c4cdd3b4..1153a961 100644 --- a/pkg/network/slirp4netns/slirp4netns.go +++ b/pkg/network/slirp4netns/slirp4netns.go @@ -217,6 +217,8 @@ func (d *parentDriver) ConfigureNetwork(childPID int, stateDir, detachedNetNSPat detachedNetNSPath) } opts = append(opts, tap) + + logrus.Debugf("start %v with args: %v", d.binary, opts) cmd := exec.Command(d.binary, opts...) // FIXME: Stdout doen't seem captured cmd.Stdout = d.logWriter @@ -242,9 +244,11 @@ func (d *parentDriver) ConfigureNetwork(childPID int, stateDir, detachedNetNSPat return nil, common.Seq(cleanups), fmt.Errorf("waiting for ready fd (%v): %w", cmd, err) } netmsg := messages.ParentInitNetworkDriverCompleted{ - Dev: tap, - DNS: make([]string, 0, 2), - MTU: d.mtu, + Dev: tap, + IPs: make([]messages.NetworkDriverIP, 0, 2), + DNS: make([]string, 0, 2), + Gateways: make([]string, 0, 2), + MTU: d.mtu, } if d.ipnet != nil { // TODO: get the actual configuration via slirp4netns API? @@ -252,22 +256,23 @@ func (d *parentDriver) ConfigureNetwork(childPID int, stateDir, detachedNetNSPat if err != nil { return nil, common.Seq(cleanups), err } - netmsg.IP = x.String() - netmsg.Netmask, _ = d.ipnet.Mask.Size() + + netmask, _ := d.ipnet.Mask.Size() + + netmsg.IPs = append(netmsg.IPs, messages.NetworkDriverIP{IP: x.String(), PrefixLen: netmask}) x, err = iputils.AddIPInt(d.ipnet.IP, 2) if err != nil { return nil, common.Seq(cleanups), err } - netmsg.Gateway = x.String() + netmsg.Gateways = append(netmsg.Gateways, x.String()) x, err = iputils.AddIPInt(d.ipnet.IP, 3) if err != nil { return nil, common.Seq(cleanups), err } netmsg.DNS = append(netmsg.DNS, x.String()) } else { - netmsg.IP = "10.0.2.100" - netmsg.Netmask = 24 - netmsg.Gateway = "10.0.2.2" + netmsg.IPs = append(netmsg.IPs, messages.NetworkDriverIP{IP: "10.0.2.100", PrefixLen: 24}) + netmsg.Gateways = append(netmsg.Gateways, "10.0.2.2") netmsg.DNS = append(netmsg.DNS, "10.0.2.3") } @@ -275,6 +280,11 @@ func (d *parentDriver) ConfigureNetwork(childPID int, stateDir, detachedNetNSPat // for now slirp4netns only supports fd00::3 as v6 nameserver // https://github.com/rootless-containers/slirp4netns/blob/ee1542e1532e6a7f266b8b6118973ab3b10a8bb5/slirp4netns.c#L272 netmsg.DNS = append(netmsg.DNS, "fd00::3") + + // TODO(aperevalov --cidr option of slirp4netns now supports only ipv4 address + // add ipv6 gateway + netmsg.Gateways = append(netmsg.Gateways, "fd00::2") + netmsg.IPs = append(netmsg.IPs, messages.NetworkDriverIP{IP: "fd00::1", PrefixLen: 64}) } apiDNS := make([]net.IP, 0, cap(netmsg.DNS)) @@ -287,7 +297,7 @@ func (d *parentDriver) ConfigureNetwork(childPID int, stateDir, detachedNetNSPat return &api.NetworkDriverInfo{ Driver: DriverName, DNS: apiDNS, - ChildIP: net.ParseIP(netmsg.IP), + ChildIP: net.ParseIP(netmsg.IPs[0].IP), DynamicChildIP: false, } } diff --git a/pkg/network/vpnkit/vpnkit.go b/pkg/network/vpnkit/vpnkit.go index 6a2b3a64..45ba1dee 100644 --- a/pkg/network/vpnkit/vpnkit.go +++ b/pkg/network/vpnkit/vpnkit.go @@ -123,12 +123,13 @@ func (d *parentDriver) ConfigureNetwork(childPID int, stateDir, detachedNetNSPat logrus.Debugf("connected to VPNKit vmnet") // TODO: support configuration netmsg := messages.ParentInitNetworkDriverCompleted{ - Dev: d.ifname, - IP: vif.IP.String(), - Netmask: 24, - Gateway: "192.168.65.1", - DNS: []string{"192.168.65.1"}, - MTU: d.mtu, + Dev: d.ifname, + IPs: []messages.NetworkDriverIP{ + messages.NetworkDriverIP{IP: vif.IP.String(), PrefixLen: 24}, + }, + Gateways: []string{"192.168.65.1"}, + DNS: []string{"192.168.65.1"}, + MTU: d.mtu, NetworkDriverOpaque: map[string]string{ opaqueMAC: vif.ClientMAC.String(), opaqueSocket: vpnkitSocket, @@ -140,7 +141,7 @@ func (d *parentDriver) ConfigureNetwork(childPID int, stateDir, detachedNetNSPat return &api.NetworkDriverInfo{ Driver: DriverName, DNS: []net.IP{net.ParseIP(netmsg.DNS[0])}, - ChildIP: net.ParseIP(netmsg.IP), + ChildIP: net.ParseIP(netmsg.IPs[0].IP), DynamicChildIP: false, } } diff --git a/pkg/parent/parent.go b/pkg/parent/parent.go index 733d603e..d93bdefd 100644 --- a/pkg/parent/parent.go +++ b/pkg/parent/parent.go @@ -289,7 +289,7 @@ func Parent(opt Opt) error { if opt.PortDriver != nil { msgParentInitPortDriverCompleted.U.ParentInitPortDriverCompleted.PortDriverOpaque = opt.PortDriver.OpaqueForChild() cctx := &port.ChildContext{ - IP: net.ParseIP(msgParentInitNetworkDriverCompleted.U.ParentInitNetworkDriverCompleted.IP).To4(), + IP: net.ParseIP(msgParentInitNetworkDriverCompleted.U.ParentInitNetworkDriverCompleted.IPs[0].IP).To4(), } go func() { portDriverErr <- opt.PortDriver.RunParentDriver(portDriverInitComplete,