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. //! Cgroup device programs.
use log::warn;
use std::os::fd::AsFd; use std::os::fd::AsFd;
use crate::{ use crate::{
@ -70,31 +71,43 @@ impl CgroupDevice {
let prog_fd = prog_fd.as_fd(); let prog_fd = prog_fd.as_fd();
let cgroup_fd = cgroup.as_fd(); let cgroup_fd = cgroup.as_fd();
if KernelVersion::current().unwrap() >= KernelVersion::new(5, 7, 0) { match KernelVersion::current() {
let link_fd = bpf_link_create( Ok(version) => {
prog_fd, if version >= KernelVersion::new(5, 7, 0) {
LinkTarget::Fd(cgroup_fd), let link_fd = bpf_link_create(
BPF_CGROUP_DEVICE, prog_fd,
None, LinkTarget::Fd(cgroup_fd),
mode.into(), BPF_CGROUP_DEVICE,
) None,
.map_err(|(_, io_error)| SyscallError { mode.into(),
call: "bpf_link_create", )
io_error, .map_err(|(_, io_error)| SyscallError {
})?; call: "bpf_link_create",
self.data io_error,
.links })?;
.insert(CgroupDeviceLink::new(CgroupDeviceLinkInner::Fd( self.data
FdLink::new(link_fd), .links
))) .insert(CgroupDeviceLink::new(CgroupDeviceLinkInner::Fd(
} else { FdLink::new(link_fd),
let link = ProgAttachLink::attach(prog_fd, cgroup_fd, BPF_CGROUP_DEVICE, mode)?; )))
} else {
self.data let link = ProgAttachLink::attach(prog_fd, cgroup_fd, BPF_CGROUP_DEVICE, mode)?;
.links
.insert(CgroupDeviceLink::new(CgroupDeviceLinkInner::ProgAttach( self.data.links.insert(CgroupDeviceLink::new(
link, 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 std::{hash::Hash, os::fd::AsFd, path::Path};
use log::warn;
use crate::{ use crate::{
generated::{ generated::{
bpf_attach_type::{BPF_CGROUP_INET_EGRESS, BPF_CGROUP_INET_INGRESS}, bpf_attach_type::{BPF_CGROUP_INET_EGRESS, BPF_CGROUP_INET_INGRESS},
@ -98,29 +100,41 @@ impl CgroupSkb {
CgroupSkbAttachType::Ingress => BPF_CGROUP_INET_INGRESS, CgroupSkbAttachType::Ingress => BPF_CGROUP_INET_INGRESS,
CgroupSkbAttachType::Egress => BPF_CGROUP_INET_EGRESS, CgroupSkbAttachType::Egress => BPF_CGROUP_INET_EGRESS,
}; };
if KernelVersion::current().unwrap() >= KernelVersion::new(5, 7, 0) { match KernelVersion::current() {
let link_fd = bpf_link_create( Ok(version) => {
prog_fd, if version >= KernelVersion::new(5, 7, 0) {
LinkTarget::Fd(cgroup_fd), let link_fd = bpf_link_create(
attach_type, prog_fd,
None, LinkTarget::Fd(cgroup_fd),
mode.into(), attach_type,
) None,
.map_err(|(_, io_error)| SyscallError { mode.into(),
call: "bpf_link_create", )
io_error, .map_err(|(_, io_error)| SyscallError {
})?; call: "bpf_link_create",
self.data io_error,
.links })?;
.insert(CgroupSkbLink::new(CgroupSkbLinkInner::Fd(FdLink::new( self.data
link_fd, .links
)))) .insert(CgroupSkbLink::new(CgroupSkbLinkInner::Fd(FdLink::new(
} else { link_fd,
let link = ProgAttachLink::attach(prog_fd, cgroup_fd, attach_type, mode)?; ))))
} else {
self.data let link = ProgAttachLink::attach(prog_fd, cgroup_fd, attach_type, mode)?;
.links
.insert(CgroupSkbLink::new(CgroupSkbLinkInner::ProgAttach(link))) 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}; use std::{hash::Hash, os::fd::AsFd, path::Path};
pub use aya_obj::programs::CgroupSockAttachType; pub use aya_obj::programs::CgroupSockAttachType;
use log::warn;
use crate::{ use crate::{
generated::bpf_prog_type::BPF_PROG_TYPE_CGROUP_SOCK, generated::bpf_prog_type::BPF_PROG_TYPE_CGROUP_SOCK,
@ -76,29 +77,42 @@ impl CgroupSock {
let prog_fd = prog_fd.as_fd(); let prog_fd = prog_fd.as_fd();
let cgroup_fd = cgroup.as_fd(); let cgroup_fd = cgroup.as_fd();
let attach_type = self.data.expected_attach_type.unwrap(); let attach_type = self.data.expected_attach_type.unwrap();
if KernelVersion::current().unwrap() >= KernelVersion::new(5, 7, 0) {
let link_fd = bpf_link_create( match KernelVersion::current() {
prog_fd, Ok(version) => {
LinkTarget::Fd(cgroup_fd), if version >= KernelVersion::new(5, 7, 0) {
attach_type, let link_fd = bpf_link_create(
None, prog_fd,
mode.into(), LinkTarget::Fd(cgroup_fd),
) attach_type,
.map_err(|(_, io_error)| SyscallError { None,
call: "bpf_link_create", mode.into(),
io_error, )
})?; .map_err(|(_, io_error)| SyscallError {
self.data call: "bpf_link_create",
.links io_error,
.insert(CgroupSockLink::new(CgroupSockLinkInner::Fd(FdLink::new( })?;
link_fd, self.data
)))) .links
} else { .insert(CgroupSockLink::new(CgroupSockLinkInner::Fd(FdLink::new(
let link = ProgAttachLink::attach(prog_fd, cgroup_fd, attach_type, mode)?; link_fd,
))))
self.data } else {
.links let link = ProgAttachLink::attach(prog_fd, cgroup_fd, attach_type, mode)?;
.insert(CgroupSockLink::new(CgroupSockLinkInner::ProgAttach(link)))
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}; use std::{hash::Hash, os::fd::AsFd, path::Path};
pub use aya_obj::programs::CgroupSockAddrAttachType; pub use aya_obj::programs::CgroupSockAddrAttachType;
use log::warn;
use crate::{ use crate::{
generated::bpf_prog_type::BPF_PROG_TYPE_CGROUP_SOCK_ADDR, generated::bpf_prog_type::BPF_PROG_TYPE_CGROUP_SOCK_ADDR,
@ -77,29 +78,42 @@ impl CgroupSockAddr {
let prog_fd = prog_fd.as_fd(); let prog_fd = prog_fd.as_fd();
let cgroup_fd = cgroup.as_fd(); let cgroup_fd = cgroup.as_fd();
let attach_type = self.data.expected_attach_type.unwrap(); let attach_type = self.data.expected_attach_type.unwrap();
if KernelVersion::current().unwrap() >= KernelVersion::new(5, 7, 0) {
let link_fd = bpf_link_create( match KernelVersion::current() {
prog_fd, Ok(version) => {
LinkTarget::Fd(cgroup_fd), if version >= KernelVersion::new(5, 7, 0) {
attach_type, let link_fd = bpf_link_create(
None, prog_fd,
mode.into(), LinkTarget::Fd(cgroup_fd),
) attach_type,
.map_err(|(_, io_error)| SyscallError { None,
call: "bpf_link_create", mode.into(),
io_error, )
})?; .map_err(|(_, io_error)| SyscallError {
self.data call: "bpf_link_create",
.links io_error,
.insert(CgroupSockAddrLink::new(CgroupSockAddrLinkInner::Fd( })?;
FdLink::new(link_fd), self.data
))) .links
} else { .insert(CgroupSockAddrLink::new(CgroupSockAddrLinkInner::Fd(
let link = ProgAttachLink::attach(prog_fd, cgroup_fd, attach_type, mode)?; FdLink::new(link_fd),
)))
self.data.links.insert(CgroupSockAddrLink::new( } else {
CgroupSockAddrLinkInner::ProgAttach(link), 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}; use std::{hash::Hash, os::fd::AsFd, path::Path};
pub use aya_obj::programs::CgroupSockoptAttachType; pub use aya_obj::programs::CgroupSockoptAttachType;
use log::warn;
use crate::{ use crate::{
generated::bpf_prog_type::BPF_PROG_TYPE_CGROUP_SOCKOPT, generated::bpf_prog_type::BPF_PROG_TYPE_CGROUP_SOCKOPT,
@ -74,31 +75,43 @@ impl CgroupSockopt {
let prog_fd = prog_fd.as_fd(); let prog_fd = prog_fd.as_fd();
let cgroup_fd = cgroup.as_fd(); let cgroup_fd = cgroup.as_fd();
let attach_type = self.data.expected_attach_type.unwrap(); let attach_type = self.data.expected_attach_type.unwrap();
if KernelVersion::current().unwrap() >= KernelVersion::new(5, 7, 0) { match KernelVersion::current() {
let link_fd = bpf_link_create( Ok(version) => {
prog_fd, if version >= KernelVersion::new(5, 7, 0) {
LinkTarget::Fd(cgroup_fd), let link_fd = bpf_link_create(
attach_type, prog_fd,
None, LinkTarget::Fd(cgroup_fd),
mode.into(), attach_type,
) None,
.map_err(|(_, io_error)| SyscallError { mode.into(),
call: "bpf_link_create", )
io_error, .map_err(|(_, io_error)| SyscallError {
})?; call: "bpf_link_create",
self.data io_error,
.links })?;
.insert(CgroupSockoptLink::new(CgroupSockoptLinkInner::Fd( self.data
FdLink::new(link_fd), .links
))) .insert(CgroupSockoptLink::new(CgroupSockoptLinkInner::Fd(
} else { FdLink::new(link_fd),
let link = ProgAttachLink::attach(prog_fd, cgroup_fd, attach_type, mode)?; )))
} else {
self.data let link = ProgAttachLink::attach(prog_fd, cgroup_fd, attach_type, mode)?;
.links
.insert(CgroupSockoptLink::new(CgroupSockoptLinkInner::ProgAttach( self.data.links.insert(CgroupSockoptLink::new(
link, 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 std::{hash::Hash, os::fd::AsFd};
use log::warn;
use crate::{ use crate::{
generated::{bpf_attach_type::BPF_CGROUP_SYSCTL, bpf_prog_type::BPF_PROG_TYPE_CGROUP_SYSCTL}, generated::{bpf_attach_type::BPF_CGROUP_SYSCTL, bpf_prog_type::BPF_PROG_TYPE_CGROUP_SYSCTL},
programs::{ programs::{
@ -69,31 +71,43 @@ impl CgroupSysctl {
let prog_fd = prog_fd.as_fd(); let prog_fd = prog_fd.as_fd();
let cgroup_fd = cgroup.as_fd(); let cgroup_fd = cgroup.as_fd();
if KernelVersion::current().unwrap() >= KernelVersion::new(5, 7, 0) { match KernelVersion::current() {
let link_fd = bpf_link_create( Ok(version) => {
prog_fd, if version >= KernelVersion::new(5, 7, 0) {
LinkTarget::Fd(cgroup_fd), let link_fd = bpf_link_create(
BPF_CGROUP_SYSCTL, prog_fd,
None, LinkTarget::Fd(cgroup_fd),
mode.into(), BPF_CGROUP_SYSCTL,
) None,
.map_err(|(_, io_error)| SyscallError { mode.into(),
call: "bpf_link_create", )
io_error, .map_err(|(_, io_error)| SyscallError {
})?; call: "bpf_link_create",
self.data io_error,
.links })?;
.insert(CgroupSysctlLink::new(CgroupSysctlLinkInner::Fd( self.data
FdLink::new(link_fd), .links
))) .insert(CgroupSysctlLink::new(CgroupSysctlLinkInner::Fd(
} else { FdLink::new(link_fd),
let link = ProgAttachLink::attach(prog_fd, cgroup_fd, BPF_CGROUP_SYSCTL, mode)?; )))
} else {
self.data let link = ProgAttachLink::attach(prog_fd, cgroup_fd, BPF_CGROUP_SYSCTL, mode)?;
.links
.insert(CgroupSysctlLink::new(CgroupSysctlLinkInner::ProgAttach( self.data.links.insert(CgroupSysctlLink::new(
link, 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 libc::pid_t;
use log::warn;
use crate::{ use crate::{
programs::{ programs::{
@ -117,13 +118,23 @@ pub(crate) fn attach<T: Link + From<PerfLinkInner>>(
// Use debugfs to create probe // Use debugfs to create probe
let prog_fd = program_data.fd()?; let prog_fd = program_data.fd()?;
let prog_fd = prog_fd.as_fd(); let prog_fd = prog_fd.as_fd();
let link = if KernelVersion::current().unwrap() < KernelVersion::new(4, 17, 0) { let link = match KernelVersion::current() {
let (fd, event_alias) = create_as_trace_point(kind, fn_name, offset, pid)?; Ok(version) => {
perf_attach_debugfs(prog_fd, fd, ProbeEvent { kind, event_alias }) if version < KernelVersion::new(4, 17, 0) {
} else { let (fd, event_alias) = create_as_trace_point(kind, fn_name, offset, pid)?;
let fd = create_as_probe(kind, fn_name, offset, pid)?; perf_attach_debugfs(prog_fd, fd, ProbeEvent { kind, event_alias })
perf_attach(prog_fd, fd) } 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)) program_data.links.insert(T::from(link))
} }

@ -1,6 +1,8 @@
//! Socket option programs. //! Socket option programs.
use std::os::fd::AsFd; use std::os::fd::AsFd;
use log::warn;
use crate::{ use crate::{
generated::{bpf_attach_type::BPF_CGROUP_SOCK_OPS, bpf_prog_type::BPF_PROG_TYPE_SOCK_OPS}, generated::{bpf_attach_type::BPF_CGROUP_SOCK_OPS, bpf_prog_type::BPF_PROG_TYPE_SOCK_OPS},
programs::{ programs::{
@ -68,27 +70,40 @@ impl SockOps {
let prog_fd = prog_fd.as_fd(); let prog_fd = prog_fd.as_fd();
let cgroup_fd = cgroup.as_fd(); let cgroup_fd = cgroup.as_fd();
let attach_type = BPF_CGROUP_SOCK_OPS; let attach_type = BPF_CGROUP_SOCK_OPS;
if KernelVersion::current().unwrap() >= KernelVersion::new(5, 7, 0) {
let link_fd = bpf_link_create( match KernelVersion::current() {
prog_fd, Ok(version) => {
LinkTarget::Fd(cgroup_fd), if version >= KernelVersion::new(5, 7, 0) {
attach_type, let link_fd = bpf_link_create(
None, prog_fd,
mode.into(), LinkTarget::Fd(cgroup_fd),
) attach_type,
.map_err(|(_, io_error)| SyscallError { None,
call: "bpf_link_create", mode.into(),
io_error, )
})?; .map_err(|(_, io_error)| SyscallError {
self.data call: "bpf_link_create",
.links io_error,
.insert(SockOpsLink::new(SockOpsLinkInner::Fd(FdLink::new(link_fd)))) })?;
} else { self.data
let link = ProgAttachLink::attach(prog_fd, cgroup_fd, attach_type, mode)?; .links
.insert(SockOpsLink::new(SockOpsLinkInner::Fd(FdLink::new(link_fd))))
self.data } else {
.links let link = ProgAttachLink::attach(prog_fd, cgroup_fd, attach_type, mode)?;
.insert(SockOpsLink::new(SockOpsLinkInner::ProgAttach(link)))
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 libc::if_nametoindex;
use log::warn;
use thiserror::Error; use thiserror::Error;
use crate::{ use crate::{
@ -135,42 +136,61 @@ impl Xdp {
let prog_fd = self.fd()?; let prog_fd = self.fd()?;
let prog_fd = prog_fd.as_fd(); let prog_fd = prog_fd.as_fd();
if KernelVersion::current().unwrap() >= KernelVersion::new(5, 9, 0) { match KernelVersion::current() {
// Unwrap safety: the function starts with `self.fd()?` that will succeed if and only Ok(kernel_version) => {
// if the program has been loaded, i.e. there is an fd. We get one by: if kernel_version >= KernelVersion::new(5, 9, 0) {
// - Using `Xdp::from_pin` that sets `expected_attach_type` // Unwrap safety: the function starts with `self.fd()?` that will succeed if and only
// - Calling `Xdp::attach` that sets `expected_attach_type`, as geting an `Xdp` // if the program has been loaded, i.e. there is an fd. We get one by:
// instance trhough `Xdp:try_from(Program)` does not set any fd. // - Using `Xdp::from_pin` that sets `expected_attach_type`
// So, in all cases where we have an fd, we have an expected_attach_type. Thus, if we // - Calling `Xdp::attach` that sets `expected_attach_type`, as geting an `Xdp`
// reach this point, expected_attach_type is guaranteed to be Some(_). // instance trhough `Xdp:try_from(Program)` does not set any fd.
let attach_type = self.data.expected_attach_type.unwrap(); // So, in all cases where we have an fd, we have an expected_attach_type. Thus, if we
let link_fd = bpf_link_create( // reach this point, expected_attach_type is guaranteed to be Some(_).
prog_fd, let attach_type = self.data.expected_attach_type.unwrap();
LinkTarget::IfIndex(if_index), let link_fd = bpf_link_create(
attach_type, prog_fd,
None, LinkTarget::IfIndex(if_index),
flags.bits(), attach_type,
) None,
.map_err(|(_, io_error)| SyscallError { flags.bits(),
call: "bpf_link_create", )
io_error, .map_err(|(_, io_error)| SyscallError {
})?; call: "bpf_link_create",
self.data io_error,
.links })?;
.insert(XdpLink::new(XdpLinkInner::FdLink(FdLink::new(link_fd)))) self.data
} else { .links
let if_index = if_index as i32; .insert(XdpLink::new(XdpLinkInner::FdLink(FdLink::new(link_fd))))
unsafe { netlink_set_xdp_fd(if_index, Some(prog_fd), None, flags.bits()) } } else {
.map_err(|io_error| XdpError::NetlinkError { io_error })?; let if_index = if_index as i32;
unsafe { netlink_set_xdp_fd(if_index, Some(prog_fd), None, flags.bits()) }
let prog_fd = prog_fd.as_raw_fd(); .map_err(|io_error| XdpError::NetlinkError { io_error })?;
self.data
.links let prog_fd = prog_fd.as_raw_fd();
.insert(XdpLink::new(XdpLinkInner::NlLink(NlLink { self.data
if_index, .links
prog_fd, .insert(XdpLink::new(XdpLinkInner::NlLink(NlLink {
flags, 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> { fn detach(self) -> Result<(), ProgramError> {
let flags = if KernelVersion::current().unwrap() >= KernelVersion::new(5, 7, 0) { let flags = match KernelVersion::current() {
self.flags.bits() | XDP_FLAGS_REPLACE Ok(kernel_version) => {
} else { if kernel_version >= KernelVersion::new(5, 7, 0) {
self.flags.bits() 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. // 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 prog_fd = unsafe { BorrowedFd::borrow_raw(self.prog_fd) };
let _ = unsafe { netlink_set_xdp_fd(self.if_index, None, Some(prog_fd), flags) }; let _ = unsafe { netlink_set_xdp_fd(self.if_index, None, Some(prog_fd), flags) };

Loading…
Cancel
Save