device.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. package overlay
  2. import (
  3. "io"
  4. "net/netip"
  5. "github.com/slackhq/nebula/routing"
  6. )
  7. // defaultBatchBufSize is the per-Queue scratch size for Read on backends
  8. // that don't do TSO segmentation. 65535 covers any single IP packet.
  9. const defaultBatchBufSize = 65535
  10. // Queue is a readable/writable tun queue. One Queue is driven by a single
  11. // read goroutine plus concurrent writers (see Write / WriteReject below).
  12. type Queue interface {
  13. io.Closer
  14. // Read returns one or more packets. The returned slices are borrowed
  15. // from the Queue's internal buffer and are only valid until the next
  16. // Read or Close on this Queue — callers must encrypt or copy each
  17. // slice before the next call. Not safe for concurrent Reads; exactly
  18. // one goroutine per Queue reads.
  19. Read() ([][]byte, error)
  20. // Write emits a single packet on the plaintext (outside→inside)
  21. // delivery path. May run concurrently with WriteReject on the same
  22. // Queue, but not with itself.
  23. Write(p []byte) (int, error)
  24. // WriteReject writes a single packet that originated from the inside
  25. // path (reject replies or self-forward) using scratch state distinct
  26. // from Write, so it can run concurrently with Write on the same Queue
  27. // without a data race. On backends without a shared-scratch Write, a
  28. // trivial delegation to Write is acceptable.
  29. WriteReject(p []byte) (int, error)
  30. }
  31. type Device interface {
  32. Queue
  33. Activate() error
  34. Networks() []netip.Prefix
  35. Name() string
  36. RoutesFor(netip.Addr) routing.Gateways
  37. SupportsMultiqueue() bool
  38. NewMultiQueueReader() (Queue, error)
  39. }
  40. // GSOWriter is implemented by Queues that can emit a TCP TSO superpacket
  41. // assembled from a header prefix plus one or more borrowed payload
  42. // fragments, in a single vectored write (writev with a leading
  43. // virtio_net_hdr). This lets the coalescer avoid copying payload bytes
  44. // between the caller's decrypt buffer and the TUN. Backends without GSO
  45. // support return false from GSOSupported and coalescing is skipped.
  46. //
  47. // hdr contains the IPv4/IPv6 + TCP header prefix (mutable — callers will
  48. // have filled in total length and pseudo-header partial). pays are
  49. // non-overlapping payload fragments whose concatenation is the full
  50. // superpacket payload; they are read-only from the writer's perspective
  51. // and must remain valid until the call returns. gsoSize is the MSS:
  52. // every segment except possibly the last is exactly that many bytes.
  53. // csumStart is the byte offset where the TCP header begins within hdr.
  54. //
  55. // hdr's TCP checksum field must already hold the pseudo-header partial
  56. // sum (single-fold, not inverted), per virtio NEEDS_CSUM semantics.
  57. type GSOWriter interface {
  58. WriteGSO(hdr []byte, pays [][]byte, gsoSize uint16, isV6 bool, csumStart uint16) error
  59. GSOSupported() bool
  60. }