tun_freebsd.go 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. package nebula
  2. import (
  3. "fmt"
  4. "io"
  5. "net"
  6. "os"
  7. "os/exec"
  8. "regexp"
  9. "strconv"
  10. "strings"
  11. )
  12. var deviceNameRE = regexp.MustCompile(`^tun[0-9]+$`)
  13. type Tun struct {
  14. Device string
  15. Cidr *net.IPNet
  16. MTU int
  17. UnsafeRoutes []route
  18. io.ReadWriteCloser
  19. }
  20. func newTun(deviceName string, cidr *net.IPNet, defaultMTU int, routes []route, unsafeRoutes []route, txQueueLen int) (ifce *Tun, err error) {
  21. if len(routes) > 0 {
  22. return nil, fmt.Errorf("Route MTU not supported in FreeBSD")
  23. }
  24. if strings.HasPrefix(deviceName, "/dev/") {
  25. deviceName = strings.TrimPrefix(deviceName, "/dev/")
  26. }
  27. if !deviceNameRE.MatchString(deviceName) {
  28. return nil, fmt.Errorf("tun.dev must match `tun[0-9]+`")
  29. }
  30. return &Tun{
  31. Device: deviceName,
  32. Cidr: cidr,
  33. MTU: defaultMTU,
  34. UnsafeRoutes: unsafeRoutes,
  35. }, nil
  36. }
  37. func (c *Tun) Activate() error {
  38. var err error
  39. c.ReadWriteCloser, err = os.OpenFile("/dev/"+c.Device, os.O_RDWR, 0)
  40. if err != nil {
  41. return fmt.Errorf("Activate failed: %v", err)
  42. }
  43. // TODO use syscalls instead of exec.Command
  44. l.Debug("command: ifconfig", c.Device, c.Cidr.String(), c.Cidr.IP.String())
  45. if err = exec.Command("/sbin/ifconfig", c.Device, c.Cidr.String(), c.Cidr.IP.String()).Run(); err != nil {
  46. return fmt.Errorf("failed to run 'ifconfig': %s", err)
  47. }
  48. l.Debug("command: route", "-n", "add", "-net", c.Cidr.String(), "-interface", c.Device)
  49. if err = exec.Command("/sbin/route", "-n", "add", "-net", c.Cidr.String(), "-interface", c.Device).Run(); err != nil {
  50. return fmt.Errorf("failed to run 'route add': %s", err)
  51. }
  52. l.Debug("command: ifconfig", c.Device, "mtu", strconv.Itoa(c.MTU))
  53. if err = exec.Command("/sbin/ifconfig", c.Device, "mtu", strconv.Itoa(c.MTU)).Run(); err != nil {
  54. return fmt.Errorf("failed to run 'ifconfig': %s", err)
  55. }
  56. // Unsafe path routes
  57. for _, r := range c.UnsafeRoutes {
  58. l.Debug("command: route", "-n", "add", "-net", r.route.String(), "-interface", c.Device)
  59. if err = exec.Command("/sbin/route", "-n", "add", "-net", r.route.String(), "-interface", c.Device).Run(); err != nil {
  60. return fmt.Errorf("failed to run 'route add' for unsafe_route %s: %s", r.route.String(), err)
  61. }
  62. }
  63. return nil
  64. }
  65. func (c *Tun) WriteRaw(b []byte) error {
  66. _, err := c.Write(b)
  67. return err
  68. }