pub struct RelativeAddressesAndOffsets
{
pub start_of_packet: UserMemoryAreaRelativeAddress,
pub length_of_packet: usize,
pub start_of_our_frame_headroom: UserMemoryAreaRelativeAddress,
pub length_of_our_frame_headroom: usize,
pub end_of_xdp_headroom: UserMemoryAreaRelativeAddress,
pub xdp_headroom_length: usize,
pub start_of_xdp_headroom: UserMemoryAreaRelativeAddress,
pub orig_addr: UserMemoryAreaRelativeAddress,
pub offset: usize,
}
impl RelativeAddressesAndOffsets
{
#[inline(always)]
pub(crate) fn xdp_headroom<'a>(&self, user_memory_area: &'a UserMemoryArea) -> &'a [u8]
{
user_memory_area.slice(self.start_of_xdp_headroom, self.xdp_headroom_length)
}
#[inline(always)]
pub(crate) fn our_frame_headroom_mut<'a>(&self, user_memory_area: &'a UserMemoryArea) -> &'a mut [u8]
{
user_memory_area.slice_mut(self.start_of_our_frame_headroom, self.length_of_our_frame_headroom)
}
#[inline(always)]
pub(crate) fn ethernet_packet_mut<'a>(&self, user_memory_area: &'a UserMemoryArea) -> &'a mut [u8]
{
user_memory_area.slice_mut(self.start_of_packet, self.length_of_packet)
}
#[inline(always)]
fn minimum_end_of_chunk(&self) -> UserMemoryAreaRelativeAddress
{
self.start_of_packet + self.length_of_packet
}
#[inline(always)]
pub(crate) fn minimum_tailroom_length(&self, chunk_size: impl ChunkSize) -> usize
{
let minimum_end_of_chunk = self.minimum_end_of_chunk();
let length_occupied = minimum_end_of_chunk - self.orig_addr;
let chunk_size: usize = chunk_size.into();
debug_assert!(length_occupied <= chunk_size);
(chunk_size - length_occupied) as usize
}
#[inline(always)]
pub(crate) fn fill_frame_descriptor_bitfield_if_constructed_from_received_frame_descriptor_if_aligned(&self) -> FrameDescriptorBitfield
{
FrameDescriptorBitfield::for_aligned(self.start_of_packet)
}
#[inline(always)]
pub(crate) fn fill_frame_descriptor_bitfield_if_constructed_from_received_frame_descriptor_if_unaligned(&self) -> FrameDescriptorBitfield
{
FrameDescriptorBitfield::for_unaligned(self.orig_addr, self.offset)
}
#[inline(always)]
pub(crate) fn fill_frame_descriptor_bitfield_if_unaligned(&self) -> FrameDescriptorBitfield
{
FrameDescriptorBitfield::for_unaligned(self.orig_addr, self.offset)
}
#[inline(always)]
pub(crate) fn transmit_frame_descriptor_bitfield_if_unaligned(&self) -> FrameDescriptorBitfield
{
FrameDescriptorBitfield::for_unaligned(self.orig_addr, self.offset)
}
const TransmittedXdpHeadroomLength: usize = 0;
#[inline(always)]
pub(crate) fn for_transmitted_frame_descriptor(orig_addr: UserMemoryAreaRelativeAddress, frame_headroom: FrameHeadroom, length_of_packet: usize) -> Self
{
let start_of_xdp_headroom = orig_addr;
let xdp_headroom_length: usize = Self::TransmittedXdpHeadroomLength;
let end_of_xdp_headroom = start_of_xdp_headroom + xdp_headroom_length;
let start_of_our_frame_headroom = end_of_xdp_headroom;
let length_of_our_frame_headroom = frame_headroom.into();
let start_of_packet = start_of_our_frame_headroom + length_of_our_frame_headroom;
let offset = xdp_headroom_length + length_of_our_frame_headroom;
Self
{
start_of_packet,
length_of_packet,
start_of_our_frame_headroom,
length_of_our_frame_headroom,
end_of_xdp_headroom,
xdp_headroom_length,
start_of_xdp_headroom,
orig_addr,
offset,
}
}
#[inline(always)]
pub(crate) fn from_completed_frame_descriptor_if_aligned(frame_descriptor_bitfield: FrameDescriptorBitfield, frame_headroom: FrameHeadroom) -> Self
{
let start_of_packet = frame_descriptor_bitfield.start_of_packet_if_aligned();
let length_of_packet = 0;
let length_of_our_frame_headroom = frame_headroom.into();
let start_of_our_frame_headroom = start_of_packet - length_of_our_frame_headroom;
let end_of_xdp_headroom = start_of_our_frame_headroom;
let xdp_headroom_length = Self::TransmittedXdpHeadroomLength;
let start_of_xdp_headroom = end_of_xdp_headroom - xdp_headroom_length;
let orig_addr = start_of_xdp_headroom;
let offset = xdp_headroom_length + length_of_our_frame_headroom;
Self
{
start_of_packet,
length_of_packet,
start_of_our_frame_headroom,
length_of_our_frame_headroom,
end_of_xdp_headroom,
xdp_headroom_length,
start_of_xdp_headroom,
orig_addr,
offset,
}
}
#[inline(always)]
pub(crate) fn from_completed_frame_descriptor_if_unaligned(frame_descriptor_bitfield: FrameDescriptorBitfield, frame_headroom: FrameHeadroom) -> Self
{
let start_of_packet = frame_descriptor_bitfield.start_of_packet_if_unaligned();
let length_of_packet = 0;
let length_of_our_frame_headroom = frame_headroom.into();
let start_of_our_frame_headroom = start_of_packet - length_of_our_frame_headroom;
let end_of_xdp_headroom = start_of_our_frame_headroom;
let xdp_headroom_length = Self::TransmittedXdpHeadroomLength;
let start_of_xdp_headroom = end_of_xdp_headroom - xdp_headroom_length;
let orig_addr = start_of_xdp_headroom;
debug_assert_eq!(orig_addr, frame_descriptor_bitfield.orig_addr_if_unaligned());
let offset = xdp_headroom_length + length_of_our_frame_headroom;
debug_assert_eq!(offset, frame_descriptor_bitfield.offset_if_unaligned());
Self
{
start_of_packet,
length_of_packet,
start_of_our_frame_headroom,
length_of_our_frame_headroom,
end_of_xdp_headroom,
xdp_headroom_length,
start_of_xdp_headroom,
orig_addr,
offset,
}
}
#[inline(always)]
pub(crate) fn start_of_packet_for_fill_queue_if_aligned(orig_addr: UserMemoryAreaRelativeAddress, frame_headroom: FrameHeadroom) -> UserMemoryAreaRelativeAddress
{
let xdp_headroom_length = XDP_PACKET_HEADROOM;
let length_of_our_frame_headroom: usize = frame_headroom.into();
let offset = xdp_headroom_length + length_of_our_frame_headroom;
orig_addr + offset
}
#[inline(always)]
pub(crate) fn from_received_frame_descriptor_if_aligned(frame_descriptor_bitfield: FrameDescriptorBitfield, length_of_packet: u32, frame_headroom: FrameHeadroom) -> Self
{
let start_of_packet = frame_descriptor_bitfield.start_of_packet_if_aligned();
let length_of_packet = length_of_packet as usize;
let length_of_our_frame_headroom = frame_headroom.into();
let start_of_our_frame_headroom = start_of_packet - length_of_our_frame_headroom;
let end_of_xdp_headroom = start_of_our_frame_headroom;
let xdp_headroom_length = XDP_PACKET_HEADROOM;
let start_of_xdp_headroom = start_of_our_frame_headroom - xdp_headroom_length;
let orig_addr = end_of_xdp_headroom - xdp_headroom_length;
let offset = (start_of_packet - orig_addr) as usize;
Self
{
start_of_packet,
length_of_packet,
start_of_our_frame_headroom,
length_of_our_frame_headroom,
end_of_xdp_headroom,
xdp_headroom_length,
start_of_xdp_headroom,
orig_addr,
offset,
}
}
#[inline(always)]
pub(crate) fn from_received_frame_descriptor_if_unaligned(frame_descriptor_bitfield: FrameDescriptorBitfield, length_of_packet: u32, frame_headroom: FrameHeadroom) -> Self
{
let orig_addr = frame_descriptor_bitfield.orig_addr_if_unaligned();
let offset = frame_descriptor_bitfield.offset_if_unaligned() as usize;
let start_of_packet = orig_addr + offset;
let length_of_packet = length_of_packet as usize;
let length_of_our_frame_headroom = frame_headroom.into();
let start_of_our_frame_headroom = start_of_packet - length_of_our_frame_headroom;
let end_of_xdp_headroom = start_of_our_frame_headroom;
let xdp_headroom_length = offset - length_of_our_frame_headroom;
debug_assert_eq!(xdp_headroom_length, XDP_PACKET_HEADROOM);
let start_of_xdp_headroom = start_of_our_frame_headroom - xdp_headroom_length;
Self
{
start_of_packet,
length_of_packet,
start_of_our_frame_headroom,
length_of_our_frame_headroom,
end_of_xdp_headroom,
xdp_headroom_length,
start_of_xdp_headroom,
orig_addr,
offset,
}
}
}