Skip to content

Commit

Permalink
[catpowder] Enhancement: Improve XDP LibOS
Browse files Browse the repository at this point in the history
  • Loading branch information
ppenna committed Jul 3, 2024
1 parent 5021349 commit 9439fa5
Show file tree
Hide file tree
Showing 12 changed files with 137 additions and 104 deletions.
14 changes: 10 additions & 4 deletions src/rust/catpowder/win/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,12 @@ use ::windows::core::{
Error,
HRESULT,
};
use ::xdp_rs;

//======================================================================================================================
// Structures
//======================================================================================================================

/// A wrapper structure for an XDP API.
/// A wrapper structure for n XDP API endpoint.
#[repr(C)]
pub struct XdpApi(*const xdp_rs::XDP_API_TABLE);

Expand All @@ -32,15 +31,21 @@ impl XdpApi {

let result: HRESULT = unsafe { xdp_rs::XdpOpenApi(xdp_rs::XDP_API_VERSION_1, &mut api) };

let error: windows::core::Error = Error::from_hresult(result);
let error: Error = Error::from_hresult(result);
match error.code().is_ok() {
true => Ok(Self(api)),
false => Err(Fail::from(&error)),
false => {
let fail: Fail = Fail::from(&error);
error!("new(): {:?}", &fail);
Err(fail)
},
}
}

