|  |  |  | @ -12,16 +12,12 @@ use aya::{ | 
		
	
		
			
				|  |  |  |  |     Ebpf, | 
		
	
		
			
				|  |  |  |  |     maps::{Array, HashMap, IterableMap as _, MapError, MapType, loaded_maps}, | 
		
	
		
			
				|  |  |  |  |     programs::{ProgramError, ProgramType, SocketFilter, TracePoint, loaded_programs}, | 
		
	
		
			
				|  |  |  |  |     sys::enable_stats, | 
		
	
		
			
				|  |  |  |  |     util::KernelVersion, | 
		
	
		
			
				|  |  |  |  | }; | 
		
	
		
			
				|  |  |  |  | use libc::EINVAL; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | use crate::utils::{kernel_assert, kernel_assert_eq}; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | const BPF_JIT_ENABLE: &str = "/proc/sys/net/core/bpf_jit_enable"; | 
		
	
		
			
				|  |  |  |  | const BPF_STATS_ENABLED: &str = "/proc/sys/kernel/bpf_stats_enabled"; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | #[test] | 
		
	
		
			
				|  |  |  |  | fn test_loaded_programs() { | 
		
	
		
			
				|  |  |  |  |     // Load a program.
 | 
		
	
	
		
			
				
					|  |  |  | @ -57,16 +53,7 @@ fn test_loaded_programs() { | 
		
	
		
			
				|  |  |  |  | #[test] | 
		
	
		
			
				|  |  |  |  | fn test_program_info() { | 
		
	
		
			
				|  |  |  |  |     // Kernels below v4.15 have been observed to have `bpf_jit_enable` disabled by default.
 | 
		
	
		
			
				|  |  |  |  |     let previously_enabled = is_sysctl_enabled(BPF_JIT_ENABLE); | 
		
	
		
			
				|  |  |  |  |     // Restore to previous state when panic occurs.
 | 
		
	
		
			
				|  |  |  |  |     let prev_panic = panic::take_hook(); | 
		
	
		
			
				|  |  |  |  |     panic::set_hook(Box::new(move |panic_info| { | 
		
	
		
			
				|  |  |  |  |         if !previously_enabled { | 
		
	
		
			
				|  |  |  |  |             disable_sysctl_param(BPF_JIT_ENABLE); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         prev_panic(panic_info); | 
		
	
		
			
				|  |  |  |  |     })); | 
		
	
		
			
				|  |  |  |  |     let jit_enabled = previously_enabled || enable_sysctl_param(BPF_JIT_ENABLE); | 
		
	
		
			
				|  |  |  |  |     let _guard = ensure_sysctl_enabled("/proc/sys/net/core/bpf_jit_enable"); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     let mut bpf = Ebpf::load(crate::SIMPLE_PROG).unwrap(); | 
		
	
		
			
				|  |  |  |  |     let prog: &mut SocketFilter = bpf.program_mut("simple_prog").unwrap().try_into().unwrap(); | 
		
	
	
		
			
				
					|  |  |  | @ -81,9 +68,7 @@ fn test_program_info() { | 
		
	
		
			
				|  |  |  |  |     ); | 
		
	
		
			
				|  |  |  |  |     kernel_assert!(test_prog.id() > 0, KernelVersion::new(4, 13, 0)); | 
		
	
		
			
				|  |  |  |  |     kernel_assert!(test_prog.tag() > 0, KernelVersion::new(4, 13, 0)); | 
		
	
		
			
				|  |  |  |  |     if jit_enabled { | 
		
	
		
			
				|  |  |  |  |     kernel_assert!(test_prog.size_jitted() > 0, KernelVersion::new(4, 13, 0)); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |     kernel_assert!( | 
		
	
		
			
				|  |  |  |  |         test_prog.size_translated().is_some(), | 
		
	
		
			
				|  |  |  |  |         KernelVersion::new(4, 13, 0), | 
		
	
	
		
			
				
					|  |  |  | @ -121,11 +106,6 @@ fn test_program_info() { | 
		
	
		
			
				|  |  |  |  |     // Ensure rest of the fields do not panic.
 | 
		
	
		
			
				|  |  |  |  |     test_prog.memory_locked().unwrap(); | 
		
	
		
			
				|  |  |  |  |     test_prog.fd().unwrap(); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     // Restore to previous state
 | 
		
	
		
			
				|  |  |  |  |     if !previously_enabled { | 
		
	
		
			
				|  |  |  |  |         disable_sysctl_param(BPF_JIT_ENABLE); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | #[test] | 
		
	
	
		
			
				
					|  |  |  | @ -184,23 +164,7 @@ fn test_prog_stats() { | 
		
	
		
			
				|  |  |  |  |         return; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     let stats_fd = enable_stats(aya::sys::Stats::RunTime).ok(); | 
		
	
		
			
				|  |  |  |  |     // Restore to previous state when panic occurs.
 | 
		
	
		
			
				|  |  |  |  |     let previously_enabled = is_sysctl_enabled(BPF_STATS_ENABLED); | 
		
	
		
			
				|  |  |  |  |     let prev_panic = panic::take_hook(); | 
		
	
		
			
				|  |  |  |  |     panic::set_hook(Box::new(move |panic_info| { | 
		
	
		
			
				|  |  |  |  |         if !previously_enabled { | 
		
	
		
			
				|  |  |  |  |             disable_sysctl_param(BPF_STATS_ENABLED); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         prev_panic(panic_info); | 
		
	
		
			
				|  |  |  |  |     })); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     let stats_enabled = | 
		
	
		
			
				|  |  |  |  |         stats_fd.is_some() || previously_enabled || enable_sysctl_param(BPF_STATS_ENABLED); | 
		
	
		
			
				|  |  |  |  |     if !stats_enabled { | 
		
	
		
			
				|  |  |  |  |         eprintln!("ignoring test completely as bpf stats could not be enabled on the host"); | 
		
	
		
			
				|  |  |  |  |         return; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |     let _guard = ensure_sysctl_enabled("/proc/sys/kernel/bpf_stats_enabled"); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     let mut bpf = Ebpf::load(crate::TEST).unwrap(); | 
		
	
		
			
				|  |  |  |  |     let prog: &mut TracePoint = bpf | 
		
	
	
		
			
				
					|  |  |  | @ -213,11 +177,6 @@ fn test_prog_stats() { | 
		
	
		
			
				|  |  |  |  |     let test_prog = prog.info().unwrap(); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     kernel_assert!(test_prog.run_count() > 0, KernelVersion::new(5, 1, 0)); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     // Restore to previous state
 | 
		
	
		
			
				|  |  |  |  |     if !previously_enabled { | 
		
	
		
			
				|  |  |  |  |         disable_sysctl_param(BPF_STATS_ENABLED); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | #[test] | 
		
	
	
		
			
				
					|  |  |  | @ -318,20 +277,12 @@ fn test_map_info() { | 
		
	
		
			
				|  |  |  |  |     array.fd().unwrap(); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | /// Whether sysctl parameter is enabled in the `/proc` file.
 | 
		
	
		
			
				|  |  |  |  | fn is_sysctl_enabled(path: &str) -> bool { | 
		
	
		
			
				|  |  |  |  |     match fs::read_to_string(path) { | 
		
	
		
			
				|  |  |  |  |         Ok(contents) => contents.chars().next().is_some_and(|c| c == '1'), | 
		
	
		
			
				|  |  |  |  |         Err(_) => false, | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | /// Enable sysctl parameter through procfs.
 | 
		
	
		
			
				|  |  |  |  | fn enable_sysctl_param(path: &str) -> bool { | 
		
	
		
			
				|  |  |  |  |     fs::write(path, b"1").is_ok() | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | /// Disable sysctl parameter through procfs.
 | 
		
	
		
			
				|  |  |  |  | fn disable_sysctl_param(path: &str) -> bool { | 
		
	
		
			
				|  |  |  |  |     fs::write(path, b"0").is_ok() | 
		
	
		
			
				|  |  |  |  | fn ensure_sysctl_enabled<'a>( | 
		
	
		
			
				|  |  |  |  |     path: &'a str, | 
		
	
		
			
				|  |  |  |  | ) -> Option<scopeguard::ScopeGuard<&'a str, impl FnOnce(&'a str)>> { | 
		
	
		
			
				|  |  |  |  |     let content = fs::read_to_string(path).unwrap(); | 
		
	
		
			
				|  |  |  |  |     (!content.starts_with('1')).then(move || { | 
		
	
		
			
				|  |  |  |  |         fs::write(path, b"1").unwrap(); | 
		
	
		
			
				|  |  |  |  |         scopeguard::guard(path, |path| fs::write(path, b"0").unwrap()) | 
		
	
		
			
				|  |  |  |  |     }) | 
		
	
		
			
				|  |  |  |  | } | 
		
	
	
		
			
				
					|  |  |  | 
 |