Skip to content

Commit

Permalink
integration-test: Use veth pair instead of lo
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinji committed Apr 4, 2024
1 parent baf8522 commit 3e2225c
Show file tree
Hide file tree
Showing 4 changed files with 193 additions and 57 deletions.
35 changes: 27 additions & 8 deletions test/integration-test/src/tests/load.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,25 @@ use aya::{
use aya_obj::programs::XdpAttachType;
use test_log::test;

use crate::utils::NetNsGuard;

const MAX_RETRIES: usize = 100;
const RETRY_DURATION: Duration = Duration::from_millis(10);

#[test]
fn long_name() {
let netns = NetNsGuard::new();

let mut bpf = Ebpf::load(crate::NAME_TEST).unwrap();
let name_prog: &mut Xdp = bpf
.program_mut("ihaveaverylongname")
.unwrap()
.try_into()
.unwrap();
name_prog.load().unwrap();
name_prog.attach("lo", XdpFlags::default()).unwrap();
name_prog
.attach_to_if_index(netns.if_idx2, XdpFlags::default())
.unwrap();

// We used to be able to assert with bpftool that the program name was short.
// It seem though that it now uses the name from the ELF symbol table instead.
Expand Down Expand Up @@ -198,11 +204,15 @@ fn assert_unloaded(name: &str) {

#[test]
fn unload_xdp() {
let netns = NetNsGuard::new();

let mut bpf = Ebpf::load(crate::TEST).unwrap();
let prog: &mut Xdp = bpf.program_mut("pass").unwrap().try_into().unwrap();
prog.load().unwrap();
assert_loaded("pass");
let link = prog.attach("lo", XdpFlags::default()).unwrap();
let link = prog
.attach_to_if_index(netns.if_idx2, XdpFlags::default())
.unwrap();
{
let _link_owned = prog.take_link(link).unwrap();
prog.unload().unwrap();
Expand All @@ -213,7 +223,8 @@ fn unload_xdp() {
prog.load().unwrap();

assert_loaded("pass");
prog.attach("lo", XdpFlags::default()).unwrap();
prog.attach_to_if_index(netns.if_idx2, XdpFlags::default())
.unwrap();

assert_loaded("pass");
prog.unload().unwrap();
Expand Down Expand Up @@ -351,15 +362,19 @@ fn pin_link() {
return;
}

let netns = NetNsGuard::new();

let mut bpf = Ebpf::load(crate::TEST).unwrap();
let prog: &mut Xdp = bpf.program_mut("pass").unwrap().try_into().unwrap();
prog.load().unwrap();
let link_id = prog.attach("lo", XdpFlags::default()).unwrap();
let link_id = prog
.attach_to_if_index(netns.if_idx2, XdpFlags::default())
.unwrap();
let link = prog.take_link(link_id).unwrap();
assert_loaded("pass");

let fd_link: FdLink = link.try_into().unwrap();
let pinned = fd_link.pin("/sys/fs/bpf/aya-xdp-test-lo").unwrap();
let pinned = fd_link.pin("/sys/fs/bpf/aya-xdp-test-veth-pair").unwrap();

// because of the pin, the program is still attached
prog.unload().unwrap();
Expand All @@ -382,6 +397,8 @@ fn pin_lifecycle() {
return;
}

let netns = NetNsGuard::new();

// 1. Load Program and Pin
{
let mut bpf = Ebpf::load(crate::PASS).unwrap();
Expand All @@ -405,10 +422,12 @@ fn pin_lifecycle() {
{
let mut prog =
Xdp::from_pin("/sys/fs/bpf/aya-xdp-test-prog", XdpAttachType::Interface).unwrap();
let link_id = prog.attach("lo", XdpFlags::default()).unwrap();
let link_id = prog
.attach_to_if_index(netns.if_idx2, XdpFlags::default())
.unwrap();
let link = prog.take_link(link_id).unwrap();
let fd_link: FdLink = link.try_into().unwrap();
fd_link.pin("/sys/fs/bpf/aya-xdp-test-lo").unwrap();
fd_link.pin("/sys/fs/bpf/aya-xdp-test-veth-pair").unwrap();

// Unpin the program. It will stay attached since its links were pinned.
prog.unpin().unwrap();
Expand All @@ -423,7 +442,7 @@ fn pin_lifecycle() {
let prog: &mut Xdp = bpf.program_mut("pass").unwrap().try_into().unwrap();
prog.load().unwrap();

let link = PinnedLink::from_pin("/sys/fs/bpf/aya-xdp-test-lo")
let link = PinnedLink::from_pin("/sys/fs/bpf/aya-xdp-test-veth-pair")
.unwrap()
.unpin()
.unwrap();
Expand Down
23 changes: 17 additions & 6 deletions test/integration-test/src/tests/smoke.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ fn xdp() {
return;
}

let _netns = NetNsGuard::new();
let netns = NetNsGuard::new();

let mut bpf = Ebpf::load(crate::PASS).unwrap();
let dispatcher: &mut Xdp = bpf.program_mut("pass").unwrap().try_into().unwrap();
dispatcher.load().unwrap();
dispatcher.attach("lo", XdpFlags::default()).unwrap();
dispatcher
.attach_to_if_index(netns.if_idx2, XdpFlags::default())
.unwrap();
}

#[test]
Expand Down Expand Up @@ -54,12 +56,13 @@ fn extension() {
return;
}

let _netns = NetNsGuard::new();
let netns = NetNsGuard::new();

let mut bpf = Ebpf::load(crate::MAIN).unwrap();
let pass: &mut Xdp = bpf.program_mut("xdp_pass").unwrap().try_into().unwrap();
pass.load().unwrap();
pass.attach("lo", XdpFlags::default()).unwrap();
pass.attach_to_if_index(netns.if_idx2, XdpFlags::default())
.unwrap();

let mut bpf = EbpfLoader::new()
.extension("xdp_drop")
Expand All @@ -73,11 +76,15 @@ fn extension() {

#[test]
fn list_loaded_programs() {
let netns = NetNsGuard::new();

// Load a program.
let mut bpf = Ebpf::load(crate::PASS).unwrap();
let dispatcher: &mut Xdp = bpf.program_mut("pass").unwrap().try_into().unwrap();
dispatcher.load().unwrap();
dispatcher.attach("lo", XdpFlags::default()).unwrap();
dispatcher
.attach_to_if_index(netns.if_idx2, XdpFlags::default())
.unwrap();

// Ensure the loaded_programs() api doesn't panic.
let prog = loaded_programs()
Expand All @@ -102,11 +109,15 @@ fn list_loaded_programs() {

#[test]
fn list_loaded_maps() {
let netns = NetNsGuard::new();

// Load a program with maps.
let mut bpf = Ebpf::load(crate::MAP_TEST).unwrap();
let dispatcher: &mut Xdp = bpf.program_mut("pass").unwrap().try_into().unwrap();
dispatcher.load().unwrap();
dispatcher.attach("lo", XdpFlags::default()).unwrap();
dispatcher
.attach_to_if_index(netns.if_idx2, XdpFlags::default())
.unwrap();

// Ensure the loaded_maps() api doesn't panic and retrieve a map.
let map = loaded_maps()
Expand Down
44 changes: 25 additions & 19 deletions test/integration-test/src/tests/xdp.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{ffi::CStr, mem::MaybeUninit, net::UdpSocket, num::NonZeroU32, time::Duration};
use std::{mem::MaybeUninit, net::UdpSocket, num::NonZeroU32, time::Duration};

use aya::{
maps::{Array, CpuMap, XskMap},
Expand All @@ -9,11 +9,11 @@ use object::{Object, ObjectSection, ObjectSymbol, SymbolSection};
use test_log::test;
use xdpilone::{BufIdx, IfInfo, Socket, SocketConfig, Umem, UmemConfig};

use crate::utils::NetNsGuard;
use crate::utils::{NetNsGuard, IP_ADDR_1, IP_ADDR_2};

#[test]
fn af_xdp() {
let _netns = NetNsGuard::new();
let netns = NetNsGuard::new();

let mut bpf = Ebpf::load(crate::REDIRECT).unwrap();
let mut socks: XskMap<_> = bpf.take_map("SOCKS").unwrap().try_into().unwrap();
Expand All @@ -24,7 +24,8 @@ fn af_xdp() {
.try_into()
.unwrap();
xdp.load().unwrap();
xdp.attach("lo", XdpFlags::default()).unwrap();
xdp.attach_to_if_index(netns.if_idx2, XdpFlags::default())
.unwrap();

// So this needs to be page aligned. Pages are 4k on all mainstream architectures except for
// Apple Silicon which uses 16k pages. So let's align on that for tests to run natively there.
Expand All @@ -41,9 +42,7 @@ fn af_xdp() {
};

let mut iface = IfInfo::invalid();
iface
.from_name(CStr::from_bytes_with_nul(b"lo\0").unwrap())
.unwrap();
iface.from_ifindex(netns.if_idx1).unwrap();
let sock = Socket::with_shared(&iface, &umem).unwrap();

let mut fq_cq = umem.fq_cq(&sock).unwrap(); // Fill Queue / Completion Queue
Expand All @@ -66,9 +65,12 @@ fn af_xdp() {
writer.insert_once(frame.offset);
writer.commit();

let sock = UdpSocket::bind("127.0.0.1:0").unwrap();
let port = sock.local_addr().unwrap().port();
sock.send_to(b"hello AF_XDP", "127.0.0.1:1777").unwrap();
let sock = UdpSocket::bind((IP_ADDR_1, 0)).unwrap();
let src_port = sock.local_addr().unwrap().port();

const DST_PORT: u16 = 1777;
sock.send_to(b"hello AF_XDP", (IP_ADDR_2, DST_PORT))
.unwrap();

assert_eq!(rx.available(), 1);
let desc = rx.receive(1).read().unwrap();
Expand All @@ -81,8 +83,8 @@ fn af_xdp() {
let (ip, buf) = buf.split_at(20);
assert_eq!(ip[9], 17); // UDP
let (udp, payload) = buf.split_at(8);
assert_eq!(&udp[0..2], port.to_be_bytes().as_slice()); // Source
assert_eq!(&udp[2..4], 1777u16.to_be_bytes().as_slice()); // Dest
assert_eq!(&udp[0..2], src_port.to_be_bytes().as_slice()); // Source
assert_eq!(&udp[2..4], DST_PORT.to_be_bytes().as_slice()); // Dest
assert_eq!(payload, b"hello AF_XDP");
}

Expand Down Expand Up @@ -134,7 +136,7 @@ fn map_load() {

#[test]
fn cpumap_chain() {
let _netns = NetNsGuard::new();
let netns = NetNsGuard::new();

let mut bpf = Ebpf::load(crate::REDIRECT).unwrap();

Expand All @@ -157,20 +159,24 @@ fn cpumap_chain() {
// Load the main program
let xdp: &mut Xdp = bpf.program_mut("redirect_cpu").unwrap().try_into().unwrap();
xdp.load().unwrap();
xdp.attach("lo", XdpFlags::default()).unwrap();
xdp.attach_to_if_index(netns.if_idx2, XdpFlags::default())
.unwrap();

const PAYLOAD: &str = "hello cpumap";

let sock = UdpSocket::bind("127.0.0.1:0").unwrap();
let addr = sock.local_addr().unwrap();
sock.set_read_timeout(Some(Duration::from_secs(60)))
let sock1 = UdpSocket::bind((IP_ADDR_1, 0)).unwrap();
let sock2 = UdpSocket::bind((IP_ADDR_2, 0)).unwrap();
sock2
.set_read_timeout(Some(Duration::from_secs(60)))
.unwrap();
sock1
.send_to(PAYLOAD.as_bytes(), sock2.local_addr().unwrap())
.unwrap();
sock.send_to(PAYLOAD.as_bytes(), addr).unwrap();

// Read back the packet to ensure it went through the entire network stack, including our two
// probes.
let mut buf = [0u8; PAYLOAD.len() + 1];
let n = sock.recv(&mut buf).unwrap();
let n = sock2.recv(&mut buf).unwrap();

assert_eq!(&buf[..n], PAYLOAD.as_bytes());
assert_eq!(hits.get(&0, 0).unwrap(), 1);
Expand Down

0 comments on commit 3e2225c

Please sign in to comment.