link_vtap.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. package handler
  2. import (
  3. "fmt"
  4. "net"
  5. "os"
  6. "strings"
  7. "syscall"
  8. "unsafe"
  9. "github.com/bjdgyc/anylink/base"
  10. "github.com/bjdgyc/anylink/pkg/utils"
  11. "github.com/bjdgyc/anylink/sessdata"
  12. )
  13. // link vtap
  14. const vTapPrefix = "lvtap"
  15. type Vtap struct {
  16. *os.File
  17. ifName string
  18. }
  19. func (v *Vtap) Close() error {
  20. v.File.Close()
  21. cmdstr := fmt.Sprintf("ip link del %s", v.ifName)
  22. return execCmd([]string{cmdstr})
  23. }
  24. func checkMacvtap() {
  25. _setGateway()
  26. _checkTapIp(base.Cfg.Ipv4Master)
  27. ifName := "anylinkMacvtap"
  28. // 加载 macvtap
  29. cmdstr0 := fmt.Sprintln("modprobe -i macvtap")
  30. // 开启主网卡混杂模式
  31. cmdstr1 := fmt.Sprintf("ip link set dev %s promisc on", base.Cfg.Ipv4Master)
  32. // 测试 macvtap 功能
  33. cmdstr2 := fmt.Sprintf("ip link add link %s name %s type macvtap mode bridge", base.Cfg.Ipv4Master, ifName)
  34. cmdstr3 := fmt.Sprintf("ip link del %s", ifName)
  35. err := execCmd([]string{cmdstr0, cmdstr1, cmdstr2, cmdstr3})
  36. if err != nil {
  37. base.Fatal(err)
  38. }
  39. }
  40. // 创建 Macvtap 网卡
  41. func LinkMacvtap(cSess *sessdata.ConnSession) error {
  42. capL := sessdata.IpPool.IpLongMax - sessdata.IpPool.IpLongMin
  43. ipN := utils.Ip2long(cSess.IpAddr) % capL
  44. ifName := fmt.Sprintf("%s%d", vTapPrefix, ipN)
  45. cSess.SetIfName(ifName)
  46. cmdstr1 := fmt.Sprintf("ip link add link %s name %s type macvtap mode bridge", base.Cfg.Ipv4Master, ifName)
  47. cmdstr2 := fmt.Sprintf("ip link set dev %s up mtu %d address %s", ifName, cSess.Mtu, cSess.MacHw)
  48. err := execCmd([]string{cmdstr1, cmdstr2})
  49. if err != nil {
  50. base.Error(err)
  51. return err
  52. }
  53. cmdstr3 := fmt.Sprintf("sysctl -w net.ipv6.conf.%s.disable_ipv6=1", ifName)
  54. execCmd([]string{cmdstr3})
  55. return createVtap(cSess, ifName)
  56. }
  57. // func checkIpvtap() {
  58. // }
  59. // 创建 Ipvtap 网卡
  60. func LinkIpvtap(cSess *sessdata.ConnSession) error {
  61. return nil
  62. }
  63. type ifReq struct {
  64. Name [0x10]byte
  65. Flags uint16
  66. pad [0x28 - 0x10 - 2]byte
  67. }
  68. func createVtap(cSess *sessdata.ConnSession, ifName string) error {
  69. // 初始化 ifName
  70. inf, err := net.InterfaceByName(ifName)
  71. if err != nil {
  72. base.Error(err)
  73. return err
  74. }
  75. tName := fmt.Sprintf("/dev/tap%d", inf.Index)
  76. var fdInt int
  77. fdInt, err = syscall.Open(tName, syscall.O_RDWR|syscall.O_NONBLOCK, 0)
  78. if err != nil {
  79. return err
  80. }
  81. var flags uint16 = syscall.IFF_TAP | syscall.IFF_NO_PI
  82. var req ifReq
  83. req.Flags = flags
  84. _, _, errno := syscall.Syscall(
  85. syscall.SYS_IOCTL,
  86. uintptr(fdInt),
  87. uintptr(syscall.TUNSETIFF),
  88. uintptr(unsafe.Pointer(&req)),
  89. )
  90. if errno != 0 {
  91. return os.NewSyscallError("ioctl", errno)
  92. }
  93. file := os.NewFile(uintptr(fdInt), tName)
  94. ifce := &Vtap{file, ifName}
  95. go allTapRead(ifce, cSess)
  96. go allTapWrite(ifce, cSess)
  97. return nil
  98. }
  99. // 销毁未关闭的vtap
  100. func destroyVtap() {
  101. its, err := net.Interfaces()
  102. if err != nil {
  103. base.Error(err)
  104. return
  105. }
  106. for _, v := range its {
  107. if strings.HasPrefix(v.Name, vTapPrefix) {
  108. // 删除原来的网卡
  109. cmdstr := fmt.Sprintf("ip link del %s", v.Name)
  110. execCmd([]string{cmdstr})
  111. }
  112. }
  113. }