handle error while getting current kernel version

pull/1042/head
Badr 4 months ago
parent 0f163633e3
commit eea36282ea

@ -1,5 +1,6 @@
//! Cgroup device programs.
use log::warn;
use std::os::fd::AsFd;
use crate::{
@ -70,31 +71,43 @@ impl CgroupDevice {
let prog_fd = prog_fd.as_fd();
let cgroup_fd = cgroup.as_fd();
if KernelVersion::current().unwrap() >= KernelVersion::new(5, 7, 0) {
let link_fd = bpf_link_create(
prog_fd,
LinkTarget::Fd(cgroup_fd),
BPF_CGROUP_DEVICE,
None,
mode.into(),
)
.map_err(|(_, io_error)| SyscallError {
call: "bpf_link_create",
io_error,
})?;
self.data
.links
.insert(CgroupDeviceLink::new(CgroupDeviceLinkInner::Fd(
FdLink::new(link_fd),
)))
} else {
let link = ProgAttachLink::attach(prog_fd, cgroup_fd, BPF_CGROUP_DEVICE, mode)?;
self.data
.links
.insert(CgroupDeviceLink::new(CgroupDeviceLinkInner::ProgAttach(
link,
)))
match KernelVersion::current() {
Ok(version) => {
if version >= KernelVersion::new(5, 7, 0) {
let link_fd = bpf_link_create(
prog_fd,
LinkTarget::Fd(cgroup_fd),
BPF_CGROUP_DEVICE,
None,
mode.into(),
)
.map_err(|(_, io_error)| SyscallError {
call: "bpf_link_create",
io_error,
})?;
self.data
.links
.insert(CgroupDeviceLink::new(CgroupDeviceLinkInner::Fd(
FdLink::new(link_fd),
)))
} else {
let link = ProgAttachLink::attach(prog_fd, cgroup_fd, BPF_CGROUP_DEVICE, mode)?;
self.data.links.insert(CgroupDeviceLink::new(
CgroupDeviceLinkInner::ProgAttach(link),
))
}
}
Err(_) => {
warn!("Warning: Can not get the current kernel version");
let link = ProgAttachLink::attach(prog_fd, cgroup_fd, BPF_CGROUP_DEVICE, mode)?;
self.data
.links
.insert(CgroupDeviceLink::new(CgroupDeviceLinkInner::ProgAttach(
link,
)))
}
}
}

@ -2,6 +2,8 @@
use std::{hash::Hash, os::fd::AsFd, path::Path};
use log::warn;
use crate::{
generated::{
bpf_attach_type::{BPF_CGROUP_INET_EGRESS, BPF_CGROUP_INET_INGRESS},
@ -98,29 +100,41 @@ impl CgroupSkb {
CgroupSkbAttachType::Ingress => BPF_CGROUP_INET_INGRESS,
CgroupSkbAttachType::Egress => BPF_CGROUP_INET_EGRESS,
};
if KernelVersion::current().unwrap() >= KernelVersion::new(5, 7, 0) {
let link_fd = bpf_link_create(
prog_fd,
LinkTarget::Fd(cgroup_fd),
attach_type,
None,
mode.into(),
)
.map_err(|(_, io_error)| SyscallError {
call: "bpf_link_create",
io_error,
})?;
self.data
.links
.insert(CgroupSkbLink::new(CgroupSkbLinkInner::Fd(FdLink::new(
link_fd,
))))
} else {
let link = ProgAttachLink::attach(prog_fd, cgroup_fd, attach_type, mode)?;
self.data
.links
.insert(CgroupSkbLink::new(CgroupSkbLinkInner::ProgAttach(link)))
match KernelVersion::current() {
Ok(version) => {
if version >= KernelVersion::new(5, 7, 0) {
let link_fd = bpf_link_create(
prog_fd,
LinkTarget::Fd(cgroup_fd),
attach_type,
None,
mode.into(),
)
.map_err(|(_, io_error)| SyscallError {
call: "bpf_link_create",
io_error,
})?;
self.data
.links
.insert(CgroupSkbLink::new(CgroupSkbLinkInner::Fd(FdLink::new(
link_fd,
))))
} else {
let link = ProgAttachLink::attach(prog_fd, cgroup_fd, attach_type, mode)?;
self.data
.links
.insert(CgroupSkbLink::new(CgroupSkbLinkInner::ProgAttach(link)))
}
}
Err(_) => {
warn!("Warning: Can not get the current kernel version");
let link = ProgAttachLink::attach(prog_fd, cgroup_fd, attach_type, mode)?;
self.data
.links
.insert(CgroupSkbLink::new(CgroupSkbLinkInner::ProgAttach(link)))
}
}
}

@ -3,6 +3,7 @@
use std::{hash::Hash, os::fd::AsFd, path::Path};
pub use aya_obj::programs::CgroupSockAttachType;
use log::warn;
use crate::{
generated::bpf_prog_type::BPF_PROG_TYPE_CGROUP_SOCK,
@ -76,29 +77,42 @@ impl CgroupSock {
let prog_fd = prog_fd.as_fd();
let cgroup_fd = cgroup.as_fd();
let attach_type = self.data.expected_attach_type.unwrap();
if KernelVersion::current().unwrap() >= KernelVersion::new(5, 7, 0) {
let link_fd = bpf_link_create(
prog_fd,
LinkTarget::Fd(cgroup_fd),
attach_type,
None,
mode.into(),
)
.map_err(|(_, io_error)| SyscallError {
call: "bpf_link_create",
io_error,
})?;
self.data
.links
.insert(CgroupSockLink::new(CgroupSockLinkInner::Fd(FdLink::new(
link_fd,
))))
} else {
let link = ProgAttachLink::attach(prog_fd, cgroup_fd, attach_type, mode)?;
self.data
.links
.insert(CgroupSockLink::new(CgroupSockLinkInner::ProgAttach(link)))
match KernelVersion::current() {
Ok(version) => {
if version >= KernelVersion::new(5, 7, 0) {
let link_fd = bpf_link_create(
prog_fd,
LinkTarget::Fd(cgroup_fd),
attach_type,
None,
mode.into(),
)
.map_err(|(_, io_error)| SyscallError {
call: "bpf_link_create",
io_error,
})?;
self.data
.links
.insert(CgroupSockLink::new(CgroupSockLinkInner::Fd(FdLink::new(
link_fd,
))))
} else {
let link = ProgAttachLink::attach(prog_fd, cgroup_fd, attach_type, mode)?;
self.data
.links
.insert(CgroupSockLink::new(CgroupSockLinkInner::ProgAttach(link)))
}
}
Err(_) => {
warn!("Warning: Can not get the current kernel version");
let link = ProgAttachLink::attach(prog_fd, cgroup_fd, attach_type, mode)?;
self.data
.links
.insert(CgroupSockLink::new(CgroupSockLinkInner::ProgAttach(link)))
}
}
}

@ -3,6 +3,7 @@
use std::{hash::Hash, os::fd::AsFd, path::Path};
pub use aya_obj::programs::CgroupSockAddrAttachType;
use log::warn;
use crate::{
generated::bpf_prog_type::BPF_PROG_TYPE_CGROUP_SOCK_ADDR,
@ -77,29 +78,42 @@ impl CgroupSockAddr {
let prog_fd = prog_fd.as_fd();
let cgroup_fd = cgroup.as_fd();
let attach_type = self.data.expected_attach_type.unwrap();
if KernelVersion::current().unwrap() >= KernelVersion::new(5, 7, 0) {
let link_fd = bpf_link_create(
prog_fd,
LinkTarget::Fd(cgroup_fd),
attach_type,
None,
mode.into(),
)
.map_err(|(_, io_error)| SyscallError {
call: "bpf_link_create",
io_error,
})?;
self.data
.links
.insert(CgroupSockAddrLink::new(CgroupSockAddrLinkInner::Fd(
FdLink::new(link_fd),
)))
} else {
let link = ProgAttachLink::attach(prog_fd, cgroup_fd, attach_type, mode)?;
self.data.links.insert(CgroupSockAddrLink::new(
CgroupSockAddrLinkInner::ProgAttach(link),
))
match KernelVersion::current() {
Ok(version) => {
if version >= KernelVersion::new(5, 7, 0) {
let link_fd = bpf_link_create(
prog_fd,
LinkTarget::Fd(cgroup_fd),
attach_type,
None,
mode.into(),
)
.map_err(|(_, io_error)| SyscallError {
call: "bpf_link_create",
io_error,
})?;
self.data
.links
.insert(CgroupSockAddrLink::new(CgroupSockAddrLinkInner::Fd(
FdLink::new(link_fd),
)))
} else {
let link = ProgAttachLink::attach(prog_fd, cgroup_fd, attach_type, mode)?;
self.data.links.insert(CgroupSockAddrLink::new(
CgroupSockAddrLinkInner::ProgAttach(link),
))
}
}
Err(_) => {
warn!("Warning: Can not get the current kernel version");
let link = ProgAttachLink::attach(prog_fd, cgroup_fd, attach_type, mode)?;
self.data.links.insert(CgroupSockAddrLink::new(
CgroupSockAddrLinkInner::ProgAttach(link),
))
}
}
}

@ -3,6 +3,7 @@
use std::{hash::Hash, os::fd::AsFd, path::Path};
pub use aya_obj::programs::CgroupSockoptAttachType;
use log::warn;
use crate::{
generated::bpf_prog_type::BPF_PROG_TYPE_CGROUP_SOCKOPT,
@ -74,31 +75,43 @@ impl CgroupSockopt {
let prog_fd = prog_fd.as_fd();
let cgroup_fd = cgroup.as_fd();
let attach_type = self.data.expected_attach_type.unwrap();
if KernelVersion::current().unwrap() >= KernelVersion::new(5, 7, 0) {
let link_fd = bpf_link_create(
prog_fd,
LinkTarget::Fd(cgroup_fd),
attach_type,
None,
mode.into(),
)
.map_err(|(_, io_error)| SyscallError {
call: "bpf_link_create",
io_error,
})?;
self.data
.links
.insert(CgroupSockoptLink::new(CgroupSockoptLinkInner::Fd(
FdLink::new(link_fd),
)))
} else {
let link = ProgAttachLink::attach(prog_fd, cgroup_fd, attach_type, mode)?;
self.data
.links
.insert(CgroupSockoptLink::new(CgroupSockoptLinkInner::ProgAttach(
link,
)))
match KernelVersion::current() {
Ok(version) => {
if version >= KernelVersion::new(5, 7, 0) {
let link_fd = bpf_link_create(
prog_fd,
LinkTarget::Fd(cgroup_fd),
attach_type,
None,
mode.into(),
)
.map_err(|(_, io_error)| SyscallError {
call: "bpf_link_create",
io_error,
})?;
self.data
.links
.insert(CgroupSockoptLink::new(CgroupSockoptLinkInner::Fd(
FdLink::new(link_fd),
)))
} else {
let link = ProgAttachLink::attach(prog_fd, cgroup_fd, attach_type, mode)?;
self.data.links.insert(CgroupSockoptLink::new(
CgroupSockoptLinkInner::ProgAttach(link),
))
}
}
Err(_) => {
warn!("Warning: Can not get the current kernel version");
let link = ProgAttachLink::attach(prog_fd, cgroup_fd, attach_type, mode)?;
self.data
.links
.insert(CgroupSockoptLink::new(CgroupSockoptLinkInner::ProgAttach(
link,
)))
}
}
}

@ -2,6 +2,8 @@
use std::{hash::Hash, os::fd::AsFd};
use log::warn;
use crate::{
generated::{bpf_attach_type::BPF_CGROUP_SYSCTL, bpf_prog_type::BPF_PROG_TYPE_CGROUP_SYSCTL},
programs::{
@ -69,31 +71,43 @@ impl CgroupSysctl {
let prog_fd = prog_fd.as_fd();
let cgroup_fd = cgroup.as_fd();
if KernelVersion::current().unwrap() >= KernelVersion::new(5, 7, 0) {
let link_fd = bpf_link_create(
prog_fd,
LinkTarget::Fd(cgroup_fd),
BPF_CGROUP_SYSCTL,
None,
mode.into(),
)
.map_err(|(_, io_error)| SyscallError {
call: "bpf_link_create",
io_error,
})?;
self.data
.links
.insert(CgroupSysctlLink::new(CgroupSysctlLinkInner::Fd(
FdLink::new(link_fd),
)))
} else {
let link = ProgAttachLink::attach(prog_fd, cgroup_fd, BPF_CGROUP_SYSCTL, mode)?;
self.data
.links
.insert(CgroupSysctlLink::new(CgroupSysctlLinkInner::ProgAttach(
link,
)))
match KernelVersion::current() {
Ok(version) => {
if version >= KernelVersion::new(5, 7, 0) {
let link_fd = bpf_link_create(
prog_fd,
LinkTarget::Fd(cgroup_fd),
BPF_CGROUP_SYSCTL,
None,
mode.into(),
)
.map_err(|(_, io_error)| SyscallError {
call: "bpf_link_create",
io_error,
})?;
self.data
.links
.insert(CgroupSysctlLink::new(CgroupSysctlLinkInner::Fd(
FdLink::new(link_fd),
)))
} else {
let link = ProgAttachLink::attach(prog_fd, cgroup_fd, BPF_CGROUP_SYSCTL, mode)?;
self.data.links.insert(CgroupSysctlLink::new(
CgroupSysctlLinkInner::ProgAttach(link),
))
}
}
Err(_) => {
warn!("Warning: Can not get the current kernel version");
let link = ProgAttachLink::attach(prog_fd, cgroup_fd, BPF_CGROUP_SYSCTL, mode)?;
self.data
.links
.insert(CgroupSysctlLink::new(CgroupSysctlLinkInner::ProgAttach(
link,
)))
}
}
}

@ -10,6 +10,7 @@ use std::{
};
use libc::pid_t;
use log::warn;
use crate::{
programs::{
@ -117,13 +118,23 @@ pub(crate) fn attach<T: Link + From<PerfLinkInner>>(
// Use debugfs to create probe
let prog_fd = program_data.fd()?;
let prog_fd = prog_fd.as_fd();
let link = if KernelVersion::current().unwrap() < KernelVersion::new(4, 17, 0) {
let (fd, event_alias) = create_as_trace_point(kind, fn_name, offset, pid)?;
perf_attach_debugfs(prog_fd, fd, ProbeEvent { kind, event_alias })
} else {
let fd = create_as_probe(kind, fn_name, offset, pid)?;
perf_attach(prog_fd, fd)
let link = match KernelVersion::current() {
Ok(version) => {
if version < KernelVersion::new(4, 17, 0) {
let (fd, event_alias) = create_as_trace_point(kind, fn_name, offset, pid)?;
perf_attach_debugfs(prog_fd, fd, ProbeEvent { kind, event_alias })
} else {
let fd = create_as_probe(kind, fn_name, offset, pid)?;
perf_attach(prog_fd, fd)
}
}
Err(_) => {
warn!("Warning: Can not get the current kernel version");
let fd = create_as_probe(kind, fn_name, offset, pid)?;
perf_attach(prog_fd, fd)
}
}?;
program_data.links.insert(T::from(link))
}

@ -1,6 +1,8 @@
//! Socket option programs.
use std::os::fd::AsFd;
use log::warn;
use crate::{
generated::{bpf_attach_type::BPF_CGROUP_SOCK_OPS, bpf_prog_type::BPF_PROG_TYPE_SOCK_OPS},
programs::{
@ -68,27 +70,40 @@ impl SockOps {
let prog_fd = prog_fd.as_fd();
let cgroup_fd = cgroup.as_fd();
let attach_type = BPF_CGROUP_SOCK_OPS;
if KernelVersion::current().unwrap() >= KernelVersion::new(5, 7, 0) {
let link_fd = bpf_link_create(
prog_fd,
LinkTarget::Fd(cgroup_fd),
attach_type,
None,
mode.into(),
)
.map_err(|(_, io_error)| SyscallError {
call: "bpf_link_create",
io_error,
})?;
self.data
.links
.insert(SockOpsLink::new(SockOpsLinkInner::Fd(FdLink::new(link_fd))))
} else {
let link = ProgAttachLink::attach(prog_fd, cgroup_fd, attach_type, mode)?;
self.data
.links
.insert(SockOpsLink::new(SockOpsLinkInner::ProgAttach(link)))
match KernelVersion::current() {
Ok(version) => {
if version >= KernelVersion::new(5, 7, 0) {
let link_fd = bpf_link_create(
prog_fd,
LinkTarget::Fd(cgroup_fd),
attach_type,
None,
mode.into(),
)
.map_err(|(_, io_error)| SyscallError {
call: "bpf_link_create",
io_error,
})?;
self.data
.links
.insert(SockOpsLink::new(SockOpsLinkInner::Fd(FdLink::new(link_fd))))
} else {
let link = ProgAttachLink::attach(prog_fd, cgroup_fd, attach_type, mode)?;
self.data
.links
.insert(SockOpsLink::new(SockOpsLinkInner::ProgAttach(link)))
}
}
Err(_) => {
warn!("Warning: Can not get the current kernel version");
let link = ProgAttachLink::attach(prog_fd, cgroup_fd, attach_type, mode)?;
self.data
.links
.insert(SockOpsLink::new(SockOpsLinkInner::ProgAttach(link)))
}
}
}

@ -9,6 +9,7 @@ use std::{
};
use libc::if_nametoindex;
use log::warn;
use thiserror::Error;
use crate::{
@ -135,42 +136,61 @@ impl Xdp {
let prog_fd = self.fd()?;
let prog_fd = prog_fd.as_fd();
if KernelVersion::current().unwrap() >= KernelVersion::new(5, 9, 0) {
// Unwrap safety: the function starts with `self.fd()?` that will succeed if and only
// if the program has been loaded, i.e. there is an fd. We get one by:
// - Using `Xdp::from_pin` that sets `expected_attach_type`
// - Calling `Xdp::attach` that sets `expected_attach_type`, as geting an `Xdp`
// instance trhough `Xdp:try_from(Program)` does not set any fd.
// So, in all cases where we have an fd, we have an expected_attach_type. Thus, if we
// reach this point, expected_attach_type is guaranteed to be Some(_).
let attach_type = self.data.expected_attach_type.unwrap();
let link_fd = bpf_link_create(
prog_fd,
LinkTarget::IfIndex(if_index),
attach_type,
None,
flags.bits(),
)
.map_err(|(_, io_error)| SyscallError {
call: "bpf_link_create",
io_error,
})?;
self.data
.links
.insert(XdpLink::new(XdpLinkInner::FdLink(FdLink::new(link_fd))))
} else {
let if_index = if_index as i32;
unsafe { netlink_set_xdp_fd(if_index, Some(prog_fd), None, flags.bits()) }
.map_err(|io_error| XdpError::NetlinkError { io_error })?;
let prog_fd = prog_fd.as_raw_fd();
self.data
.links
.insert(XdpLink::new(XdpLinkInner::NlLink(NlLink {
if_index,
prog_fd,
flags,
})))
match KernelVersion::current() {
Ok(kernel_version) => {
if kernel_version >= KernelVersion::new(5, 9, 0) {
// Unwrap safety: the function starts with `self.fd()?` that will succeed if and only
// if the program has been loaded, i.e. there is an fd. We get one by:
// - Using `Xdp::from_pin` that sets `expected_attach_type`
// - Calling `Xdp::attach` that sets `expected_attach_type`, as geting an `Xdp`
// instance trhough `Xdp:try_from(Program)` does not set any fd.
// So, in all cases where we have an fd, we have an expected_attach_type. Thus, if we
// reach this point, expected_attach_type is guaranteed to be Some(_).
let attach_type = self.data.expected_attach_type.unwrap();
let link_fd = bpf_link_create(
prog_fd,
LinkTarget::IfIndex(if_index),
attach_type,
None,
flags.bits(),
)
.map_err(|(_, io_error)| SyscallError {
call: "bpf_link_create",
io_error,
})?;
self.data
.links
.insert(XdpLink::new(XdpLinkInner::FdLink(FdLink::new(link_fd))))
} else {
let if_index = if_index as i32;
unsafe { netlink_set_xdp_fd(if_index, Some(prog_fd), None, flags.bits()) }
.map_err(|io_error| XdpError::NetlinkError { io_error })?;
let prog_fd = prog_fd.as_raw_fd();
self.data
.links
.insert(XdpLink::new(XdpLinkInner::NlLink(NlLink {
if_index,
prog_fd,
flags,
})))
}
}
Err(e) => {
eprintln!("Error getting the current kernel version");
let if_index = if_index as i32;
unsafe { netlink_set_xdp_fd(if_index, Some(prog_fd), None, flags.bits()) }
.map_err(|io_error| XdpError::NetlinkError { io_error })?;
let prog_fd = prog_fd.as_raw_fd();
self.data
.links
.insert(XdpLink::new(XdpLinkInner::NlLink(NlLink {
if_index,
prog_fd,
flags,
})))
}
}
}
@ -269,11 +289,20 @@ impl Link for NlLink {
}
fn detach(self) -> Result<(), ProgramError> {
let flags = if KernelVersion::current().unwrap() >= KernelVersion::new(5, 7, 0) {
self.flags.bits() | XDP_FLAGS_REPLACE
} else {
self.flags.bits()
let flags = match KernelVersion::current() {
Ok(kernel_version) => {
if kernel_version >= KernelVersion::new(5, 7, 0) {
self.flags.bits() | XDP_FLAGS_REPLACE
} else {
self.flags.bits()
}
}
Err(_) => {
warn!("Warning: Can not get the current kernel version");
self.flags.bits()
}
};
// SAFETY: TODO(https://github.com/aya-rs/aya/issues/612): make this safe by not holding `RawFd`s.
let prog_fd = unsafe { BorrowedFd::borrow_raw(self.prog_fd) };
let _ = unsafe { netlink_set_xdp_fd(self.if_index, None, Some(prog_fd), flags) };

Loading…
Cancel
Save