|
@@ -2,8 +2,11 @@
|
|
|
|
|
|
use super::error::{self, SocketError};
|
|
|
use crate::volatile::ReadOnly;
|
|
|
-use core::convert::TryInto;
|
|
|
-use core::{convert::TryFrom, mem::size_of};
|
|
|
+use core::{
|
|
|
+ convert::{TryFrom, TryInto},
|
|
|
+ fmt,
|
|
|
+ mem::size_of,
|
|
|
+};
|
|
|
use zerocopy::{
|
|
|
byteorder::{LittleEndian, U16, U32, U64},
|
|
|
AsBytes, FromBytes,
|
|
@@ -19,7 +22,7 @@ pub struct VirtioVsockConfig {
|
|
|
///
|
|
|
/// We need to split the guest_cid into two parts because VirtIO only guarantees 4 bytes alignment.
|
|
|
pub guest_cid_low: ReadOnly<u32>,
|
|
|
- pub _guest_cid_high: ReadOnly<u32>,
|
|
|
+ pub guest_cid_high: ReadOnly<u32>,
|
|
|
}
|
|
|
|
|
|
/// The message header for data packets sent on the tx/rx queues
|
|
@@ -31,7 +34,7 @@ pub struct VirtioVsockHdr {
|
|
|
pub src_port: U32<LittleEndian>,
|
|
|
pub dst_port: U32<LittleEndian>,
|
|
|
pub len: U32<LittleEndian>,
|
|
|
- pub r#type: U16<LittleEndian>,
|
|
|
+ pub socket_type: U16<LittleEndian>,
|
|
|
pub op: U16<LittleEndian>,
|
|
|
pub flags: U32<LittleEndian>,
|
|
|
pub buf_alloc: U32<LittleEndian>,
|
|
@@ -46,7 +49,7 @@ impl Default for VirtioVsockHdr {
|
|
|
src_port: 0.into(),
|
|
|
dst_port: 0.into(),
|
|
|
len: 0.into(),
|
|
|
- r#type: TYPE_STREAM_SOCKET.into(),
|
|
|
+ socket_type: TYPE_STREAM_SOCKET.into(),
|
|
|
op: 0.into(),
|
|
|
flags: 0.into(),
|
|
|
buf_alloc: 0.into(),
|
|
@@ -62,11 +65,8 @@ pub struct VirtioVsockPacket<'a> {
|
|
|
}
|
|
|
|
|
|
impl<'a> VirtioVsockPacket<'a> {
|
|
|
- pub fn read_from(buffer: &'a [u8]) -> Result<Self, SocketError> {
|
|
|
- let hdr = buffer
|
|
|
- .get(0..size_of::<VirtioVsockHdr>())
|
|
|
- .ok_or(SocketError::BufferTooShort)?;
|
|
|
- let hdr = VirtioVsockHdr::read_from(hdr).ok_or(SocketError::PacketParsingFailed)?;
|
|
|
+ pub fn read_from(buffer: &'a [u8]) -> error::Result<Self> {
|
|
|
+ let hdr = VirtioVsockHdr::read_from_prefix(buffer).ok_or(SocketError::BufferTooShort)?;
|
|
|
let data_end = size_of::<VirtioVsockHdr>() + (hdr.len.get() as usize);
|
|
|
let data = buffer
|
|
|
.get(size_of::<VirtioVsockHdr>()..data_end)
|
|
@@ -74,7 +74,7 @@ impl<'a> VirtioVsockPacket<'a> {
|
|
|
Ok(Self { hdr, data })
|
|
|
}
|
|
|
|
|
|
- pub fn op(&self) -> error::Result<Op> {
|
|
|
+ pub fn op(&self) -> error::Result<VirtioVsockOp> {
|
|
|
self.hdr.op.try_into()
|
|
|
}
|
|
|
}
|
|
@@ -87,48 +87,62 @@ pub struct VirtioVsockEvent {
|
|
|
pub id: U32<LittleEndian>,
|
|
|
}
|
|
|
|
|
|
-#[allow(non_camel_case_types)]
|
|
|
-#[derive(Copy, Clone, Eq, PartialEq, Debug)]
|
|
|
+#[derive(Copy, Clone, Eq, PartialEq)]
|
|
|
#[repr(u16)]
|
|
|
-pub enum Op {
|
|
|
- VIRTIO_VSOCK_OP_INVALID = 0,
|
|
|
+pub enum VirtioVsockOp {
|
|
|
+ Invalid = 0,
|
|
|
|
|
|
/* Connect operations */
|
|
|
- VIRTIO_VSOCK_OP_REQUEST = 1,
|
|
|
- VIRTIO_VSOCK_OP_RESPONSE = 2,
|
|
|
- VIRTIO_VSOCK_OP_RST = 3,
|
|
|
- VIRTIO_VSOCK_OP_SHUTDOWN = 4,
|
|
|
+ Request = 1,
|
|
|
+ Response = 2,
|
|
|
+ Rst = 3,
|
|
|
+ Shutdown = 4,
|
|
|
|
|
|
/* To send payload */
|
|
|
- VIRTIO_VSOCK_OP_RW = 5,
|
|
|
+ Rw = 5,
|
|
|
|
|
|
/* Tell the peer our credit info */
|
|
|
- VIRTIO_VSOCK_OP_CREDIT_UPDATE = 6,
|
|
|
+ CreditUpdate = 6,
|
|
|
/* Request the peer to send the credit info to us */
|
|
|
- VIRTIO_VSOCK_OP_CREDIT_REQUEST = 7,
|
|
|
+ CreditRequest = 7,
|
|
|
}
|
|
|
|
|
|
-impl Into<U16<LittleEndian>> for Op {
|
|
|
+impl Into<U16<LittleEndian>> for VirtioVsockOp {
|
|
|
fn into(self) -> U16<LittleEndian> {
|
|
|
(self as u16).into()
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl TryFrom<U16<LittleEndian>> for Op {
|
|
|
+impl TryFrom<U16<LittleEndian>> for VirtioVsockOp {
|
|
|
type Error = SocketError;
|
|
|
|
|
|
fn try_from(v: U16<LittleEndian>) -> Result<Self, Self::Error> {
|
|
|
let op = match u16::from(v) {
|
|
|
- 0 => Self::VIRTIO_VSOCK_OP_INVALID,
|
|
|
- 1 => Self::VIRTIO_VSOCK_OP_REQUEST,
|
|
|
- 2 => Self::VIRTIO_VSOCK_OP_RESPONSE,
|
|
|
- 3 => Self::VIRTIO_VSOCK_OP_RST,
|
|
|
- 4 => Self::VIRTIO_VSOCK_OP_SHUTDOWN,
|
|
|
- 5 => Self::VIRTIO_VSOCK_OP_RW,
|
|
|
- 6 => Self::VIRTIO_VSOCK_OP_CREDIT_UPDATE,
|
|
|
- 7 => Self::VIRTIO_VSOCK_OP_CREDIT_REQUEST,
|
|
|
+ 0 => Self::Invalid,
|
|
|
+ 1 => Self::Request,
|
|
|
+ 2 => Self::Response,
|
|
|
+ 3 => Self::Rst,
|
|
|
+ 4 => Self::Shutdown,
|
|
|
+ 5 => Self::Rw,
|
|
|
+ 6 => Self::CreditUpdate,
|
|
|
+ 7 => Self::CreditRequest,
|
|
|
_ => return Err(SocketError::UnknownOperation(v.into())),
|
|
|
};
|
|
|
Ok(op)
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+impl fmt::Debug for VirtioVsockOp {
|
|
|
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
+ match self {
|
|
|
+ Self::Invalid => write!(f, "VIRTIO_VSOCK_OP_INVALID"),
|
|
|
+ Self::Request => write!(f, "VIRTIO_VSOCK_OP_REQUEST"),
|
|
|
+ Self::Response => write!(f, "VIRTIO_VSOCK_OP_RESPONSE"),
|
|
|
+ Self::Rst => write!(f, "VIRTIO_VSOCK_OP_RST"),
|
|
|
+ Self::Shutdown => write!(f, "VIRTIO_VSOCK_OP_SHUTDOWN"),
|
|
|
+ Self::Rw => write!(f, "VIRTIO_VSOCK_OP_RW"),
|
|
|
+ Self::CreditUpdate => write!(f, "VIRTIO_VSOCK_OP_CREDIT_UPDATE"),
|
|
|
+ Self::CreditRequest => write!(f, "VIRTIO_VSOCK_OP_CREDIT_REQUEST"),
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|