pub trait BpfFileDescriptor: FileDescriptor
{
type Identifier: Identifier;
type Information: Information<Identifier=Self::Identifier>;
type Access;
#[doc(hidden)]
const GetFileDescriptor: bpf_cmd;
#[doc(hidden)]
const DefaultAccess: Self::Access;
#[doc(hidden)]
fn access_permissions_to_open_flags(access: Self::Access) -> u32;
#[inline(always)]
fn get_information(&self) -> Result<Self::Information, Errno>
{
let mut information: Self::Information = unsafe_uninitialized();
let mut attr = bpf_attr::default();
attr.info = BpfCommandObjectGetInformationByFileDescriptor
{
bpf_fd: self.as_raw_fd(),
info_len: size_of::<Self::Information>() as u32,
info: AlignedU64::from(&mut information),
};
let result = attr.syscall(bpf_cmd::BPF_OBJ_GET_INFO_BY_FD);
if likely!(result == 0)
{
Ok(information)
}
else if likely!(result == -1)
{
Err(errno())
}
else
{
unreachable_code(format_args!("Unexpected result `{}` from bpf(BPF_OBJ_GET_INFO_BY_FD)", result))
}
}
#[inline(always)]
fn pin_to_path(&self, mount_point: &BpfMountPoint, relative_path: &OsStr) -> Result<(), Errno>
{
let path = mount_point.with_relative_path(relative_path);
let mut path = path_bytes_without_trailing_nul(&path).to_vec();
path.push(b'\0');
let mut attr = bpf_attr::default();
attr.object = BpfCommandObject
{
pathname: AlignedU64::from(path.as_mut_ptr()),
bpf_fd: self.as_raw_fd(),
file_flags: 0,
};
let result = attr.syscall(bpf_cmd::BPF_OBJ_PIN);
if likely!(result == 0)
{
Ok(())
}
else if likely!(result == -1)
{
Err(errno())
}
else
{
unreachable_code(format_args!("Unexpected result `{}` from bpf(BPF_OBJ_PIN)", result))
}
}
#[inline(always)]
fn get_pinned_relative_path(mount_point: &BpfMountPoint, relative_path: &OsStr, access_permissions: KernelOnlyAccessPermissions) -> Result<Self, Errno>
{
let absolute_path = mount_point.with_relative_path(relative_path);
Self::get_pinned_absolute_path(&absolute_path, access_permissions)
}
#[inline(always)]
fn get_pinned_absolute_path(absolute_path: &impl AsRef<Path>, access_permissions: KernelOnlyAccessPermissions) -> Result<Self, Errno>
{
let mut path = path_bytes_without_trailing_nul(&absolute_path).to_vec();
path.push(b'\0');
let mut attr = bpf_attr::default();
attr.object = BpfCommandObject
{
pathname: AlignedU64::from(path.as_mut_ptr()),
bpf_fd: 0,
file_flags: access_permissions.to_map_flags().bits(),
};
let result = attr.syscall(bpf_cmd::BPF_OBJ_GET);
if likely!(result == 0)
{
Ok(unsafe { Self::from_raw_fd(attr.object.bpf_fd) })
}
else if likely!(result == -1)
{
Err(errno())
}
else
{
unreachable_code(format_args!("Unexpected result `{}` from bpf(BPF_OBJ_GET)", result))
}
}
#[inline(always)]
fn from_identifier_with_access_defaults(identifier: Self::Identifier) -> Result<Option<Self>, Errno>
{
Self::from_identifier(identifier, Self::DefaultAccess)
}
#[inline(always)]
fn from_identifier(identifier: Self::Identifier, access_permissions: Self::Access) -> Result<Option<Self>, Errno>
{
let mut attr = bpf_attr::default();
attr.get_identifier = BpfCommandGetIdentifier
{
value_of_identifier: identifier.into(),
next_id: 0,
open_flags: Self::access_permissions_to_open_flags(access_permissions),
};
let result = attr.syscall(Self::GetFileDescriptor);
if likely!(result > 0)
{
Ok(Some(unsafe { Self::from_raw_fd(result) }))
}
else if likely!(result == -1)
{
let errno = errno();
match errno.0
{
ENOENT => Ok(None),
_ => Err(errno)
}
}
else
{
unreachable_code(format_args!("Unexpected result `{}` from bpf({:?})", result, Self::GetFileDescriptor))
}
}
}