2
0

tun_darwin.go 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. // +build !ios
  2. package nebula
  3. import (
  4. "fmt"
  5. "io"
  6. "net"
  7. "os/exec"
  8. "strconv"
  9. "github.com/sirupsen/logrus"
  10. "github.com/songgao/water"
  11. )
  12. type Tun struct {
  13. Device string
  14. Cidr *net.IPNet
  15. MTU int
  16. UnsafeRoutes []route
  17. l *logrus.Logger
  18. *water.Interface
  19. }
  20. func newTun(l *logrus.Logger, deviceName string, cidr *net.IPNet, defaultMTU int, routes []route, unsafeRoutes []route, txQueueLen int, multiqueue bool) (ifce *Tun, err error) {
  21. if len(routes) > 0 {
  22. return nil, fmt.Errorf("route MTU not supported in Darwin")
  23. }
  24. // NOTE: You cannot set the deviceName under Darwin, so you must check tun.Device after calling .Activate()
  25. return &Tun{
  26. Cidr: cidr,
  27. MTU: defaultMTU,
  28. UnsafeRoutes: unsafeRoutes,
  29. l: l,
  30. }, nil
  31. }
  32. func newTunFromFd(l *logrus.Logger, deviceFd int, cidr *net.IPNet, defaultMTU int, routes []route, unsafeRoutes []route, txQueueLen int) (ifce *Tun, err error) {
  33. return nil, fmt.Errorf("newTunFromFd not supported in Darwin")
  34. }
  35. func (c *Tun) Activate() error {
  36. var err error
  37. c.Interface, err = water.New(water.Config{
  38. DeviceType: water.TUN,
  39. })
  40. if err != nil {
  41. return fmt.Errorf("activate failed: %v", err)
  42. }
  43. c.Device = c.Interface.Name()
  44. // TODO use syscalls instead of exec.Command
  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. if err = exec.Command("/sbin/route", "-n", "add", "-net", c.Cidr.String(), "-interface", c.Device).Run(); err != nil {
  49. return fmt.Errorf("failed to run 'route add': %s", err)
  50. }
  51. if err = exec.Command("/sbin/ifconfig", c.Device, "mtu", strconv.Itoa(c.MTU)).Run(); err != nil {
  52. return fmt.Errorf("failed to run 'ifconfig': %s", err)
  53. }
  54. // Unsafe path routes
  55. for _, r := range c.UnsafeRoutes {
  56. if err = exec.Command("/sbin/route", "-n", "add", "-net", r.route.String(), "-interface", c.Device).Run(); err != nil {
  57. return fmt.Errorf("failed to run 'route add' for unsafe_route %s: %s", r.route.String(), err)
  58. }
  59. }
  60. return nil
  61. }
  62. func (c *Tun) CidrNet() *net.IPNet {
  63. return c.Cidr
  64. }
  65. func (c *Tun) DeviceName() string {
  66. return c.Device
  67. }
  68. func (c *Tun) WriteRaw(b []byte) error {
  69. _, err := c.Write(b)
  70. return err
  71. }
  72. func (t *Tun) NewMultiQueueReader() (io.ReadWriteCloser, error) {
  73. return nil, fmt.Errorf("TODO: multiqueue not implemented for darwin")
  74. }