diff --git a/aya/src/programs/cgroup_device.rs b/aya/src/programs/cgroup_device.rs index 78b01d05c..de376a1fe 100644 --- a/aya/src/programs/cgroup_device.rs +++ b/aya/src/programs/cgroup_device.rs @@ -2,6 +2,8 @@ use std::os::fd::AsFd; +use log::warn; + use crate::{ generated::{bpf_attach_type::BPF_CGROUP_DEVICE, bpf_prog_type::BPF_PROG_TYPE_CGROUP_DEVICE}, programs::{ @@ -70,31 +72,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, + ))) + } } } diff --git a/aya/src/programs/cgroup_skb.rs b/aya/src/programs/cgroup_skb.rs index 5054a2592..f7fb147c4 100644 --- a/aya/src/programs/cgroup_skb.rs +++ b/aya/src/programs/cgroup_skb.rs @@ -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))) + } } } diff --git a/aya/src/programs/cgroup_sock.rs b/aya/src/programs/cgroup_sock.rs index 878c617f0..aa5d98fc1 100644 --- a/aya/src/programs/cgroup_sock.rs +++ b/aya/src/programs/cgroup_sock.rs @@ -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))) + } } } diff --git a/aya/src/programs/cgroup_sock_addr.rs b/aya/src/programs/cgroup_sock_addr.rs index 876037b31..be1ac7a5c 100644 --- a/aya/src/programs/cgroup_sock_addr.rs +++ b/aya/src/programs/cgroup_sock_addr.rs @@ -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), + )) + } } } diff --git a/aya/src/programs/cgroup_sockopt.rs b/aya/src/programs/cgroup_sockopt.rs index c67dcc5b1..90de42498 100644 --- a/aya/src/programs/cgroup_sockopt.rs +++ b/aya/src/programs/cgroup_sockopt.rs @@ -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, + ))) + } } } diff --git a/aya/src/programs/cgroup_sysctl.rs b/aya/src/programs/cgroup_sysctl.rs index 94ccd47fd..c384526ab 100644 --- a/aya/src/programs/cgroup_sysctl.rs +++ b/aya/src/programs/cgroup_sysctl.rs @@ -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, + ))) + } } } diff --git a/aya/src/programs/probe.rs b/aya/src/programs/probe.rs index 4d737e346..9b750d7ce 100644 --- a/aya/src/programs/probe.rs +++ b/aya/src/programs/probe.rs @@ -10,6 +10,7 @@ use std::{ }; use libc::pid_t; +use log::warn; use crate::{ programs::{ @@ -117,13 +118,23 @@ pub(crate) fn attach>( // 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)) } diff --git a/aya/src/programs/sock_ops.rs b/aya/src/programs/sock_ops.rs index 60f4e08f0..d44bb6da7 100644 --- a/aya/src/programs/sock_ops.rs +++ b/aya/src/programs/sock_ops.rs @@ -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))) + } } } diff --git a/aya/src/programs/xdp.rs b/aya/src/programs/xdp.rs index 5d49f4f11..ba0753761 100644 --- a/aya/src/programs/xdp.rs +++ b/aya/src/programs/xdp.rs @@ -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) };