Skip to content

Commit

Permalink
test: add AF_XDP integration test
Browse files Browse the repository at this point in the history
  • Loading branch information
Tuetuopay committed Feb 21, 2023
1 parent ee4b347 commit 2f227e7
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 0 deletions.
4 changes: 4 additions & 0 deletions test/integration-ebpf/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,7 @@ path = "src/pass.rs"
[[bin]]
name = "test"
path = "src/test.rs"

[[bin]]
name = "redirect"
path = "src/redirect.rs"
43 changes: 43 additions & 0 deletions test/integration-ebpf/src/redirect.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#![no_std]
#![no_main]

use aya_bpf::{
bindings::xdp_action,
macros::{map, xdp},
maps::{CpuMap, DevMap, DevMapHash, XskMap},
programs::XdpContext,
};

#[map]
static SOCKS: XskMap = XskMap::with_max_entries(1, 0);
#[map]
static DEVS: DevMap = DevMap::with_max_entries(1, 0);
#[map]
static DEVS_HASH: DevMapHash = DevMapHash::with_max_entries(1, 0);
#[map]
static CPUS: CpuMap = CpuMap::with_max_entries(1, 0);

#[xdp(name = "redirect_sock")]
pub fn redirect_sock(_ctx: XdpContext) -> u32 {
SOCKS.redirect(0, xdp_action::XDP_ABORTED as u64)
}

#[xdp(name = "redirect_dev")]
pub fn redirect_dev(_ctx: XdpContext) -> u32 {
DEVS.redirect(0, xdp_action::XDP_ABORTED as u64)
}

#[xdp(name = "redirect_dev_hash")]
pub fn redirect_dev_hash(_ctx: XdpContext) -> u32 {
DEVS_HASH.redirect(10, xdp_action::XDP_ABORTED as u64)
}

#[xdp(name = "redirect_cpu")]
pub fn redirect_cpu(_ctx: XdpContext) -> u32 {
CPUS.redirect(0, xdp_action::XDP_ABORTED as u64)
}

#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
unsafe { core::hint::unreachable_unchecked() }
}
1 change: 1 addition & 0 deletions test/integration-test/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ object = { version = "0.30", default-features = false, features = ["std", "read_
rbpf = "0.1.0"
regex = "1"
tempfile = "3.3.0"
xsk-rs = "0.4"
libtest-mimic = "0.6.0"
1 change: 1 addition & 0 deletions test/integration-test/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub mod load;
pub mod rbpf;
pub mod relocations;
pub mod smoke;
pub mod xdp;

pub use integration_test_macros::integration_test;
#[derive(Debug)]
Expand Down
60 changes: 60 additions & 0 deletions test/integration-test/src/tests/xdp.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
use std::{os::fd::AsRawFd, process::Command};

use aya::{
include_bytes_aligned,
maps::XskMap,
programs::{Xdp, XdpFlags},
Bpf,
};
use xsk_rs::{
config::{LibbpfFlags, SocketConfigBuilder},
Socket, Umem,
};

use super::{integration_test, IntegrationTest};

#[integration_test]
fn af_xdp() {
let bytes = include_bytes_aligned!("../../../../target/bpfel-unknown-none/debug/redirect");
let mut bpf = Bpf::load(bytes).unwrap();
let xdp: &mut Xdp = bpf
.program_mut("redirect_sock")
.unwrap()
.try_into()
.unwrap();
xdp.load().unwrap();
xdp.attach("lo", XdpFlags::default()).unwrap();

let (umem, mut descs) = Umem::new(Default::default(), 32.try_into().unwrap(), false).unwrap();
let sk_cfg = SocketConfigBuilder::new()
.libbpf_flags(LibbpfFlags::XSK_LIBBPF_FLAGS_INHIBIT_PROG_LOAD)
.build();
let (_tx, mut rx, fq_cq) = Socket::new(sk_cfg, &umem, &"lo".parse().unwrap(), 0).unwrap();
let (mut fq, _cq) = fq_cq.unwrap();

let mut socks: XskMap<_> = bpf.map_mut("SOCKS").unwrap().try_into().unwrap();
socks.set(0, rx.fd().as_raw_fd(), 0).unwrap();

// SAFETY: descs are from the same umem as the socket is tied to
// (valid for all further unsafe)
unsafe { fq.produce(&descs) };

// Expected to fail as our probe redirects all packets to the socket
let out = Command::new("ping")
.args(["-c", "1", "-w", "1", "127.0.0.1"])
.output()
.unwrap();
assert!(!out.status.success());

let n = unsafe { rx.consume(&mut descs) };
assert_eq!(n, 1);

let data = unsafe { umem.data(&descs[0]) };
let buf = data.contents();
let (eth, buf) = buf.split_at(14);
assert_eq!(eth[12..14], [0x08, 0x00]); // IP
let (ip, buf) = buf.split_at(20);
assert_eq!(ip[9], 1); // ICMP
let (icmp, _buf) = buf.split_at(8);
assert_eq!(icmp[0], 8); // Echo request
}

0 comments on commit 2f227e7

Please sign in to comment.