mirror of https://github.com/aya-rs/aya
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
103 lines
3.6 KiB
Rust
103 lines
3.6 KiB
Rust
use aya::{
|
|
Ebpf,
|
|
programs::{LinkOrder, ProgramId, SchedClassifier, TcAttachType, tc::TcAttachOptions},
|
|
util::KernelVersion,
|
|
};
|
|
use test_log::test;
|
|
|
|
use crate::utils::NetNsGuard;
|
|
|
|
#[test]
|
|
fn tcx() {
|
|
let kernel_version = KernelVersion::current().unwrap();
|
|
if kernel_version < KernelVersion::new(6, 6, 0) {
|
|
eprintln!("skipping tcx_attach test on kernel {kernel_version:?}");
|
|
return;
|
|
}
|
|
|
|
let _netns = NetNsGuard::new();
|
|
|
|
// We need a dedicated `Ebpf` instance for each program that we load
|
|
// since TCX does not allow the same program ID to be attached multiple
|
|
// times to the same interface/direction.
|
|
//
|
|
// Variables declared within this macro are within a closure scope to avoid
|
|
// variable name conflicts.
|
|
//
|
|
// Yields a tuple of the `Ebpf` which must remain in scope for the duration
|
|
// of the test, and the link ID of the attached program.
|
|
macro_rules! attach_program_with_link_order_inner {
|
|
($program_name:ident, $link_order:expr) => {
|
|
let mut ebpf = Ebpf::load(crate::TCX).unwrap();
|
|
let $program_name: &mut SchedClassifier =
|
|
ebpf.program_mut("tcx_next").unwrap().try_into().unwrap();
|
|
$program_name.load().unwrap();
|
|
};
|
|
}
|
|
macro_rules! attach_program_with_link_order {
|
|
($program_name:ident, $link_order:expr) => {
|
|
attach_program_with_link_order_inner!($program_name, $link_order);
|
|
$program_name
|
|
.attach_with_options(
|
|
"lo",
|
|
TcAttachType::Ingress,
|
|
TcAttachOptions::TcxOrder($link_order),
|
|
)
|
|
.unwrap();
|
|
};
|
|
($program_name:ident, $link_id_name:ident, $link_order:expr) => {
|
|
attach_program_with_link_order_inner!($program_name, $link_order);
|
|
let $link_id_name = $program_name
|
|
.attach_with_options(
|
|
"lo",
|
|
TcAttachType::Ingress,
|
|
TcAttachOptions::TcxOrder($link_order),
|
|
)
|
|
.unwrap();
|
|
};
|
|
}
|
|
|
|
attach_program_with_link_order!(default, LinkOrder::default());
|
|
attach_program_with_link_order!(first, LinkOrder::first());
|
|
attach_program_with_link_order!(last, last_link_id, LinkOrder::last());
|
|
|
|
let last_link = last.take_link(last_link_id).unwrap();
|
|
|
|
attach_program_with_link_order!(before_last, LinkOrder::before_link(&last_link).unwrap());
|
|
attach_program_with_link_order!(after_last, LinkOrder::after_link(&last_link).unwrap());
|
|
|
|
attach_program_with_link_order!(before_default, LinkOrder::before_program(default).unwrap());
|
|
attach_program_with_link_order!(after_default, LinkOrder::after_program(default).unwrap());
|
|
|
|
attach_program_with_link_order!(
|
|
before_first,
|
|
LinkOrder::before_program_id(unsafe { ProgramId::new(first.info().unwrap().id()) })
|
|
);
|
|
attach_program_with_link_order!(
|
|
after_first,
|
|
LinkOrder::after_program_id(unsafe { ProgramId::new(first.info().unwrap().id()) })
|
|
);
|
|
|
|
let expected_order = [
|
|
before_first,
|
|
first,
|
|
after_first,
|
|
before_default,
|
|
default,
|
|
after_default,
|
|
before_last,
|
|
last,
|
|
after_last,
|
|
]
|
|
.iter()
|
|
.map(|program| program.info().unwrap().id())
|
|
.collect::<Vec<_>>();
|
|
|
|
let (revision, got_order) = SchedClassifier::query_tcx("lo", TcAttachType::Ingress).unwrap();
|
|
assert_eq!(revision, (expected_order.len() + 1) as u64);
|
|
assert_eq!(
|
|
got_order.iter().map(|p| p.id()).collect::<Vec<_>>(),
|
|
expected_order
|
|
);
|
|
}
|