device.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. package overlay
  2. import (
  3. "io"
  4. "net/netip"
  5. "sync"
  6. "github.com/slackhq/nebula/routing"
  7. )
  8. type Device interface {
  9. io.ReadWriteCloser
  10. Activate() error
  11. Networks() []netip.Prefix
  12. Name() string
  13. RoutesFor(netip.Addr) routing.Gateways
  14. NewMultiQueueReader() (io.ReadWriteCloser, error)
  15. }
  16. // Packet represents a single packet buffer with optional headroom to carry
  17. // metadata (for example virtio-net headers).
  18. type Packet struct {
  19. Buf []byte
  20. Offset int
  21. Len int
  22. release func()
  23. }
  24. func (p *Packet) Payload() []byte {
  25. return p.Buf[p.Offset : p.Offset+p.Len]
  26. }
  27. func (p *Packet) Reset() {
  28. p.Len = 0
  29. p.Offset = 0
  30. p.release = nil
  31. }
  32. func (p *Packet) Release() {
  33. if p.release != nil {
  34. p.release()
  35. p.release = nil
  36. }
  37. }
  38. func (p *Packet) Capacity() int {
  39. return len(p.Buf) - p.Offset
  40. }
  41. // PacketPool manages reusable buffers with headroom.
  42. type PacketPool struct {
  43. headroom int
  44. blksz int
  45. pool sync.Pool
  46. }
  47. func NewPacketPool(headroom, payload int) *PacketPool {
  48. p := &PacketPool{headroom: headroom, blksz: headroom + payload}
  49. p.pool.New = func() any {
  50. buf := make([]byte, p.blksz)
  51. return &Packet{Buf: buf, Offset: headroom}
  52. }
  53. return p
  54. }
  55. func (p *PacketPool) Get() *Packet {
  56. pkt := p.pool.Get().(*Packet)
  57. pkt.Offset = p.headroom
  58. pkt.Len = 0
  59. pkt.release = func() { p.put(pkt) }
  60. return pkt
  61. }
  62. func (p *PacketPool) put(pkt *Packet) {
  63. pkt.Reset()
  64. p.pool.Put(pkt)
  65. }
  66. // BatchReader allows reading multiple packets into a shared pool with
  67. // preallocated headroom (e.g. virtio-net headers).
  68. type BatchReader interface {
  69. ReadIntoBatch(pool *PacketPool) ([]*Packet, error)
  70. }
  71. // BatchWriter writes a slice of packets that carry their own metadata.
  72. type BatchWriter interface {
  73. WriteBatch(packets []*Packet) (int, error)
  74. }
  75. // BatchCapableDevice describes a device that can efficiently read and write
  76. // batches of packets with virtio headroom.
  77. type BatchCapableDevice interface {
  78. Device
  79. BatchReader
  80. BatchWriter
  81. BatchHeadroom() int
  82. BatchPayloadCap() int
  83. BatchSize() int
  84. }