vnethdr_linux.go 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839
  1. package tio
  2. import "encoding/binary"
  3. // Size of the legacy struct virtio_net_hdr that the kernel prepends/expects on
  4. // a TUN opened with IFF_VNET_HDR (TUNSETVNETHDRSZ not set).
  5. const virtioNetHdrLen = 10
  6. type VirtioNetHdr struct {
  7. Flags uint8
  8. GSOType uint8
  9. HdrLen uint16
  10. GSOSize uint16
  11. CsumStart uint16
  12. CsumOffset uint16
  13. }
  14. // decode reads a virtio_net_hdr in host byte order (TUN default; we never
  15. // call TUNSETVNETLE so the kernel matches our endianness).
  16. func (h *VirtioNetHdr) decode(b []byte) {
  17. h.Flags = b[0]
  18. h.GSOType = b[1]
  19. h.HdrLen = binary.NativeEndian.Uint16(b[2:4])
  20. h.GSOSize = binary.NativeEndian.Uint16(b[4:6])
  21. h.CsumStart = binary.NativeEndian.Uint16(b[6:8])
  22. h.CsumOffset = binary.NativeEndian.Uint16(b[8:10])
  23. }
  24. // encode is the inverse of decode: writes the virtio_net_hdr fields into b
  25. // (must be at least virtioNetHdrLen bytes). Used to emit a TSO superpacket
  26. // on egress.
  27. func (h *VirtioNetHdr) encode(b []byte) {
  28. b[0] = h.Flags
  29. b[1] = h.GSOType
  30. binary.NativeEndian.PutUint16(b[2:4], h.HdrLen)
  31. binary.NativeEndian.PutUint16(b[4:6], h.GSOSize)
  32. binary.NativeEndian.PutUint16(b[6:8], h.CsumStart)
  33. binary.NativeEndian.PutUint16(b[8:10], h.CsumOffset)
  34. }