Skip to content

Commit

Permalink
Bump to new DPDK bindings
Browse files Browse the repository at this point in the history
> [!WARNING]
> Do not merge this code until githedgehog/dpdk-sys#69 is merged.

In this commit, we begin using the new dpdk-sys bindings.

The major changes are:

1. We now have low-level wrappers for basically all `static inline` DPDK functions thanks to dpdk-sys #69.
2. Thanks to new features in bindgen and doxygen-rs we now have rust docs for most DPDK functions.
3. We no longer need `w` prefixed dpdk-sys functions.

Signed-off-by: Daniel Noland <[email protected]>
  • Loading branch information
daniel-noland committed Jan 24, 2025
1 parent 7037abb commit 3b26892
Show file tree
Hide file tree
Showing 9 changed files with 89 additions and 52 deletions.
27 changes: 22 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions dpdk-sys/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ description = "Low-level bindings to the Data Plane Development Kit (DPDK)"
publish = false

[build-dependencies]
bindgen = { workspace = true, features = ["runtime"] }
doxygen-rs = { workspace = true }
bindgen = { version = "0.71.1", features = ["runtime", "experimental"]}
doxygen-rs = { version = "0.4.2" }
dpdk-sysroot-helper = { path = "../dpdk-sysroot-helper", version = "0.0.1" }
48 changes: 34 additions & 14 deletions dpdk-sys/build.rs
Original file line number Diff line number Diff line change
@@ -1,30 +1,39 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Open Network Fabric Authors

use std::env;

use bindgen::callbacks::ParseCallbacks;
use std::env;
use std::panic::catch_unwind;
use std::path::{Path, PathBuf};

#[derive(Debug)]
struct Cb;

