tun_linux.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788
  1. //go:build !android && !e2e_testing
  2. // +build !android,!e2e_testing
  3. package overlay
  4. import (
  5. "fmt"
  6. "net"
  7. "net/netip"
  8. "os"
  9. "strings"
  10. "sync/atomic"
  11. "time"
  12. "unsafe"
  13. "github.com/gaissmai/bart"
  14. "github.com/sirupsen/logrus"
  15. "github.com/slackhq/nebula/config"
  16. "github.com/slackhq/nebula/overlay/vhostnet"
  17. "github.com/slackhq/nebula/packet"
  18. "github.com/slackhq/nebula/routing"
  19. "github.com/slackhq/nebula/util"
  20. "github.com/slackhq/nebula/util/virtio"
  21. "github.com/vishvananda/netlink"
  22. "golang.org/x/sys/unix"
  23. )
  24. type tun struct {
  25. file *os.File
  26. fd int
  27. vdev []*vhostnet.Device
  28. Device string
  29. vpnNetworks []netip.Prefix
  30. MaxMTU int
  31. DefaultMTU int
  32. TXQueueLen int
  33. deviceIndex int
  34. ioctlFd uintptr
  35. Routes atomic.Pointer[[]Route]
  36. routeTree atomic.Pointer[bart.Table[routing.Gateways]]
  37. routeChan chan struct{}
  38. useSystemRoutes bool
  39. useSystemRoutesBufferSize int
  40. isV6 bool
  41. l *logrus.Logger
  42. }
  43. func (t *tun) Networks() []netip.Prefix {
  44. return t.vpnNetworks
  45. }
  46. type ifReq struct {
  47. Name [16]byte
  48. Flags uint16
  49. pad [8]byte
  50. }
  51. type ifreqMTU struct {
  52. Name [16]byte
  53. MTU int32
  54. pad [8]byte
  55. }
  56. type ifreqQLEN struct {
  57. Name [16]byte
  58. Value int32
  59. pad [8]byte
  60. }
  61. func newTunFromFd(c *config.C, l *logrus.Logger, deviceFd int, vpnNetworks []netip.Prefix) (*tun, error) {
  62. file := os.NewFile(uintptr(deviceFd), "/dev/net/tun")
  63. t, err := newTunGeneric(c, l, file, vpnNetworks)
  64. if err != nil {
  65. return nil, err
  66. }
  67. t.Device = "tun0"
  68. return t, nil
  69. }
  70. func newTun(c *config.C, l *logrus.Logger, vpnNetworks []netip.Prefix, multiqueue bool) (*tun, error) {
  71. fd, err := unix.Open("/dev/net/tun", os.O_RDWR, 0)
  72. if err != nil {
  73. // If /dev/net/tun doesn't exist, try to create it (will happen in docker)
  74. if os.IsNotExist(err) {
  75. err = os.MkdirAll("/dev/net", 0755)
  76. if err != nil {
  77. return nil, fmt.Errorf("/dev/net/tun doesn't exist, failed to mkdir -p /dev/net: %w", err)
  78. }
  79. err = unix.Mknod("/dev/net/tun", unix.S_IFCHR|0600, int(unix.Mkdev(10, 200)))
  80. if err != nil {
  81. return nil, fmt.Errorf("failed to create /dev/net/tun: %w", err)
  82. }
  83. fd, err = unix.Open("/dev/net/tun", os.O_RDWR, 0)
  84. if err != nil {
  85. return nil, fmt.Errorf("created /dev/net/tun, but still failed: %w", err)
  86. }
  87. } else {
  88. return nil, err
  89. }
  90. }
  91. var req ifReq
  92. req.Flags = uint16(unix.IFF_TUN | unix.IFF_NO_PI | unix.IFF_TUN_EXCL | unix.IFF_VNET_HDR | unix.IFF_NAPI)
  93. if multiqueue {
  94. req.Flags |= unix.IFF_MULTI_QUEUE
  95. }
  96. copy(req.Name[:], c.GetString("tun.dev", ""))
  97. if err = ioctl(uintptr(fd), uintptr(unix.TUNSETIFF), uintptr(unsafe.Pointer(&req))); err != nil {
  98. return nil, err
  99. }
  100. name := strings.Trim(string(req.Name[:]), "\x00")
  101. if err = unix.SetNonblock(fd, true); err != nil {
  102. _ = unix.Close(fd)
  103. return nil, fmt.Errorf("make file descriptor non-blocking: %w", err)
  104. }
  105. file := os.NewFile(uintptr(fd), "/dev/net/tun")
  106. err = unix.IoctlSetPointerInt(fd, unix.TUNSETVNETHDRSZ, virtio.NetHdrSize)
  107. if err != nil {
  108. return nil, fmt.Errorf("set vnethdr size: %w", err)
  109. }
  110. flags := 0
  111. //flags = //unix.TUN_F_CSUM //| unix.TUN_F_TSO4 | unix.TUN_F_USO4 | unix.TUN_F_TSO6 | unix.TUN_F_USO6
  112. err = unix.IoctlSetInt(fd, unix.TUNSETOFFLOAD, flags)
  113. if err != nil {
  114. return nil, fmt.Errorf("set offloads: %w", err)
  115. }
  116. t, err := newTunGeneric(c, l, file, vpnNetworks)
  117. if err != nil {
  118. return nil, err
  119. }
  120. t.fd = fd
  121. t.Device = name
  122. vdev, err := vhostnet.NewDevice(
  123. vhostnet.WithBackendFD(fd),
  124. vhostnet.WithQueueSize(8192), //todo config
  125. )
  126. if err != nil {
  127. return nil, err
  128. }
  129. t.vdev = []*vhostnet.Device{vdev}
  130. return t, nil
  131. }
  132. func newTunGeneric(c *config.C, l *logrus.Logger, file *os.File, vpnNetworks []netip.Prefix) (*tun, error) {
  133. t := &tun{
  134. file: file,
  135. fd: int(file.Fd()),
  136. vpnNetworks: vpnNetworks,
  137. TXQueueLen: c.GetInt("tun.tx_queue", 500),
  138. useSystemRoutes: c.GetBool("tun.use_system_route_table", false),
  139. useSystemRoutesBufferSize: c.GetInt("tun.use_system_route_table_buffer_size", 0),
  140. l: l,
  141. }
  142. if len(vpnNetworks) != 0 {
  143. t.isV6 = vpnNetworks[0].Addr().Is6() //todo what about multi-IP?
  144. }
  145. err := t.reload(c, true)
  146. if err != nil {
  147. return nil, err
  148. }
  149. c.RegisterReloadCallback(func(c *config.C) {
  150. err := t.reload(c, false)
  151. if err != nil {
  152. util.LogWithContextIfNeeded("failed to reload tun device", err, t.l)
  153. }
  154. })
  155. return t, nil
  156. }
  157. func (t *tun) reload(c *config.C, initial bool) error {
  158. routeChange, routes, err := getAllRoutesFromConfig(c, t.vpnNetworks, initial)
  159. if err != nil {
  160. return err
  161. }
  162. if !initial && !routeChange && !c.HasChanged("tun.mtu") {
  163. return nil
  164. }
  165. routeTree, err := makeRouteTree(t.l, routes, true)
  166. if err != nil {
  167. return err
  168. }
  169. oldDefaultMTU := t.DefaultMTU
  170. oldMaxMTU := t.MaxMTU
  171. newDefaultMTU := c.GetInt("tun.mtu", DefaultMTU)
  172. newMaxMTU := newDefaultMTU
  173. for i, r := range routes {
  174. if r.MTU == 0 {
  175. routes[i].MTU = newDefaultMTU
  176. }
  177. if r.MTU > t.MaxMTU {
  178. newMaxMTU = r.MTU
  179. }
  180. }
  181. t.MaxMTU = newMaxMTU
  182. t.DefaultMTU = newDefaultMTU
  183. // Teach nebula how to handle the routes before establishing them in the system table
  184. oldRoutes := t.Routes.Swap(&routes)
  185. t.routeTree.Store(routeTree)
  186. if !initial {
  187. if oldMaxMTU != newMaxMTU {
  188. t.setMTU()
  189. t.l.Infof("Set max MTU to %v was %v", t.MaxMTU, oldMaxMTU)
  190. }
  191. if oldDefaultMTU != newDefaultMTU {
  192. for i := range t.vpnNetworks {
  193. err := t.setDefaultRoute(t.vpnNetworks[i])
  194. if err != nil {
  195. t.l.Warn(err)
  196. } else {
  197. t.l.Infof("Set default MTU to %v was %v", t.DefaultMTU, oldDefaultMTU)
  198. }
  199. }
  200. }
  201. // Remove first, if the system removes a wanted route hopefully it will be re-added next
  202. t.removeRoutes(findRemovedRoutes(routes, *oldRoutes))
  203. // Ensure any routes we actually want are installed
  204. err = t.addRoutes(true)
  205. if err != nil {
  206. // This should never be called since addRoutes should log its own errors in a reload condition
  207. util.LogWithContextIfNeeded("Failed to refresh routes", err, t.l)
  208. }
  209. }
  210. return nil
  211. }
  212. func (t *tun) SupportsMultiqueue() bool {
  213. return true
  214. }
  215. func (t *tun) NewMultiQueueReader() (TunDev, error) {
  216. fd, err := unix.Open("/dev/net/tun", os.O_RDWR, 0)
  217. if err != nil {
  218. return nil, err
  219. }
  220. var req ifReq
  221. req.Flags = uint16(unix.IFF_TUN | unix.IFF_NO_PI | unix.IFF_MULTI_QUEUE)
  222. copy(req.Name[:], t.Device)
  223. if err = ioctl(uintptr(fd), uintptr(unix.TUNSETIFF), uintptr(unsafe.Pointer(&req))); err != nil {
  224. return nil, err
  225. }
  226. vdev, err := vhostnet.NewDevice(
  227. vhostnet.WithBackendFD(fd),
  228. vhostnet.WithQueueSize(8192), //todo config
  229. )
  230. if err != nil {
  231. return nil, err
  232. }
  233. t.vdev = append(t.vdev, vdev)
  234. return t, nil
  235. }
  236. func (t *tun) RoutesFor(ip netip.Addr) routing.Gateways {
  237. r, _ := t.routeTree.Load().Lookup(ip)
  238. return r
  239. }
  240. func (t *tun) deviceBytes() (o [16]byte) {
  241. for i, c := range t.Device {
  242. o[i] = byte(c)
  243. }
  244. return
  245. }
  246. func hasNetlinkAddr(al []*netlink.Addr, x netlink.Addr) bool {
  247. for i := range al {
  248. if al[i].Equal(x) {
  249. return true
  250. }
  251. }
  252. return false
  253. }
  254. // addIPs uses netlink to add all addresses that don't exist, then it removes ones that should not be there
  255. func (t *tun) addIPs(link netlink.Link) error {
  256. newAddrs := make([]*netlink.Addr, len(t.vpnNetworks))
  257. for i := range t.vpnNetworks {
  258. newAddrs[i] = &netlink.Addr{
  259. IPNet: &net.IPNet{
  260. IP: t.vpnNetworks[i].Addr().AsSlice(),
  261. Mask: net.CIDRMask(t.vpnNetworks[i].Bits(), t.vpnNetworks[i].Addr().BitLen()),
  262. },
  263. Label: t.vpnNetworks[i].Addr().Zone(),
  264. }
  265. }
  266. //add all new addresses
  267. for i := range newAddrs {
  268. //AddrReplace still adds new IPs, but if their properties change it will change them as well
  269. if err := netlink.AddrReplace(link, newAddrs[i]); err != nil {
  270. return err
  271. }
  272. }
  273. //iterate over remainder, remove whoever shouldn't be there
  274. al, err := netlink.AddrList(link, netlink.FAMILY_ALL)
  275. if err != nil {
  276. return fmt.Errorf("failed to get tun address list: %s", err)
  277. }
  278. for i := range al {
  279. if hasNetlinkAddr(newAddrs, al[i]) {
  280. continue
  281. }
  282. err = netlink.AddrDel(link, &al[i])
  283. if err != nil {
  284. t.l.WithError(err).Error("failed to remove address from tun address list")
  285. } else {
  286. t.l.WithField("removed", al[i].String()).Info("removed address not listed in cert(s)")
  287. }
  288. }
  289. return nil
  290. }
  291. func (t *tun) Activate() error {
  292. devName := t.deviceBytes()
  293. if t.useSystemRoutes {
  294. t.watchRoutes()
  295. }
  296. s, err := unix.Socket(
  297. unix.AF_INET, //because everything we use t.ioctlFd for is address family independent, this is fine
  298. unix.SOCK_DGRAM,
  299. unix.IPPROTO_IP,
  300. )
  301. if err != nil {
  302. return err
  303. }
  304. t.ioctlFd = uintptr(s)
  305. // Set the device name
  306. ifrf := ifReq{Name: devName}
  307. if err = ioctl(t.ioctlFd, unix.SIOCGIFFLAGS, uintptr(unsafe.Pointer(&ifrf))); err != nil {
  308. return fmt.Errorf("failed to set tun device name: %s", err)
  309. }
  310. link, err := netlink.LinkByName(t.Device)
  311. if err != nil {
  312. return fmt.Errorf("failed to get tun device link: %s", err)
  313. }
  314. t.deviceIndex = link.Attrs().Index
  315. // Setup our default MTU
  316. t.setMTU()
  317. // Set the transmit queue length
  318. ifrq := ifreqQLEN{Name: devName, Value: int32(t.TXQueueLen)}
  319. if err = ioctl(t.ioctlFd, unix.SIOCSIFTXQLEN, uintptr(unsafe.Pointer(&ifrq))); err != nil {
  320. // If we can't set the queue length nebula will still work but it may lead to packet loss
  321. t.l.WithError(err).Error("Failed to set tun tx queue length")
  322. }
  323. const modeNone = 1
  324. if err = netlink.LinkSetIP6AddrGenMode(link, modeNone); err != nil {
  325. t.l.WithError(err).Warn("Failed to disable link local address generation")
  326. }
  327. if err = t.addIPs(link); err != nil {
  328. return err
  329. }
  330. // Bring up the interface
  331. ifrf.Flags = ifrf.Flags | unix.IFF_UP
  332. if err = ioctl(t.ioctlFd, unix.SIOCSIFFLAGS, uintptr(unsafe.Pointer(&ifrf))); err != nil {
  333. return fmt.Errorf("failed to bring the tun device up: %s", err)
  334. }
  335. //set route MTU
  336. for i := range t.vpnNetworks {
  337. if err = t.setDefaultRoute(t.vpnNetworks[i]); err != nil {
  338. return fmt.Errorf("failed to set default route MTU: %w", err)
  339. }
  340. }
  341. // Set the routes
  342. if err = t.addRoutes(false); err != nil {
  343. return err
  344. }
  345. // Run the interface
  346. ifrf.Flags = ifrf.Flags | unix.IFF_UP | unix.IFF_RUNNING
  347. if err = ioctl(t.ioctlFd, unix.SIOCSIFFLAGS, uintptr(unsafe.Pointer(&ifrf))); err != nil {
  348. return fmt.Errorf("failed to run tun device: %s", err)
  349. }
  350. return nil
  351. }
  352. func (t *tun) setMTU() {
  353. // Set the MTU on the device
  354. ifm := ifreqMTU{Name: t.deviceBytes(), MTU: int32(t.MaxMTU)}
  355. if err := ioctl(t.ioctlFd, unix.SIOCSIFMTU, uintptr(unsafe.Pointer(&ifm))); err != nil {
  356. // This is currently a non fatal condition because the route table must have the MTU set appropriately as well
  357. t.l.WithError(err).Error("Failed to set tun mtu")
  358. }
  359. }
  360. func (t *tun) setDefaultRoute(cidr netip.Prefix) error {
  361. dr := &net.IPNet{
  362. IP: cidr.Masked().Addr().AsSlice(),
  363. Mask: net.CIDRMask(cidr.Bits(), cidr.Addr().BitLen()),
  364. }
  365. nr := netlink.Route{
  366. LinkIndex: t.deviceIndex,
  367. Dst: dr,
  368. MTU: t.DefaultMTU,
  369. AdvMSS: t.advMSS(Route{}),
  370. Scope: unix.RT_SCOPE_LINK,
  371. Src: net.IP(cidr.Addr().AsSlice()),
  372. Protocol: unix.RTPROT_KERNEL,
  373. Table: unix.RT_TABLE_MAIN,
  374. Type: unix.RTN_UNICAST,
  375. }
  376. err := netlink.RouteReplace(&nr)
  377. if err != nil {
  378. t.l.WithError(err).WithField("cidr", cidr).Warn("Failed to set default route MTU, retrying")
  379. //retry twice more -- on some systems there appears to be a race condition where if we set routes too soon, netlink says `invalid argument`
  380. for i := 0; i < 2; i++ {
  381. time.Sleep(100 * time.Millisecond)
  382. err = netlink.RouteReplace(&nr)
  383. if err == nil {
  384. break
  385. } else {
  386. t.l.WithError(err).WithField("cidr", cidr).WithField("mtu", t.DefaultMTU).Warn("Failed to set default route MTU, retrying")
  387. }
  388. }
  389. if err != nil {
  390. return fmt.Errorf("failed to set mtu %v on the default route %v; %v", t.DefaultMTU, dr, err)
  391. }
  392. }
  393. return nil
  394. }
  395. func (t *tun) addRoutes(logErrors bool) error {
  396. // Path routes
  397. routes := *t.Routes.Load()
  398. for _, r := range routes {
  399. if !r.Install {
  400. continue
  401. }
  402. dr := &net.IPNet{
  403. IP: r.Cidr.Masked().Addr().AsSlice(),
  404. Mask: net.CIDRMask(r.Cidr.Bits(), r.Cidr.Addr().BitLen()),
  405. }
  406. nr := netlink.Route{
  407. LinkIndex: t.deviceIndex,
  408. Dst: dr,
  409. MTU: r.MTU,
  410. AdvMSS: t.advMSS(r),
  411. Scope: unix.RT_SCOPE_LINK,
  412. }
  413. if r.Metric > 0 {
  414. nr.Priority = r.Metric
  415. }
  416. err := netlink.RouteReplace(&nr)
  417. if err != nil {
  418. retErr := util.NewContextualError("Failed to add route", map[string]any{"route": r}, err)
  419. if logErrors {
  420. retErr.Log(t.l)
  421. } else {
  422. return retErr
  423. }
  424. } else {
  425. t.l.WithField("route", r).Info("Added route")
  426. }
  427. }
  428. return nil
  429. }
  430. func (t *tun) removeRoutes(routes []Route) {
  431. for _, r := range routes {
  432. if !r.Install {
  433. continue
  434. }
  435. dr := &net.IPNet{
  436. IP: r.Cidr.Masked().Addr().AsSlice(),
  437. Mask: net.CIDRMask(r.Cidr.Bits(), r.Cidr.Addr().BitLen()),
  438. }
  439. nr := netlink.Route{
  440. LinkIndex: t.deviceIndex,
  441. Dst: dr,
  442. MTU: r.MTU,
  443. AdvMSS: t.advMSS(r),
  444. Scope: unix.RT_SCOPE_LINK,
  445. }
  446. if r.Metric > 0 {
  447. nr.Priority = r.Metric
  448. }
  449. err := netlink.RouteDel(&nr)
  450. if err != nil {
  451. t.l.WithError(err).WithField("route", r).Error("Failed to remove route")
  452. } else {
  453. t.l.WithField("route", r).Info("Removed route")
  454. }
  455. }
  456. }
  457. func (t *tun) Name() string {
  458. return t.Device
  459. }
  460. func (t *tun) advMSS(r Route) int {
  461. mtu := r.MTU
  462. if r.MTU == 0 {
  463. mtu = t.DefaultMTU
  464. }
  465. // We only need to set advmss if the route MTU does not match the device MTU
  466. if mtu != t.MaxMTU {
  467. return mtu - 40
  468. }
  469. return 0
  470. }
  471. func (t *tun) watchRoutes() {
  472. rch := make(chan netlink.RouteUpdate)
  473. doneChan := make(chan struct{})
  474. netlinkOptions := netlink.RouteSubscribeOptions{
  475. ReceiveBufferSize: t.useSystemRoutesBufferSize,
  476. ReceiveBufferForceSize: t.useSystemRoutesBufferSize != 0,
  477. ErrorCallback: func(e error) { t.l.WithError(e).Errorf("netlink error") },
  478. }
  479. if err := netlink.RouteSubscribeWithOptions(rch, doneChan, netlinkOptions); err != nil {
  480. t.l.WithError(err).Errorf("failed to subscribe to system route changes")
  481. return
  482. }
  483. t.routeChan = doneChan
  484. go func() {
  485. for {
  486. select {
  487. case r, ok := <-rch:
  488. if ok {
  489. t.updateRoutes(r)
  490. } else {
  491. // may be should do something here as
  492. // netlink stops sending updates
  493. return
  494. }
  495. case <-doneChan:
  496. // netlink.RouteSubscriber will close the rch for us
  497. return
  498. }
  499. }
  500. }()
  501. }
  502. func (t *tun) isGatewayInVpnNetworks(gwAddr netip.Addr) bool {
  503. withinNetworks := false
  504. for i := range t.vpnNetworks {
  505. if t.vpnNetworks[i].Contains(gwAddr) {
  506. withinNetworks = true
  507. break
  508. }
  509. }
  510. return withinNetworks
  511. }
  512. func (t *tun) getGatewaysFromRoute(r *netlink.Route) routing.Gateways {
  513. var gateways routing.Gateways
  514. link, err := netlink.LinkByName(t.Device)
  515. if err != nil {
  516. t.l.WithField("deviceName", t.Device).Error("Ignoring route update: failed to get link by name")
  517. return gateways
  518. }
  519. // If this route is relevant to our interface and there is a gateway then add it
  520. if r.LinkIndex == link.Attrs().Index {
  521. gwAddr, ok := getGatewayAddr(r.Gw, r.Via)
  522. if ok {
  523. if t.isGatewayInVpnNetworks(gwAddr) {
  524. gateways = append(gateways, routing.NewGateway(gwAddr, 1))
  525. } else {
  526. // Gateway isn't in our overlay network, ignore
  527. t.l.WithField("route", r).Debug("Ignoring route update, gateway is not in our network")
  528. }
  529. } else {
  530. t.l.WithField("route", r).Debug("Ignoring route update, invalid gateway or via address")
  531. }
  532. }
  533. for _, p := range r.MultiPath {
  534. // If this route is relevant to our interface and there is a gateway then add it
  535. if p.LinkIndex == link.Attrs().Index {
  536. gwAddr, ok := getGatewayAddr(p.Gw, p.Via)
  537. if ok {
  538. if t.isGatewayInVpnNetworks(gwAddr) {
  539. gateways = append(gateways, routing.NewGateway(gwAddr, p.Hops+1))
  540. } else {
  541. // Gateway isn't in our overlay network, ignore
  542. t.l.WithField("route", r).Debug("Ignoring route update, gateway is not in our network")
  543. }
  544. } else {
  545. t.l.WithField("route", r).Debug("Ignoring route update, invalid gateway or via address")
  546. }
  547. }
  548. }
  549. routing.CalculateBucketsForGateways(gateways)
  550. return gateways
  551. }
  552. func getGatewayAddr(gw net.IP, via netlink.Destination) (netip.Addr, bool) {
  553. // Try to use the old RTA_GATEWAY first
  554. gwAddr, ok := netip.AddrFromSlice(gw)
  555. if !ok {
  556. // Fallback to the new RTA_VIA
  557. rVia, ok := via.(*netlink.Via)
  558. if ok {
  559. gwAddr, ok = netip.AddrFromSlice(rVia.Addr)
  560. }
  561. }
  562. if gwAddr.IsValid() {
  563. gwAddr = gwAddr.Unmap()
  564. return gwAddr, true
  565. }
  566. return netip.Addr{}, false
  567. }
  568. func (t *tun) updateRoutes(r netlink.RouteUpdate) {
  569. gateways := t.getGatewaysFromRoute(&r.Route)
  570. if len(gateways) == 0 {
  571. // No gateways relevant to our network, no routing changes required.
  572. t.l.WithField("route", r).Debug("Ignoring route update, no gateways")
  573. return
  574. }
  575. if r.Dst == nil {
  576. t.l.WithField("route", r).Debug("Ignoring route update, no destination address")
  577. return
  578. }
  579. dstAddr, ok := netip.AddrFromSlice(r.Dst.IP)
  580. if !ok {
  581. t.l.WithField("route", r).Debug("Ignoring route update, invalid destination address")
  582. return
  583. }
  584. ones, _ := r.Dst.Mask.Size()
  585. dst := netip.PrefixFrom(dstAddr, ones)
  586. newTree := t.routeTree.Load().Clone()
  587. if r.Type == unix.RTM_NEWROUTE {
  588. t.l.WithField("destination", dst).WithField("via", gateways).Info("Adding route")
  589. newTree.Insert(dst, gateways)
  590. } else {
  591. t.l.WithField("destination", dst).WithField("via", gateways).Info("Removing route")
  592. newTree.Delete(dst)
  593. }
  594. t.routeTree.Store(newTree)
  595. }
  596. func (t *tun) Close() error {
  597. if t.routeChan != nil {
  598. close(t.routeChan)
  599. }
  600. for _, v := range t.vdev {
  601. if v != nil {
  602. _ = v.Close()
  603. }
  604. }
  605. if t.file != nil {
  606. _ = t.file.Close()
  607. }
  608. if t.ioctlFd > 0 {
  609. _ = os.NewFile(t.ioctlFd, "ioctlFd").Close()
  610. }
  611. return nil
  612. }
  613. func (t *tun) ReadMany(p []*packet.VirtIOPacket, q int) (int, error) {
  614. n, err := t.vdev[q].ReceivePackets(p) //we are TXing
  615. if err != nil {
  616. return 0, err
  617. }
  618. return n, nil
  619. }
  620. func (t *tun) Write(b []byte) (int, error) {
  621. maximum := len(b) //we are RXing
  622. //todo garbagey
  623. out := packet.NewOut()
  624. x, err := t.AllocSeg(out, 0)
  625. if err != nil {
  626. return 0, err
  627. }
  628. copy(out.SegmentPayloads[x], b)
  629. err = t.vdev[0].TransmitPacket(out, true)
  630. if err != nil {
  631. t.l.WithError(err).Error("Transmitting packet")
  632. return 0, err
  633. }
  634. return maximum, nil
  635. }
  636. func (t *tun) AllocSeg(pkt *packet.OutPacket, q int) (int, error) {
  637. idx, buf, err := t.vdev[q].GetPacketForTx()
  638. if err != nil {
  639. return 0, err
  640. }
  641. x := pkt.UseSegment(idx, buf, t.isV6)
  642. return x, nil
  643. }
  644. func (t *tun) WriteOne(x *packet.OutPacket, kick bool, q int) (int, error) {
  645. if err := t.vdev[q].TransmitPacket(x, kick); err != nil {
  646. t.l.WithError(err).Error("Transmitting packet")
  647. return 0, err
  648. }
  649. return 1, nil
  650. }
  651. func (t *tun) WriteMany(x []*packet.OutPacket, q int) (int, error) {
  652. maximum := len(x) //we are RXing
  653. if maximum == 0 {
  654. return 0, nil
  655. }
  656. err := t.vdev[q].TransmitPackets(x)
  657. if err != nil {
  658. t.l.WithError(err).Error("Transmitting packet")
  659. return 0, err
  660. }
  661. return maximum, nil
  662. }
  663. func (t *tun) RecycleRxSeg(pkt *packet.VirtIOPacket, kick bool, q int) error {
  664. return t.vdev[q].ReceiveQueue.OfferDescriptorChains(pkt.Chains, kick)
  665. }