diff --git a/Cargo.lock b/Cargo.lock index e4fa4a4..70c1c3b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -177,6 +177,7 @@ dependencies = [ "bindgen", "cc", "libc", + "pkg-config", ] [[package]] diff --git a/Prerequisites.md b/Prerequisites.md index 1937646..941528a 100644 --- a/Prerequisites.md +++ b/Prerequisites.md @@ -37,7 +37,6 @@ exit ### Otherwise ```bash sudo vim /etc/sysctl.conf # Add "vm.nr_hugepages=2048" at the end of the file -sudo sysctl.conf sudo sysctl -e -p ``` diff --git a/dpdk-sys/Cargo.toml b/dpdk-sys/Cargo.toml index ca56177..4e1b1e6 100644 --- a/dpdk-sys/Cargo.toml +++ b/dpdk-sys/Cargo.toml @@ -18,6 +18,7 @@ doctest = false bindgen = "0.56.0" cc = "1.0" libc = "0.2" +pkg-config = "0.3.19" [features] rustdoc = [] diff --git a/dpdk-sys/build.rs b/dpdk-sys/build.rs index d489279..15bebfb 100644 --- a/dpdk-sys/build.rs +++ b/dpdk-sys/build.rs @@ -1,25 +1,188 @@ -use bindgen::Builder; -use std::{ - env, - path::PathBuf, - process::{exit, Command, Stdio}, -}; +/* +* Copyright 2019 Comcast Cable Communications Management, LLC +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +* SPDX-License-Identifier: Apache-2.0 +*/ -fn main() { +#[cfg(not(feature = "rustdoc"))] +use std::env; +#[cfg(not(feature = "rustdoc"))] +use std::path::{Path, PathBuf}; + +#[cfg(not(feature = "rustdoc"))] +const RTE_CORE_LIBS: &[&str] = &[ + "rte_acl", + "rte_bbdev", + "rte_bitratestats", + "rte_bpf", + "rte_bus_dpaa", + "rte_bus_fslmc", + "rte_bus_ifpga", + "rte_bus_pci", + "rte_bus_vdev", + "rte_bus_vmbus", + "rte_cfgfile", + "rte_cmdline", + "rte_common_cpt", + "rte_common_dpaax", + "rte_common_octeontx", + "rte_common_octeontx2", + "rte_compressdev", + "rte_cryptodev", + "rte_distributor", + "rte_eal", + "rte_efd", + "rte_ethdev", + "rte_eventdev", + "rte_fib", + "rte_flow_classify", + "rte_gro", + "rte_gso", + "rte_hash", + "rte_ip_frag", + "rte_ipsec", + "rte_jobstats", + "rte_kni", + "rte_kvargs", + "rte_latencystats", + "rte_lpm", + // "rte_malloc", // Added by Deep + "rte_mbuf", + "rte_member", + "rte_mempool", + "rte_mempool_bucket", + "rte_mempool_dpaa", + "rte_mempool_dpaa2", + "rte_mempool_octeontx", + "rte_mempool_octeontx2", + "rte_mempool_ring", + "rte_mempool_stack", + "rte_meter", + "rte_metrics", + "rte_net", + "rte_pci", + "rte_pdump", + "rte_pipeline", + "rte_port", + "rte_power", + "rte_rawdev", + "rte_rawdev_dpaa2_cmdif", + "rte_rawdev_dpaa2_qdma", + "rte_rawdev_ioat", + "rte_rawdev_ntb", + "rte_rawdev_octeontx2_dma", + "rte_rawdev_skeleton", + "rte_rcu", + "rte_reorder", + "rte_rib", + "rte_ring", + "rte_sched", + "rte_security", + "rte_stack", + "rte_table", + "rte_timer", + "rte_vhost", +]; + +#[cfg(not(feature = "rustdoc"))] +static RTE_PMD_LIBS: &[&str] = &[ + "rte_pmd_af_packet", + "rte_pmd_ark", + "rte_pmd_atlantic", + "rte_pmd_avp", + "rte_pmd_axgbe", + "rte_pmd_bbdev_fpga_lte_fec", + "rte_pmd_bbdev_null", + "rte_pmd_bbdev_turbo_sw", + "rte_pmd_bnxt", + "rte_pmd_bond", + "rte_pmd_caam_jr", + "rte_pmd_crypto_scheduler", + "rte_pmd_cxgbe", + "rte_pmd_dpaa", + "rte_pmd_dpaa2", + "rte_pmd_dpaa2_event", + "rte_pmd_dpaa2_sec", + "rte_pmd_dpaa_event", + "rte_pmd_dpaa_sec", + "rte_pmd_dsw_event", + "rte_pmd_e1000", + "rte_pmd_ena", + "rte_pmd_enetc", + "rte_pmd_enic", + "rte_pmd_failsafe", + "rte_pmd_fm10k", + "rte_pmd_hinic", + "rte_pmd_hns3", + "rte_pmd_i40e", + "rte_pmd_iavf", + "rte_pmd_ice", + "rte_pmd_ifc", + "rte_pmd_ixgbe", + "rte_pmd_kni", + "rte_pmd_liquidio", + "rte_pmd_memif", + "rte_pmd_netvsc", + "rte_pmd_nfp", + "rte_pmd_nitrox", + "rte_pmd_null", + "rte_pmd_null_crypto", + "rte_pmd_octeontx", + "rte_pmd_octeontx2", + "rte_pmd_octeontx2_crypto", + "rte_pmd_octeontx2_event", + "rte_pmd_octeontx_compress", + "rte_pmd_octeontx_crypto", + "rte_pmd_octeontx_event", + "rte_pmd_opdl_event", + "rte_pmd_pcap", + "rte_pmd_pfe", + "rte_pmd_qat", + "rte_pmd_qede", + "rte_pmd_ring", + "rte_pmd_sfc", + "rte_pmd_skeleton_event", + "rte_pmd_softnic", + "rte_pmd_sw_event", + "rte_pmd_tap", + "rte_pmd_thunderx", + "rte_pmd_vdev_netvsc", + "rte_pmd_vhost", + "rte_pmd_virtio", + "rte_pmd_virtio_crypto", + "rte_pmd_vmxnet3", +]; + +#[cfg(not(feature = "rustdoc"))] +const RTE_DEPS_LIBS: &[&str] = &["numa", "pcap"]; + +#[cfg(not(feature = "rustdoc"))] +fn bind(path: &Path) { cc::Build::new() .file("src/shim.c") .flag("-march=corei7") .flag("-mavx") .compile("rte_shim"); - let bindings = Builder::default() - .clang_arg("-I${RTE_SDK}/build/lib") + bindgen::Builder::default() .header("src/bindings.h") - .layout_tests(false) + // .generate_comments(true) + .layout_tests(false) // added by Deep .generate_inline_functions(true) - .parse_callbacks(Box::new(bindgen::CargoCallbacks)) - // .blacklist_type("rte_arp_ipv4") - // .blacklist_type("rte_arp_hdr") + // treat as opaque as per issue w/ combining align/packed: + // https://github.com/rust-lang/rust-bindgen/issues/1538 .opaque_type(r"rte_arp_ipv4|rte_arp_hdr") .whitelist_type(r"(rte|eth|pcap)_.*") .whitelist_function(r"(_rte|rte|_pkt|eth|numa|pcap)_.*") @@ -34,36 +197,29 @@ fn main() { .clang_arg("-mavx") .rustfmt_bindings(true) .generate() - .expect("Failed to generate bindings"); + .expect("Unable to generate bindings") + .write_to_file(path.join("bindings.rs")) + .expect("Couldn't write bindings!"); +} +#[cfg(not(feature = "rustdoc"))] +fn main() { let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); - bindings - .write_to_file(out_path.join("bindings.rs")) - .expect("Failed to write bindings"); - - let child = Command::new("./pkg_names.sh") - .stdout(Stdio::piped()) - .spawn() - .expect("command failed"); - let output = child.wait_with_output().unwrap(); - let mut rte_libs = Vec::new(); + bind(&out_path); - if output.status.success() { - let output = String::from_utf8_lossy(&output.stdout); - for out in output.split_ascii_whitespace() { - rte_libs.push(out.to_owned()); - } - } else { - exit(1); - } - - rte_libs + RTE_CORE_LIBS .iter() + .chain(RTE_PMD_LIBS) + .chain(RTE_DEPS_LIBS) .for_each(|lib| println!("cargo:rustc-link-lib=dylib={}", lib)); + // re-run build.rs upon changes println!("cargo:rerun-if-changed=build.rs"); - println!("cargo:rerun-if-changed=src/bindings.h"); - println!("cargo:rerun-if-changed=src/shim.c"); + println!("cargo:rerun-if-changed=src/"); println!("cargo:rustc-link-search=/usr/local/lib/x86_64-linux-gnu/"); } + +// Skip the build script on docs.rs +#[cfg(feature = "rustdoc")] +fn main() {} diff --git a/dpdk-sys/build.rs.v2 b/dpdk-sys/build.rs.v2 new file mode 100644 index 0000000..078d837 --- /dev/null +++ b/dpdk-sys/build.rs.v2 @@ -0,0 +1,83 @@ +use bindgen::Builder; +use pkg_config; +use std::{ + env, + path::PathBuf, + // process::{exit, Command, Stdio}, +}; + +fn main() { + cc::Build::new() + .file("src/shim.c") + .flag("-march=corei7") + .flag("-mavx") + .compile("rte_shim"); + + let bindings = Builder::default() + .clang_arg("-I${RTE_SDK}/build/lib") + .header("src/bindings.h") + .layout_tests(false) + .generate_inline_functions(true) + .parse_callbacks(Box::new(bindgen::CargoCallbacks)) + .opaque_type(r"rte_arp_ipv4|rte_arp_hdr") + .whitelist_type(r"(rte|eth|pcap)_.*") + .whitelist_function(r"(_rte|rte|_pkt|eth|numa|pcap|memif)_.*") + .whitelist_var(r"(RTE|DEV|ETH|MEMPOOL|PKT|rte|memif)_.*") + .derive_copy(true) + .derive_debug(true) + .derive_default(true) + .derive_partialeq(true) + .default_enum_style(bindgen::EnumVariation::ModuleConsts) + .clang_arg("-finline-functions") + .clang_arg("-march=corei7") + .clang_arg("-mavx") + .rustfmt_bindings(true) + .generate() + .expect("Failed to generate bindings"); + + let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); + bindings + .write_to_file(out_path.join("bindings.rs")) + .expect("Failed to write bindings"); + + // let child = Command::new("./pkg_names.py") + // .stdout(Stdio::piped()) + // .spawn() + // .expect("command failed"); + // let output = child.wait_with_output().unwrap(); + + // let mut rte_libs = Vec::new(); + + // if output.status.success() { + // let output = String::from_utf8_lossy(&output.stdout); + // let mut iter = output.split_ascii_whitespace(); + // loop { + // if let Some(out) = iter.next() { + // let out = out.trim_matches(|c| c == '{' || c == '}' || c == '\'' || c == ','); + // rte_libs.push(out.to_owned()); + // } else { + // break; + // } + // } + // } else { + // exit(1); + // } + + // rte_libs + // .iter() + // .for_each(|lib| println!("cargo:rustc-link-lib=dylib={}", lib)); + pkg_config::Config::new().probe("libdpdk-libs").unwrap(); + pkg_config::Config::new().probe("libdpdk").unwrap(); + println!("cargo:rustc-link-lib=dylib=numa"); + + // RTE_CORE_LIBS + // .iter() + // .chain(RTE_PMD_LIBS) + // .chain(RTE_DEPS_LIBS) + // .for_each(|lib| println!("cargo:rustc-link-lib=dylib={}", lib)); + + println!("cargo:rerun-if-changed=build.rs"); + println!("cargo:rerun-if-changed=src/bindings.h"); + println!("cargo:rerun-if-changed=src/shim.c"); + println!("cargo:rustc-link-search=/usr/local/lib/x86_64-linux-gnu/"); +} diff --git a/dpdk-sys/pkg_names.py b/dpdk-sys/pkg_names.py new file mode 100755 index 0000000..94fb5d0 --- /dev/null +++ b/dpdk-sys/pkg_names.py @@ -0,0 +1,23 @@ +#!/usr/bin/python3 +import subprocess +import os + +# cmd = "pkg-config --static --libs libdpdk" +d = os.getenv("RTE_SDK") +libs = os.listdir(d + "/build/lib") +for lib in libs: + if lib.endswith("so"): + +proc = subprocess.Popen(cmd, stdout=subprocess.PIPE) +output, err = proc.communicate() + +pkglist = set() + +for elem in output.split(): + e = elem.decode('utf-8') + if e.find("-l:lib") > -1: + pkglist.add(e[6:-2]) + elif e.find("-lrte") > -1: + pkglist.add(e[2:]) + +print(pkglist) \ No newline at end of file diff --git a/l3enginelib/src/apis/memzone.rs b/l3enginelib/src/apis/memzone.rs index 7d62640..151f12e 100644 --- a/l3enginelib/src/apis/memzone.rs +++ b/l3enginelib/src/apis/memzone.rs @@ -3,9 +3,9 @@ * Created by Ratnadeep Bhattacharya */ +use super::{MemoryError, WrappedCString}; use dpdk_sys; use std::result::Result; -use super::{MemoryError, WrappedCString}; pub struct Memzone { raw: *const dpdk_sys::rte_memzone, @@ -14,8 +14,14 @@ pub struct Memzone { impl Memzone { pub fn new(name: &str, len: usize) -> Result { let nm = WrappedCString::to_cstring(name)?; - let raw = unsafe { dpdk_sys::rte_memzone_reserve(nm.as_ptr(), len as u64, dpdk_sys::rte_socket_id() as i32, dpdk_sys::RTE_MEMZONE_2MB)}; - + let raw = unsafe { + dpdk_sys::rte_memzone_reserve( + nm.as_ptr(), + len as u64, + dpdk_sys::rte_socket_id() as i32, + dpdk_sys::RTE_MEMZONE_2MB, + ) + }; if raw.is_null() { return Err(MemoryError::new()); } @@ -32,15 +38,16 @@ impl Memzone { } pub fn virt_addr(&self) -> u64 { - unsafe { (*self.raw).__bindgen_anon_1.addr_64 } + // unsafe { (*self.raw).__bindgen_anon_1.addr_64 } + unsafe { (*self.raw).__bindgen_anon_2.addr_64 } } } impl Drop for Memzone { fn drop(&mut self) { - match unsafe { dpdk_sys::rte_memzone_free(self.raw)} { - 0 => {}, + match unsafe { dpdk_sys::rte_memzone_free(self.raw) } { + 0 => {} _ => log::error!("resource release failed; invalid memzone"), } } -} \ No newline at end of file +} diff --git a/l3enginepacketiser/src/main.rs b/l3enginepacketiser/src/main.rs index 8cb8977..23d5499 100644 --- a/l3enginepacketiser/src/main.rs +++ b/l3enginepacketiser/src/main.rs @@ -19,6 +19,7 @@ mod net; mod packetiser; use ctrlc; +use net::{EthDevEmulator, IfaceEmulator, SockSet}; use std::{ process::exit, sync::{ @@ -75,7 +76,16 @@ fn main() { let kr = keep_running.clone(); handle_signal(keep_running.clone()); + // create device + let mac = [0x90, 0xe2, 0xba, 0xb2, 0x98, 0x48]; + let addr = [10, 10, 1, 1]; + let prefix = 24; + let mut sockets = SockSet::new(mac, addr, prefix); + #[cfg(feature = "debug")] + println!("packetiser: sockets created"); + while kr.load(Ordering::SeqCst) { + sockets.process_pkts(); match proc.recv_from_engine_burst() { Ok(_count) => { diff --git a/l3enginepacketiser/src/net/tcp.rs b/l3enginepacketiser/src/net/tcp.rs index df5749b..c7a221a 100644 --- a/l3enginepacketiser/src/net/tcp.rs +++ b/l3enginepacketiser/src/net/tcp.rs @@ -1,5 +1,6 @@ //! Implements the support for TCP at the packetiser +use ctrlc::set_handler; use smoltcp::{ iface::EthernetInterface, socket::{ @@ -8,7 +9,13 @@ use smoltcp::{ }, time::Instant, }; -use std::{collections::HashMap, sync::Arc}; +use std::{ + collections::HashMap, + sync::{ + atomic::{AtomicBool, Ordering}, + Arc, + }, +}; use crate::send_icmp_ping; @@ -73,32 +80,26 @@ impl<'a> SockSet<'a> { } pub(crate) fn process_pkts(&mut self) { - loop { - let timestamp = Instant::now(); - // let sock_set = *self.sock_set.clone(); - match self.iface.poll(&mut self.sock_set, timestamp) { - Ok(_) => {} - Err(e) => log::error!("poll error: {}", e), - } + let timestamp = Instant::now(); + // let sock_set = *self.sock_set.clone(); + match self.iface.poll(&mut self.sock_set, timestamp) { + Ok(_) => {} + Err(e) => log::error!("poll error: {}", e), + } + { + let _timestamp = Instant::now(); { - let _timestamp = Instant::now(); - { - let mut icmp_sock = self.sock_set.get::(self.icmp_handle); - #[cfg(feature = "debug")] - println!("got icmp socket"); - if !icmp_sock.is_open() { - icmp_sock - .bind(IcmpEndpoint::Ident(IcmpSock::IDENT)) - .unwrap(); - } - // TODO: hand over to icmp processing - } - { - let mut _tcp_sock = self.sock_set.get::(self.tcp_handle); - #[cfg(feature = "debug")] - println!("got tcp socket"); - // TODO: hand over to tcp processing} + let mut icmp_sock = self.sock_set.get::(self.icmp_handle); + if !icmp_sock.is_open() { + icmp_sock + .bind(IcmpEndpoint::Ident(IcmpSock::IDENT)) + .unwrap(); } + // TODO: hand over to icmp processing + } + { + let mut _tcp_sock = self.sock_set.get::(self.tcp_handle); + // TODO: hand over to tcp processing} } } }