1use xdpsock::{
2 socket::{BindFlags, SocketConfig, SocketConfigBuilder, XdpFlags},
3 umem::{UmemConfig, UmemConfigBuilder},
4 xsk::Xsk2,
5};
6
7use libc::{c_char, size_t};
8use std::ffi::CStr;
9use std::slice;
10
11#[no_mangle]
12pub extern "C" fn xsk_new<'a>(ifname: *const c_char) -> *mut Xsk2<'a> {
13 let ifname = unsafe {
14 assert!(!ifname.is_null());
15 CStr::from_ptr(ifname)
16 };
17
18 let ifname = ifname.to_str().unwrap();
19
20 let umem_config = UmemConfigBuilder::new()
21 .frame_count(8192)
22 .comp_queue_size(4096)
23 .fill_queue_size(4096)
24 .build()
25 .unwrap();
26
27 let socket_config = SocketConfigBuilder::new()
28 .tx_queue_size(4096)
29 .rx_queue_size(4096)
30 .bind_flags(BindFlags::XDP_COPY)
31 .xdp_flags(XdpFlags::XDP_FLAGS_SKB_MODE)
32 .build()
33 .unwrap();
34
35 let n_tx_frames = umem_config.frame_count() / 2;
36
37 let mut xsk = Xsk2::new(&ifname, 0, umem_config, socket_config, n_tx_frames as usize);
38 Box::into_raw(Box::new(xsk))
39}
40
41#[no_mangle]
42pub extern "C" fn xsk_delete(xsk_ptr: *mut Xsk2) {
43 let xsk = unsafe {
44 assert!(!xsk_ptr.is_null());
45 &mut *xsk_ptr
46 };
47
48 let tx_stats = xsk.shutdown_tx().expect("failed to shutdown tx");
49 let rx_stats = xsk.shutdown_rx().expect("failed to shut down rx");
50 eprintln!("tx_stats = {:?}", tx_stats);
51 eprintln!("tx duration = {:?}", tx_stats.duration());
52 eprintln!("tx pps = {:?}", tx_stats.pps());
53 eprintln!("rx_stats = {:?}", rx_stats);
54 unsafe {
55 Box::from_raw(xsk_ptr);
56 }
57}
58
59#[no_mangle]
60pub extern "C" fn xsk_send(xsk_ptr: *mut Xsk2, pkt: *const u8, len: size_t) {
61 let xsk = unsafe {
62 assert!(!xsk_ptr.is_null());
63 &mut *xsk_ptr
64 };
65
66 let pkt = unsafe {
67 assert!(!pkt.is_null());
68 slice::from_raw_parts(pkt, len as usize)
69 };
70
71 xsk.send(&pkt);
72}
73
74#[no_mangle]
75pub extern "C" fn xsk_recv(xsk_ptr: *mut Xsk2, pkt: *mut u8, len: size_t) {
76 let xsk = unsafe {
77 assert!(!xsk_ptr.is_null());
78 &mut *xsk_ptr
79 };
80
81 let mut pkt = unsafe {
82 assert!(!pkt.is_null());
83 slice::from_raw_parts_mut(pkt, len as usize)
84 };
85
86 let (recvd_pkt, len) = xsk.recv().expect("failed to recv");
87 pkt[..len].clone_from_slice(&recvd_pkt[..len]);
88}