tun_tester.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. //go:build e2e_testing
  2. // +build e2e_testing
  3. package overlay
  4. import (
  5. "fmt"
  6. "io"
  7. "net/netip"
  8. "os"
  9. "sync/atomic"
  10. "github.com/gaissmai/bart"
  11. "github.com/sirupsen/logrus"
  12. "github.com/slackhq/nebula/config"
  13. "github.com/slackhq/nebula/routing"
  14. )
  15. type TestTun struct {
  16. Device string
  17. vpnNetworks []netip.Prefix
  18. unsafeNetworks []netip.Prefix
  19. snatAddr netip.Prefix
  20. unsafeIPv4Origin netip.Prefix
  21. Routes []Route
  22. routeTree *bart.Table[routing.Gateways]
  23. l *logrus.Logger
  24. closed atomic.Bool
  25. rxPackets chan []byte // Packets to receive into nebula
  26. TxPackets chan []byte // Packets transmitted outside by nebula
  27. }
  28. func newTun(c *config.C, l *logrus.Logger, vpnNetworks []netip.Prefix, unsafeNetworks []netip.Prefix, _ bool) (*TestTun, error) {
  29. _, routes, err := getAllRoutesFromConfig(c, vpnNetworks, true)
  30. if err != nil {
  31. return nil, err
  32. }
  33. routeTree, err := makeRouteTree(l, routes, false)
  34. if err != nil {
  35. return nil, err
  36. }
  37. tt := &TestTun{
  38. Device: c.GetString("tun.dev", ""),
  39. vpnNetworks: vpnNetworks,
  40. unsafeNetworks: unsafeNetworks,
  41. Routes: routes,
  42. routeTree: routeTree,
  43. l: l,
  44. rxPackets: make(chan []byte, 10),
  45. TxPackets: make(chan []byte, 10),
  46. }
  47. tt.unsafeIPv4Origin = prepareUnsafeOriginAddr(tt, l, c, routes)
  48. tt.snatAddr = prepareSnatAddr(tt, tt.l, c)
  49. return tt, nil
  50. }
  51. func newTunFromFd(_ *config.C, _ *logrus.Logger, _ int, _ []netip.Prefix, _ []netip.Prefix) (*TestTun, error) {
  52. return nil, fmt.Errorf("newTunFromFd not supported")
  53. }
  54. // Send will place a byte array onto the receive queue for nebula to consume
  55. // These are unencrypted ip layer frames destined for another nebula node.
  56. // packets should exit the udp side, capture them with udpConn.Get
  57. func (t *TestTun) Send(packet []byte) {
  58. if t.closed.Load() {
  59. return
  60. }
  61. if t.l.Level >= logrus.DebugLevel {
  62. t.l.WithField("dataLen", len(packet)).Debug("Tun receiving injected packet")
  63. }
  64. t.rxPackets <- packet
  65. }
  66. // Get will pull an unencrypted ip layer frame from the transmit queue
  67. // nebula meant to send this message to some application on the local system
  68. // packets were ingested from the udp side, you can send them with udpConn.Send
  69. func (t *TestTun) Get(block bool) []byte {
  70. if block {
  71. return <-t.TxPackets
  72. }
  73. select {
  74. case p := <-t.TxPackets:
  75. return p
  76. default:
  77. return nil
  78. }
  79. }
  80. //********************************************************************************************************************//
  81. // Below this is boilerplate implementation to make nebula actually work
  82. //********************************************************************************************************************//
  83. func (t *TestTun) RoutesFor(ip netip.Addr) routing.Gateways {
  84. r, _ := t.routeTree.Lookup(ip)
  85. return r
  86. }
  87. func (t *TestTun) Activate() error {
  88. return nil
  89. }
  90. func (t *TestTun) Networks() []netip.Prefix {
  91. return t.vpnNetworks
  92. }
  93. func (t *TestTun) Name() string {
  94. return t.Device
  95. }
  96. func (t *TestTun) Write(b []byte) (n int, err error) {
  97. if t.closed.Load() {
  98. return 0, io.ErrClosedPipe
  99. }
  100. packet := make([]byte, len(b), len(b))
  101. copy(packet, b)
  102. t.TxPackets <- packet
  103. return len(b), nil
  104. }
  105. func (t *TestTun) Close() error {
  106. if t.closed.CompareAndSwap(false, true) {
  107. close(t.rxPackets)
  108. close(t.TxPackets)
  109. }
  110. return nil
  111. }
  112. func (t *TestTun) Read(b []byte) (int, error) {
  113. p, ok := <-t.rxPackets
  114. if !ok {
  115. return 0, os.ErrClosed
  116. }
  117. copy(b, p)
  118. return len(p), nil
  119. }
  120. func (t *TestTun) SupportsMultiqueue() bool {
  121. return false
  122. }
  123. func (t *TestTun) NewMultiQueueReader() (io.ReadWriteCloser, error) {
  124. return nil, fmt.Errorf("TODO: multiqueue not implemented")
  125. }
  126. func (t *TestTun) UnsafeNetworks() []netip.Prefix {
  127. return t.unsafeNetworks
  128. }
  129. func (t *TestTun) UnsafeIPv4OriginAddress() netip.Prefix {
  130. return t.unsafeIPv4Origin
  131. }
  132. func (t *TestTun) SNATAddress() netip.Prefix {
  133. return t.snatAddr
  134. }