#[allow(dead_code)] mod common; use std::os::fd::AsFd; use scopeguard::defer; use test_tag::tag; use libbpf_rs::Xdp; use libbpf_rs::XdpFlags; use crate::common::bump_rlimit_mlock; use crate::common::get_prog_mut; use crate::common::get_test_object; const LO_IFINDEX: i32 = 1; #[tag(root)] #[test] fn test_xdp() { bump_rlimit_mlock(); let mut obj = get_test_object("xdp.bpf.o"); let prog = get_prog_mut(&mut obj, "xdp_filter"); let fd = prog.as_fd(); let mut obj1 = get_test_object("xdp.bpf.o"); let prog1 = get_prog_mut(&mut obj1, "xdp_filter"); let fd1 = prog1.as_fd(); let xdp_prog = Xdp::new(fd); let xdp_prog1 = Xdp::new(fd1); defer! { xdp_prog.detach(LO_IFINDEX, XdpFlags::UPDATE_IF_NOEXIST).unwrap(); } assert!(xdp_prog .attach(LO_IFINDEX, XdpFlags::UPDATE_IF_NOEXIST) .is_ok()); // Second attach should fail as a prog is already loaded assert!(xdp_prog .attach(LO_IFINDEX, XdpFlags::UPDATE_IF_NOEXIST) .is_err()); assert!(xdp_prog .query_id(LO_IFINDEX, XdpFlags::UPDATE_IF_NOEXIST) .is_ok()); assert!(xdp_prog .query(LO_IFINDEX, XdpFlags::UPDATE_IF_NOEXIST) .is_ok()); let old_prog_id = xdp_prog .query_id(LO_IFINDEX, XdpFlags::UPDATE_IF_NOEXIST) .unwrap(); assert!(xdp_prog1.replace(LO_IFINDEX, fd).is_ok()); let new_prog_id = xdp_prog1 .query_id(LO_IFINDEX, XdpFlags::UPDATE_IF_NOEXIST) .unwrap(); // If xdp prog is replaced, prog id should change. assert!(old_prog_id != new_prog_id); assert!(xdp_prog .detach(LO_IFINDEX, XdpFlags::UPDATE_IF_NOEXIST) .is_ok()); }