Struct virtio_vsock::packet::VsockPacket

source ·
pub struct VsockPacket<'a, B: BitmapSlice> { /* private fields */ }
Expand description

The vsock packet, implemented as a wrapper over a virtio descriptor chain:

  • the chain head, holding the packet header;
  • an optional data/buffer descriptor, only present for data packets (for VSOCK_OP_RW requests).

Implementations§

source§

impl<'a, B: BitmapSlice> VsockPacket<'a, B>

source

pub fn header_slice(&self) -> &VolatileSlice<'a, B>

Return a reference to the header_slice of the packet.

source

pub fn data_slice(&self) -> Option<&VolatileSlice<'a, B>>

Return a reference to the data_slice of the packet.

source

pub fn set_header_from_raw(&mut self, bytes: &[u8]) -> Result<()>

Write to the packet header from an input of raw bytes.

§Example
use virtio_vsock::packet::{VsockPacket, PKT_HEADER_SIZE};

const MAX_PKT_BUF_SIZE: u32 = 64 * 1024;

let mem = GuestMemoryMmap::<()>::from_ranges(&[(GuestAddress(0), 0x10_0000)]).unwrap();
// Create a queue and populate it with a descriptor chain.
let mut queue = create_queue_with_chain(&mem);

while let Some(mut head) = queue.pop_descriptor_chain(&mem) {
    let mut pkt = VsockPacket::from_rx_virtq_chain(&mem, &mut head, MAX_PKT_BUF_SIZE).unwrap();
    pkt.set_header_from_raw(&[0u8; PKT_HEADER_SIZE]).unwrap();
}
source

pub fn src_cid(&self) -> u64

Return the src_cid of the header.

source

pub fn set_src_cid(&mut self, cid: u64) -> &mut Self

Set the src_cid of the header.

source

pub fn dst_cid(&self) -> u64

Return the dst_cid of the header.

source

pub fn set_dst_cid(&mut self, cid: u64) -> &mut Self

Set the dst_cid of the header.

source

pub fn src_port(&self) -> u32

Return the src_port of the header.

source

pub fn set_src_port(&mut self, port: u32) -> &mut Self

Set the src_port of the header.

source

pub fn dst_port(&self) -> u32

Return the dst_port of the header.

source

pub fn set_dst_port(&mut self, port: u32) -> &mut Self

Set the dst_port of the header.

source

pub fn len(&self) -> u32

Return the len of the header.

source

pub fn is_empty(&self) -> bool

Returns whether the len field of the header is 0 or not.

source

pub fn set_len(&mut self, len: u32) -> &mut Self

Set the len of the header.

source

pub fn type_(&self) -> u16

Return the type of the header.

source

pub fn set_type(&mut self, type_: u16) -> &mut Self

Set the type of the header.

source

pub fn op(&self) -> u16

Return the op of the header.

source

pub fn set_op(&mut self, op: u16) -> &mut Self

Set the op of the header.

source

pub fn flags(&self) -> u32

Return the flags of the header.

source

pub fn set_flags(&mut self, flags: u32) -> &mut Self

Set the flags of the header.

source

pub fn set_flag(&mut self, flag: u32) -> &mut Self

Set a specific flag of the header.

source

pub fn buf_alloc(&self) -> u32

Return the buf_alloc of the header.

source

pub fn set_buf_alloc(&mut self, buf_alloc: u32) -> &mut Self

Set the buf_alloc of the header.

source

pub fn fwd_cnt(&self) -> u32

Return the fwd_cnt of the header.

source

pub fn set_fwd_cnt(&mut self, fwd_cnt: u32) -> &mut Self

Set the fwd_cnt of the header.

source

pub fn 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,

Create the packet wrapper from a TX chain.

The chain head is expected to hold a valid packet header. A following packet data descriptor can optionally end the chain.

§Arguments
  • mem - the GuestMemory object that can be used to access the queue buffers.
  • desc_chain - the descriptor chain corresponding to a packet.
  • max_data_size - the maximum size allowed for the packet payload, that was negotiated between the device and the driver. Tracking issue for defining this feature in virtio-spec here.
§Example
use virtio_vsock::packet::{VsockPacket, PKT_HEADER_SIZE};

const MAX_PKT_BUF_SIZE: u32 = 64 * 1024;
const OP_RW: u16 = 5;

let mem = GuestMemoryMmap::<()>::from_ranges(&[(GuestAddress(0), 0x10000)]).unwrap();
// Create a queue and populate it with a descriptor chain.
let mut queue = create_queue_with_chain(&mem);

