1use std::fmt::{self, Display};
36use std::ops::Deref;
37
38use virtio_queue::DescriptorChain;
39use vm_memory::bitmap::{BitmapSlice, WithBitmapSlice};
40use vm_memory::{
41 Address, ByteValued, Bytes, GuestMemory, GuestMemoryError, GuestMemoryRegion, Le16, Le32, Le64,
42 VolatileMemoryError, VolatileSlice,
43};
44
45#[derive(Debug)]
47pub enum Error {
48 DescriptorChainTooShort,
50 DescriptorLengthTooSmall,
52 DescriptorLengthTooLong,
54 InvalidHeaderInputSize(usize),
56 InvalidHeaderLen(u32),
58 InvalidMemoryAccess(GuestMemoryError),
60 InvalidVolatileAccess(VolatileMemoryError),
62 UnexpectedReadOnlyDescriptor,
64 UnexpectedWriteOnlyDescriptor,
66}
67
68impl std::error::Error for Error {}
69
70impl Display for Error {
71 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)]
108pub 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
122unsafe impl ByteValued for PacketHeader {}
126pub const PKT_HEADER_SIZE: usize = std::mem::size_of::<PacketHeader>();
135
136const SRC_CID_OFFSET: usize = 0;
138const DST_CID_OFFSET: usize = 8;
139const SRC_PORT_OFFSET: usize = 16;
140const DST_PORT_OFFSET: usize = 20;
141const LEN_OFFSET: usize = 24;
142const TYPE_OFFSET: usize = 28;
143const OP_OFFSET: usize = 30;
144const FLAGS_OFFSET: usize = 32;
145const BUF_ALLOC_OFFSET: usize = 36;
146const FWD_CNT_OFFSET: usize = 40;
147
148pub type Result<T> = std::result::Result<T, Error>;
150
151#[derive(Debug)]
155pub struct VsockPacket<'a, B: BitmapSlice> {
156 header_slice: VolatileSlice<'a, B>,
162 header: PacketHeader,
163 data_slice: Option<VolatileSlice<'a, B>>,
164}
165
166macro_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 .unwrap();
177 };
178}
179
180impl<'a, B: BitmapSlice> VsockPacket<'a, B> {
181 pub fn header_slice(&self) -> &VolatileSlice<'a, B> {
183 &self.header_slice
184 }
185
186 pub fn data_slice(&self) -> Option<&VolatileSlice<'a, B>> {
188 self.data_slice.as_ref()
189 }
190
191 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 pub fn src_cid(&self) -> u64 {
241 self.header.src_cid.into()
242 }
243
244 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 pub fn dst_cid(&self) -> u64 {
252 self.header.dst_cid.into()
253 }
254
255 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 pub fn src_port(&self) -> u32 {
263 self.header.src_port.into()
264 }
265
266 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 pub fn dst_port(&self) -> u32 {
274 self.header.dst_port.into()
275 }
276
277 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 pub fn len(&self) -> u32 {
285 self.header.len.into()
286 }
287
288 pub fn is_empty(&self) -> bool {
290 self.len() == 0
291 }
292
293 pub fn set_len(&mut self, len: u32) -> &mut Self {
295 set_header_field!(self, len, LEN_OFFSET, len);
296 self
297 }
298
299 pub fn type_(&self) -> u16 {
301 self.header.type_.into()
302 }
303
304 pub fn set_type(&mut self, type_: u16) -> &mut Self {
306 set_header_field!(self, type_, TYPE_OFFSET, type_);
307 self
308 }
309
310 pub fn op(&self) -> u16 {
312 self.header.op.into()
313 }
314
315 pub fn set_op(&mut self, op: u16) -> &mut Self {
317 set_header_field!(self, op, OP_OFFSET, op);
318 self
319 }
320
321 pub fn flags(&self) -> u32 {
323 self.header.flags.into()
324 }
325
326 pub fn set_flags(&mut self, flags: u32) -> &mut Self {
328 set_header_field!(self, flags, FLAGS_OFFSET, flags);
329 self
330 }
331
332 pub fn set_flag(&mut self, flag: u32) -> &mut Self {
334 self.set_flags(self.flags() | flag);
335 self
336 }
337
338 pub fn buf_alloc(&self) -> u32 {
340 self.header.buf_alloc.into()
341 }
342
343 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 pub fn fwd_cnt(&self) -> u32 {
351 self.header.fwd_cnt.into()
352 }
353
354 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 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 if chain_head.is_write_only() {
432 return Err(Error::UnexpectedWriteOnlyDescriptor);
433 }
434
435 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 pkt.is_empty() {
456 return Ok(pkt);
457 }
458
459 if pkt.len() > max_data_size {
461 return Err(Error::InvalidHeaderLen(pkt.len()));
462 }
463
464 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 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 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 if !chain_head.is_write_only() {
595 return Err(Error::UnexpectedReadOnlyDescriptor);
596 }
597
598 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 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
645impl<'a> VsockPacket<'a, ()> {
646 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)]
681mod 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 {
691 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 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]
730 fn test_from_rx_virtq_chain() {
731 let mem: GuestMemoryMmap =
732 GuestMemoryMmap::from_ranges(&[(GuestAddress(0), 0x1000_0000)]).unwrap();
733
734 let v = vec![
736 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 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 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 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 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 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 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 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 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 assert_eq!(
896 VsockPacket::from_rx_virtq_chain(&mem, &mut chain, MAX_PKT_BUF_SIZE).unwrap_err(),
897 Error::DescriptorChainTooShort
898 );
899
900 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]
929 fn test_from_tx_virtq_chain() {
930 let mem: GuestMemoryMmap =
931 GuestMemoryMmap::from_ranges(&[(GuestAddress(0), 0x1000_0000)]).unwrap();
932
933 let v = vec![
935 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 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 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 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 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 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 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 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 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 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 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 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 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 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 assert_eq!(
1136 VsockPacket::from_tx_virtq_chain(&mem, &mut chain, MAX_PKT_BUF_SIZE).unwrap_err(),
1137 Error::DescriptorChainTooShort
1138 );
1139
1140 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 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]
1171 fn test_header_set_get() {
1172 let mem: GuestMemoryMmap =
1173 GuestMemoryMmap::from_ranges(&[(GuestAddress(0), 0x30_0000)]).unwrap();
1174 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]
1295 fn test_set_header_from_raw() {
1296 let mem: GuestMemoryMmap =
1297 GuestMemoryMmap::from_ranges(&[(GuestAddress(0), 0x30_0000)]).unwrap();
1298 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 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]
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 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 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 unsafe { VsockPacket::new(&mut hdr_raw, None).unwrap_err() },
1375 Error::InvalidHeaderInputSize(PKT_HEADER_SIZE - 1)
1376 );
1377 }
1378
1379 #[test]
1380 #[should_panic]
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 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 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}