/// Gets the API table from the target API endpoint.
pub fn get(&self) -> xdp_rs::XDP_API_TABLE {
unsafe {
// TODO: consider returning individual function pointers instead of the entire table.
let api: *const xdp_rs::XDP_API_TABLE = self.0;
*api
}
Expand All @@ -54,6 +59,7 @@ impl Drop for XdpApi {
*api
};

// Closes the XDP API endpoint.
if let Some(close) = api.XdpCloseApi {
unsafe { close(self.0) };
}
Expand Down
10 changes: 7 additions & 3 deletions src/rust/catpowder/win/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,26 @@ use ::std::ops::{
Deref,
DerefMut,
};
use std::{
cell::RefCell,
rc::Rc,
};

//======================================================================================================================
// Structures
//======================================================================================================================

pub struct XdpBuffer {
b: *mut xdp_rs::XSK_BUFFER_DESCRIPTOR,
umemreg: UmemReg,
umemreg: Rc<RefCell<UmemReg>>,
}

//======================================================================================================================
// Implementations
//======================================================================================================================

impl XdpBuffer {
pub fn new(b: *mut xdp_rs::XSK_BUFFER_DESCRIPTOR, umemreg: UmemReg) -> Self {
pub fn new(b: *mut xdp_rs::XSK_BUFFER_DESCRIPTOR, umemreg: Rc<RefCell<UmemReg>>) -> Self {
Self { b, umemreg }
}

Expand All @@ -48,7 +52,7 @@ impl XdpBuffer {
}

unsafe fn addr(&self) -> *mut core::ffi::c_void {
let mut ptr: *mut u8 = self.umemreg.get_address() as *mut u8;
let mut ptr: *mut u8 = self.umemreg.borrow_mut().address() as *mut u8;
ptr = ptr.add(self.base_address() as usize);
ptr = ptr.add(self.offset() as usize);
ptr as *mut core::ffi::c_void
Expand Down
1 change: 1 addition & 0 deletions src/rust/catpowder/win/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ mod api;
mod buffer;
mod params;
mod program;
mod ring;
mod rule;
mod rx_ring;
mod socket;
Expand Down
13 changes: 7 additions & 6 deletions src/rust/catpowder/win/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,28 @@ use ::std::mem;
// Structures
//======================================================================================================================

/// A wrapper structure for a XDP redirect parameters.
#[repr(C)]
pub struct XdpRedirectParams {
redirect: xdp_rs::XDP_REDIRECT_PARAMS,
}
pub struct XdpRedirectParams(xdp_rs::XDP_REDIRECT_PARAMS);

//======================================================================================================================
// Implementations
//======================================================================================================================

impl XdpRedirectParams {
/// Creates a new XDP redirect parameters for the target socket.
pub fn new(socket: &XdpSocket) -> Self {
let redirect: xdp_rs::XDP_REDIRECT_PARAMS = {
let mut redirect: xdp_rs::_XDP_REDIRECT_PARAMS = unsafe { mem::zeroed() };
redirect.TargetType = xdp_rs::_XDP_REDIRECT_TARGET_TYPE_XDP_REDIRECT_TARGET_TYPE_XSK;
redirect.Target = socket.get_socket();
redirect
};
Self { redirect }
Self(redirect)
}

pub fn as_ptr(&self) -> &xdp_rs::XDP_REDIRECT_PARAMS {
&self.redirect
/// Gets a reference to the underlying XDP redirect parameters.
pub fn as_ref(&self) -> &xdp_rs::XDP_REDIRECT_PARAMS {
&self.0
}
}
13 changes: 9 additions & 4 deletions src/rust/catpowder/win/program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,21 @@ use crate::{
runtime::fail::Fail,
};
use ::windows::{
core::HRESULT,
core::{
Error,
HRESULT,
},
Win32::{
Foundation,
Foundation::HANDLE,
},
};
use ::xdp_rs;

//======================================================================================================================
// Structures
//======================================================================================================================

/// A wrapper structure for a XDP program.
#[repr(C)]
pub struct XdpProgram(HANDLE);

Expand Down Expand Up @@ -59,7 +62,7 @@ impl XdpProgram {
&mut handle as *mut HANDLE,
)
};
let error: windows::core::Error = windows::core::Error::from_hresult(result);
let error: Error = Error::from_hresult(result);
match error.code().is_ok() {
true => Ok(Self(handle)),
false => Err(Fail::from(&error)),
Expand All @@ -78,6 +81,8 @@ impl XdpProgram {

impl Drop for XdpProgram {
fn drop(&mut self) {
let _ = unsafe { Foundation::CloseHandle(self.0) };
if let Err(_) = unsafe { Foundation::CloseHandle(self.0) } {
error!("drop(): Failed to close xdp program handle");
}
}
}
45 changes: 45 additions & 0 deletions src/rust/catpowder/win/ring.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

//======================================================================================================================
// Structures
//======================================================================================================================

pub struct XdpRing {
ring: xdp_rs::XSK_RING,
}

//======================================================================================================================
// Implementations
//======================================================================================================================

impl XdpRing {
pub fn ring_initialize(info: &xdp_rs::XSK_RING_INFO) -> Self {
let ring = unsafe {
let mut ring: xdp_rs::XSK_RING = std::mem::zeroed();
xdp_rs::_XskRingInitialize(&mut ring, info);
ring
};
Self { ring }
}

pub fn ring_consumer_reserve(&mut self, count: u32, idx: *mut u32) -> u32 {
unsafe { xdp_rs::_XskRingConsumerReserve(&mut self.ring, count, idx) }
}

pub fn ring_consumer_release(&mut self, count: u32) {
unsafe { xdp_rs::_XskRingConsumerRelease(&mut self.ring, count) }
}

pub fn ring_producer_reserve(&mut self, count: u32, idx: *mut u32) -> u32 {
unsafe { xdp_rs::_XskRingProducerReserve(&mut self.ring, count, idx) }
}

pub fn ring_producer_submit(&mut self, count: u32) {
unsafe { xdp_rs::_XskRingProducerSubmit(&mut self.ring, count) }
}

pub fn ring_get_element(&self, idx: u32) -> *mut std::ffi::c_void {
unsafe { xdp_rs::_XskRingGetElement(&self.ring, idx) }
}
}
2 changes: 1 addition & 1 deletion src/rust/catpowder/win/rule.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ impl XdpRule {
rule.Action = xdp_rs::_XDP_RULE_ACTION_XDP_PROGRAM_ACTION_REDIRECT;
// Perform bitwise copy from redirect to rule.
rule.__bindgen_anon_1 =
mem::transmute_copy::<xdp_rs::XDP_REDIRECT_PARAMS, xdp_rs::_XDP_RULE__bindgen_ty_1>(redirect.as_ptr());
mem::transmute_copy::<xdp_rs::XDP_REDIRECT_PARAMS, xdp_rs::_XDP_RULE__bindgen_ty_1>(redirect.as_ref());

rule
};
Expand Down
18 changes: 9 additions & 9 deletions src/rust/catpowder/win/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ use crate::{
SharedObject,
},
};
use ::arrayvec::ArrayVec;
use ::std::borrow::{
use arrayvec::ArrayVec;
use std::borrow::{
Borrow,
BorrowMut,
};
Expand All @@ -39,18 +39,18 @@ use ::std::borrow::{
// Structures
//======================================================================================================================

struct CatpowderRuntimeInner {
api: XdpApi,
tx: TxRing,
rx: RxRing,
}

/// A LibOS built on top of Windows XDP.
#[derive(Clone)]
pub struct CatpowderRuntime {
inner: SharedObject<CatpowderRuntimeInner>,
}

struct CatpowderRuntimeInner {
api: XdpApi,
tx: TxRing,
rx: RxRing,
}

//======================================================================================================================
// Associated Functions
//======================================================================================================================
Expand All @@ -66,7 +66,7 @@ impl CatpowderRuntime {}
impl NetworkRuntime for CatpowderRuntime {
fn new(config: &Config) -> Result<Self, Fail> {
let ifindex: u32 = config.local_interface_index()?;
const QUEUEID: u32 = 0; // We do no use RSS, thus `queueid` is always 0.
const QUEUEID: u32 = 0; // We do no use RSS, thus queue id is always 0.

trace!("Creating XDP runtime.");
let mut api: XdpApi = XdpApi::new()?;
Expand Down
16 changes: 9 additions & 7 deletions src/rust/catpowder/win/rx_ring.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,27 @@ use crate::{
api::XdpApi,
buffer::XdpBuffer,
program::XdpProgram,
ring::XdpRing,
rule::XdpRule,
socket::{
XdpRing,
XdpSocket,
},
socket::XdpSocket,
umemreg::UmemReg,
},
runtime::{
fail::Fail,
limits,
},
};
use ::std::{
cell::RefCell,
rc::Rc,
};

//======================================================================================================================
// Structures
//======================================================================================================================

pub struct RxRing {
mem: UmemReg,
mem: Rc<RefCell<UmemReg>>,
rx_ring: XdpRing,
rx_fill_ring: XdpRing,
_program: XdpProgram,
Expand All @@ -45,13 +47,13 @@ impl RxRing {
let mut socket: XdpSocket = XdpSocket::create(api)?;

const RING_SIZE: u32 = 1;
let mem: UmemReg = UmemReg::new(RING_SIZE, limits::RECVBUF_SIZE_MAX as u32);
let mem: Rc<RefCell<UmemReg>> = Rc::new(RefCell::new(UmemReg::new(RING_SIZE, limits::RECVBUF_SIZE_MAX as u32)));

trace!("Registering UMEM.");
socket.setsockopt(
api,
xdp_rs::XSK_SOCKOPT_UMEM_REG,
mem.as_ptr() as *const core::ffi::c_void,
mem.borrow().as_ref() as *const xdp_rs::XSK_UMEM_REG as *const core::ffi::c_void,
std::mem::size_of::<xdp_rs::XSK_UMEM_REG>() as u32,
)?;

Expand Down
Loading

0 comments on commit 9439fa5

Please sign in to comment.