Skip to main content

FStackConfig

Struct FStackConfig 

Source
pub struct FStackConfig { /* private fields */ }
Expand description

Builder for F-Stack / DPDK initialisation arguments.

Separates the config-file arguments (understood by F-Stack’s own parser) from extra EAL arguments (passed directly to DPDK’s rte_eal_init).

§Examples

Docker / TAP development:

let cfg = FStackConfig::for_docker();

Bare metal with a real NIC bound via VFIO:

let cfg = FStackConfig::for_bare_metal();

Custom build:

let cfg = FStackConfig::new("config.ini")
    .with_eal_arg("--vdev=net_tap0,iface=dtap0,mac=fixed")
    .with_eal_arg("--no-pci");

Implementations§

Source§

impl FStackConfig

Source

pub fn new(config_file: impl Into<String>) -> Self

Create a config pointing at config_file with no extra EAL arguments.

Source

pub fn with_eal_arg(self, arg: impl Into<String>) -> Self

Append a single extra EAL argument (e.g. "--no-pci").

Source

pub fn for_docker() -> Self

Docker / TAP device profile.

Injects the three EAL arguments that are required when running DPDK inside a container with a TAP virtual interface instead of a real NIC:

  • --vdev=net_tap0,iface=dtap0,mac=fixed — create a TAP-backed DPDK port tied to the kernel interface dtap0; mac=fixed makes the MAC deterministic so that it is stable across restarts. The kernel side of the TAP is automatically assigned a different MAC by entrypoint.sh (derived from the DPDK MAC by incrementing the last octet). The two MACs must differ: FreeBSD’s ether_input drops frames whose source MAC matches the interface MAC (anti-loop protection).
  • --no-pci — skip PCI bus scan; without this DPDK could claim a PCI device and push the TAP device to port 1, breaking port_list=0.
  • --iova-mode=va — force Virtual Address IOVA mode, required in containers / WSL2 where physical address access is unavailable.
Examples found in repository?
examples/udp_echo.rs (line 31)
29fn main() {
30    // Docker/TAP configuration — swap for FStackConfig::for_bare_metal() on bare metal.
31    let cfg = FStackConfig::for_docker();
32
33    println!("Initializing F-Stack...");
34    init_fstack(&cfg.config_args(), &cfg.eal_args());
35
36    let bind_ip   = "0.0.0.0".to_string();
37    let bind_port = 8080u16;
38
39    println!("Creating UDP socket on {}:{}...", bind_ip, bind_port);
40    let socket: UniquePtr<FStackUdpSocket> =
41        create_udp_socket(&bind_ip, bind_port, on_packet);
42
43    unsafe {
44        GLOBAL_SOCKET = Some(&*socket as *const FStackUdpSocket);
45    }
46
47    println!("Starting F-Stack UDP event loop...");
48    run_fstack(&socket);
49}
More examples
Hide additional examples
examples/tcp_echo.rs (line 40)
38fn main() {
39    // Docker/TAP configuration — swap for FStackConfig::for_bare_metal() on bare metal.
40    let cfg = FStackConfig::for_docker();
41
42    println!("Initializing F-Stack...");
43    init_fstack(&cfg.config_args(), &cfg.eal_args());
44
45    let bind_ip   = "0.0.0.0".to_string();
46    let bind_port = 8080u16;
47
48    let tcp_opts = TcpSocketOptions::default()
49        .nodelay(true)
50        .quickack(true);
51
52    println!("Creating TCP listener on {}:{}...", bind_ip, bind_port);
53    let listener: UniquePtr<FStackTcpListener> =
54        create_tcp_listener(&bind_ip, bind_port, &tcp_opts.to_ffi(), on_connect, on_data, on_disconnect);
55
56    unsafe {
57        GLOBAL_LISTENER = Some(&*listener as *const FStackTcpListener);
58    }
59
60    println!("Starting F-Stack TCP event loop...");
61    run_fstack_tcp(&listener);
62}
Source

pub fn for_bare_metal() -> Self

Bare-metal / AWS profile.

No extra EAL arguments are needed: DPDK discovers the NIC via the allow= key in config.ini, PCI scanning is required, and IOVA mode is auto-detected based on whether IOMMU is present.

Source

pub fn config_args(&self) -> Vec<String>

