1 // Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 //
3 // SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
4 
5 //! Vsock packet abstraction.
6 //!
7 //! This module provides the following abstraction for parsing a vsock packet, and working with it:
8 //!
9 //! - [`VsockPacket`](struct.VsockPacket.html) which handles the parsing of the vsock packet from
10 //! either a TX descriptor chain via
11 //! [`VsockPacket::from_tx_virtq_chain`](struct.VsockPacket.html#method.from_tx_virtq_chain), or an
12 //! RX descriptor chain via
13 //! [`VsockPacket::from_rx_virtq_chain`](struct.VsockPacket.html#method.from_rx_virtq_chain).
14 //! The virtio vsock packet is defined in the standard as having a header of type `virtio_vsock_hdr`
15 //! and an optional `data` array of bytes. The methods mentioned above assume that both packet
16 //! elements are on the same descriptor, or each of the packet elements occupies exactly one
17 //! descriptor. For the usual drivers, this assumption stands,
18 //! but in the future we might make the implementation more generic by removing any constraint
19 //! regarding the number of descriptors that correspond to the header/data. The buffers associated
20 //! to the TX virtio queue are device-readable, and the ones associated to the RX virtio queue are
21 //! device-writable.
22 ///
23 /// The `VsockPacket` abstraction is using vm-memory's `VolatileSlice` for representing the header
24 /// and the data. `VolatileSlice` is a safe wrapper over a raw pointer, which also handles the dirty
25 /// page tracking behind the scenes. A limitation of the current implementation is that it does not
26 /// cover the scenario where the header or data buffer doesn't fit in a single `VolatileSlice`
27 /// because the guest memory regions of the buffer are contiguous in the guest physical address
28 /// space, but not in the host virtual one as well. If this becomes an use case, we can extend this
29 /// solution to use an array of `VolatileSlice`s for the header and data.
30 /// The `VsockPacket` abstraction is also storing a `virtio_vsock_hdr` instance (which is defined
31 /// here as `PacketHeader`). This is needed so that we always access the same data that was read the
32 /// first time from the descriptor chain. We avoid this way potential time-of-check time-of-use
33 /// problems that may occur when reading later a header field from the underlying memory itself
34 /// (i.e. from the header's `VolatileSlice` object).
35 use std::fmt::{self, Display};
36 use std::ops::Deref;
37 
38 use virtio_queue::DescriptorChain;
39 use vm_memory::bitmap::{BitmapSlice, WithBitmapSlice};
40 use vm_memory::{
41     Address, ByteValued, Bytes, GuestMemory, GuestMemoryError, GuestMemoryRegion, Le16, Le32, Le64,
42     VolatileMemoryError, VolatileSlice,
43 };
44 
45 /// Vsock packet parsing errors.
46 #[derive(Debug)]
47 pub enum Error {
48     /// Too few descriptors in a descriptor chain.
49     DescriptorChainTooShort,
50     /// Descriptor that was too short to use.
51     DescriptorLengthTooSmall,
52     /// Descriptor that was too long to use.
53     DescriptorLengthTooLong,
54     /// The slice for creating a header has an invalid length.
55     InvalidHeaderInputSize(usize),
56     /// The `len` header field value exceeds the maximum allowed data size.
57     InvalidHeaderLen(u32),
58     /// Invalid guest memory access.
59     InvalidMemoryAccess(GuestMemoryError),
60     /// Invalid volatile memory access.
61     InvalidVolatileAccess(VolatileMemoryError),
62     /// Read only descriptor that protocol says to write to.
63     UnexpectedReadOnlyDescriptor,
64     /// Write only descriptor that protocol says to read from.
65     UnexpectedWriteOnlyDescriptor,
66 }
67 
68 impl std::error::Error for Error {}
69 
70 impl Display for Error {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result71     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
72         match self {
73             Error::DescriptorChainTooShort => {
74                 write!(f, "There are not enough descriptors in the chain.")
75             }
76             Error::DescriptorLengthTooSmall => write!(
77                 f,
78                 "The descriptor is pointing to a buffer that has a smaller length than expected."
79             ),
80             Error::DescriptorLengthTooLong => write!(
81                 f,
82                 "The descriptor is pointing to a buffer that has a longer length than expected."
83             ),
84             Error::InvalidHeaderInputSize(size) => {
85                 write!(f, "Invalid header input size: {}", size)
86             }
87             Error::InvalidHeaderLen(size) => {
88                 write!(f, "Invalid header `len` field value: {}", size)
89             }
90             Error::InvalidMemoryAccess(error) => {
91                 write!(f, "Invalid guest memory access: {}", error)
92             }
93             Error::InvalidVolatileAccess(error) => {
94                 write!(f, "Invalid volatile memory access: {}", error)
95             }
96             Error::UnexpectedReadOnlyDescriptor => {
97                 write!(f, "Unexpected read-only descriptor.")
98             }
99             Error::UnexpectedWriteOnlyDescriptor => {
100                 write!(f, "Unexpected write-only descriptor.")
101             }
102         }
103     }
104 }
105 
106 #[repr(C, packed)]
107 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
108 /// The vsock packet header structure.
109 pub struct PacketHeader {
110     src_cid: Le64,
111     dst_cid: Le64,
112     src_port: Le32,
113     dst_port: Le32,
114     len: Le32,
115     type_: Le16,
116     op: Le16,
117     flags: Le32,
118     buf_alloc: Le32,
119     fwd_cnt: Le32,
120 }
121 
122 // SAFETY: This is safe because `PacketHeader` contains only wrappers over POD types
123 // and all accesses through safe `vm-memory` API will validate any garbage that could
124 // be included in there.
125 unsafe impl ByteValued for PacketHeader {}
126 //
127 // This structure will occupy the buffer pointed to by the head of the descriptor chain. Below are
128 // the offsets for each field, as well as the packed structure size.
129 // Note that these offsets are only used privately by the `VsockPacket` struct, the public interface
130 // consisting of getter and setter methods, for each struct field, that will also handle the correct
131 // endianness.
132 
133 /// The size of the header structure (when packed).
134 pub const PKT_HEADER_SIZE: usize = std::mem::size_of::<PacketHeader>();
135 
136 // Offsets of the header fields.
137 const SRC_CID_OFFSET: usize = 0;
138 const DST_CID_OFFSET: usize = 8;
139 const SRC_PORT_OFFSET: usize = 16;
140 const DST_PORT_OFFSET: usize = 20;
141 const LEN_OFFSET: usize = 24;
142 const TYPE_OFFSET: usize = 28;
143 const OP_OFFSET: usize = 30;
144 const FLAGS_OFFSET: usize = 32;
145 const BUF_ALLOC_OFFSET: usize = 36;
146 const FWD_CNT_OFFSET: usize = 40;
147 
148 /// Dedicated [`Result`](https://doc.rust-lang.org/std/result/) type.
149 pub type Result<T> = std::result::Result<T, Error>;
150 
151 /// The vsock packet, implemented as a wrapper over a virtio descriptor chain:
152 /// - the chain head, holding the packet header;
153 /// - an optional data/buffer descriptor, only present for data packets (for VSOCK_OP_RW requests).
154 #[derive(Debug)]
155 pub struct VsockPacket<'a, B: BitmapSlice> {
156     // When writing to the header slice, we are using the `write` method of `VolatileSlice`s Bytes
157     // implementation. Because that can only return an error if we pass an invalid offset, we can
158     // safely use `unwraps` in the setters below. If we switch to a type different than
159     // `VolatileSlice`, this assumption can no longer hold. We also must always make sure the
160     // `VsockPacket` API is creating headers with PKT_HEADER_SIZE size.
161     header_slice: VolatileSlice<'a, B>,
162     header: PacketHeader,
163     data_slice: Option<VolatileSlice<'a, B>>,
164 }
165 
166 // This macro is intended to be used for setting a header field in both the `VolatileSlice` and the
167 // `PacketHeader` structure from a packet. `$offset` should be a valid offset in the `header_slice`,
168 // otherwise the macro will panic.
169 macro_rules! set_header_field {
170     ($packet:ident, $field:ident, $offset:ident, $value:ident) => {
171         $packet.header.$field = $value.into();
172         $packet
173             .header_slice
174             .write(&$value.to_le_bytes(), $offset)
175             // This unwrap is safe only if `$offset` is a valid offset in the `header_slice`.
176             .unwrap();
177     };
178 }
179 
180 impl<'a, B: BitmapSlice> VsockPacket<'a, B> {
181     /// Return a reference to the `header_slice` of the packet.
header_slice(&self) -> &VolatileSlice<'a, B>182     pub fn header_slice(&self) -> &VolatileSlice<'a, B> {
183         &self.header_slice
184     }
185 
186     /// Return a reference to the `data_slice` of the packet.
data_slice(&self) -> Option<&VolatileSlice<'a, B>>187     pub fn data_slice(&self) -> Option<&VolatileSlice<'a, B>> {
188         self.data_slice.as_ref()
189     }
190 
191     /// Write to the packet header from an input of raw bytes.
192     ///
193     /// # Example
194     ///
195     /// ```rust
196     /// # use virtio_bindings::bindings::virtio_ring::VRING_DESC_F_WRITE;
197     /// # use virtio_queue::mock::MockSplitQueue;
198     /// # use virtio_queue::{Descriptor, Queue, QueueT};
199     /// use virtio_vsock::packet::{VsockPacket, PKT_HEADER_SIZE};
200     /// # use vm_memory::{Bytes, GuestAddress, GuestAddressSpace, GuestMemoryMmap};
201     ///
202     /// const MAX_PKT_BUF_SIZE: u32 = 64 * 1024;
203     ///
204     /// # fn create_queue_with_chain(m: &GuestMemoryMmap) -> Queue {
205     /// #     let vq = MockSplitQueue::new(m, 16);
206     /// #     let mut q = vq.create_queue().unwrap();
207     /// #
208     /// #     let v = vec![
209     /// #         Descriptor::new(0x5_0000, 0x100, VRING_DESC_F_WRITE as u16, 0),
210     /// #         Descriptor::new(0x8_0000, 0x100, VRING_DESC_F_WRITE as u16, 0),
211     /// #     ];
212     /// #     let mut chain = vq.build_desc_chain(&v);
213     /// #     q
214     /// # }
215     /// let mem = GuestMemoryMmap::<()>::from_ranges(&[(GuestAddress(0), 0x10_0000)]).unwrap();
216     /// // Create a queue and populate it with a descriptor chain.
217     /// let mut queue = create_queue_with_chain(&mem);
218     ///
219     /// while let Some(mut head) = queue.pop_descriptor_chain(&mem) {
220     ///     let mut pkt = VsockPacket::from_rx_virtq_chain(&mem, &mut head, MAX_PKT_BUF_SIZE).unwrap();
221     ///     pkt.set_header_from_raw(&[0u8; PKT_HEADER_SIZE]).unwrap();
222     /// }
223     /// ```
set_header_from_raw(&mut self, bytes: &[u8]) -> Result<()>224     pub fn set_header_from_raw(&mut self, bytes: &[u8]) -> Result<()> {
225         if bytes.len() != PKT_HEADER_SIZE {
226             return Err(Error::InvalidHeaderInputSize(bytes.len()));
227         }
228         self.header_slice
229             .write(bytes, 0)
230             .map_err(Error::InvalidVolatileAccess)?;
231         let header = self
232             .header_slice()
233             .read_obj::<PacketHeader>(0)
234             .map_err(Error::InvalidVolatileAccess)?;
235         self.header = header;
236         Ok(())
237     }
238 
239     /// Return the `src_cid` of the header.
src_cid(&self) -> u64240     pub fn src_cid(&self) -> u64 {
241         self.header.src_cid.into()
242     }
243 
244     /// Set the `src_cid` of the header.
set_src_cid(&mut self, cid: u64) -> &mut Self245     pub fn set_src_cid(&mut self, cid: u64) -> &mut Self {
246         set_header_field!(self, src_cid, SRC_CID_OFFSET, cid);
247         self
248     }
249 
250     /// Return the `dst_cid` of the header.
dst_cid(&self) -> u64251     pub fn dst_cid(&self) -> u64 {
252         self.header.dst_cid.into()
253     }
254 
255     /// Set the `dst_cid` of the header.
set_dst_cid(&mut self, cid: u64) -> &mut Self256     pub fn set_dst_cid(&mut self, cid: u64) -> &mut Self {
257         set_header_field!(self, dst_cid, DST_CID_OFFSET, cid);
258         self
259     }
260 
261     /// Return the `src_port` of the header.
src_port(&self) -> u32262     pub fn src_port(&self) -> u32 {
263         self.header.src_port.into()
264     }
265 
266     /// Set the `src_port` of the header.
set_src_port(&mut self, port: u32) -> &mut Self267     pub fn set_src_port(&mut self, port: u32) -> &mut Self {
268         set_header_field!(self, src_port, SRC_PORT_OFFSET, port);
269         self
270     }
271 
272     /// Return the `dst_port` of the header.
dst_port(&self) -> u32273     pub fn dst_port(&self) -> u32 {
274         self.header.dst_port.into()
275     }
276 
277     /// Set the `dst_port` of the header.
set_dst_port(&mut self, port: u32) -> &mut Self278     pub fn set_dst_port(&mut self, port: u32) -> &mut Self {
279         set_header_field!(self, dst_port, DST_PORT_OFFSET, port);
280         self
281     }
282 
283     /// Return the `len` of the header.
len(&self) -> u32284     pub fn len(&self) -> u32 {
285         self.header.len.into()
286     }
287 
288     /// Returns whether the `len` field of the header is 0 or not.
is_empty(&self) -> bool289     pub fn is_empty(&self) -> bool {
290         self.len() == 0
291     }
292 
293     /// Set the `len` of the header.
set_len(&mut self, len: u32) -> &mut Self294     pub fn set_len(&mut self, len: u32) -> &mut Self {
295         set_header_field!(self, len, LEN_OFFSET, len);
296         self
297     }
298 
299     /// Return the `type` of the header.
type_(&self) -> u16300     pub fn type_(&self) -> u16 {
301         self.header.type_.into()
302     }
303 
304     /// Set the `type` of the header.
set_type(&mut self, type_: u16) -> &mut Self305     pub fn set_type(&mut self, type_: u16) -> &mut Self {
306         set_header_field!(self, type_, TYPE_OFFSET, type_);
307         self
308     }
309 
310     /// Return the `op` of the header.
op(&self) -> u16311     pub fn op(&self) -> u16 {
312         self.header.op.into()
313     }
314 
315     /// Set the `op` of the header.
set_op(&mut self, op: u16) -> &mut Self316     pub fn set_op(&mut self, op: u16) -> &mut Self {
317         set_header_field!(self, op, OP_OFFSET, op);
318         self
319     }
320 
321     /// Return the `flags` of the header.
flags(&self) -> u32322     pub fn flags(&self) -> u32 {
323         self.header.flags.into()
324     }
325 
326     /// Set the `flags` of the header.
set_flags(&mut self, flags: u32) -> &mut Self327     pub fn set_flags(&mut self, flags: u32) -> &mut Self {
328         set_header_field!(self, flags, FLAGS_OFFSET, flags);
329         self
330     }
331 
332     /// Set a specific flag of the header.
set_flag(&mut self, flag: u32) -> &mut Self333     pub fn set_flag(&mut self, flag: u32) -> &mut Self {
334         self.set_flags(self.flags() | flag);
335         self
336     }
337 
338     /// Return the `buf_alloc` of the header.
buf_alloc(&self) -> u32339     pub fn buf_alloc(&self) -> u32 {
340         self.header.buf_alloc.into()
341     }
342 
343     /// Set the `buf_alloc` of the header.
set_buf_alloc(&mut self, buf_alloc: u32) -> &mut Self344     pub fn set_buf_alloc(&mut self, buf_alloc: u32) -> &mut Self {
345         set_header_field!(self, buf_alloc, BUF_ALLOC_OFFSET, buf_alloc);
346         self
347     }
348 
349     /// Return the `fwd_cnt` of the header.
fwd_cnt(&self) -> u32350     pub fn fwd_cnt(&self) -> u32 {
351         self.header.fwd_cnt.into()
352     }
353 
354     /// Set the `fwd_cnt` of the header.
set_fwd_cnt(&mut self, fwd_cnt: u32) -> &mut Self355     pub fn set_fwd_cnt(&mut self, fwd_cnt: u32) -> &mut Self {
356         set_header_field!(self, fwd_cnt, FWD_CNT_OFFSET, fwd_cnt);
357         self
358     }
359 
360     /// Create the packet wrapper from a TX chain.
361     ///
362     /// The chain head is expected to hold a valid packet header. A following packet data
363     /// descriptor can optionally end the chain.
364     ///
365     /// # Arguments
366     /// * `mem` - the `GuestMemory` object that can be used to access the queue buffers.
367     /// * `desc_chain` - the descriptor chain corresponding to a packet.
368     /// * `max_data_size` - the maximum size allowed for the packet payload, that was negotiated
369     ///                     between the device and the driver. Tracking issue for defining this
370     ///                     feature in virtio-spec
371     ///                     [here](https://github.com/oasis-tcs/virtio-spec/issues/140).
372     ///
373     /// # Example
374     ///
375     /// ```rust
376     /// # use virtio_queue::mock::MockSplitQueue;
377     /// # use virtio_queue::{Descriptor, Queue, QueueT};
378     /// use virtio_vsock::packet::{VsockPacket, PKT_HEADER_SIZE};
379     /// # use vm_memory::{Bytes, GuestAddress, GuestAddressSpace, GuestMemoryMmap};
380     ///
381     /// const MAX_PKT_BUF_SIZE: u32 = 64 * 1024;
382     /// const OP_RW: u16 = 5;
383     ///
384     /// # fn create_queue_with_chain(m: &GuestMemoryMmap) -> Queue {
385     /// #     let vq = MockSplitQueue::new(m, 16);
386     /// #     let mut q = vq.create_queue().unwrap();
387     /// #
388     /// #     let v = vec![
389     /// #         Descriptor::new(0x5_0000, 0x100, 0, 0),
390     /// #         Descriptor::new(0x8_0000, 0x100, 0, 0),
391     /// #     ];
392     /// #     let mut chain = vq.build_desc_chain(&v);
393     /// #     q
394     /// # }
395     /// let mem = GuestMemoryMmap::<()>::from_ranges(&[(GuestAddress(0), 0x10000)]).unwrap();
396     /// // Create a queue and populate it with a descriptor chain.
397     /// let mut queue = create_queue_with_chain(&mem);
398     ///
399     /// while let Some(mut head) = queue.pop_descriptor_chain(&mem) {
400     ///     let pkt = match VsockPacket::from_tx_virtq_chain(&mem, &mut head, MAX_PKT_BUF_SIZE) {
401     ///         Ok(pkt) => pkt,
402     ///         Err(_e) => {
403     ///             // Do some error handling.
404     ///             queue.add_used(&mem, head.head_index(), 0);
405     ///             continue;
406     ///         }
407     ///     };
408     ///     // Here we would send the packet to the backend. Depending on the operation type, a
409     ///     // different type of action will be done.
410     ///
411     ///     // For example, if it's a RW packet, we will forward the packet payload to the backend.
412     ///     if pkt.op() == OP_RW {
413     ///         // Send the packet payload to the backend.
414     ///     }
415     ///     queue.add_used(&mem, head.head_index(), 0);
416     /// }
417     /// ```
from_tx_virtq_chain<M, T>( mem: &'a M, desc_chain: &mut DescriptorChain<T>, max_data_size: u32, ) -> Result<Self> where M: GuestMemory, <<M as GuestMemory>::R as GuestMemoryRegion>::B: WithBitmapSlice<'a, S = B>, T: Deref, T::Target: GuestMemory,418     pub fn from_tx_virtq_chain<M, T>(
419         mem: &'a M,
420         desc_chain: &mut DescriptorChain<T>,
421         max_data_size: u32,
422     ) -> Result<Self>
423     where
424         M: GuestMemory,
425         <<M as GuestMemory>::R as GuestMemoryRegion>::B: WithBitmapSlice<'a, S = B>,
426         T: Deref,
427         T::Target: GuestMemory,
428     {
429         let chain_head = desc_chain.next().ok_or(Error::DescriptorChainTooShort)?;
430         // All TX buffers must be device-readable.
431         if chain_head.is_write_only() {
432             return Err(Error::UnexpectedWriteOnlyDescriptor);
433         }
434 
435         // The packet header should fit inside the buffer corresponding to the head descriptor.
436         if (chain_head.len() as usize) < PKT_HEADER_SIZE {
437             return Err(Error::DescriptorLengthTooSmall);
438         }
439 
440         let header_slice = mem
441             .get_slice(chain_head.addr(), PKT_HEADER_SIZE)
442             .map_err(Error::InvalidMemoryAccess)?;
443 
444         let header = mem
445             .read_obj(chain_head.addr())
446             .map_err(Error::InvalidMemoryAccess)?;
447 
448         let mut pkt = Self {
449             header_slice,
450             header,
451             data_slice: None,
452         };
453 
454         // If the `len` field of the header is zero, then the packet doesn't have a `data` element.
455         if pkt.is_empty() {
456             return Ok(pkt);
457         }
458 
459         // Reject packets that exceed the maximum allowed value for payload.
460         if pkt.len() > max_data_size {
461             return Err(Error::InvalidHeaderLen(pkt.len()));
462         }
463 
464         // Starting from Linux 6.2 the virtio-vsock driver can use a single descriptor for both
465         // header and data.
466         let data_slice =
467             if !chain_head.has_next() && chain_head.len() - PKT_HEADER_SIZE as u32 >= pkt.len() {
468                 mem.get_slice(
469                     chain_head
470                         .addr()
471                         .checked_add(PKT_HEADER_SIZE as u64)
472                         .ok_or(Error::DescriptorLengthTooSmall)?,
473                     pkt.len() as usize,
474                 )
475                 .map_err(Error::InvalidMemoryAccess)?
476             } else {
477                 if !chain_head.has_next() {
478                     return Err(Error::DescriptorChainTooShort);
479                 }
480 
481                 let data_desc = desc_chain.next().ok_or(Error::DescriptorChainTooShort)?;
482 
483                 if data_desc.is_write_only() {
484                     return Err(Error::UnexpectedWriteOnlyDescriptor);
485                 }
486 
487                 // The data buffer should be large enough to fit the size of the data, as described by
488                 // the header descriptor.
489                 if data_desc.len() < pkt.len() {
490                     return Err(Error::DescriptorLengthTooSmall);
491                 }
492 
493                 mem.get_slice(data_desc.addr(), pkt.len() as usize)
494                     .map_err(Error::InvalidMemoryAccess)?
495             };
496 
497         pkt.data_slice = Some(data_slice);
498         Ok(pkt)
499     }
500 
501     /// Create the packet wrapper from an RX chain.
502     ///
503     /// There must be two descriptors in the chain, both writable: a header descriptor and a data
504     /// descriptor.
505     ///
506     /// # Arguments
507     /// * `mem` - the `GuestMemory` object that can be used to access the queue buffers.
508     /// * `desc_chain` - the descriptor chain corresponding to a packet.
509     /// * `max_data_size` - the maximum size allowed for the packet payload, that was negotiated
510     ///                     between the device and the driver. Tracking issue for defining this
511     ///                     feature in virtio-spec
512     ///                     [here](https://github.com/oasis-tcs/virtio-spec/issues/140).
513     ///
514     /// # Example
515     ///
516     /// ```rust
517     /// # use virtio_bindings::bindings::virtio_ring::VRING_DESC_F_WRITE;
518     /// # use virtio_queue::mock::MockSplitQueue;
519     /// # use virtio_queue::{Descriptor, Queue, QueueT};
520     /// use virtio_vsock::packet::{VsockPacket, PKT_HEADER_SIZE};
521     /// # use vm_memory::{Bytes, GuestAddress, GuestAddressSpace, GuestMemoryMmap};
522     ///
523     /// # const MAX_PKT_BUF_SIZE: u32 = 64 * 1024;
524     /// # const SRC_CID: u64 = 1;
525     /// # const DST_CID: u64 = 2;
526     /// # const SRC_PORT: u32 = 3;
527     /// # const DST_PORT: u32 = 4;
528     /// # const LEN: u32 = 16;
529     /// # const TYPE_STREAM: u16 = 1;
530     /// # const OP_RW: u16 = 5;
531     /// # const FLAGS: u32 = 7;
532     /// # const FLAG: u32 = 8;
533     /// # const BUF_ALLOC: u32 = 256;
534     /// # const FWD_CNT: u32 = 9;
535     ///
536     /// # fn create_queue_with_chain(m: &GuestMemoryMmap) -> Queue {
537     /// #     let vq = MockSplitQueue::new(m, 16);
538     /// #     let mut q = vq.create_queue().unwrap();
539     /// #
540     /// #     let v = vec![
541     /// #         Descriptor::new(0x5_0000, 0x100, VRING_DESC_F_WRITE as u16, 0),
542     /// #         Descriptor::new(0x8_0000, 0x100, VRING_DESC_F_WRITE as u16, 0),
543     /// #     ];
544     /// #     let mut chain = vq.build_desc_chain(&v);
545     /// #    q
546     /// # }
547     /// let mem = GuestMemoryMmap::<()>::from_ranges(&[(GuestAddress(0), 0x10000)]).unwrap();
548     /// // Create a queue and populate it with a descriptor chain.
549     /// let mut queue = create_queue_with_chain(&mem);
550     ///
551     /// while let Some(mut head) = queue.pop_descriptor_chain(&mem) {
552     ///     let used_len = match VsockPacket::from_rx_virtq_chain(&mem, &mut head, MAX_PKT_BUF_SIZE) {
553     ///         Ok(mut pkt) => {
554     ///             // Make sure the header is zeroed out first.
555     ///             pkt.header_slice()
556     ///                 .write(&[0u8; PKT_HEADER_SIZE], 0)
557     ///                 .unwrap();
558     ///             // Write data to the packet, using the setters.
559     ///             pkt.set_src_cid(SRC_CID)
560     ///                 .set_dst_cid(DST_CID)
561     ///                 .set_src_port(SRC_PORT)
562     ///                 .set_dst_port(DST_PORT)
563     ///                 .set_type(TYPE_STREAM)
564     ///                 .set_buf_alloc(BUF_ALLOC)
565     ///                 .set_fwd_cnt(FWD_CNT);
566     ///             // In this example, we are sending a RW packet.
567     ///             pkt.data_slice()
568     ///                 .unwrap()
569     ///                 .write_slice(&[1u8; LEN as usize], 0);
570     ///             pkt.set_op(OP_RW).set_len(LEN);
571     ///             pkt.header_slice().len() as u32 + LEN
572     ///         }
573     ///         Err(_e) => {
574     ///             // Do some error handling.
575     ///             0
576     ///         }
577     ///     };
578     ///     queue.add_used(&mem, head.head_index(), used_len);
579     /// }
580     /// ```
from_rx_virtq_chain<M, T>( mem: &'a M, desc_chain: &mut DescriptorChain<T>, max_data_size: u32, ) -> Result<Self> where M: GuestMemory, <<M as GuestMemory>::R as GuestMemoryRegion>::B: WithBitmapSlice<'a, S = B>, T: Deref, T::Target: GuestMemory,581     pub fn from_rx_virtq_chain<M, T>(
582         mem: &'a M,
583         desc_chain: &mut DescriptorChain<T>,
584         max_data_size: u32,
585     ) -> Result<Self>
586     where
587         M: GuestMemory,
588         <<M as GuestMemory>::R as GuestMemoryRegion>::B: WithBitmapSlice<'a, S = B>,
589         T: Deref,
590         T::Target: GuestMemory,
591     {
592         let chain_head = desc_chain.next().ok_or(Error::DescriptorChainTooShort)?;
593         // All RX buffers must be device-writable.
594         if !chain_head.is_write_only() {
595             return Err(Error::UnexpectedReadOnlyDescriptor);
596         }
597 
598         // The packet header should fit inside the head descriptor.
599         if (chain_head.len() as usize) < PKT_HEADER_SIZE {
600             return Err(Error::DescriptorLengthTooSmall);
601         }
602 
603         let header_slice = mem
604             .get_slice(chain_head.addr(), PKT_HEADER_SIZE)
605             .map_err(Error::InvalidMemoryAccess)?;
606 
607         // Starting from Linux 6.2 the virtio-vsock driver can use a single descriptor for both
608         // header and data.
609         let data_slice = if !chain_head.has_next() && chain_head.len() as usize > PKT_HEADER_SIZE {
610             mem.get_slice(
611                 chain_head
612                     .addr()
613                     .checked_add(PKT_HEADER_SIZE as u64)
614                     .ok_or(Error::DescriptorLengthTooSmall)?,
615                 chain_head.len() as usize - PKT_HEADER_SIZE,
616             )
617             .map_err(Error::InvalidMemoryAccess)?
618         } else {
619             if !chain_head.has_next() {
620                 return Err(Error::DescriptorChainTooShort);
621             }
622 
623             let data_desc = desc_chain.next().ok_or(Error::DescriptorChainTooShort)?;
624 
625             if !data_desc.is_write_only() {
626                 return Err(Error::UnexpectedReadOnlyDescriptor);
627             }
628 
629             if data_desc.len() > max_data_size {
630                 return Err(Error::DescriptorLengthTooLong);
631             }
632 
633             mem.get_slice(data_desc.addr(), data_desc.len() as usize)
634                 .map_err(Error::InvalidMemoryAccess)?
635         };
636 
637         Ok(Self {
638             header_slice,
639             header: Default::default(),
640             data_slice: Some(data_slice),
641         })
642     }
643 }
644 
645 impl<'a> VsockPacket<'a, ()> {
646     /// Create a packet based on one pointer for the header, and an optional one for data.
647     ///
648     /// # Safety
649     ///
650     /// To use this safely, the caller must guarantee that the memory pointed to by the `hdr` and
651     /// `data` slices is available for the duration of the lifetime of the new `VolatileSlice`. The
652     /// caller must also guarantee that all other users of the given chunk of memory are using
653     /// volatile accesses.
654     ///
655     /// # Example
656     ///
657     /// ```rust
658     /// use virtio_vsock::packet::{VsockPacket, PKT_HEADER_SIZE};
659     ///
660     /// const LEN: usize = 16;
661     ///
662     /// let mut pkt_raw = [0u8; PKT_HEADER_SIZE + LEN];
663     /// let (hdr_raw, data_raw) = pkt_raw.split_at_mut(PKT_HEADER_SIZE);
664     /// // Safe because `hdr_raw` and `data_raw` live for as long as the scope of the current
665     /// // example.
666     /// let packet = unsafe { VsockPacket::new(hdr_raw, Some(data_raw)).unwrap() };
667     /// ```
new(header: &mut [u8], data: Option<&mut [u8]>) -> Result<VsockPacket<'a, ()>>668     pub unsafe fn new(header: &mut [u8], data: Option<&mut [u8]>) -> Result<VsockPacket<'a, ()>> {
669         if header.len() != PKT_HEADER_SIZE {
670             return Err(Error::InvalidHeaderInputSize(header.len()));
671         }
672         Ok(VsockPacket {
673             header_slice: VolatileSlice::new(header.as_mut_ptr(), PKT_HEADER_SIZE),
674             header: Default::default(),
675             data_slice: data.map(|data| VolatileSlice::new(data.as_mut_ptr(), data.len())),
676         })
677     }
678 }
679 
680 #[cfg(test)]
681 mod tests {
682     use super::*;
683 
684     use vm_memory::{GuestAddress, GuestMemoryMmap};
685 
686     use virtio_bindings::bindings::virtio_ring::VRING_DESC_F_WRITE;
687     use virtio_queue::mock::MockSplitQueue;
688     use virtio_queue::Descriptor;
689 
690     impl PartialEq for Error {
eq(&self, other: &Self) -> bool691         fn eq(&self, other: &Self) -> bool {
692             use self::Error::*;
693             match (self, other) {
694                 (DescriptorChainTooShort, DescriptorChainTooShort) => true,
695                 (DescriptorLengthTooSmall, DescriptorLengthTooSmall) => true,
696                 (DescriptorLengthTooLong, DescriptorLengthTooLong) => true,
697                 (InvalidHeaderInputSize(size), InvalidHeaderInputSize(other_size)) => {
698                     size == other_size
699                 }
700                 (InvalidHeaderLen(size), InvalidHeaderLen(other_size)) => size == other_size,
701                 (InvalidMemoryAccess(ref e), InvalidMemoryAccess(ref other_e)) => {
702                     format!("{}", e).eq(&format!("{}", other_e))
703                 }
704                 (InvalidVolatileAccess(ref e), InvalidVolatileAccess(ref other_e)) => {
705                     format!("{}", e).eq(&format!("{}", other_e))
706                 }
707                 (UnexpectedReadOnlyDescriptor, UnexpectedReadOnlyDescriptor) => true,
708                 (UnexpectedWriteOnlyDescriptor, UnexpectedWriteOnlyDescriptor) => true,
709                 _ => false,
710             }
711         }
712     }
713 
714     // Random values to be used by the tests for the header fields.
715     const SRC_CID: u64 = 1;
716     const DST_CID: u64 = 2;
717     const SRC_PORT: u32 = 3;
718     const DST_PORT: u32 = 4;
719     const LEN: u32 = 16;
720     const TYPE: u16 = 5;
721     const OP: u16 = 6;
722     const FLAGS: u32 = 7;
723     const FLAG: u32 = 8;
724     const BUF_ALLOC: u32 = 256;
725     const FWD_CNT: u32 = 9;
726 
727     const MAX_PKT_BUF_SIZE: u32 = 64 * 1024;
728 
729     #[test]
test_from_rx_virtq_chain()730     fn test_from_rx_virtq_chain() {
731         let mem: GuestMemoryMmap =
732             GuestMemoryMmap::from_ranges(&[(GuestAddress(0), 0x1000_0000)]).unwrap();
733 
734         // The `build_desc_chain` function will populate the `NEXT` related flags and field.
735         let v = vec![
736             // A device-readable packet header descriptor should be invalid.
737             Descriptor::new(0x10_0000, 0x100, 0, 0),
738             Descriptor::new(0x20_0000, 0x100, VRING_DESC_F_WRITE as u16, 0),
739         ];
740         let queue = MockSplitQueue::new(&mem, 16);
741         let mut chain = queue.build_desc_chain(&v).unwrap();
742         assert_eq!(
743             VsockPacket::from_rx_virtq_chain(&mem, &mut chain, MAX_PKT_BUF_SIZE).unwrap_err(),
744             Error::UnexpectedReadOnlyDescriptor
745         );
746 
747         let v = vec![
748             // A header length < PKT_HEADER_SIZE is invalid.
749             Descriptor::new(
750                 0x10_0000,
751                 PKT_HEADER_SIZE as u32 - 1,
752                 VRING_DESC_F_WRITE as u16,
753                 0,
754             ),
755             Descriptor::new(0x20_0000, 0x100, VRING_DESC_F_WRITE as u16, 0),
756         ];
757         let mut chain = queue.build_desc_chain(&v).unwrap();
758         assert_eq!(
759             VsockPacket::from_rx_virtq_chain(&mem, &mut chain, MAX_PKT_BUF_SIZE).unwrap_err(),
760             Error::DescriptorLengthTooSmall
761         );
762 
763         let v = vec![
764             Descriptor::new(
765                 0x10_0000,
766                 PKT_HEADER_SIZE as u32,
767                 VRING_DESC_F_WRITE as u16,
768                 0,
769             ),
770             Descriptor::new(
771                 0x20_0000,
772                 MAX_PKT_BUF_SIZE + 1,
773                 VRING_DESC_F_WRITE as u16,
774                 0,
775             ),
776         ];
777         let mut chain = queue.build_desc_chain(&v).unwrap();
778         assert_eq!(
779             VsockPacket::from_rx_virtq_chain(&mem, &mut chain, MAX_PKT_BUF_SIZE).unwrap_err(),
780             Error::DescriptorLengthTooLong
781         );
782 
783         let v = vec![
784             // The data descriptor should always be present on the RX path.
785             Descriptor::new(
786                 0x10_0000,
787                 PKT_HEADER_SIZE as u32,
788                 VRING_DESC_F_WRITE as u16,
789                 0,
790             ),
791         ];
792         let mut chain = queue.build_desc_chain(&v).unwrap();
793         assert_eq!(
794             VsockPacket::from_rx_virtq_chain(&mem, &mut chain, MAX_PKT_BUF_SIZE).unwrap_err(),
795             Error::DescriptorChainTooShort
796         );
797 
798         let v = vec![
799             Descriptor::new(0x10_0000, 0x100, 0, 0),
800             Descriptor::new(0x20_0000, 0x100, VRING_DESC_F_WRITE as u16, 0),
801         ];
802         let mut chain = queue.build_desc_chain(&v).unwrap();
803         assert_eq!(
804             VsockPacket::from_rx_virtq_chain(&mem, &mut chain, MAX_PKT_BUF_SIZE).unwrap_err(),
805             Error::UnexpectedReadOnlyDescriptor
806         );
807 
808         let mem: GuestMemoryMmap =
809             GuestMemoryMmap::from_ranges(&[(GuestAddress(0), 0x10_0004)]).unwrap();
810 
811         let v = vec![
812             // The header doesn't fit entirely in the memory bounds.
813             Descriptor::new(0x10_0000, 0x100, VRING_DESC_F_WRITE as u16, 0),
814             Descriptor::new(0x20_0000, 0x100, VRING_DESC_F_WRITE as u16, 0),
815         ];
816         let queue = MockSplitQueue::new(&mem, 16);
817         let mut chain = queue.build_desc_chain(&v).unwrap();
818         assert_eq!(
819             VsockPacket::from_rx_virtq_chain(&mem, &mut chain, MAX_PKT_BUF_SIZE).unwrap_err(),
820             Error::InvalidMemoryAccess(GuestMemoryError::InvalidBackendAddress)
821         );
822 
823         let v = vec![
824             // The header is outside the memory bounds.
825             Descriptor::new(0x20_0000, 0x100, VRING_DESC_F_WRITE as u16, 0),
826             Descriptor::new(0x30_0000, 0x100, VRING_DESC_F_WRITE as u16, 0),
827         ];
828         let mut chain = queue.build_desc_chain(&v).unwrap();
829         assert_eq!(
830             VsockPacket::from_rx_virtq_chain(&mem, &mut chain, MAX_PKT_BUF_SIZE).unwrap_err(),
831             Error::InvalidMemoryAccess(GuestMemoryError::InvalidGuestAddress(GuestAddress(
832                 0x20_0000
833             )))
834         );
835 
836         let v = vec![
837             Descriptor::new(0x5_0000, 0x100, VRING_DESC_F_WRITE as u16, 0),
838             // A device-readable packet data descriptor should be invalid.
839             Descriptor::new(0x8_0000, 0x100, 0, 0),
840         ];
841         let mut chain = queue.build_desc_chain(&v).unwrap();
842         assert_eq!(
843             VsockPacket::from_rx_virtq_chain(&mem, &mut chain, MAX_PKT_BUF_SIZE).unwrap_err(),
844             Error::UnexpectedReadOnlyDescriptor
845         );
846         let v = vec![
847             Descriptor::new(0x5_0000, 0x100, VRING_DESC_F_WRITE as u16, 0),
848             // The data array doesn't fit entirely in the memory bounds.
849             Descriptor::new(0x10_0000, 0x100, VRING_DESC_F_WRITE as u16, 0),
850         ];
851         let mut chain = queue.build_desc_chain(&v).unwrap();
852         assert_eq!(
853             VsockPacket::from_rx_virtq_chain(&mem, &mut chain, MAX_PKT_BUF_SIZE).unwrap_err(),
854             Error::InvalidMemoryAccess(GuestMemoryError::InvalidBackendAddress)
855         );
856 
857         let v = vec![
858             Descriptor::new(0x5_0000, 0x100, VRING_DESC_F_WRITE as u16, 0),
859             // The data array is outside the memory bounds.
860             Descriptor::new(0x20_0000, 0x100, VRING_DESC_F_WRITE as u16, 0),
861         ];
862         let mut chain = queue.build_desc_chain(&v).unwrap();
863         assert_eq!(
864             VsockPacket::from_rx_virtq_chain(&mem, &mut chain, MAX_PKT_BUF_SIZE).unwrap_err(),
865             Error::InvalidMemoryAccess(GuestMemoryError::InvalidGuestAddress(GuestAddress(
866                 0x20_0000
867             )))
868         );
869 
870         // Let's also test a valid descriptor chain.
871         let v = vec![
872             Descriptor::new(0x5_0000, 0x100, VRING_DESC_F_WRITE as u16, 0),
873             Descriptor::new(0x8_0000, 0x100, VRING_DESC_F_WRITE as u16, 0),
874         ];
875         let mut chain = queue.build_desc_chain(&v).unwrap();
876 
877         let packet = VsockPacket::from_rx_virtq_chain(&mem, &mut chain, MAX_PKT_BUF_SIZE).unwrap();
878         assert_eq!(packet.header, PacketHeader::default());
879         let header = packet.header_slice();
880         assert_eq!(
881             header.ptr_guard().as_ptr(),
882             mem.get_host_address(GuestAddress(0x5_0000)).unwrap()
883         );
884         assert_eq!(header.len(), PKT_HEADER_SIZE);
885 
886         let data = packet.data_slice().unwrap();
887         assert_eq!(
888             data.ptr_guard().as_ptr(),
889             mem.get_host_address(GuestAddress(0x8_0000)).unwrap()
890         );
891         assert_eq!(data.len(), 0x100);
892 
893         // If we try to get a vsock packet again, it fails because we already consumed all the
894         // descriptors from the chain.
895         assert_eq!(
896             VsockPacket::from_rx_virtq_chain(&mem, &mut chain, MAX_PKT_BUF_SIZE).unwrap_err(),
897             Error::DescriptorChainTooShort
898         );
899 
900         // Let's also test a valid descriptor chain, with both header and data on a single
901         // descriptor.
902         let v = vec![Descriptor::new(
903             0x5_0000,
904             PKT_HEADER_SIZE as u32 + 0x100,
905             VRING_DESC_F_WRITE as u16,
906             0,
907         )];
908         let mut chain = queue.build_desc_chain(&v).unwrap();
909 
910         let packet = VsockPacket::from_rx_virtq_chain(&mem, &mut chain, MAX_PKT_BUF_SIZE).unwrap();
911         assert_eq!(packet.header, PacketHeader::default());
912         let header = packet.header_slice();
913         assert_eq!(
914             header.ptr_guard().as_ptr(),
915             mem.get_host_address(GuestAddress(0x5_0000)).unwrap()
916         );
917         assert_eq!(header.len(), PKT_HEADER_SIZE);
918 
919         let data = packet.data_slice().unwrap();
920         assert_eq!(
921             data.ptr_guard().as_ptr(),
922             mem.get_host_address(GuestAddress(0x5_0000 + PKT_HEADER_SIZE as u64))
923                 .unwrap()
924         );
925         assert_eq!(data.len(), 0x100);
926     }
927 
928     #[test]
test_from_tx_virtq_chain()929     fn test_from_tx_virtq_chain() {
930         let mem: GuestMemoryMmap =
931             GuestMemoryMmap::from_ranges(&[(GuestAddress(0), 0x1000_0000)]).unwrap();
932 
933         // The `build_desc_chain` function will populate the `NEXT` related flags and field.
934         let v = vec![
935             // A device-writable packet header descriptor should be invalid.
936             Descriptor::new(0x10_0000, 0x100, VRING_DESC_F_WRITE as u16, 0),
937             Descriptor::new(0x20_0000, 0x100, 0, 0),
938         ];
939         let queue = MockSplitQueue::new(&mem, 16);
940         let mut chain = queue.build_desc_chain(&v).unwrap();
941         assert_eq!(
942             VsockPacket::from_tx_virtq_chain(&mem, &mut chain, MAX_PKT_BUF_SIZE).unwrap_err(),
943             Error::UnexpectedWriteOnlyDescriptor
944         );
945 
946         let v = vec![
947             // A header length < PKT_HEADER_SIZE is invalid.
948             Descriptor::new(0x10_0000, PKT_HEADER_SIZE as u32 - 1, 0, 0),
949             Descriptor::new(0x20_0000, 0x100, 0, 0),
950         ];
951         let mut chain = queue.build_desc_chain(&v).unwrap();
952         assert_eq!(
953             VsockPacket::from_tx_virtq_chain(&mem, &mut chain, MAX_PKT_BUF_SIZE).unwrap_err(),
954             Error::DescriptorLengthTooSmall
955         );
956 
957         // On the TX path, it is allowed to not have a data descriptor.
958         let v = vec![Descriptor::new(0x10_0000, PKT_HEADER_SIZE as u32, 0, 0)];
959         let mut chain = queue.build_desc_chain(&v).unwrap();
960 
961         let header = PacketHeader {
962             src_cid: SRC_CID.into(),
963             dst_cid: DST_CID.into(),
964             src_port: SRC_PORT.into(),
965             dst_port: DST_PORT.into(),
966             len: 0.into(),
967             type_: 0.into(),
968             op: 0.into(),
969             flags: 0.into(),
970             buf_alloc: 0.into(),
971             fwd_cnt: 0.into(),
972         };
973         mem.write_obj(header, GuestAddress(0x10_0000)).unwrap();
974 
975         let packet = VsockPacket::from_tx_virtq_chain(&mem, &mut chain, MAX_PKT_BUF_SIZE).unwrap();
976         assert_eq!(packet.header, header);
977         let header_slice = packet.header_slice();
978         assert_eq!(
979             header_slice.ptr_guard().as_ptr(),
980             mem.get_host_address(GuestAddress(0x10_0000)).unwrap()
981         );
982         assert_eq!(header_slice.len(), PKT_HEADER_SIZE);
983         assert!(packet.data_slice().is_none());
984 
985         let mem: GuestMemoryMmap =
986             GuestMemoryMmap::from_ranges(&[(GuestAddress(0), 0x10_0004)]).unwrap();
987 
988         let v = vec![
989             // The header doesn't fit entirely in the memory bounds.
990             Descriptor::new(0x10_0000, 0x100, 0, 0),
991             Descriptor::new(0x20_0000, 0x100, 0, 0),
992         ];
993         let queue = MockSplitQueue::new(&mem, 16);
994         let mut chain = queue.build_desc_chain(&v).unwrap();
995         assert_eq!(
996             VsockPacket::from_tx_virtq_chain(&mem, &mut chain, MAX_PKT_BUF_SIZE).unwrap_err(),
997             Error::InvalidMemoryAccess(GuestMemoryError::InvalidBackendAddress)
998         );
999 
1000         let v = vec![
1001             // The header is outside the memory bounds.
1002             Descriptor::new(0x20_0000, 0x100, 0, 0),
1003             Descriptor::new(0x30_0000, 0x100, 0, 0),
1004         ];
1005         let mut chain = queue.build_desc_chain(&v).unwrap();
1006         assert_eq!(
1007             VsockPacket::from_tx_virtq_chain(&mem, &mut chain, MAX_PKT_BUF_SIZE).unwrap_err(),
1008             Error::InvalidMemoryAccess(GuestMemoryError::InvalidGuestAddress(GuestAddress(
1009                 0x20_0000
1010             )))
1011         );
1012 
1013         // Write some non-zero value to the `len` field of the header, which means there is also
1014         // a data descriptor in the chain, first with a value that exceeds the maximum allowed one.
1015         let header = PacketHeader {
1016             src_cid: SRC_CID.into(),
1017             dst_cid: DST_CID.into(),
1018             src_port: SRC_PORT.into(),
1019             dst_port: DST_PORT.into(),
1020             len: (MAX_PKT_BUF_SIZE + 1).into(),
1021             type_: 0.into(),
1022             op: 0.into(),
1023             flags: 0.into(),
1024             buf_alloc: 0.into(),
1025             fwd_cnt: 0.into(),
1026         };
1027         mem.write_obj(header, GuestAddress(0x5_0000)).unwrap();
1028         let v = vec![
1029             Descriptor::new(0x5_0000, 0x100, 0, 0),
1030             Descriptor::new(0x8_0000, 0x100, 0, 0),
1031         ];
1032         let mut chain = queue.build_desc_chain(&v).unwrap();
1033         assert_eq!(
1034             VsockPacket::from_tx_virtq_chain(&mem, &mut chain, MAX_PKT_BUF_SIZE).unwrap_err(),
1035             Error::InvalidHeaderLen(MAX_PKT_BUF_SIZE + 1)
1036         );
1037 
1038         // Write some non-zero, valid value to the `len` field of the header.
1039         let header = PacketHeader {
1040             src_cid: SRC_CID.into(),
1041             dst_cid: DST_CID.into(),
1042             src_port: SRC_PORT.into(),
1043             dst_port: DST_PORT.into(),
1044             len: LEN.into(),
1045             type_: 0.into(),
1046             op: 0.into(),
1047             flags: 0.into(),
1048             buf_alloc: 0.into(),
1049             fwd_cnt: 0.into(),
1050         };
1051         mem.write_obj(header, GuestAddress(0x5_0000)).unwrap();
1052         let v = vec![
1053             // The data descriptor is missing.
1054             Descriptor::new(0x5_0000, PKT_HEADER_SIZE as u32, 0, 0),
1055         ];
1056         let mut chain = queue.build_desc_chain(&v).unwrap();
1057         assert_eq!(
1058             VsockPacket::from_tx_virtq_chain(&mem, &mut chain, MAX_PKT_BUF_SIZE).unwrap_err(),
1059             Error::DescriptorChainTooShort
1060         );
1061 
1062         let v = vec![
1063             Descriptor::new(0x5_0000, 0x100, 0, 0),
1064             // The data array doesn't fit entirely in the memory bounds.
1065             Descriptor::new(0x10_0000, 0x100, 0, 0),
1066         ];
1067         let mut chain = queue.build_desc_chain(&v).unwrap();
1068         assert_eq!(
1069             VsockPacket::from_tx_virtq_chain(&mem, &mut chain, MAX_PKT_BUF_SIZE).unwrap_err(),
1070             Error::InvalidMemoryAccess(GuestMemoryError::InvalidBackendAddress)
1071         );
1072 
1073         let v = vec![
1074             Descriptor::new(0x5_0000, 0x100, 0, 0),
1075             // The data array is outside the memory bounds.
1076             Descriptor::new(0x20_0000, 0x100, 0, 0),
1077         ];
1078         let mut chain = queue.build_desc_chain(&v).unwrap();
1079         assert_eq!(
1080             VsockPacket::from_tx_virtq_chain(&mem, &mut chain, MAX_PKT_BUF_SIZE).unwrap_err(),
1081             Error::InvalidMemoryAccess(GuestMemoryError::InvalidGuestAddress(GuestAddress(
1082                 0x20_0000
1083             )))
1084         );
1085 
1086         let v = vec![
1087             Descriptor::new(0x5_0000, 0x100, 0, 0),
1088             // A device-writable packet data descriptor should be invalid.
1089             Descriptor::new(0x8_0000, 0x100, VRING_DESC_F_WRITE as u16, 0),
1090         ];
1091         let mut chain = queue.build_desc_chain(&v).unwrap();
1092         assert_eq!(
1093             VsockPacket::from_tx_virtq_chain(&mem, &mut chain, MAX_PKT_BUF_SIZE).unwrap_err(),
1094             Error::UnexpectedWriteOnlyDescriptor
1095         );
1096 
1097         let v = vec![
1098             Descriptor::new(0x5_0000, 0x100, 0, 0),
1099             // A data length < the length of data as described by the header.
1100             Descriptor::new(0x8_0000, LEN - 1, 0, 0),
1101         ];
1102         let mut chain = queue.build_desc_chain(&v).unwrap();
1103         assert_eq!(
1104             VsockPacket::from_tx_virtq_chain(&mem, &mut chain, MAX_PKT_BUF_SIZE).unwrap_err(),
1105             Error::DescriptorLengthTooSmall
1106         );
1107 
1108         // Let's also test a valid descriptor chain, with both header and data.
1109         let v = vec![
1110             Descriptor::new(0x5_0000, 0x100, 0, 0),
1111             Descriptor::new(0x8_0000, 0x100, 0, 0),
1112         ];
1113         let mut chain = queue.build_desc_chain(&v).unwrap();
1114 
1115         let packet = VsockPacket::from_tx_virtq_chain(&mem, &mut chain, MAX_PKT_BUF_SIZE).unwrap();
1116         assert_eq!(packet.header, header);
1117         let header_slice = packet.header_slice();
1118         assert_eq!(
1119             header_slice.ptr_guard().as_ptr(),
1120             mem.get_host_address(GuestAddress(0x5_0000)).unwrap()
1121         );
1122         assert_eq!(header_slice.len(), PKT_HEADER_SIZE);
1123         // The `len` field of the header was set to 16.
1124         assert_eq!(packet.len(), LEN);
1125 
1126         let data = packet.data_slice().unwrap();
1127         assert_eq!(
1128             data.ptr_guard().as_ptr(),
1129             mem.get_host_address(GuestAddress(0x8_0000)).unwrap()
1130         );
1131         assert_eq!(data.len(), LEN as usize);
1132 
1133         // If we try to get a vsock packet again, it fails because we already consumed all the
1134         // descriptors from the chain.
1135         assert_eq!(
1136             VsockPacket::from_tx_virtq_chain(&mem, &mut chain, MAX_PKT_BUF_SIZE).unwrap_err(),
1137             Error::DescriptorChainTooShort
1138         );
1139 
1140         // Let's also test a valid descriptor chain, with both header and data on a single
1141         // descriptor.
1142         let v = vec![Descriptor::new(
1143             0x5_0000,
1144             PKT_HEADER_SIZE as u32 + 0x100,
1145             0,
1146             0,
1147         )];
1148         let mut chain = queue.build_desc_chain(&v).unwrap();
1149 
1150         let packet = VsockPacket::from_tx_virtq_chain(&mem, &mut chain, MAX_PKT_BUF_SIZE).unwrap();
1151         assert_eq!(packet.header, header);
1152         let header_slice = packet.header_slice();
1153         assert_eq!(
1154             header_slice.ptr_guard().as_ptr(),
1155             mem.get_host_address(GuestAddress(0x5_0000)).unwrap()
1156         );
1157         assert_eq!(header_slice.len(), PKT_HEADER_SIZE);
1158         // The `len` field of the header was set to 16.
1159         assert_eq!(packet.len(), LEN);
1160 
1161         let data = packet.data_slice().unwrap();
1162         assert_eq!(
1163             data.ptr_guard().as_ptr(),
1164             mem.get_host_address(GuestAddress(0x5_0000 + PKT_HEADER_SIZE as u64))
1165                 .unwrap()
1166         );
1167         assert_eq!(data.len(), LEN as usize);
1168     }
1169 
1170     #[test]
test_header_set_get()1171     fn test_header_set_get() {
1172         let mem: GuestMemoryMmap =
1173             GuestMemoryMmap::from_ranges(&[(GuestAddress(0), 0x30_0000)]).unwrap();
1174         // The `build_desc_chain` function will populate the `NEXT` related flags and field.
1175         let v = vec![
1176             Descriptor::new(0x10_0000, 0x100, VRING_DESC_F_WRITE as u16, 0),
1177             Descriptor::new(0x20_0000, 0x100, VRING_DESC_F_WRITE as u16, 0),
1178         ];
1179         let queue = MockSplitQueue::new(&mem, 16);
1180         let mut chain = queue.build_desc_chain(&v).unwrap();
1181 
1182         let mut packet =
1183             VsockPacket::from_rx_virtq_chain(&mem, &mut chain, MAX_PKT_BUF_SIZE).unwrap();
1184         packet
1185             .set_src_cid(SRC_CID)
1186             .set_dst_cid(DST_CID)
1187             .set_src_port(SRC_PORT)
1188             .set_dst_port(DST_PORT)
1189             .set_len(LEN)
1190             .set_type(TYPE)
1191             .set_op(OP)
1192             .set_flags(FLAGS)
1193             .set_flag(FLAG)
1194             .set_buf_alloc(BUF_ALLOC)
1195             .set_fwd_cnt(FWD_CNT);
1196 
1197         assert_eq!(packet.flags(), FLAGS | FLAG);
1198         assert_eq!(packet.op(), OP);
1199         assert_eq!(packet.type_(), TYPE);
1200         assert_eq!(packet.dst_cid(), DST_CID);
1201         assert_eq!(packet.dst_port(), DST_PORT);
1202         assert_eq!(packet.src_cid(), SRC_CID);
1203         assert_eq!(packet.src_port(), SRC_PORT);
1204         assert_eq!(packet.fwd_cnt(), FWD_CNT);
1205         assert_eq!(packet.len(), LEN);
1206         assert_eq!(packet.buf_alloc(), BUF_ALLOC);
1207 
1208         let expected_header = PacketHeader {
1209             src_cid: SRC_CID.into(),
1210             dst_cid: DST_CID.into(),
1211             src_port: SRC_PORT.into(),
1212             dst_port: DST_PORT.into(),
1213             len: LEN.into(),
1214             type_: TYPE.into(),
1215             op: OP.into(),
1216             flags: (FLAGS | FLAG).into(),
1217             buf_alloc: BUF_ALLOC.into(),
1218             fwd_cnt: FWD_CNT.into(),
1219         };
1220 
1221         assert_eq!(packet.header, expected_header);
1222         assert_eq!(
1223             u64::from_le(
1224                 packet
1225                     .header_slice()
1226                     .read_obj::<u64>(SRC_CID_OFFSET)
1227                     .unwrap()
1228             ),
1229             SRC_CID
1230         );
1231         assert_eq!(
1232             u64::from_le(
1233                 packet
1234                     .header_slice()
1235                     .read_obj::<u64>(DST_CID_OFFSET)
1236                     .unwrap()
1237             ),
1238             DST_CID
1239         );
1240         assert_eq!(
1241             u32::from_le(
1242                 packet
1243                     .header_slice()
1244                     .read_obj::<u32>(SRC_PORT_OFFSET)
1245                     .unwrap()
1246             ),
1247             SRC_PORT
1248         );
1249         assert_eq!(
1250             u32::from_le(
1251                 packet
1252                     .header_slice()
1253                     .read_obj::<u32>(DST_PORT_OFFSET)
1254                     .unwrap()
1255             ),
1256             DST_PORT,
1257         );
1258         assert_eq!(
1259             u32::from_le(packet.header_slice().read_obj::<u32>(LEN_OFFSET).unwrap()),
1260             LEN
1261         );
1262         assert_eq!(
1263             u16::from_le(packet.header_slice().read_obj::<u16>(TYPE_OFFSET).unwrap()),
1264             TYPE
1265         );
1266         assert_eq!(
1267             u16::from_le(packet.header_slice().read_obj::<u16>(OP_OFFSET).unwrap()),
1268             OP
1269         );
1270         assert_eq!(
1271             u32::from_le(packet.header_slice().read_obj::<u32>(FLAGS_OFFSET).unwrap()),
1272             FLAGS | FLAG
1273         );
1274         assert_eq!(
1275             u32::from_le(
1276                 packet
1277                     .header_slice()
1278                     .read_obj::<u32>(BUF_ALLOC_OFFSET)
1279                     .unwrap()
1280             ),
1281             BUF_ALLOC
1282         );
1283         assert_eq!(
1284             u32::from_le(
1285                 packet
1286                     .header_slice()
1287                     .read_obj::<u32>(FWD_CNT_OFFSET)
1288                     .unwrap()
1289             ),
1290             FWD_CNT
1291         );
1292     }
1293 
1294     #[test]
test_set_header_from_raw()1295     fn test_set_header_from_raw() {
1296         let mem: GuestMemoryMmap =
1297             GuestMemoryMmap::from_ranges(&[(GuestAddress(0), 0x30_0000)]).unwrap();
1298         // The `build_desc_chain` function will populate the `NEXT` related flags and field.
1299         let v = vec![
1300             Descriptor::new(0x10_0000, 0x100, VRING_DESC_F_WRITE as u16, 0),
1301             Descriptor::new(0x20_0000, 0x100, VRING_DESC_F_WRITE as u16, 0),
1302         ];
1303         let queue = MockSplitQueue::new(&mem, 16);
1304         let mut chain = queue.build_desc_chain(&v).unwrap();
1305 
1306         let mut packet =
1307             VsockPacket::from_rx_virtq_chain(&mem, &mut chain, MAX_PKT_BUF_SIZE).unwrap();
1308 
1309         let header = PacketHeader {
1310             src_cid: SRC_CID.into(),
1311             dst_cid: DST_CID.into(),
1312             src_port: SRC_PORT.into(),
1313             dst_port: DST_PORT.into(),
1314             len: LEN.into(),
1315             type_: TYPE.into(),
1316             op: OP.into(),
1317             flags: (FLAGS | FLAG).into(),
1318             buf_alloc: BUF_ALLOC.into(),
1319             fwd_cnt: FWD_CNT.into(),
1320         };
1321 
1322         // SAFETY: created from an existing packet header.
1323         let slice = unsafe {
1324             std::slice::from_raw_parts(
1325                 (&header as *const PacketHeader) as *const u8,
1326                 std::mem::size_of::<PacketHeader>(),
1327             )
1328         };
1329         assert_eq!(packet.header, PacketHeader::default());
1330         packet.set_header_from_raw(slice).unwrap();
1331         assert_eq!(packet.header, header);
1332         let header_from_slice: PacketHeader = packet.header_slice().read_obj(0).unwrap();
1333         assert_eq!(header_from_slice, header);
1334 
1335         let invalid_slice = [0; PKT_HEADER_SIZE - 1];
1336         assert_eq!(
1337             packet.set_header_from_raw(&invalid_slice).unwrap_err(),
1338             Error::InvalidHeaderInputSize(PKT_HEADER_SIZE - 1)
1339         );
1340     }
1341 
1342     #[test]
test_packet_new()1343     fn test_packet_new() {
1344         let mut pkt_raw = [0u8; PKT_HEADER_SIZE + LEN as usize];
1345         let (hdr_raw, data_raw) = pkt_raw.split_at_mut(PKT_HEADER_SIZE);
1346         // SAFETY: safe because ``hdr_raw` and `data_raw` live for as long as
1347         // the scope of the current test.
1348         let packet = unsafe { VsockPacket::new(hdr_raw, Some(data_raw)).unwrap() };
1349         assert_eq!(
1350             packet.header_slice.ptr_guard().as_ptr(),
1351             hdr_raw.as_mut_ptr(),
1352         );
1353         assert_eq!(packet.header_slice.len(), PKT_HEADER_SIZE);
1354         assert_eq!(packet.header, PacketHeader::default());
1355         assert_eq!(
1356             packet.data_slice.unwrap().ptr_guard().as_ptr(),
1357             data_raw.as_mut_ptr(),
1358         );
1359         assert_eq!(packet.data_slice.unwrap().len(), LEN as usize);
1360 
1361         // SAFETY: Safe because ``hdr_raw` and `data_raw` live as long as the
1362         // scope of the current test.
1363         let packet = unsafe { VsockPacket::new(hdr_raw, None).unwrap() };
1364         assert_eq!(
1365             packet.header_slice.ptr_guard().as_ptr(),
1366             hdr_raw.as_mut_ptr(),
1367         );
1368         assert_eq!(packet.header, PacketHeader::default());
1369         assert!(packet.data_slice.is_none());
1370 
1371         let mut hdr_raw = [0u8; PKT_HEADER_SIZE - 1];
1372         assert_eq!(
1373             // SAFETY: Safe because ``hdr_raw` lives for as long as the scope of the current test.
1374             unsafe { VsockPacket::new(&mut hdr_raw, None).unwrap_err() },
1375             Error::InvalidHeaderInputSize(PKT_HEADER_SIZE - 1)
1376         );
1377     }
1378 
1379     #[test]
1380     #[should_panic]
test_set_header_field_with_invalid_offset()1381     fn test_set_header_field_with_invalid_offset() {
1382         const INVALID_OFFSET: usize = 50;
1383 
1384         impl<'a, B: BitmapSlice> VsockPacket<'a, B> {
1385             /// Set the `src_cid` of the header, but use an invalid offset for that.
1386             pub fn set_src_cid_invalid(&mut self, cid: u64) -> &mut Self {
1387                 set_header_field!(self, src_cid, INVALID_OFFSET, cid);
1388                 self
1389             }
1390         }
1391 
1392         let mem: GuestMemoryMmap =
1393             GuestMemoryMmap::from_ranges(&[(GuestAddress(0), 0x30_0000)]).unwrap();
1394         // The `build_desc_chain` function will populate the `NEXT` related flags and field.
1395         let v = vec![
1396             Descriptor::new(0x10_0000, 0x100, VRING_DESC_F_WRITE as u16, 0),
1397             Descriptor::new(0x20_0000, 0x100, VRING_DESC_F_WRITE as u16, 0),
1398         ];
1399         let queue = MockSplitQueue::new(&mem, 16);
1400         let mut chain = queue.build_desc_chain(&v).unwrap();
1401 
1402         let mut packet =
1403             VsockPacket::from_rx_virtq_chain(&mem, &mut chain, MAX_PKT_BUF_SIZE).unwrap();
1404         packet.set_src_cid_invalid(SRC_CID);
1405     }
1406 }
1407