In particular, the virtio header always has the u16 num_buffers field. We define a new 'struct virtio_net_hdr_v1' for this (rather than simply calling it 'struct virtio_net_hdr', to avoid nasty type errors if some parts of a project define VIRTIO_NET_NO_LEGACY and some don't. Transitional devices (which can't define VIRTIO_NET_NO_LEGACY) will have to keep using struct virtio_net_hdr_mrg_rxbuf, which has the same byte layout as struct virtio_net_hdr_v1.
Showing the changes to include/uapi/linux (1 of 1 file). Show all
Unified · Split
| @@ -35,7 +35,6 @@ · 34 unmodified lines | ||
| 35 | 35 | #define VIRTIO_NET_F_CSUM 0 /* Host handles pkts w/ partial csum */ |
| 36 | 36 | #define VIRTIO_NET_F_GUEST_CSUM 1 /* Guest handles pkts w/ partial csum */ |
| 37 | 37 | #define VIRTIO_NET_F_MAC 5 /* Host has given MAC address. */ |
| 38 | −#define VIRTIO_NET_F_GSO 6 /* Host handles pkts w/ any GSO type */ | |
| 39 | 38 | #define VIRTIO_NET_F_GUEST_TSO4 7 /* Guest can handle TSOv4 in. */ |
| 40 | 39 | #define VIRTIO_NET_F_GUEST_TSO6 8 /* Guest can handle TSOv6 in. */ |
| 41 | 40 | #define VIRTIO_NET_F_GUEST_ECN 9 /* Guest can handle TSO[6] w/ ECN in. */ |
| @@ -56,6 +55,10 @@ · 14 unmodified lines | ||
| 56 | 55 | * Steering */ |
| 57 | 56 | #define VIRTIO_NET_F_CTRL_MAC_ADDR 23 /* Set MAC address */ |
| 58 | 57 | |
| 58 | +#ifndef VIRTIO_NET_NO_LEGACY | |
| 59 | +#define VIRTIO_NET_F_GSO 6 /* Host handles pkts w/ any GSO type */ | |
| 60 | +#endif /* VIRTIO_NET_NO_LEGACY */ | |
| 61 | + | |
| 59 | 62 | #define VIRTIO_NET_S_LINK_UP 1 /* Link is up */ |
| 60 | 63 | #define VIRTIO_NET_S_ANNOUNCE 2 /* Announcement is needed */ |
| 61 | 64 | |
| @@ -71,8 +74,9 @@ struct virtio_net_config { · 9 unmodified lines | ||
| 71 | 74 | __u16 max_virtqueue_pairs; |
| 72 | 75 | } __attribute__((packed)); |
| 73 | 76 | |
| 77 | +#ifndef VIRTIO_NET_NO_LEGACY | |
| 74 | 78 | /* This header comes first in the scatter-gather list. |
| 75 | − * If VIRTIO_F_ANY_LAYOUT is not negotiated, it must | |
| 79 | + * For legacy virtio, if VIRTIO_F_ANY_LAYOUT is not negotiated, it must | |
| 76 | 80 | * be the first element of the scatter-gather list. If you don't |
| 77 | 81 | * specify GSO or CSUM features, you can simply ignore the header. */ |
| 78 | 82 | struct virtio_net_hdr { |
| @@ -97,6 +101,30 @@ struct virtio_net_hdr_mrg_rxbuf { · 18 unmodified lines | ||
| 97 | 101 | struct virtio_net_hdr hdr; |
| 98 | 102 | __virtio16 num_buffers; /* Number of merged rx buffers */ |
| 99 | 103 | }; |
| 104 | +#else /* ... VIRTIO_NET_NO_LEGACY */ | |
| 105 | +/* | |
| 106 | + * This header comes first in the scatter-gather list. If you don't | |
| 107 | + * specify GSO or CSUM features, you can simply ignore the header. | |
| 108 | + * | |
| 109 | + * This is bitwise-equivalent to the legacy struct virtio_net_hdr_mrg_rxbuf. | |
| 110 | + */ | |
| 111 | +struct virtio_net_hdr_v1 { | |
| 112 | +#define VIRTIO_NET_HDR_F_NEEDS_CSUM 1 /* Use csum_start, csum_offset */ | |
| 113 | +#define VIRTIO_NET_HDR_F_DATA_VALID 2 /* Csum is valid */ | |
| 114 | + __u8 flags; | |
| 115 | +#define VIRTIO_NET_HDR_GSO_NONE 0 /* Not a GSO frame */ | |
| 116 | +#define VIRTIO_NET_HDR_GSO_TCPV4 1 /* GSO frame, IPv4 TCP (TSO) */ | |
| 117 | +#define VIRTIO_NET_HDR_GSO_UDP 3 /* GSO frame, IPv4 UDP (UFO) */ | |
| 118 | +#define VIRTIO_NET_HDR_GSO_TCPV6 4 /* GSO frame, IPv6 TCP */ | |
| 119 | +#define VIRTIO_NET_HDR_GSO_ECN 0x80 /* TCP has ECN set */ | |
| 120 | + __u8 gso_type; | |
| 121 | + __virtio16 hdr_len; /* Ethernet + IP + tcp/udp hdrs */ | |
| 122 | + __virtio16 gso_size; /* Bytes to append to hdr_len per frame */ | |
| 123 | + __virtio16 csum_start; /* Position to start checksumming from */ | |
| 124 | + __virtio16 csum_offset; /* Offset after that to place checksum */ | |
| 125 | + __virtio16 num_buffers; /* Number of merged rx buffers */ | |
| 126 | +}; | |
| 127 | +#endif /* ...VIRTIO_NET_NO_LEGACY */ | |
| 100 | 128 | |
| 101 | 129 | /* |
| 102 | 130 | * Control virtqueue data structures |