impl ParseCallbacks for Cb {
fn process_comment(&self, comment: &str) -> Option<String> {
match doxygen_rs::generator::rustdoc(comment.into()) {
Ok(transformed) => Some(transformed),
match catch_unwind(|| match doxygen_rs::generator::rustdoc(comment.into()) {
Ok(transformed) => transformed,
Err(_) => comment.into(),
}) {
Ok(s) => Some(s),
Err(_) => Some(comment.into()),
}
}
}

fn bind(path: &Path, sysroot: &str) {
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
let static_fn_path = out_path.join("generated.h");
bindgen::Builder::default()
.header(format!("{sysroot}/include/dpdk_wrapper.h"))
.anon_fields_prefix("annon")
.use_core()
.generate_comments(true)
.generate_inline_functions(false)
.generate_block(true)
.clang_arg("-Wno-deprecated-declarations")
// .clang_arg("-Dinline=") // hack to make bindgen spit out wrappers
.wrap_static_fns(true)
.wrap_static_fns_suffix("_w")
.wrap_static_fns_path(static_fn_path)
.array_pointers_in_arguments(false)
.detect_include_paths(true)
.prepend_enum_name(false)
Expand All @@ -37,6 +46,7 @@ fn bind(path: &Path, sysroot: &str) {
.parse_callbacks(Box::new(Cb))
.layout_tests(true)
.default_enum_style(bindgen::EnumVariation::ModuleConsts)
.blocklist_item("rte_atomic.*")
.allowlist_item("rte.*")
.allowlist_item("wrte_.*")
.allowlist_item("RTE.*")
Expand Down Expand Up @@ -64,14 +74,14 @@ fn bind(path: &Path, sysroot: &str) {
.clang_arg(format!("-I{sysroot}/include"))
.clang_arg("-fretain-comments-from-system-headers")
.clang_arg("-fparse-all-comments")
.clang_arg("-march=native")
.generate()
.expect("Unable to generate bindings")
.write_to_file(path.join("generated.rs"))
.expect("Couldn't write bindings!");
}

fn main() {
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
let sysroot = dpdk_sysroot_helper::get_sysroot();

println!("cargo:rustc-link-arg=--sysroot={sysroot}");
Expand Down Expand Up @@ -101,6 +111,22 @@ fn main() {
"rte_log",
"ibverbs",
"mlx5",
"mlx4",
"efa",
"hns",
"mana",
"bnxt_re-rdmav34",
"cxgb4-rdmav34",
"erdma-rdmav34",
"hfi1verbs-rdmav34",
"ipathverbs-rdmav34",
"irdma-rdmav34",
"mthca-rdmav34",
"ocrdma-rdmav34",
"qedr-rdmav34",
"rxe-rdmav34",
"siw-rdmav34",
"vmw_pvrdma-rdmav34",
"nl-route-3",
"nl-3",
"numa",
Expand All @@ -109,15 +135,9 @@ fn main() {
for dep in &depends {
println!("cargo:rustc-link-lib=static:+whole-archive,+bundle={dep}");
}

let rerun_if_changed = ["build.rs"];

let rerun_if_changed = ["build.rs", "../scripts/dpdk-sys.env"];
for file in &rerun_if_changed {
println!("cargo:rerun-if-changed={file}");
}

let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
// let out_path = PathBuf::from("src");

bind(&out_path, sysroot.as_str());
}
36 changes: 18 additions & 18 deletions dpdk/src/dev.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ impl DevIndex {
pub fn socket_id(&self) -> Result<SocketId, errno::ErrorCode> {
let socket_id = unsafe { rte_eth_dev_socket_id(self.as_u16()) };
if socket_id == -1 {
match unsafe { wrte_errno() } {
match unsafe { rte_errno_get() } {
0 => {
debug!("Unable to determine SocketId for port {self}. Using ANY",);
return Ok(SocketId::ANY);
Expand Down Expand Up @@ -384,7 +384,7 @@ impl Display for TxOffloadConfig {

impl From<TxOffloadConfig> for TxOffload {
fn from(value: TxOffloadConfig) -> Self {
use wrte_eth_tx_offload::*;
use rte_eth_tx_offload::*;
TxOffload(
if value.geneve_tnl_tso {
TX_OFFLOAD_GENEVE_TNL_TSO
Expand Down Expand Up @@ -446,7 +446,7 @@ impl From<TxOffloadConfig> for TxOffload {

impl From<TxOffload> for TxOffloadConfig {
fn from(value: TxOffload) -> Self {
use wrte_eth_tx_offload::*;
use rte_eth_tx_offload::*;
TxOffloadConfig {
geneve_tnl_tso: value.0 & TX_OFFLOAD_GENEVE_TNL_TSO != 0,
gre_tnl_tso: value.0 & TX_OFFLOAD_GRE_TNL_TSO != 0,
Expand All @@ -469,38 +469,38 @@ impl From<TxOffload> for TxOffloadConfig {

impl TxOffload {
/// GENEVE tunnel segmentation offload.
pub const GENEVE_TNL_TSO: TxOffload = TxOffload(wrte_eth_tx_offload::TX_OFFLOAD_GENEVE_TNL_TSO);
pub const GENEVE_TNL_TSO: TxOffload = TxOffload(rte_eth_tx_offload::TX_OFFLOAD_GENEVE_TNL_TSO);
/// GRE tunnel segmentation offload.
pub const GRE_TNL_TSO: TxOffload = TxOffload(wrte_eth_tx_offload::TX_OFFLOAD_GRE_TNL_TSO);
pub const GRE_TNL_TSO: TxOffload = TxOffload(rte_eth_tx_offload::TX_OFFLOAD_GRE_TNL_TSO);
/// IPIP tunnel segmentation offload.
pub const IPIP_TNL_TSO: TxOffload = TxOffload(wrte_eth_tx_offload::TX_OFFLOAD_IPIP_TNL_TSO);
pub const IPIP_TNL_TSO: TxOffload = TxOffload(rte_eth_tx_offload::TX_OFFLOAD_IPIP_TNL_TSO);
/// IPv4 checksum calculation.
pub const IPV4_CKSUM: TxOffload = TxOffload(wrte_eth_tx_offload::TX_OFFLOAD_IPV4_CKSUM);
pub const IPV4_CKSUM: TxOffload = TxOffload(rte_eth_tx_offload::TX_OFFLOAD_IPV4_CKSUM);
/// MACsec insertion.
pub const MACSEC_INSERT: TxOffload = TxOffload(wrte_eth_tx_offload::TX_OFFLOAD_MACSEC_INSERT);
pub const MACSEC_INSERT: TxOffload = TxOffload(rte_eth_tx_offload::TX_OFFLOAD_MACSEC_INSERT);
/// Outer IPv4 checksum calculation.
pub const OUTER_IPV4_CKSUM: TxOffload =
TxOffload(wrte_eth_tx_offload::TX_OFFLOAD_OUTER_IPV4_CKSUM);
TxOffload(rte_eth_tx_offload::TX_OFFLOAD_OUTER_IPV4_CKSUM);
/// QinQ (double VLAN) insertion.
pub const QINQ_INSERT: TxOffload = TxOffload(wrte_eth_tx_offload::TX_OFFLOAD_QINQ_INSERT);
pub const QINQ_INSERT: TxOffload = TxOffload(rte_eth_tx_offload::TX_OFFLOAD_QINQ_INSERT);
/// SCTP checksum calculation.
pub const SCTP_CKSUM: TxOffload = TxOffload(wrte_eth_tx_offload::TX_OFFLOAD_SCTP_CKSUM);
pub const SCTP_CKSUM: TxOffload = TxOffload(rte_eth_tx_offload::TX_OFFLOAD_SCTP_CKSUM);
/// TCP checksum calculation.
pub const TCP_CKSUM: TxOffload = TxOffload(wrte_eth_tx_offload::TX_OFFLOAD_TCP_CKSUM);
pub const TCP_CKSUM: TxOffload = TxOffload(rte_eth_tx_offload::TX_OFFLOAD_TCP_CKSUM);
/// TCP segmentation offload.
pub const TCP_TSO: TxOffload = TxOffload(wrte_eth_tx_offload::TX_OFFLOAD_TCP_TSO);
pub const TCP_TSO: TxOffload = TxOffload(rte_eth_tx_offload::TX_OFFLOAD_TCP_TSO);
/// UDP checksum calculation.
pub const UDP_CKSUM: TxOffload = TxOffload(wrte_eth_tx_offload::TX_OFFLOAD_UDP_CKSUM);
pub const UDP_CKSUM: TxOffload = TxOffload(rte_eth_tx_offload::TX_OFFLOAD_UDP_CKSUM);
/// UDP segmentation offload.
pub const UDP_TSO: TxOffload = TxOffload(wrte_eth_tx_offload::TX_OFFLOAD_UDP_TSO);
pub const UDP_TSO: TxOffload = TxOffload(rte_eth_tx_offload::TX_OFFLOAD_UDP_TSO);
/// VXLAN tunnel segmentation offload.
pub const VXLAN_TNL_TSO: TxOffload = TxOffload(wrte_eth_tx_offload::TX_OFFLOAD_VXLAN_TNL_TSO);
pub const VXLAN_TNL_TSO: TxOffload = TxOffload(rte_eth_tx_offload::TX_OFFLOAD_VXLAN_TNL_TSO);
/// VLAN tag insertion.
pub const VLAN_INSERT: TxOffload = TxOffload(wrte_eth_tx_offload::TX_OFFLOAD_VLAN_INSERT);
pub const VLAN_INSERT: TxOffload = TxOffload(rte_eth_tx_offload::TX_OFFLOAD_VLAN_INSERT);

/// Union of all [`TxOffload`]s documented at the time of writing.
pub const ALL_KNOWN: TxOffload = {
use wrte_eth_tx_offload::*;
use rte_eth_tx_offload::*;
TxOffload(
TX_OFFLOAD_GENEVE_TNL_TSO
| TX_OFFLOAD_GRE_TNL_TSO
Expand Down
4 changes: 2 additions & 2 deletions dpdk/src/eal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ pub fn init<T: Debug + AsRef<str>>(args: Vec<T>) -> Result<Eal, InitError> {
let ret = unsafe { rte_eal_init(len, args_as_pointers.as_mut_ptr()) };

if ret < 0 {
let rte_errno = unsafe { wrte_errno() };
let rte_errno = unsafe { rte_errno_get() };
let error = errno::Errno::from(rte_errno);
error!("EAL initialization failed: {error:?} (rte_errno: {rte_errno})");
Err(InitError::InitializationFailed(error))
Expand Down Expand Up @@ -154,7 +154,7 @@ impl Eal {
///
/// If the err
pub fn errno() -> errno::ErrorCode {
errno::ErrorCode::parse_i32(unsafe { wrte_errno() })
errno::ErrorCode::parse_i32(unsafe { rte_errno_get() })
}
}

Expand Down
4 changes: 2 additions & 2 deletions dpdk/src/mem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ impl PoolHandle {

let pool = match NonNull::new(pool) {
None => {
let errno = unsafe { wrte_errno() };
let errno = unsafe { rte_errno_get() };
let c_err_str = unsafe { rte_strerror(errno) };
let err_str = unsafe { CStr::from_ptr(c_err_str) };
#[allow(clippy::expect_used)]
Expand Down Expand Up @@ -375,7 +375,7 @@ impl Mbuf {
///
/// # Safety
///
/// This function is is unsafe if passed an invalid pointer.
/// This function is unsafe if passed an invalid pointer.
///
/// The only defense made against invalid pointers here is the use of `NonNull::new` to ensure
/// the pointer is not null.
Expand Down
2 changes: 1 addition & 1 deletion dpdk/src/queue/rx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ impl RxQueue {
dev = self.dev.as_u16()
);
let nb_rx = unsafe {
wrte_eth_rx_burst(
rte_eth_rx_burst(
self.dev.as_u16(),
self.config.queue_index.as_u16(),
pkts.as_mut_ptr(),
Expand Down
14 changes: 7 additions & 7 deletions scratch/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ impl Drop for RteFlow {
return;
}

let rte_err = unsafe { wrte_errno() };
let rte_err = unsafe { rte_errno_get() };
let err_msg = unsafe { CStr::from_ptr(rte_strerror(res)) }
.to_str()
.unwrap();
Expand Down Expand Up @@ -220,12 +220,12 @@ fn check_hairpin_cap(port_id: u16) {
fn init_port2(port_id: u16, mbuf_pool: &mut rte_mempool) {
let mut port_conf = rte_eth_conf {
txmode: rte_eth_txmode {
offloads: wrte_eth_tx_offload::TX_OFFLOAD_VLAN_INSERT
| wrte_eth_tx_offload::TX_OFFLOAD_IPV4_CKSUM
| wrte_eth_tx_offload::TX_OFFLOAD_UDP_CKSUM
| wrte_eth_tx_offload::TX_OFFLOAD_TCP_CKSUM
| wrte_eth_tx_offload::TX_OFFLOAD_SCTP_CKSUM
| wrte_eth_tx_offload::TX_OFFLOAD_TCP_TSO,
offloads: rte_eth_tx_offload::TX_OFFLOAD_VLAN_INSERT
| rte_eth_tx_offload::TX_OFFLOAD_IPV4_CKSUM
| rte_eth_tx_offload::TX_OFFLOAD_UDP_CKSUM
| rte_eth_tx_offload::TX_OFFLOAD_TCP_CKSUM
| rte_eth_tx_offload::TX_OFFLOAD_SCTP_CKSUM
| rte_eth_tx_offload::TX_OFFLOAD_TCP_TSO,
..Default::default()
},
..Default::default()
Expand Down
2 changes: 1 addition & 1 deletion scripts/dpdk-sys.env
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
DPDK_SYS_BRANCH="main"
DPDK_SYS_COMMIT="fa00d8c0d874e12208bbea9b48cee62da3f37db0"
DPDK_SYS_COMMIT="35f5284b860154d6ebe0e113b3e5c7c891a7d4ab"

0 comments on commit 3b26892

Please sign in to comment.