//go:build linux && !android package iface import ( "os" log "github.com/sirupsen/logrus" "github.com/vishvananda/netlink" ) func (c *tunDevice) Create() error { log.Infof("create tun interface with userspace WireGuard support: %s", c.DeviceName()) var err error c.netInterface, err = c.createWithUserspace() if err != nil { return err } return c.assignAddr() } // createWithKernel Creates a new WireGuard interface using kernel WireGuard module. // Works for Linux and offers much better network performance func (c *tunDevice) createWithKernel() error { link := newWGLink(c.name) // check if interface exists l, err := netlink.LinkByName(c.name) if err != nil { switch err.(type) { case netlink.LinkNotFoundError: break default: return err } } // remove if interface exists if l != nil { err = netlink.LinkDel(link) if err != nil { return err } } log.Debugf("adding device: %s", c.name) err = netlink.LinkAdd(link) if os.IsExist(err) { log.Infof("interface %s already exists. Will reuse.", c.name) } else if err != nil { return err } c.netInterface = link err = c.assignAddr() if err != nil { return err } // todo do a discovery log.Debugf("setting MTU: %d interface: %s", c.mtu, c.name) err = netlink.LinkSetMTU(link, c.mtu) if err != nil { log.Errorf("error setting MTU on interface: %s", c.name) return err } log.Debugf("bringing up interface: %s", c.name) err = netlink.LinkSetUp(link) if err != nil { log.Errorf("error bringing up interface: %s", c.name) return err } return nil } // assignAddr Adds IP address to the tunnel interface func (c *tunDevice) assignAddr() error { return nil } type wgLink struct { attrs *netlink.LinkAttrs } func newWGLink(name string) *wgLink { attrs := netlink.NewLinkAttrs() attrs.Name = name return &wgLink{ attrs: &attrs, } } // Attrs returns the Wireguard's default attributes func (l *wgLink) Attrs() *netlink.LinkAttrs { return l.attrs } // Type returns the interface type func (l *wgLink) Type() string { return "wireguard" } // Close deletes the link interface func (l *wgLink) Close() error { return netlink.LinkDel(l) }