virtio_spec/
net.rs

1//! Network Device
2
3use num_enum::{FromPrimitive, IntoPrimitive, TryFromPrimitive};
4use volatile::access::ReadOnly;
5use volatile_macro::VolatileFieldAccess;
6
7pub use super::features::net::F;
8use crate::{le16, le32};
9
10endian_bitflags! {
11    /// Network Device Status Flags
12    #[doc(alias = "VIRTIO_NET_S")]
13    pub struct S: le16 {
14        #[doc(alias = "VIRTIO_NET_S_LINK_UP")]
15        const LINK_UP = 1;
16
17        #[doc(alias = "VIRTIO_NET_S_ANNOUNCE")]
18        const ANNOUNCE = 2;
19    }
20}
21
22/// Network Device Configuration Layout
23///
24/// Use [`ConfigVolatileFieldAccess`] to work with this struct.
25#[doc(alias = "virtio_net_config")]
26#[cfg_attr(
27    feature = "zerocopy",
28    derive(
29        zerocopy_derive::KnownLayout,
30        zerocopy_derive::Immutable,
31        zerocopy_derive::FromBytes,
32    )
33)]
34#[derive(VolatileFieldAccess)]
35#[repr(C)]
36pub struct Config {
37    #[access(ReadOnly)]
38    mac: [u8; 6],
39
40    #[access(ReadOnly)]
41    status: S,
42
43    #[access(ReadOnly)]
44    max_virtqueue_pairs: le16,
45
46    #[access(ReadOnly)]
47    mtu: le16,
48
49    #[access(ReadOnly)]
50    speed: le32,
51
52    #[access(ReadOnly)]
53    duplex: u8,
54
55    #[access(ReadOnly)]
56    rss_max_key_size: u8,
57
58    #[access(ReadOnly)]
59    rss_max_indirection_table_length: le16,
60
61    #[access(ReadOnly)]
62    supported_hash_types: le32,
63}
64
65virtio_bitflags! {
66    /// Network Device Header Flags
67    #[doc(alias = "VIRTIO_NET_HDR_F")]
68    pub struct HdrF: u8 {
69        #[doc(alias = "VIRTIO_NET_HDR_F_NEEDS_CSUM")]
70        const NEEDS_CSUM = 1;
71
72        #[doc(alias = "VIRTIO_NET_HDR_F_DATA_VALID")]
73        const DATA_VALID = 2;
74
75        #[doc(alias = "VIRTIO_NET_HDR_F_RSC_INFO")]
76        const RSC_INFO = 4;
77    }
78}
79
80/// Network Device Header GSO Type
81///
82/// <div class="warning">
83///
84/// This enum is not ABI-compatible with it's corresponding field.
85/// Use [`HdrGso::from`] for converting from an integer.
86///
87/// </div>
88///
89/// [`HdrGso::from`]: HdrGso#impl-From<u8>-for-HdrGso
90#[doc(alias = "VIRTIO_NET_HDR_GSO")]
91#[derive(IntoPrimitive, FromPrimitive, PartialEq, Eq, Clone, Copy, Debug)]
92#[non_exhaustive]
93#[repr(u8)]
94pub enum HdrGso {
95    #[doc(alias = "VIRTIO_NET_HDR_GSO_NONE")]
96    None = 0,
97
98    #[doc(alias = "VIRTIO_NET_HDR_GSO_TCPV4")]
99    Tcpv4 = 1,
100
101    #[doc(alias = "VIRTIO_NET_HDR_GSO_UDP")]
102    Udp = 3,
103
104    #[doc(alias = "VIRTIO_NET_HDR_GSO_TCPV6")]
105    Tcpv6 = 4,
106
107    #[doc(alias = "VIRTIO_NET_HDR_GSO_UDP_L4")]
108    UdpL4 = 5,
109
110    #[doc(alias = "VIRTIO_NET_HDR_GSO_ECN")]
111    Ecn = 0x80,
112
113    #[num_enum(catch_all)]
114    Unknown(u8),
115}
116
117/// Network Device Header
118#[doc(alias = "virtio_net_hdr")]
119#[cfg_attr(
120    feature = "zerocopy",
121    derive(
122        zerocopy_derive::KnownLayout,
123        zerocopy_derive::Immutable,
124        zerocopy_derive::FromBytes,
125        zerocopy_derive::IntoBytes,
126    )
127)]
128#[derive(Default, Clone, Copy, Debug)]
129#[repr(C)]
130pub struct Hdr {
131    pub flags: HdrF,
132    pub gso_type: u8,
133    pub hdr_len: le16,
134    pub gso_size: le16,
135    pub csum_start: le16,
136    pub csum_offset: le16,
137    pub num_buffers: le16,
138}
139
140/// Network Device Header Hash Report
141///
142/// Only if VIRTIO_NET_F_HASH_REPORT negotiated
143#[doc(alias = "virtio_net_hdr")]
144#[cfg_attr(
145    feature = "zerocopy",
146    derive(
147        zerocopy_derive::KnownLayout,
148        zerocopy_derive::Immutable,
149        zerocopy_derive::FromBytes,
150        zerocopy_derive::IntoBytes,
151    )
152)]
153#[derive(Default, Clone, Copy, Debug)]
154#[repr(C)]
155pub struct HdrHashReport {
156    /// Only if VIRTIO_NET_F_HASH_REPORT negotiated
157    pub hash_value: le32,
158    /// Only if VIRTIO_NET_F_HASH_REPORT negotiated
159    pub hash_report: le16,
160    /// Only if VIRTIO_NET_F_HASH_REPORT negotiated
161    pub padding_reserved: le16,
162}
163
164endian_bitflags! {
165    /// Hash Type
166    #[doc(alias = "VIRTIO_NET_HASH_TYPE")]
167    pub struct HashType: le32 {
168        #[doc(alias = "VIRTIO_NET_HASH_TYPE_IPv4")]
169        const IPV4 = 1 << 0;
170
171        #[doc(alias = "VIRTIO_NET_HASH_TYPE_TCPv4")]
172        const TCPV4 = 1 << 1;
173
174        #[doc(alias = "VIRTIO_NET_HASH_TYPE_UDPv4")]
175        const UDPV4 = 1 << 2;
176
177        #[doc(alias = "VIRTIO_NET_HASH_TYPE_IPv6")]
178        const IPV6 = 1 << 3;
179
180        #[doc(alias = "VIRTIO_NET_HASH_TYPE_TCPv6")]
181        const TCPV6 = 1 << 4;
182
183        #[doc(alias = "VIRTIO_NET_HASH_TYPE_UDPv6")]
184        const UDPV6 = 1 << 5;
185
186        #[doc(alias = "VIRTIO_NET_HASH_TYPE_IP_EX")]
187        const IP_EX = 1 << 6;
188
189        #[doc(alias = "VIRTIO_NET_HASH_TYPE_TCP_EX")]
190        const TCP_EX = 1 << 7;
191
192        #[doc(alias = "VIRTIO_NET_HASH_TYPE_UDP_EX")]
193        const UDP_EX = 1 << 8;
194    }
195}
196
197/// Hash Report
198///
199/// <div class="warning">
200///
201/// This enum is not ABI-compatible with it's corresponding field.
202/// Use [`HashReport::from`] for converting from an integer.
203///
204/// </div>
205///
206/// [`HashReport::from`]: HashReport#impl-From<u16>-for-HashReport
207#[doc(alias = "VIRTIO_NET_HASH_REPORT")]
208#[derive(IntoPrimitive, FromPrimitive, PartialEq, Eq, Clone, Copy, Debug)]
209#[non_exhaustive]
210#[repr(u16)]
211pub enum HashReport {
212    #[doc(alias = "VIRTIO_NET_HASH_REPORT_NONE")]
213    None = 0,
214
215    #[doc(alias = "VIRTIO_NET_HASH_REPORT_IPv4")]
216    Ipv4 = 1,
217
218    #[doc(alias = "VIRTIO_NET_HASH_REPORT_TCPv4")]
219    Tcpv4 = 2,
220
221    #[doc(alias = "VIRTIO_NET_HASH_REPORT_UDPv4")]
222    Udpv4 = 3,
223
224    #[doc(alias = "VIRTIO_NET_HASH_REPORT_IPv6")]
225    IPv6 = 4,
226
227    #[doc(alias = "VIRTIO_NET_HASH_REPORT_TCPv6")]
228    Tcpv6 = 5,
229
230    #[doc(alias = "VIRTIO_NET_HASH_REPORT_UDPv6")]
231    Udpv6 = 6,
232
233    #[doc(alias = "VIRTIO_NET_HASH_REPORT_IPv6_EX")]
234    Ipv6Ex = 7,
235
236    #[doc(alias = "VIRTIO_NET_HASH_REPORT_TCPv6_EX")]
237    Tcpv6Ex = 8,
238
239    #[doc(alias = "VIRTIO_NET_HASH_REPORT_UDPv6_EX")]
240    Udpv6Ex = 9,
241
242    #[num_enum(catch_all)]
243    Unknown(u16),
244}
245
246/// Command class
247#[doc(alias = "VIRTIO_NET_CTRL")]
248#[derive(IntoPrimitive, TryFromPrimitive, PartialEq, Eq, Clone, Copy, Debug)]
249#[non_exhaustive]
250#[repr(u8)]
251pub enum Ctrl {
252    #[doc(alias = "VIRTIO_NET_CTRL_RX")]
253    Rx = 0,
254
255    #[doc(alias = "VIRTIO_NET_CTRL_MAC")]
256    Mac = 1,
257
258    #[doc(alias = "VIRTIO_NET_CTRL_VLAN")]
259    Vlan = 2,
260
261    #[doc(alias = "VIRTIO_NET_CTRL_ANNOUNCE")]
262    Announce = 3,
263
264    #[doc(alias = "VIRTIO_NET_CTRL_MQ")]
265    Mq = 4,
266
267    #[doc(alias = "VIRTIO_NET_CTRL_GUEST_OFFLOADS")]
268    GuestOffloads = 5,
269}
270
271/// Commands
272pub mod ctrl {
273    use num_enum::{IntoPrimitive, TryFromPrimitive};
274
275    /// Packed Receive Filtering commands
276    #[doc(alias = "VIRTIO_NET_CTRL_RX")]
277    #[derive(IntoPrimitive, TryFromPrimitive, PartialEq, Eq, Clone, Copy, Debug)]
278    #[non_exhaustive]
279    #[repr(u8)]
280    pub enum Rx {
281        #[doc(alias = "VIRTIO_NET_CTRL_RX_PROMISC")]
282        Promisc = 0,
283
284        #[doc(alias = "VIRTIO_NET_CTRL_RX_ALLMULTI")]
285        Allmulti = 1,
286
287        #[doc(alias = "VIRTIO_NET_CTRL_RX_ALLUNI")]
288        Alluni = 2,
289
290        #[doc(alias = "VIRTIO_NET_CTRL_RX_NOMULTI")]
291        Nomulti = 3,
292
293        #[doc(alias = "VIRTIO_NET_CTRL_RX_NOUNI")]
294        Nouni = 4,
295
296        #[doc(alias = "VIRTIO_NET_CTRL_RX_NOBCAST")]
297        Nobcast = 5,
298    }
299
300    /// MAC Address Filtering commands
301    #[doc(alias = "VIRTIO_NET_CTRL_MAC")]
302    #[derive(IntoPrimitive, TryFromPrimitive, PartialEq, Eq, Clone, Copy, Debug)]
303    #[non_exhaustive]
304    #[repr(u8)]
305    pub enum Mac {
306        #[doc(alias = "VIRTIO_NET_CTRL_MAC_TABLE_SET")]
307        TableSet = 0,
308
309        #[doc(alias = "VIRTIO_NET_CTRL_MAC_ADDR_SET")]
310        AddrSet = 1,
311    }
312
313    /// VLAN filtering commands
314    #[doc(alias = "VIRTIO_NET_CTRL_VLAN")]
315    #[derive(IntoPrimitive, TryFromPrimitive, PartialEq, Eq, Clone, Copy, Debug)]
316    #[non_exhaustive]
317    #[repr(u8)]
318    pub enum Vlan {
319        #[doc(alias = "VIRTIO_NET_CTRL_VLAN_ADD")]
320        Add = 0,
321
322        #[doc(alias = "VIRTIO_NET_CTRL_VLAN_DEL")]
323        Del = 1,
324    }
325
326    /// Gratuitous Packet Sending commands
327    #[doc(alias = "VIRTIO_NET_CTRL_ANNOUNCE")]
328    #[derive(IntoPrimitive, TryFromPrimitive, PartialEq, Eq, Clone, Copy, Debug)]
329    #[non_exhaustive]
330    #[repr(u8)]
331    pub enum Announce {
332        #[doc(alias = "VIRTIO_NET_CTRL_ANNOUNCE_ACK")]
333        Ack = 0,
334    }
335
336    /// Multiqueue mode commands
337    #[doc(alias = "VIRTIO_NET_CTRL_MQ")]
338    #[derive(IntoPrimitive, TryFromPrimitive, PartialEq, Eq, Clone, Copy, Debug)]
339    #[non_exhaustive]
340    #[repr(u8)]
341    pub enum Mq {
342        /// For automatic receive steering
343        #[doc(alias = "VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET")]
344        VqPairsSet = 0,
345
346        /// For configurable receive steering
347        #[doc(alias = "VIRTIO_NET_CTRL_MQ_RSS_CONFIG")]
348        RssConfig = 1,
349
350        /// For configurable hash calculation
351        #[doc(alias = "VIRTIO_NET_CTRL_MQ_HASH_CONFIG")]
352        HashConfig = 2,
353    }
354
355    /// Setting Offloads State commands
356    #[doc(alias = "VIRTIO_NET_CTRL_GUEST_OFFLOADS")]
357    #[derive(IntoPrimitive, TryFromPrimitive, PartialEq, Eq, Clone, Copy, Debug)]
358    #[non_exhaustive]
359    #[repr(u8)]
360    pub enum GuestOffloads {
361        #[doc(alias = "VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET")]
362        Set = 0,
363    }
364}