1 #[allow(dead_code)]
2 mod common;
3 
4 use std::os::fd::AsFd;
5 
6 use scopeguard::defer;
7 
8 use test_tag::tag;
9 
10 use libbpf_rs::Xdp;
11 use libbpf_rs::XdpFlags;
12 
13 use crate::common::bump_rlimit_mlock;
14 use crate::common::get_prog_mut;
15 use crate::common::get_test_object;
16 
17 
18 const LO_IFINDEX: i32 = 1;
19 
20 
21 #[tag(root)]
22 #[test]
test_xdp()23 fn test_xdp() {
24     bump_rlimit_mlock();
25 
26     let mut obj = get_test_object("xdp.bpf.o");
27     let prog = get_prog_mut(&mut obj, "xdp_filter");
28     let fd = prog.as_fd();
29 
30     let mut obj1 = get_test_object("xdp.bpf.o");
31     let prog1 = get_prog_mut(&mut obj1, "xdp_filter");
32     let fd1 = prog1.as_fd();
33 
34     let xdp_prog = Xdp::new(fd);
35     let xdp_prog1 = Xdp::new(fd1);
36 
37     defer! {
38         xdp_prog.detach(LO_IFINDEX, XdpFlags::UPDATE_IF_NOEXIST).unwrap();
39     }
40 
41     assert!(xdp_prog
42         .attach(LO_IFINDEX, XdpFlags::UPDATE_IF_NOEXIST)
43         .is_ok());
44 
45     // Second attach should fail as a prog is already loaded
46     assert!(xdp_prog
47         .attach(LO_IFINDEX, XdpFlags::UPDATE_IF_NOEXIST)
48         .is_err());
49 
50     assert!(xdp_prog
51         .query_id(LO_IFINDEX, XdpFlags::UPDATE_IF_NOEXIST)
52         .is_ok());
53 
54     assert!(xdp_prog
55         .query(LO_IFINDEX, XdpFlags::UPDATE_IF_NOEXIST)
56         .is_ok());
57 
58     let old_prog_id = xdp_prog
59         .query_id(LO_IFINDEX, XdpFlags::UPDATE_IF_NOEXIST)
60         .unwrap();
61     assert!(xdp_prog1.replace(LO_IFINDEX, fd).is_ok());
62     let new_prog_id = xdp_prog1
63         .query_id(LO_IFINDEX, XdpFlags::UPDATE_IF_NOEXIST)
64         .unwrap();
65     // If xdp prog is replaced, prog id should change.
66     assert!(old_prog_id != new_prog_id);
67 
68     assert!(xdp_prog
69         .detach(LO_IFINDEX, XdpFlags::UPDATE_IF_NOEXIST)
70         .is_ok());
71 }
72