• Home
  • Raw
  • Download

Lines Matching +full:is +full:- +full:data +full:- +full:descriptor

3 // SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
9 //! - [`VsockPacket`](struct.VsockPacket.html) which handles the parsing of the vsock packet from
10 //! either a TX descriptor chain via
12 //! RX descriptor chain via
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,
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.
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`
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
48 /// Too few descriptors in a descriptor chain.
50 /// Descriptor that was too short to use.
52 /// Descriptor that was too long to use.
56 /// The `len` header field value exceeds the maximum allowed data size.
62 /// Read only descriptor that protocol says to write to.
64 /// Write only descriptor that protocol says to read from.
71 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { in fmt()
78 "The descriptor is pointing to a buffer that has a smaller length than expected." in fmt()
82 "The descriptor is pointing to a buffer that has a longer length than expected." in fmt()
97 write!(f, "Unexpected read-only descriptor.") in fmt()
100 write!(f, "Unexpected write-only descriptor.") in fmt()
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
127 // This structure will occupy the buffer pointed to by the head of the descriptor chain. Below are
148 /// Dedicated [`Result`](https://doc.rust-lang.org/std/result/) type.
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).
160 // `VsockPacket` API is creating headers with PKT_HEADER_SIZE size.
166 // This macro is intended to be used for setting a header field in both the `VolatileSlice` and the
175 // This unwrap is safe only if `$offset` is a valid offset in the `header_slice`.
182 pub fn header_slice(&self) -> &VolatileSlice<'a, B> { in header_slice()
187 pub fn data_slice(&self) -> Option<&VolatileSlice<'a, B>> { in data_slice()
198 /// # use virtio_queue::{Descriptor, Queue, QueueT};
204 /// # fn create_queue_with_chain(m: &GuestMemoryMmap) -> Queue {
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),
216 /// // Create a queue and populate it with a descriptor chain.
224 pub fn set_header_from_raw(&mut self, bytes: &[u8]) -> Result<()> { in set_header_from_raw()
240 pub fn src_cid(&self) -> u64 { in src_cid()
245 pub fn set_src_cid(&mut self, cid: u64) -> &mut Self { in set_src_cid()
251 pub fn dst_cid(&self) -> u64 { in dst_cid()
256 pub fn set_dst_cid(&mut self, cid: u64) -> &mut Self { in set_dst_cid()
262 pub fn src_port(&self) -> u32 { in src_port()
267 pub fn set_src_port(&mut self, port: u32) -> &mut Self { in set_src_port()
273 pub fn dst_port(&self) -> u32 { in dst_port()
278 pub fn set_dst_port(&mut self, port: u32) -> &mut Self { in set_dst_port()
284 pub fn len(&self) -> u32 { in len()
288 /// Returns whether the `len` field of the header is 0 or not.
289 pub fn is_empty(&self) -> bool { in is_empty()
294 pub fn set_len(&mut self, len: u32) -> &mut Self { in set_len()
300 pub fn type_(&self) -> u16 { in type_()
305 pub fn set_type(&mut self, type_: u16) -> &mut Self { in set_type()
311 pub fn op(&self) -> u16 { in op()
316 pub fn set_op(&mut self, op: u16) -> &mut Self { in set_op()
322 pub fn flags(&self) -> u32 { in flags()
327 pub fn set_flags(&mut self, flags: u32) -> &mut Self { in set_flags()
333 pub fn set_flag(&mut self, flag: u32) -> &mut Self { in set_flag()
339 pub fn buf_alloc(&self) -> u32 { in buf_alloc()
344 pub fn set_buf_alloc(&mut self, buf_alloc: u32) -> &mut Self { in set_buf_alloc()
350 pub fn fwd_cnt(&self) -> u32 { in fwd_cnt()
355 pub fn set_fwd_cnt(&mut self, fwd_cnt: u32) -> &mut Self { in set_fwd_cnt()
362 /// The chain head is expected to hold a valid packet header. A following packet data
363 /// descriptor can optionally end the chain.
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
370 /// feature in virtio-spec
371 /// [here](https://github.com/oasis-tcs/virtio-spec/issues/140).
377 /// # use virtio_queue::{Descriptor, Queue, QueueT};
384 /// # fn create_queue_with_chain(m: &GuestMemoryMmap) -> Queue {
389 /// # Descriptor::new(0x5_0000, 0x100, 0, 0),
390 /// # Descriptor::new(0x8_0000, 0x100, 0, 0),
396 /// // Create a queue and populate it with a descriptor chain.
422 ) -> Result<Self> in from_tx_virtq_chain()
430 // All TX buffers must be device-readable. in from_tx_virtq_chain()
435 // The packet header should fit inside the buffer corresponding to the head descriptor. in from_tx_virtq_chain()
454 // If the `len` field of the header is zero, then the packet doesn't have a `data` element. in from_tx_virtq_chain()
464 // Starting from Linux 6.2 the virtio-vsock driver can use a single descriptor for both in from_tx_virtq_chain()
465 // header and data. in from_tx_virtq_chain()
467 if !chain_head.has_next() && chain_head.len() - PKT_HEADER_SIZE as u32 >= pkt.len() { in from_tx_virtq_chain()
487 … // The data buffer should be large enough to fit the size of the data, as described by in from_tx_virtq_chain()
488 // the header descriptor. in from_tx_virtq_chain()
503 /// There must be two descriptors in the chain, both writable: a header descriptor and a data
504 /// descriptor.
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
511 /// feature in virtio-spec
512 /// [here](https://github.com/oasis-tcs/virtio-spec/issues/140).
519 /// # use virtio_queue::{Descriptor, Queue, QueueT};
536 /// # fn create_queue_with_chain(m: &GuestMemoryMmap) -> Queue {
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),
548 /// // Create a queue and populate it with a descriptor chain.
554 /// // Make sure the header is zeroed out first.
558 /// // Write data to the packet, using the setters.
585 ) -> Result<Self> in from_rx_virtq_chain()
593 // All RX buffers must be device-writable. in from_rx_virtq_chain()
598 // The packet header should fit inside the head descriptor. in from_rx_virtq_chain()
607 // Starting from Linux 6.2 the virtio-vsock driver can use a single descriptor for both in from_rx_virtq_chain()
608 // header and data. in from_rx_virtq_chain()
615 chain_head.len() as usize - PKT_HEADER_SIZE, in from_rx_virtq_chain()
646 /// Create a packet based on one pointer for the header, and an optional one for data.
651 /// `data` slices is available for the duration of the lifetime of the new `VolatileSlice`. The
668 pub unsafe fn new(header: &mut [u8], data: Option<&mut [u8]>) -> Result<VsockPacket<'a, ()>> { in new()
675 data_slice: data.map(|data| VolatileSlice::new(data.as_mut_ptr(), data.len())), in new()
688 use virtio_queue::Descriptor;
691 fn eq(&self, other: &Self) -> bool { in eq()
736 // A device-readable packet header descriptor should be invalid. in test_from_rx_virtq_chain()
737 Descriptor::new(0x10_0000, 0x100, 0, 0), in test_from_rx_virtq_chain()
738 Descriptor::new(0x20_0000, 0x100, VRING_DESC_F_WRITE as u16, 0), in test_from_rx_virtq_chain()
748 // A header length < PKT_HEADER_SIZE is invalid. in test_from_rx_virtq_chain()
749 Descriptor::new( in test_from_rx_virtq_chain()
751 PKT_HEADER_SIZE as u32 - 1, in test_from_rx_virtq_chain()
755 Descriptor::new(0x20_0000, 0x100, VRING_DESC_F_WRITE as u16, 0), in test_from_rx_virtq_chain()
764 Descriptor::new( in test_from_rx_virtq_chain()
770 Descriptor::new( in test_from_rx_virtq_chain()
784 // The data descriptor should always be present on the RX path. in test_from_rx_virtq_chain()
785 Descriptor::new( in test_from_rx_virtq_chain()
799 Descriptor::new(0x10_0000, 0x100, 0, 0), in test_from_rx_virtq_chain()
800 Descriptor::new(0x20_0000, 0x100, VRING_DESC_F_WRITE as u16, 0), in test_from_rx_virtq_chain()
813 Descriptor::new(0x10_0000, 0x100, VRING_DESC_F_WRITE as u16, 0), in test_from_rx_virtq_chain()
814 Descriptor::new(0x20_0000, 0x100, VRING_DESC_F_WRITE as u16, 0), in test_from_rx_virtq_chain()
824 // The header is outside the memory bounds. in test_from_rx_virtq_chain()
825 Descriptor::new(0x20_0000, 0x100, VRING_DESC_F_WRITE as u16, 0), in test_from_rx_virtq_chain()
826 Descriptor::new(0x30_0000, 0x100, VRING_DESC_F_WRITE as u16, 0), in test_from_rx_virtq_chain()
837 Descriptor::new(0x5_0000, 0x100, VRING_DESC_F_WRITE as u16, 0), in test_from_rx_virtq_chain()
838 // A device-readable packet data descriptor should be invalid. in test_from_rx_virtq_chain()
839 Descriptor::new(0x8_0000, 0x100, 0, 0), in test_from_rx_virtq_chain()
847 Descriptor::new(0x5_0000, 0x100, VRING_DESC_F_WRITE as u16, 0), in test_from_rx_virtq_chain()
848 // The data array doesn't fit entirely in the memory bounds. in test_from_rx_virtq_chain()
849 Descriptor::new(0x10_0000, 0x100, VRING_DESC_F_WRITE as u16, 0), in test_from_rx_virtq_chain()
858 Descriptor::new(0x5_0000, 0x100, VRING_DESC_F_WRITE as u16, 0), in test_from_rx_virtq_chain()
859 // The data array is outside the memory bounds. in test_from_rx_virtq_chain()
860 Descriptor::new(0x20_0000, 0x100, VRING_DESC_F_WRITE as u16, 0), in test_from_rx_virtq_chain()
870 // Let's also test a valid descriptor chain. in test_from_rx_virtq_chain()
872 Descriptor::new(0x5_0000, 0x100, VRING_DESC_F_WRITE as u16, 0), in test_from_rx_virtq_chain()
873 Descriptor::new(0x8_0000, 0x100, VRING_DESC_F_WRITE as u16, 0), in test_from_rx_virtq_chain()
886 let data = packet.data_slice().unwrap(); in test_from_rx_virtq_chain() localVariable
888 data.ptr_guard().as_ptr(), in test_from_rx_virtq_chain()
891 assert_eq!(data.len(), 0x100); in test_from_rx_virtq_chain()
900 // Let's also test a valid descriptor chain, with both header and data on a single in test_from_rx_virtq_chain()
901 // descriptor. in test_from_rx_virtq_chain()
902 let v = vec![Descriptor::new( in test_from_rx_virtq_chain()
919 let data = packet.data_slice().unwrap(); in test_from_rx_virtq_chain() localVariable
921 data.ptr_guard().as_ptr(), in test_from_rx_virtq_chain()
925 assert_eq!(data.len(), 0x100); in test_from_rx_virtq_chain()
935 // A device-writable packet header descriptor should be invalid. in test_from_tx_virtq_chain()
936 Descriptor::new(0x10_0000, 0x100, VRING_DESC_F_WRITE as u16, 0), in test_from_tx_virtq_chain()
937 Descriptor::new(0x20_0000, 0x100, 0, 0), in test_from_tx_virtq_chain()
947 // A header length < PKT_HEADER_SIZE is invalid. in test_from_tx_virtq_chain()
948 Descriptor::new(0x10_0000, PKT_HEADER_SIZE as u32 - 1, 0, 0), in test_from_tx_virtq_chain()
949 Descriptor::new(0x20_0000, 0x100, 0, 0), in test_from_tx_virtq_chain()
957 // On the TX path, it is allowed to not have a data descriptor. in test_from_tx_virtq_chain()
958 let v = vec![Descriptor::new(0x10_0000, PKT_HEADER_SIZE as u32, 0, 0)]; in test_from_tx_virtq_chain()
990 Descriptor::new(0x10_0000, 0x100, 0, 0), in test_from_tx_virtq_chain()
991 Descriptor::new(0x20_0000, 0x100, 0, 0), in test_from_tx_virtq_chain()
1001 // The header is outside the memory bounds. in test_from_tx_virtq_chain()
1002 Descriptor::new(0x20_0000, 0x100, 0, 0), in test_from_tx_virtq_chain()
1003 Descriptor::new(0x30_0000, 0x100, 0, 0), in test_from_tx_virtq_chain()
1013 // Write some non-zero value to the `len` field of the header, which means there is also in test_from_tx_virtq_chain()
1014 // a data descriptor in the chain, first with a value that exceeds the maximum allowed one. in test_from_tx_virtq_chain()
1029 Descriptor::new(0x5_0000, 0x100, 0, 0), in test_from_tx_virtq_chain()
1030 Descriptor::new(0x8_0000, 0x100, 0, 0), in test_from_tx_virtq_chain()
1038 // Write some non-zero, valid value to the `len` field of the header. in test_from_tx_virtq_chain()
1053 // The data descriptor is missing. in test_from_tx_virtq_chain()
1054 Descriptor::new(0x5_0000, PKT_HEADER_SIZE as u32, 0, 0), in test_from_tx_virtq_chain()
1063 Descriptor::new(0x5_0000, 0x100, 0, 0), in test_from_tx_virtq_chain()
1064 // The data array doesn't fit entirely in the memory bounds. in test_from_tx_virtq_chain()
1065 Descriptor::new(0x10_0000, 0x100, 0, 0), in test_from_tx_virtq_chain()
1074 Descriptor::new(0x5_0000, 0x100, 0, 0), in test_from_tx_virtq_chain()
1075 // The data array is outside the memory bounds. in test_from_tx_virtq_chain()
1076 Descriptor::new(0x20_0000, 0x100, 0, 0), in test_from_tx_virtq_chain()
1087 Descriptor::new(0x5_0000, 0x100, 0, 0), in test_from_tx_virtq_chain()
1088 // A device-writable packet data descriptor should be invalid. in test_from_tx_virtq_chain()
1089 Descriptor::new(0x8_0000, 0x100, VRING_DESC_F_WRITE as u16, 0), in test_from_tx_virtq_chain()
1098 Descriptor::new(0x5_0000, 0x100, 0, 0), in test_from_tx_virtq_chain()
1099 // A data length < the length of data as described by the header. in test_from_tx_virtq_chain()
1100 Descriptor::new(0x8_0000, LEN - 1, 0, 0), in test_from_tx_virtq_chain()
1108 // Let's also test a valid descriptor chain, with both header and data. in test_from_tx_virtq_chain()
1110 Descriptor::new(0x5_0000, 0x100, 0, 0), in test_from_tx_virtq_chain()
1111 Descriptor::new(0x8_0000, 0x100, 0, 0), in test_from_tx_virtq_chain()
1126 let data = packet.data_slice().unwrap(); in test_from_tx_virtq_chain() localVariable
1128 data.ptr_guard().as_ptr(), in test_from_tx_virtq_chain()
1131 assert_eq!(data.len(), LEN as usize); in test_from_tx_virtq_chain()
1140 // Let's also test a valid descriptor chain, with both header and data on a single in test_from_tx_virtq_chain()
1141 // descriptor. in test_from_tx_virtq_chain()
1142 let v = vec![Descriptor::new( in test_from_tx_virtq_chain()
1161 let data = packet.data_slice().unwrap(); in test_from_tx_virtq_chain() localVariable
1163 data.ptr_guard().as_ptr(), in test_from_tx_virtq_chain()
1167 assert_eq!(data.len(), LEN as usize); in test_from_tx_virtq_chain()
1176 Descriptor::new(0x10_0000, 0x100, VRING_DESC_F_WRITE as u16, 0), in test_header_set_get()
1177 Descriptor::new(0x20_0000, 0x100, VRING_DESC_F_WRITE as u16, 0), in test_header_set_get()
1300 Descriptor::new(0x10_0000, 0x100, VRING_DESC_F_WRITE as u16, 0), in test_set_header_from_raw()
1301 Descriptor::new(0x20_0000, 0x100, VRING_DESC_F_WRITE as u16, 0), in test_set_header_from_raw()
1335 let invalid_slice = [0; PKT_HEADER_SIZE - 1]; in test_set_header_from_raw()
1338 Error::InvalidHeaderInputSize(PKT_HEADER_SIZE - 1) in test_set_header_from_raw()
1371 let mut hdr_raw = [0u8; PKT_HEADER_SIZE - 1]; in test_packet_new()
1375 Error::InvalidHeaderInputSize(PKT_HEADER_SIZE - 1) in test_packet_new()
1386 pub fn set_src_cid_invalid(&mut self, cid: u64) -> &mut Self { in test_set_header_field_with_invalid_offset()
1396 Descriptor::new(0x10_0000, 0x100, VRING_DESC_F_WRITE as u16, 0), in test_set_header_field_with_invalid_offset()
1397 Descriptor::new(0x20_0000, 0x100, VRING_DESC_F_WRITE as u16, 0), in test_set_header_field_with_invalid_offset()