From 5ec6265a7083c8bcacebfe0bfb866beb22018783 Mon Sep 17 00:00:00 2001 From: Arceliar Date: Sat, 3 Mar 2018 16:41:36 -0600 Subject: [PATCH] use netlink instead of ip commands to set address/mtu and bring up the tuntap device on linux --- src/yggdrasil/tun_linux.go | 45 +++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/src/yggdrasil/tun_linux.go b/src/yggdrasil/tun_linux.go index 09206a5f..1d4380ac 100644 --- a/src/yggdrasil/tun_linux.go +++ b/src/yggdrasil/tun_linux.go @@ -3,12 +3,14 @@ package yggdrasil // The linux platform specific tun parts // It depends on iproute2 being installed to set things on the tun device +import "errors" import "fmt" -import "os/exec" -import "strings" +import "net" import water "github.com/neilalexander/water" +import "github.com/docker/libcontainer/netlink" + func getDefaults() tunDefaultParameters { return tunDefaultParameters{ maximumIfMTU: 65535, @@ -39,26 +41,33 @@ func (tun *tunDevice) setup(ifname string, iftapmode bool, addr string, mtu int) func (tun *tunDevice) setupAddress(addr string) error { // Set address - cmd := exec.Command("ip", "-f", "inet6", - "addr", "add", addr, - "dev", tun.iface.Name()) - tun.core.log.Printf("ip command: %v", strings.Join(cmd.Args, " ")) - output, err := cmd.CombinedOutput() + var netIF *net.Interface + ifces, err := net.Interfaces() if err != nil { - tun.core.log.Printf("Linux ip failed: %v.", err) - tun.core.log.Println(string(output)) return err } - // Set MTU and bring device up - cmd = exec.Command("ip", "link", "set", - "dev", tun.iface.Name(), - "mtu", fmt.Sprintf("%d", tun.mtu), - "up") - tun.core.log.Printf("ip command: %v", strings.Join(cmd.Args, " ")) - output, err = cmd.CombinedOutput() + for _, ifce := range ifces { + if ifce.Name == tun.iface.Name() { + netIF = &ifce + } + } + if netIF == nil { + return errors.New(fmt.Sprintf("Failed to find interface: %s", tun.iface.Name())) + } + ip, ipNet, err := net.ParseCIDR(addr) + if err != nil { + return err + } + err = netlink.NetworkLinkAddIp(netIF, ip, ipNet) + if err != nil { + return err + } + err = netlink.NetworkSetMTU(netIF, tun.mtu) + if err != nil { + return err + } + netlink.NetworkLinkUp(netIF) if err != nil { - tun.core.log.Printf("Linux ip failed: %v.", err) - tun.core.log.Println(string(output)) return err } return nil