while let Some(mut head) = queue.pop_descriptor_chain(&mem) {
    let pkt = match VsockPacket::from_tx_virtq_chain(&mem, &mut head, MAX_PKT_BUF_SIZE) {
        Ok(pkt) => pkt,
        Err(_e) => {
            // Do some error handling.
            queue.add_used(&mem, head.head_index(), 0);
            continue;
        }
    };
    // Here we would send the packet to the backend. Depending on the operation type, a
    // different type of action will be done.

    // For example, if it's a RW packet, we will forward the packet payload to the backend.
    if pkt.op() == OP_RW {
        // Send the packet payload to the backend.
    }
    queue.add_used(&mem, head.head_index(), 0);
}
source

pub fn 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,

Create the packet wrapper from an RX chain.

There must be two descriptors in the chain, both writable: a header descriptor and a data descriptor.

§Arguments
  • mem - the GuestMemory object that can be used to access the queue buffers.
  • desc_chain - the descriptor chain corresponding to a packet.
  • max_data_size - the maximum size allowed for the packet payload, that was negotiated between the device and the driver. Tracking issue for defining this feature in virtio-spec here.
§Example
use virtio_vsock::packet::{VsockPacket, PKT_HEADER_SIZE};


let mem = GuestMemoryMmap::<()>::from_ranges(&[(GuestAddress(0), 0x10000)]).unwrap();
// Create a queue and populate it with a descriptor chain.
let mut queue = create_queue_with_chain(&mem);

while let Some(mut head) = queue.pop_descriptor_chain(&mem) {
    let used_len = match VsockPacket::from_rx_virtq_chain(&mem, &mut head, MAX_PKT_BUF_SIZE) {
        Ok(mut pkt) => {
            // Make sure the header is zeroed out first.
            pkt.header_slice()
                .write(&[0u8; PKT_HEADER_SIZE], 0)
                .unwrap();
            // Write data to the packet, using the setters.
            pkt.set_src_cid(SRC_CID)
                .set_dst_cid(DST_CID)
                .set_src_port(SRC_PORT)
                .set_dst_port(DST_PORT)
                .set_type(TYPE_STREAM)
                .set_buf_alloc(BUF_ALLOC)
                .set_fwd_cnt(FWD_CNT);
            // In this example, we are sending a RW packet.
            pkt.data_slice()
                .unwrap()
                .write_slice(&[1u8; LEN as usize], 0);
            pkt.set_op(OP_RW).set_len(LEN);
            pkt.header_slice().len() as u32 + LEN
        }
        Err(_e) => {
            // Do some error handling.
            0
        }
    };
    queue.add_used(&mem, head.head_index(), used_len);
}
source§

impl<'a> VsockPacket<'a, ()>

source

pub unsafe fn new( header: &mut [u8], data: Option<&mut [u8]>, ) -> Result<VsockPacket<'a, ()>>

Create a packet based on one pointer for the header, and an optional one for data.

§Safety

To use this safely, the caller must guarantee that the memory pointed to by the hdr and data slices is available for the duration of the lifetime of the new VolatileSlice. The caller must also guarantee that all other users of the given chunk of memory are using volatile accesses.

§Example
use virtio_vsock::packet::{VsockPacket, PKT_HEADER_SIZE};

const LEN: usize = 16;

let mut pkt_raw = [0u8; PKT_HEADER_SIZE + LEN];
let (hdr_raw, data_raw) = pkt_raw.split_at_mut(PKT_HEADER_SIZE);
// Safe because `hdr_raw` and `data_raw` live for as long as the scope of the current
// example.
let packet = unsafe { VsockPacket::new(hdr_raw, Some(data_raw)).unwrap() };

Trait Implementations§

source§

impl<'a, B: Debug + BitmapSlice> Debug for VsockPacket<'a, B>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'a, B> Freeze for VsockPacket<'a, B>
where B: Freeze,

§

impl<'a, B> RefUnwindSafe for VsockPacket<'a, B>
where B: RefUnwindSafe,

§

impl<'a, B> !Send for VsockPacket<'a, B>

§

impl<'a, B> !Sync for VsockPacket<'a, B>

§

impl<'a, B> Unpin for VsockPacket<'a, B>
where B: Unpin,

§

impl<'a, B> UnwindSafe for VsockPacket<'a, B>
where B: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

source§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.