tun_linux_offload.go 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. //go:build linux && !android && !e2e_testing
  2. // +build linux,!android,!e2e_testing
  3. package tio
  4. import (
  5. "fmt"
  6. "golang.org/x/sys/unix"
  7. "github.com/slackhq/nebula/overlay/tio/virtio"
  8. )
  9. // protoFromGSOType maps a virtio_net_hdr GSOType to the GSOProto value the
  10. // segment-time helpers use. Returns an error for GSO_NONE or any unknown
  11. // value — the caller should only invoke this on a confirmed superpacket.
  12. func protoFromGSOType(t uint8) (GSOProto, error) {
  13. switch t {
  14. case unix.VIRTIO_NET_HDR_GSO_TCPV4, unix.VIRTIO_NET_HDR_GSO_TCPV6:
  15. return GSOProtoTCP, nil
  16. case unix.VIRTIO_NET_HDR_GSO_UDP_L4:
  17. return GSOProtoUDP, nil
  18. default:
  19. return 0, fmt.Errorf("unsupported virtio gso type: %d", t)
  20. }
  21. }
  22. // SegmentSuperpacket invokes fn once per segment of pkt. For non-GSO pkts
  23. // fn is called once with pkt.Bytes (no segmentation, no copy). For GSO/USO
  24. // superpackets fn is called once per segment with a slice of pkt.Bytes
  25. // holding that segment's plaintext (a freshly-patched L3+L4 header sliced
  26. // in front of the original payload chunk). The slide is destructive: pkt is
  27. // consumed by this call and its bytes are in an undefined state when
  28. // SegmentSuperpacket returns. Callers must not retain pkt or any earlier
  29. // seg slice past fn's return for that segment. The scratch parameter is
  30. // unused on the destructive path and kept only for cross-platform
  31. // signature compatibility. Aborts and returns the first error from fn or
  32. // from per-segment construction.
  33. func SegmentSuperpacket(pkt Packet, fn func(seg []byte) error) error {
  34. if !pkt.GSO.IsSuperpacket() {
  35. return fn(pkt.Bytes)
  36. }
  37. switch pkt.GSO.Proto {
  38. case GSOProtoTCP:
  39. return virtio.SegmentTCP(pkt.Bytes, pkt.GSO.HdrLen, pkt.GSO.CsumStart, pkt.GSO.Size, fn)
  40. case GSOProtoUDP:
  41. return virtio.SegmentUDP(pkt.Bytes, pkt.GSO.HdrLen, pkt.GSO.CsumStart, pkt.GSO.Size, fn)
  42. default:
  43. return fmt.Errorf("unsupported gso proto: %d", pkt.GSO.Proto)
  44. }
  45. }