|
|
|
@ -3,12 +3,12 @@ use std::{
|
|
|
|
|
ffi::{CStr, CString},
|
|
|
|
|
io, iter,
|
|
|
|
|
mem::{self, MaybeUninit},
|
|
|
|
|
os::fd::{AsRawFd as _, BorrowedFd, FromRawFd as _, OwnedFd, RawFd},
|
|
|
|
|
os::fd::{AsFd as _, AsRawFd as _, BorrowedFd, FromRawFd as _, OwnedFd, RawFd},
|
|
|
|
|
slice,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
use crate::util::KernelVersion;
|
|
|
|
|
use libc::{c_char, c_long, close, ENOENT, ENOSPC};
|
|
|
|
|
use libc::{c_char, c_long, ENOENT, ENOSPC};
|
|
|
|
|
use obj::{
|
|
|
|
|
btf::{BtfEnum64, Enum64},
|
|
|
|
|
maps::{bpf_map_def, LegacyMap},
|
|
|
|
@ -190,8 +190,7 @@ pub(crate) fn bpf_load_program(
|
|
|
|
|
if let Some(v) = aya_attr.attach_btf_id {
|
|
|
|
|
u.attach_btf_id = v;
|
|
|
|
|
}
|
|
|
|
|
// SAFETY: BPF_PROG_LOAD returns a new file descriptor.
|
|
|
|
|
unsafe { fd_sys_bpf(bpf_cmd::BPF_PROG_LOAD, &mut attr) }
|
|
|
|
|
bpf_prog_load(&mut attr)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn lookup<K: Pod, V: Pod>(
|
|
|
|
@ -633,14 +632,7 @@ pub(crate) fn is_prog_name_supported() -> bool {
|
|
|
|
|
u.insns = insns.as_ptr() as u64;
|
|
|
|
|
u.prog_type = bpf_prog_type::BPF_PROG_TYPE_SOCKET_FILTER as u32;
|
|
|
|
|
|
|
|
|
|
match sys_bpf(bpf_cmd::BPF_PROG_LOAD, &mut attr) {
|
|
|
|
|
Ok(v) => {
|
|
|
|
|
let fd = v as RawFd;
|
|
|
|
|
unsafe { close(fd) };
|
|
|
|
|
true
|
|
|
|
|
}
|
|
|
|
|
Err(_) => false,
|
|
|
|
|
}
|
|
|
|
|
bpf_prog_load(&mut attr).is_ok()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub(crate) fn is_probe_read_kernel_supported() -> bool {
|
|
|
|
@ -664,14 +656,7 @@ pub(crate) fn is_probe_read_kernel_supported() -> bool {
|
|
|
|
|
u.insns = insns.as_ptr() as u64;
|
|
|
|
|
u.prog_type = bpf_prog_type::BPF_PROG_TYPE_TRACEPOINT as u32;
|
|
|
|
|
|
|
|
|
|
match sys_bpf(bpf_cmd::BPF_PROG_LOAD, &mut attr) {
|
|
|
|
|
Ok(v) => {
|
|
|
|
|
let fd = v as RawFd;
|
|
|
|
|
unsafe { close(fd) };
|
|
|
|
|
true
|
|
|
|
|
}
|
|
|
|
|
Err(_) => false,
|
|
|
|
|
}
|
|
|
|
|
bpf_prog_load(&mut attr).is_ok()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub(crate) fn is_perf_link_supported() -> bool {
|
|
|
|
@ -691,18 +676,18 @@ pub(crate) fn is_perf_link_supported() -> bool {
|
|
|
|
|
u.insns = insns.as_ptr() as u64;
|
|
|
|
|
u.prog_type = bpf_prog_type::BPF_PROG_TYPE_TRACEPOINT as u32;
|
|
|
|
|
|
|
|
|
|
if let Ok(fd) = sys_bpf(bpf_cmd::BPF_PROG_LOAD, &mut attr) {
|
|
|
|
|
if let Err((_, e)) =
|
|
|
|
|
if let Ok(fd) = bpf_prog_load(&mut attr) {
|
|
|
|
|
let fd = fd.as_fd();
|
|
|
|
|
let fd = fd.as_raw_fd();
|
|
|
|
|
matches!(
|
|
|
|
|
// Uses an invalid target FD so we get EBADF if supported.
|
|
|
|
|
bpf_link_create(fd as i32, -1, bpf_attach_type::BPF_PERF_EVENT, None, 0)
|
|
|
|
|
{
|
|
|
|
|
bpf_link_create(fd, -1, bpf_attach_type::BPF_PERF_EVENT, None, 0),
|
|
|
|
|
// Returns EINVAL if unsupported. EBADF if supported.
|
|
|
|
|
let res = e.raw_os_error() == Some(libc::EBADF);
|
|
|
|
|
unsafe { libc::close(fd as i32) };
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
Err((_, e)) if e.raw_os_error() == Some(libc::EBADF),
|
|
|
|
|
)
|
|
|
|
|
} else {
|
|
|
|
|
false
|
|
|
|
|
}
|
|
|
|
|
false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub(crate) fn is_bpf_global_data_supported() -> bool {
|
|
|
|
@ -746,16 +731,10 @@ pub(crate) fn is_bpf_global_data_supported() -> bool {
|
|
|
|
|
u.insns = insns.as_ptr() as u64;
|
|
|
|
|
u.prog_type = bpf_prog_type::BPF_PROG_TYPE_SOCKET_FILTER as u32;
|
|
|
|
|
|
|
|
|
|
if let Ok(v) = sys_bpf(bpf_cmd::BPF_PROG_LOAD, &mut attr) {
|
|
|
|
|
let fd = v as RawFd;
|
|
|
|
|
|
|
|
|
|
unsafe { close(fd) };
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
bpf_prog_load(&mut attr).is_ok()
|
|
|
|
|
} else {
|
|
|
|
|
false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub(crate) fn is_bpf_cookie_supported() -> bool {
|
|
|
|
@ -775,14 +754,7 @@ pub(crate) fn is_bpf_cookie_supported() -> bool {
|
|
|
|
|
u.insns = insns.as_ptr() as u64;
|
|
|
|
|
u.prog_type = bpf_prog_type::BPF_PROG_TYPE_KPROBE as u32;
|
|
|
|
|
|
|
|
|
|
match sys_bpf(bpf_cmd::BPF_PROG_LOAD, &mut attr) {
|
|
|
|
|
Ok(v) => {
|
|
|
|
|
let fd = v as RawFd;
|
|
|
|
|
unsafe { close(fd) };
|
|
|
|
|
true
|
|
|
|
|
}
|
|
|
|
|
Err(_) => false,
|
|
|
|
|
}
|
|
|
|
|
bpf_prog_load(&mut attr).is_ok()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub(crate) fn is_btf_supported() -> bool {
|
|
|
|
@ -941,6 +913,11 @@ pub(crate) fn is_btf_type_tag_supported() -> bool {
|
|
|
|
|
bpf_load_btf(btf_bytes.as_slice(), &mut [], Default::default()).is_ok()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn bpf_prog_load(attr: &mut bpf_attr) -> SysResult<OwnedFd> {
|
|
|
|
|
// SAFETY: BPF_PROG_LOAD returns a new file descriptor.
|
|
|
|
|
unsafe { fd_sys_bpf(bpf_cmd::BPF_PROG_LOAD, attr) }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn sys_bpf(cmd: bpf_cmd, attr: &mut bpf_attr) -> SysResult<c_long> {
|
|
|
|
|
syscall(Syscall::Bpf { cmd, attr })
|
|
|
|
|
}
|
|
|
|
|