mirror of
https://github.com/netbirdio/netbird.git
synced 2024-11-29 03:23:56 +01:00
111 lines
1.7 KiB
Go
111 lines
1.7 KiB
Go
|
//go:build linux || darwin
|
||
|
|
||
|
package tun
|
||
|
|
||
|
import (
|
||
|
"net"
|
||
|
|
||
|
log "github.com/sirupsen/logrus"
|
||
|
"github.com/songgao/water"
|
||
|
"github.com/vishvananda/netlink"
|
||
|
)
|
||
|
|
||
|
type Device struct {
|
||
|
Name string
|
||
|
IP string
|
||
|
PConn net.PacketConn
|
||
|
DstAddr net.Addr
|
||
|
|
||
|
iFace *water.Interface
|
||
|
proxy *Proxy
|
||
|
}
|
||
|
|
||
|
func (d *Device) Up() error {
|
||
|
cfg := water.Config{
|
||
|
DeviceType: water.TUN,
|
||
|
PlatformSpecificParams: water.PlatformSpecificParams{
|
||
|
Name: d.Name,
|
||
|
},
|
||
|
}
|
||
|
iFace, err := water.New(cfg)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
d.iFace = iFace
|
||
|
|
||
|
err = d.assignIP()
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
err = d.bringUp()
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
d.proxy = &Proxy{
|
||
|
Device: d,
|
||
|
PConn: d.PConn,
|
||
|
DstAddr: d.DstAddr,
|
||
|
}
|
||
|
d.proxy.Start()
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (d *Device) Close() error {
|
||
|
if d.proxy != nil {
|
||
|
d.proxy.Close()
|
||
|
}
|
||
|
if d.iFace != nil {
|
||
|
return d.iFace.Close()
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (d *Device) Read(b []byte) (int, error) {
|
||
|
return d.iFace.Read(b)
|
||
|
}
|
||
|
|
||
|
func (d *Device) Write(b []byte) (int, error) {
|
||
|
return d.iFace.Write(b)
|
||
|
}
|
||
|
|
||
|
func (d *Device) assignIP() error {
|
||
|
iface, err := netlink.LinkByName(d.Name)
|
||
|
if err != nil {
|
||
|
log.Errorf("failed to get TUN device: %v", err)
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
ip := net.IPNet{
|
||
|
IP: net.ParseIP(d.IP),
|
||
|
Mask: net.CIDRMask(24, 32),
|
||
|
}
|
||
|
|
||
|
addr := &netlink.Addr{
|
||
|
IPNet: &ip,
|
||
|
}
|
||
|
err = netlink.AddrAdd(iface, addr)
|
||
|
if err != nil {
|
||
|
log.Errorf("failed to add IP address: %v", err)
|
||
|
return err
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (d *Device) bringUp() error {
|
||
|
iface, err := netlink.LinkByName(d.Name)
|
||
|
if err != nil {
|
||
|
log.Errorf("failed to get device: %v", err)
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
// Bring the interface up
|
||
|
err = netlink.LinkSetUp(iface)
|
||
|
if err != nil {
|
||
|
log.Errorf("failed to set device up: %v", err)
|
||
|
return err
|
||
|
}
|
||
|
return nil
|
||
|
}
|