diff --git a/test/integration-test/src/tests/load.rs b/test/integration-test/src/tests/load.rs index 7187ac78..7f66a4f3 100644 --- a/test/integration-test/src/tests/load.rs +++ b/test/integration-test/src/tests/load.rs @@ -12,7 +12,8 @@ use aya::{ links::{FdLink, PinnedLink}, loaded_links, loaded_programs, tc::{clsact_qdisc_exists, qdisc_add_clsact}, - KProbe, SchedClassifier, TcAttachType, TracePoint, UProbe, Xdp, XdpFlags, + KProbe, ProgramError, SchedClassifier, TcAttachType, TcError, TracePoint, UProbe, Xdp, + XdpFlags, }, util::KernelVersion, Bpf, @@ -32,10 +33,15 @@ fn tc_name_limit() { let mut bpf = Bpf::load(crate::TC_NAME_LIMIT_TEST).unwrap(); - // This magic number (256) is derived from the fact that the kernel - // permits names with a maximum length of 256 bytes: - // https://github.com/torvalds/linux/blob/02aee814/net/sched/cls_bpf.c#L28 - // In this case, the name is 256 'a's + /* + A 256-byte-long name (all 'a's) to be used as the name of the + ebpf program. This name must match the name passed to the kernel + side (i.e. test/integration-ebpf/src/tc_name_limit.rs). + + 256 is the maximum length allowed by the kernel, so this test + should pass. + https://github.com/torvalds/linux/blob/02aee814/net/sched/cls_bpf.c#L28 + */ let long_name = "a".repeat(256); let program: &mut SchedClassifier = bpf @@ -47,6 +53,49 @@ fn tc_name_limit() { program.attach("lo", TcAttachType::Ingress).unwrap(); } +#[test] +fn tc_name_limit_exceeded() { + let clsact_exists = clsact_qdisc_exists("lo").unwrap(); + if !clsact_exists { + qdisc_add_clsact("lo").unwrap(); + } + + let mut bpf = Bpf::load(crate::TC_NAME_LIMIT_EXCEEDED_TEST).unwrap(); + + /* + A 257-byte-long name (all 'a's) to be used as the name of the + ebpf program. This name must match the name passed to the kernel + side (i.e. test/integration-ebpf/src/tc_name_limit_exceeded.rs). + + 256 is the maximum length allowed by the kernel, so this test + should fail. + https://github.com/torvalds/linux/blob/02aee814/net/sched/cls_bpf.c#L28 + */ + let long_name = "a".repeat(257); + + let program: &mut SchedClassifier = bpf + .program_mut(long_name.as_str()) + .unwrap() + .try_into() + .unwrap(); + program.load().unwrap(); + + // This code should fail while trying to attach the eBPF program + // with a name longer that the maximum length allowed by the kernel, + // as a result, all arms except the desired Err() should be unreachable!(). + match program.attach("lo", TcAttachType::Ingress) { + Ok(_) => unreachable!(), + Err(ProgramError::TcError(TcError::NetlinkError { io_error })) => { + // This assertion is checking that the raw OS error code associated + // with the io_error is indeed 22, indicating that an invalid argument + // error (EINVAL) occurred. In this case, the invalid argument is + // the tc program name which is too long. + assert_eq!(io_error.raw_os_error(), Some(22)); + } + _ => unreachable!(), + } +} + #[test] fn long_name() { let mut bpf = Bpf::load(crate::NAME_TEST).unwrap();