|
|
@ -38,7 +38,7 @@ use crate::{
|
|
|
|
is_btf_func_supported, is_btf_supported, is_btf_type_tag_supported, is_perf_link_supported,
|
|
|
|
is_btf_func_supported, is_btf_supported, is_btf_type_tag_supported, is_perf_link_supported,
|
|
|
|
is_prog_name_supported, retry_with_verifier_logs,
|
|
|
|
is_prog_name_supported, retry_with_verifier_logs,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
util::{bytes_of, bytes_of_slice, possible_cpus, VerifierLog, POSSIBLE_CPUS},
|
|
|
|
util::{bytes_of, possible_cpus, VerifierLog, POSSIBLE_CPUS},
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
pub(crate) const BPF_OBJ_NAME_LEN: usize = 16;
|
|
|
|
pub(crate) const BPF_OBJ_NAME_LEN: usize = 16;
|
|
|
@ -210,17 +210,15 @@ impl<'a> BpfLoader<'a> {
|
|
|
|
self
|
|
|
|
self
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Sets the value of a global variable.
|
|
|
|
/// Sets the value of a global variable
|
|
|
|
///
|
|
|
|
|
|
|
|
/// From Rust eBPF, a global variable can be defined as follows:
|
|
|
|
|
|
|
|
///
|
|
|
|
///
|
|
|
|
|
|
|
|
/// From Rust eBPF, a global variable would be constructed as follows:
|
|
|
|
/// ```no_run
|
|
|
|
/// ```no_run
|
|
|
|
/// #[no_mangle]
|
|
|
|
/// #[no_mangle]
|
|
|
|
/// static VERSION: i32 = 0;
|
|
|
|
/// static VERSION: i32 = 0;
|
|
|
|
/// ```
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// Then it would be accessed with `core::ptr::read_volatile` inside
|
|
|
|
/// Then it can be accessed using `core::ptr::read_volatile`:
|
|
|
|
/// functions:
|
|
|
|
///
|
|
|
|
|
|
|
|
/// ```no_run
|
|
|
|
/// ```no_run
|
|
|
|
/// # #[no_mangle]
|
|
|
|
/// # #[no_mangle]
|
|
|
|
/// # static VERSION: i32 = 0;
|
|
|
|
/// # static VERSION: i32 = 0;
|
|
|
@ -228,12 +226,10 @@ impl<'a> BpfLoader<'a> {
|
|
|
|
/// let version = core::ptr::read_volatile(&VERSION);
|
|
|
|
/// let version = core::ptr::read_volatile(&VERSION);
|
|
|
|
/// # }
|
|
|
|
/// # }
|
|
|
|
/// ```
|
|
|
|
/// ```
|
|
|
|
|
|
|
|
/// If using a struct, ensure that it is `#[repr(C)]` to ensure the size will
|
|
|
|
|
|
|
|
/// match that of the corresponding ELF symbol.
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// The type of a global variable must be `Pod` (plain old data), for instance `u8`, `u32` and
|
|
|
|
/// From C eBPF, you would annotate a variable as `volatile const`
|
|
|
|
/// all other primitive types. You may use custom types as well, but you must ensure that those
|
|
|
|
|
|
|
|
/// types are `#[repr(C)]` and only contain other `Pod` types.
|
|
|
|
|
|
|
|
///
|
|
|
|
|
|
|
|
/// From C eBPF, you would annotate a global variable as `volatile const`.
|
|
|
|
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
///
|
|
|
@ -242,17 +238,14 @@ impl<'a> BpfLoader<'a> {
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// let bpf = BpfLoader::new()
|
|
|
|
/// let bpf = BpfLoader::new()
|
|
|
|
/// .set_global("VERSION", &2)
|
|
|
|
/// .set_global("VERSION", &2)
|
|
|
|
/// .set_global("PIDS", &[1234u16, 5678])
|
|
|
|
|
|
|
|
/// .load_file("file.o")?;
|
|
|
|
/// .load_file("file.o")?;
|
|
|
|
/// # Ok::<(), aya::BpfError>(())
|
|
|
|
/// # Ok::<(), aya::BpfError>(())
|
|
|
|
/// ```
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
///
|
|
|
|
pub fn set_global<T: Into<GlobalData<'a>>>(
|
|
|
|
pub fn set_global<V: Pod>(&mut self, name: &'a str, value: &'a V) -> &mut BpfLoader<'a> {
|
|
|
|
&mut self,
|
|
|
|
// Safety: value is POD
|
|
|
|
name: &'a str,
|
|
|
|
let data = unsafe { bytes_of(value) };
|
|
|
|
value: T,
|
|
|
|
self.globals.insert(name, data);
|
|
|
|
) -> &mut BpfLoader<'a> {
|
|
|
|
|
|
|
|
self.globals.insert(name, value.into().bytes);
|
|
|
|
|
|
|
|
self
|
|
|
|
self
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -904,28 +897,3 @@ fn load_btf(raw_btf: Vec<u8>) -> Result<RawFd, BtfError> {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Global data that can be exported to eBPF programs before they are loaded.
|
|
|
|
|
|
|
|
///
|
|
|
|
|
|
|
|
/// Valid global data includes `Pod` types and slices of `Pod` types. See also
|
|
|
|
|
|
|
|
/// [BpfLoader::set_global].
|
|
|
|
|
|
|
|
pub struct GlobalData<'a> {
|
|
|
|
|
|
|
|
bytes: &'a [u8],
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl<'a, T: Pod> From<&'a [T]> for GlobalData<'a> {
|
|
|
|
|
|
|
|
fn from(s: &'a [T]) -> Self {
|
|
|
|
|
|
|
|
GlobalData {
|
|
|
|
|
|
|
|
bytes: bytes_of_slice(s),
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl<'a, T: Pod> From<&'a T> for GlobalData<'a> {
|
|
|
|
|
|
|
|
fn from(v: &'a T) -> Self {
|
|
|
|
|
|
|
|
GlobalData {
|
|
|
|
|
|
|
|
// Safety: v is Pod
|
|
|
|
|
|
|
|
bytes: unsafe { bytes_of(v) },
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|