pub fn from_tx_virtq_head(hdr_desc: &DescriptorChain) -> Result<Self> {
        Self::check_hdr_desc(hdr_desc, false)?;

        // Validate the packet header address
        if !hdr_desc.mem.check_range(hdr_desc.addr, VSOCK_PKT_HDR_SIZE) {
            return Err(VsockError::GuestMemoryBounds);
        }

        let mut pkt = Self {
            hdr_addr: hdr_desc.addr,
            // On the Tx path the header is provided by the guest and is read only for Firecracker.
            // So we read it here once and we work with the local copy from now on.
            hdr: hdr_desc
                .mem
                .read_obj(hdr_desc.addr)
                .map_err(VsockError::GuestMemoryMmap)?,
            buf_addr: None,
            buf_size: 0,
        };

        // No point looking for a data/buffer descriptor, if the packet is zero-lengthed.
        if pkt.len() == 0 {
            return Ok(pkt);
        }

        // Reject weirdly-sized packets.
        pkt.check_len()?;

        pkt.init_buf(hdr_desc, false)?;

        // The data buffer should be large enough to fit the size of the data, as described by
        // the header descriptor.
        if pkt.buf_size < pkt.len() as usize {
            return Err(VsockError::BufDescTooSmall);
        }

        Ok(pkt)
    }
/// Create the packet wrapper from a TX virtq chain head.
///
/// The chain head is expected to hold valid packet header data. A following packet buffer
/// descriptor can optionally end the chain. Bounds and pointer checks are performed when
/// creating the wrapper.
Create the packet wrapper from a TX virtq chain head.
The chain head is expected to hold valid packet header data. A following packet buffer
descriptor can optionally end the chain. Bounds and pointer checks are performed when
creating the wrapper.
Create the packet wrapper from a TX virtq chain head . The chain head is expected to hold valid packet header data . A following packet buffer descriptor can optionally end the chain . Bounds and pointer checks are performed when creating the wrapper .
pub fn from_tx_virtq_head(hdr_desc: &DescriptorChain) -> Result<Self> {
        Self::check_hdr_desc(hdr_desc, false)?;
        // Validate the packet header address
        if !hdr_desc.mem.check_range(hdr_desc.addr, VSOCK_PKT_HDR_SIZE) {
            return Err(VsockError::GuestMemoryBounds);
        }
        let mut pkt = Self {
            hdr_addr: hdr_desc.addr,
            // On the Tx path the header is provided by the guest and is read only for Firecracker.
            // So we read it here once and we work with the local copy from now on.
            hdr: hdr_desc
                .mem
                .read_obj(hdr_desc.addr)
                .map_err(VsockError::GuestMemoryMmap)?,
            buf_addr: None,
            buf_size: 0,
        };
        // No point looking for a data/buffer descriptor, if the packet is zero-lengthed.
        if pkt.len() == 0 {
            return Ok(pkt);
        }
        // Reject weirdly-sized packets.
        pkt.check_len()?;
        pkt.init_buf(hdr_desc, false)?;
        // The data buffer should be large enough to fit the size of the data, as described by
        // the header descriptor.
        if pkt.buf_size < pkt.len() as usize {
            return Err(VsockError::BufDescTooSmall);
        }
        Ok(pkt)
    }
pub fn from_tx_virtq_head ( hdr_desc : & DescriptorChain ) -> Result < Self > { Self :: check_hdr_desc ( hdr_desc , false ) ? ; // Validate the packet header address if ! hdr_desc . mem . check_range ( hdr_desc . addr , VSOCK_PKT_HDR_SIZE ) { return Err ( VsockError :: GuestMemoryBounds ) ; } let mut pkt = Self { hdr_addr : hdr_desc . addr , // On the Tx path the header is provided by the guest and is read only for Firecracker. // So we read it here once and we work with the local copy from now on. hdr : hdr_desc . mem . read_obj ( hdr_desc . addr ) . map_err ( VsockError :: GuestMemoryMmap ) ? , buf_addr : None , buf_size : 0 , } ; // No point looking for a data/buffer descriptor, if the packet is zero-lengthed. if pkt . len ( ) == 0 { return Ok ( pkt ) ; } // Reject weirdly-sized packets. pkt . check_len ( ) ? ; pkt . init_buf ( hdr_desc , false ) ? ; // The data buffer should be large enough to fit the size of the data, as described by // the header descriptor. if pkt . buf_size < pkt . len ( ) as usize { return Err ( VsockError :: BufDescTooSmall ) ; } Ok ( pkt ) }
Create the packet wrapper from a TX virtq chain head.
Create the packet wrapper from a TX virtq chain head .
hdr_desc
&DescriptorChain
hdr_desc
&DescriptorChain