diff --git a/iface/iface.go b/iface/iface.go index d33a2a829..38beba6fa 100644 --- a/iface/iface.go +++ b/iface/iface.go @@ -2,52 +2,8 @@ package iface -import ( - log "github.com/sirupsen/logrus" - "golang.zx2c4.com/wireguard/conn" - "golang.zx2c4.com/wireguard/device" - "golang.zx2c4.com/wireguard/tun" -) - -// Saves tun device object - is it required? -var tunIface tun.Device - // Create Creates a new Wireguard interface, sets a given IP and brings it up. // Will reuse an existing one. func Create(iface string, address string) error { - var err error - tunIface, err = tun.CreateTUN(iface, defaultMTU) - if err != nil { - return err - } - - // We need to create a wireguard-go device and listen to configuration requests - tunDevice := device.NewDevice(tunIface, conn.NewDefaultBind(), device.NewLogger(device.LogLevelSilent, "[wiretrustee] ")) - err = tunDevice.Up() - if err != nil { - return err - } - uapi, err := getUAPI(iface) - if err != nil { - return err - } - - go func() { - for { - uapiConn, err := uapi.Accept() - if err != nil { - log.Debugln(err) - return - } - go tunDevice.IpcHandle(uapiConn) - } - }() - - log.Debugln("UAPI listener started") - - err = assignAddr(address, tunIface) - if err != nil { - return err - } - return nil + return CreateInUserspace(iface, address) } diff --git a/iface/iface_configuration.go b/iface/iface_configuration.go index d83abb25b..f611a8553 100644 --- a/iface/iface_configuration.go +++ b/iface/iface_configuration.go @@ -1,6 +1,9 @@ package iface import ( + "golang.zx2c4.com/wireguard/conn" + "golang.zx2c4.com/wireguard/device" + "golang.zx2c4.com/wireguard/tun" "net" "time" @@ -23,6 +26,49 @@ func ConfigureWithKeyGen(iface string) (*wgtypes.Key, error) { return &key, Configure(iface, key.String()) } +// CreateInUserspace Creates a new Wireguard interface, using wireguard-go userspace implementation +func CreateInUserspace(iface string, address string) error { + var err error + tunIface, err := tun.CreateTUN(iface, defaultMTU) + if err != nil { + return err + } + + // We need to create a wireguard-go device and listen to configuration requests + tunDevice := device.NewDevice(tunIface, conn.NewDefaultBind(), device.NewLogger(device.LogLevelSilent, "[wiretrustee] ")) + err = tunDevice.Up() + if err != nil { + return err + } + uapi, err := getUAPI(iface) + if err != nil { + return err + } + + go func() { + for { + uapiConn, err := uapi.Accept() + if err != nil { + log.Debugln(err) + return + } + go tunDevice.IpcHandle(uapiConn) + } + }() + + log.Debugln("UAPI listener started") + + ifaceName, err := tunIface.Name() + if err != nil { + return err + } + err = assignAddr(address, ifaceName) + if err != nil { + return err + } + return nil +} + // Configure configures a Wireguard interface // The interface must exist before calling this method (e.g. call interface.Create() before) func Configure(iface string, privateKey string) error { diff --git a/iface/iface_darwin.go b/iface/iface_darwin.go index aa963e25e..0d07bff89 100644 --- a/iface/iface_darwin.go +++ b/iface/iface_darwin.go @@ -2,7 +2,6 @@ package iface import ( log "github.com/sirupsen/logrus" - "golang.zx2c4.com/wireguard/tun" "net" "os/exec" "strings" @@ -13,8 +12,7 @@ import ( //) // assignAddr Adds IP address to the tunnel interface and network route based on the range provided -func assignAddr(address string, tunDevice tun.Device) error { - ifaceName, err := tunDevice.Name() +func assignAddr(address string, ifaceName string) error { ip := strings.Split(address, "/") cmd := exec.Command("ifconfig", ifaceName, "inet", address, ip[0]) if out, err := cmd.CombinedOutput(); err != nil { diff --git a/iface/iface_linux.go b/iface/iface_linux.go index 120d67954..283ec2505 100644 --- a/iface/iface_linux.go +++ b/iface/iface_linux.go @@ -9,50 +9,56 @@ import ( // Create Creates a new Wireguard interface, sets a given IP and brings it up. // Will reuse an existing one. func Create(iface string, address string) error { - attrs := netlink.NewLinkAttrs() - attrs.Name = iface - link := wgLink{ - attrs: &attrs, + if WireguardModExists() { + attrs := netlink.NewLinkAttrs() + attrs.Name = iface + + link := wgLink{ + attrs: &attrs, + } + + log.Debugf("adding device: %s", iface) + err := netlink.LinkAdd(&link) + if os.IsExist(err) { + log.Infof("interface %s already exists. Will reuse.", iface) + } else if err != nil { + return err + } + + log.Debugf("adding address %s to interface: %s", address, iface) + addr, _ := netlink.ParseAddr(address) + err = netlink.AddrAdd(&link, addr) + if os.IsExist(err) { + log.Infof("interface %s already has the address: %s", iface, address) + } else if err != nil { + return err + } + err = assignAddr(address, iface) + if err != nil { + return err + } + + // todo do a discovery + log.Debugf("setting MTU: %s", iface) + err = netlink.LinkSetMTU(&link, defaultMTU) + if err != nil { + log.Errorf("error setting MTU on interface: %s", iface) + return err + } + + log.Debugf("bringing up interface: %s", iface) + err = netlink.LinkSetUp(&link) + if err != nil { + log.Errorf("error bringing up interface: %s", iface) + return err + } + + return nil + } else { + return CreateInUserspace(iface, address) } - log.Debugf("adding device: %s", iface) - err := netlink.LinkAdd(&link) - if os.IsExist(err) { - log.Infof("interface %s already exists. Will reuse.", iface) - } else if err != nil { - return err - } - - log.Debugf("adding address %s to interface: %s", address, iface) - addr, _ := netlink.ParseAddr(address) - err = netlink.AddrAdd(&link, addr) - if os.IsExist(err) { - log.Infof("interface %s already has the address: %s", iface, address) - } else if err != nil { - return err - } - err = assignAddr(address, iface) - if err != nil { - return err - } - - // todo do a discovery - log.Debugf("setting MTU: %s", iface) - err = netlink.LinkSetMTU(&link, defaultMTU) - if err != nil { - log.Errorf("error setting MTU on interface: %s", iface) - return err - } - - log.Debugf("bringing up interface: %s", iface) - err = netlink.LinkSetUp(&link) - if err != nil { - log.Errorf("error bringing up interface: %s", iface) - return err - } - - return nil } // assignAddr Adds IP address to the tunnel interface diff --git a/iface/iface_windows.go b/iface/iface_windows.go index 9ce7aeafe..601ecfa4a 100644 --- a/iface/iface_windows.go +++ b/iface/iface_windows.go @@ -9,8 +9,8 @@ import ( ) // assignAddr Adds IP address to the tunnel interface and network route based on the range provided -func assignAddr(address string, tunDevice tun.Device) error { - ifaceName, err := tunDevice.Name() +func assignAddr(address string, ifaceName string) error { + nativeTunDevice := tunDevice.(*tun.NativeTun) luid := winipcfg.LUID(nativeTunDevice.LUID())