The arguments passed to ff_load_config (F-Stack’s config parser).

Examples found in repository?
examples/udp_echo.rs (line 34)
29fn main() {
30    // Docker/TAP configuration — swap for FStackConfig::for_bare_metal() on bare metal.
31    let cfg = FStackConfig::for_docker();
32
33    println!("Initializing F-Stack...");
34    init_fstack(&cfg.config_args(), &cfg.eal_args());
35
36    let bind_ip   = "0.0.0.0".to_string();
37    let bind_port = 8080u16;
38
39    println!("Creating UDP socket on {}:{}...", bind_ip, bind_port);
40    let socket: UniquePtr<FStackUdpSocket> =
41        create_udp_socket(&bind_ip, bind_port, on_packet);
42
43    unsafe {
44        GLOBAL_SOCKET = Some(&*socket as *const FStackUdpSocket);
45    }
46
47    println!("Starting F-Stack UDP event loop...");
48    run_fstack(&socket);
49}
More examples
Hide additional examples
examples/tcp_echo.rs (line 43)
38fn main() {
39    // Docker/TAP configuration — swap for FStackConfig::for_bare_metal() on bare metal.
40    let cfg = FStackConfig::for_docker();
41
42    println!("Initializing F-Stack...");
43    init_fstack(&cfg.config_args(), &cfg.eal_args());
44
45    let bind_ip   = "0.0.0.0".to_string();
46    let bind_port = 8080u16;
47
48    let tcp_opts = TcpSocketOptions::default()
49        .nodelay(true)
50        .quickack(true);
51
52    println!("Creating TCP listener on {}:{}...", bind_ip, bind_port);
53    let listener: UniquePtr<FStackTcpListener> =
54        create_tcp_listener(&bind_ip, bind_port, &tcp_opts.to_ffi(), on_connect, on_data, on_disconnect);
55
56    unsafe {
57        GLOBAL_LISTENER = Some(&*listener as *const FStackTcpListener);
58    }
59
60    println!("Starting F-Stack TCP event loop...");
61    run_fstack_tcp(&listener);
62}
Source

pub fn eal_args(&self) -> Vec<String>

Extra EAL arguments injected into dpdk_argv after ff_load_config.

Examples found in repository?
examples/udp_echo.rs (line 34)
29fn main() {
30    // Docker/TAP configuration — swap for FStackConfig::for_bare_metal() on bare metal.
31    let cfg = FStackConfig::for_docker();
32
33    println!("Initializing F-Stack...");
34    init_fstack(&cfg.config_args(), &cfg.eal_args());
35
36    let bind_ip   = "0.0.0.0".to_string();
37    let bind_port = 8080u16;
38
39    println!("Creating UDP socket on {}:{}...", bind_ip, bind_port);
40    let socket: UniquePtr<FStackUdpSocket> =
41        create_udp_socket(&bind_ip, bind_port, on_packet);
42
43    unsafe {
44        GLOBAL_SOCKET = Some(&*socket as *const FStackUdpSocket);
45    }
46
47    println!("Starting F-Stack UDP event loop...");
48    run_fstack(&socket);
49}
More examples
Hide additional examples
examples/tcp_echo.rs (line 43)
38fn main() {
39    // Docker/TAP configuration — swap for FStackConfig::for_bare_metal() on bare metal.
40    let cfg = FStackConfig::for_docker();
41
42    println!("Initializing F-Stack...");
43    init_fstack(&cfg.config_args(), &cfg.eal_args());
44
45    let bind_ip   = "0.0.0.0".to_string();
46    let bind_port = 8080u16;
47
48    let tcp_opts = TcpSocketOptions::default()
49        .nodelay(true)
50        .quickack(true);
51
52    println!("Creating TCP listener on {}:{}...", bind_ip, bind_port);
53    let listener: UniquePtr<FStackTcpListener> =
54        create_tcp_listener(&bind_ip, bind_port, &tcp_opts.to_ffi(), on_connect, on_data, on_disconnect);
55
56    unsafe {
57        GLOBAL_LISTENER = Some(&*listener as *const FStackTcpListener);
58    }
59
60    println!("Starting F-Stack TCP event loop...");
61    run_fstack_tcp(&listener);
62}

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.