tun_disabled.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. package overlay
  2. import (
  3. "fmt"
  4. "io"
  5. "net/netip"
  6. "strings"
  7. "github.com/rcrowley/go-metrics"
  8. "github.com/sirupsen/logrus"
  9. "github.com/slackhq/nebula/iputil"
  10. "github.com/slackhq/nebula/overlay/virtqueue"
  11. "github.com/slackhq/nebula/packet"
  12. "github.com/slackhq/nebula/routing"
  13. )
  14. type disabledTun struct {
  15. read chan []byte
  16. vpnNetworks []netip.Prefix
  17. // Track these metrics since we don't have the tun device to do it for us
  18. tx metrics.Counter
  19. rx metrics.Counter
  20. l *logrus.Logger
  21. }
  22. func (t *disabledTun) NewPacketArrays(batchSize int) []TunPacket {
  23. panic("implement me") //TODO
  24. }
  25. func (*disabledTun) RecycleRxSeg(pkt TunPacket, kick bool, q int) error {
  26. return nil
  27. }
  28. func newDisabledTun(vpnNetworks []netip.Prefix, queueLen int, metricsEnabled bool, l *logrus.Logger) *disabledTun {
  29. tun := &disabledTun{
  30. vpnNetworks: vpnNetworks,
  31. read: make(chan []byte, queueLen),
  32. l: l,
  33. }
  34. if metricsEnabled {
  35. tun.tx = metrics.GetOrRegisterCounter("messages.tx.message", nil)
  36. tun.rx = metrics.GetOrRegisterCounter("messages.rx.message", nil)
  37. } else {
  38. tun.tx = &metrics.NilCounter{}
  39. tun.rx = &metrics.NilCounter{}
  40. }
  41. return tun
  42. }
  43. func (*disabledTun) GetQueues() []*virtqueue.SplitQueue {
  44. return nil
  45. }
  46. func (*disabledTun) Activate() error {
  47. return nil
  48. }
  49. func (*disabledTun) RoutesFor(addr netip.Addr) routing.Gateways {
  50. return routing.Gateways{}
  51. }
  52. func (t *disabledTun) Networks() []netip.Prefix {
  53. return t.vpnNetworks
  54. }
  55. func (*disabledTun) Name() string {
  56. return "disabled"
  57. }
  58. func (t *disabledTun) Read(b []byte) (int, error) {
  59. r, ok := <-t.read
  60. if !ok {
  61. return 0, io.EOF
  62. }
  63. if len(r) > len(b) {
  64. return 0, fmt.Errorf("packet larger than mtu: %d > %d bytes", len(r), len(b))
  65. }
  66. t.tx.Inc(1)
  67. if t.l.Level >= logrus.DebugLevel {
  68. t.l.WithField("raw", prettyPacket(r)).Debugf("Write payload")
  69. }
  70. return copy(b, r), nil
  71. }
  72. func (t *disabledTun) handleICMPEchoRequest(b []byte) bool {
  73. out := make([]byte, len(b))
  74. out = iputil.CreateICMPEchoResponse(b, out)
  75. if out == nil {
  76. return false
  77. }
  78. // attempt to write it, but don't block
  79. select {
  80. case t.read <- out:
  81. default:
  82. t.l.Debugf("tun_disabled: dropped ICMP Echo Reply response")
  83. }
  84. return true
  85. }
  86. func (t *disabledTun) Write(b []byte) (int, error) {
  87. t.rx.Inc(1)
  88. // Check for ICMP Echo Request before spending time doing the full parsing
  89. if t.handleICMPEchoRequest(b) {
  90. if t.l.Level >= logrus.DebugLevel {
  91. t.l.WithField("raw", prettyPacket(b)).Debugf("Disabled tun responded to ICMP Echo Request")
  92. }
  93. } else if t.l.Level >= logrus.DebugLevel {
  94. t.l.WithField("raw", prettyPacket(b)).Debugf("Disabled tun received unexpected payload")
  95. }
  96. return len(b), nil
  97. }
  98. func (t *disabledTun) SupportsMultiqueue() bool {
  99. return true
  100. }
  101. func (t *disabledTun) AllocSeg(pkt *packet.OutPacket, q int) (int, error) {
  102. return 0, fmt.Errorf("tun_disabled: AllocSeg not implemented")
  103. }
  104. func (t *disabledTun) WriteOne(x *packet.OutPacket, kick bool, q int) (int, error) {
  105. return 0, fmt.Errorf("tun_disabled: WriteOne not implemented")
  106. }
  107. func (t *disabledTun) WriteMany(x []*packet.OutPacket, q int) (int, error) {
  108. return 0, fmt.Errorf("tun_disabled: WriteMany not implemented")
  109. }
  110. func (t *disabledTun) ReadMany(b []TunPacket, _ int) (int, error) {
  111. return t.Read(b[0].GetPayload())
  112. }
  113. func (t *disabledTun) NewMultiQueueReader() (TunDev, error) {
  114. return t, nil
  115. }
  116. func (t *disabledTun) Close() error {
  117. if t.read != nil {
  118. close(t.read)
  119. t.read = nil
  120. }
  121. return nil
  122. }
  123. type prettyPacket []byte
  124. func (p prettyPacket) String() string {
  125. var s strings.Builder
  126. for i, b := range p {
  127. if i > 0 && i%8 == 0 {
  128. s.WriteString(" ")
  129. }
  130. s.WriteString(fmt.Sprintf("%02x ", b))
  131. }
  132. return s.String()
  133. }