| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859 |
- //go:build linux && !android
- package tio
- import (
- "fmt"
- "golang.org/x/sys/unix"
- "github.com/slackhq/nebula/overlay/tio/virtio"
- )
- // protoFromGSOType maps a virtio_net_hdr gsoType to the GSOProto value the
- // segment-time helpers use. Returns an error for GSO_NONE or any unknown
- // value. The caller should only invoke this on a confirmed superpacket.
- func protoFromGSOType(t uint8) (GSOProto, error) {
- switch t &^ unix.VIRTIO_NET_HDR_GSO_ECN {
- case unix.VIRTIO_NET_HDR_GSO_TCPV4, unix.VIRTIO_NET_HDR_GSO_TCPV6:
- return GSOProtoTCP, nil
- case unix.VIRTIO_NET_HDR_GSO_UDP_L4:
- return GSOProtoUDP, nil
- default:
- return 0, fmt.Errorf("unsupported virtio gso type: %d", t)
- }
- }
- // gsoTypeFromProto is the reverse of protoFromGSOType
- func gsoTypeFromProto(proto GSOProto, ipVer uint8) uint8 {
- switch {
- case proto == GSOProtoUDP && (ipVer == 4 || ipVer == 6):
- return unix.VIRTIO_NET_HDR_GSO_UDP_L4
- case ipVer == 6:
- return unix.VIRTIO_NET_HDR_GSO_TCPV6
- case ipVer == 4:
- return unix.VIRTIO_NET_HDR_GSO_TCPV4
- default:
- return unix.VIRTIO_NET_HDR_GSO_NONE
- }
- }
- // SegmentSuperpacket invokes fn once per segment of pkt.
- // For non-GSO pkts fn is called once with pkt.Bytes.
- // For GSO/USO superpackets, fn is called once per segment with a slice of pkt.Bytes holding that segment's plaintext
- // (a freshly-patched L3+L4 header sliced in front of the original payload chunk).
- // This slicing is destructive: pkt is consumed by this call.
- // Aborts and returns the first error from fn or from per-segment construction.
- func SegmentSuperpacket(pkt Packet, fn func(seg []byte) error) error {
- if !pkt.GSO.IsSuperpacket() {
- return fn(pkt.Bytes)
- }
- switch pkt.GSO.Proto {
- case GSOProtoTCP:
- return virtio.SegmentTCP(pkt.Bytes, pkt.GSO.HdrLen, pkt.GSO.CsumStart, pkt.GSO.Size, fn)
- case GSOProtoUDP:
- return virtio.SegmentUDP(pkt.Bytes, pkt.GSO.HdrLen, pkt.GSO.CsumStart, pkt.GSO.Size, fn)
- default:
- return fmt.Errorf("unsupported gso proto: %d", pkt.GSO.Proto)
- }
- }
|