Skip to content

Commit

Permalink
Add the option to support multiple and overrideable programs per cgroup
Browse files Browse the repository at this point in the history
This change allows multiple BPF programs to attach to a cgroup (via the option
`CgroupAttachMode::AllowMultiple`), and allows a program to specify that it can be
overridden by one in a sub-cgroup (via the option `CgroupAttachMode::AllowOverride`).
  • Loading branch information
reyzell committed Aug 28, 2024
1 parent ab5e688 commit 4103691
Show file tree
Hide file tree
Showing 18 changed files with 1,009 additions and 84 deletions.
18 changes: 11 additions & 7 deletions aya/src/programs/cgroup_device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use std::os::fd::AsFd;
use crate::{
generated::{bpf_attach_type::BPF_CGROUP_DEVICE, bpf_prog_type::BPF_PROG_TYPE_CGROUP_DEVICE},
programs::{
bpf_prog_get_fd_by_id, define_link_wrapper, load_program, query, FdLink, Link,
ProgAttachLink, ProgramData, ProgramError, ProgramFd,
bpf_prog_get_fd_by_id, define_link_wrapper, load_program, query, CgroupAttachMode, FdLink,
Link, ProgAttachLink, ProgramData, ProgramError, ProgramFd,
},
sys::{bpf_link_create, LinkTarget, SyscallError},
util::KernelVersion,
Expand Down Expand Up @@ -38,12 +38,12 @@ use crate::{
/// # Ebpf(#[from] aya::EbpfError)
/// # }
/// # let mut bpf = aya::Ebpf::load(&[])?;
/// use aya::programs::CgroupDevice;
/// use aya::programs::{CgroupAttachMode, CgroupDevice};
///
/// let cgroup = std::fs::File::open("/sys/fs/cgroup/unified")?;
/// let program: &mut CgroupDevice = bpf.program_mut("cgroup_dev").unwrap().try_into()?;
/// program.load()?;
/// program.attach(cgroup)?;
/// program.attach(cgroup, CgroupAttachMode::Single)?;
/// # Ok::<(), Error>(())
/// ```
#[derive(Debug)]
Expand All @@ -61,7 +61,11 @@ impl CgroupDevice {
/// Attaches the program to the given cgroup.
///
/// The returned value can be used to detach, see [CgroupDevice::detach]
pub fn attach<T: AsFd>(&mut self, cgroup: T) -> Result<CgroupDeviceLinkId, ProgramError> {
pub fn attach<T: AsFd>(
&mut self,
cgroup: T,
flag: CgroupAttachMode,
) -> Result<CgroupDeviceLinkId, ProgramError> {
let prog_fd = self.fd()?;
let prog_fd = prog_fd.as_fd();
let cgroup_fd = cgroup.as_fd();
Expand All @@ -72,7 +76,7 @@ impl CgroupDevice {
LinkTarget::Fd(cgroup_fd),
BPF_CGROUP_DEVICE,
None,
0,
flag.bpf_val(),
)
.map_err(|(_, io_error)| SyscallError {
call: "bpf_link_create",
Expand All @@ -84,7 +88,7 @@ impl CgroupDevice {
FdLink::new(link_fd),
)))
} else {
let link = ProgAttachLink::attach(prog_fd, cgroup_fd, BPF_CGROUP_DEVICE)?;
let link = ProgAttachLink::attach(prog_fd, cgroup_fd, BPF_CGROUP_DEVICE, flag)?;

self.data
.links
Expand Down
26 changes: 17 additions & 9 deletions aya/src/programs/cgroup_skb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ use crate::{
bpf_prog_type::BPF_PROG_TYPE_CGROUP_SKB,
},
programs::{
define_link_wrapper, load_program, FdLink, Link, ProgAttachLink, ProgramData, ProgramError,
define_link_wrapper, load_program, CgroupAttachMode, FdLink, Link, ProgAttachLink,
ProgramData, ProgramError,
},
sys::{bpf_link_create, LinkTarget, SyscallError},
util::KernelVersion,
Expand Down Expand Up @@ -43,12 +44,12 @@ use crate::{
/// # }
/// # let mut bpf = aya::Ebpf::load(&[])?;
/// use std::fs::File;
/// use aya::programs::{CgroupSkb, CgroupSkbAttachType};
/// use aya::programs::{CgroupAttachMode, CgroupSkb, CgroupSkbAttachType};
///
/// let file = File::open("/sys/fs/cgroup/unified")?;
/// let egress: &mut CgroupSkb = bpf.program_mut("egress_filter").unwrap().try_into()?;
/// egress.load()?;
/// egress.attach(file, CgroupSkbAttachType::Egress)?;
/// egress.attach(file, CgroupSkbAttachType::Egress, CgroupAttachMode::Single)?;
/// # Ok::<(), Error>(())
/// ```
#[derive(Debug)]
Expand Down Expand Up @@ -87,6 +88,7 @@ impl CgroupSkb {
&mut self,
cgroup: T,
attach_type: CgroupSkbAttachType,
flag: CgroupAttachMode,
) -> Result<CgroupSkbLinkId, ProgramError> {
let prog_fd = self.fd()?;
let prog_fd = prog_fd.as_fd();
Expand All @@ -97,18 +99,24 @@ impl CgroupSkb {
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, 0)
.map_err(|(_, io_error)| SyscallError {
call: "bpf_link_create",
io_error,
})?;
let link_fd = bpf_link_create(
prog_fd,
LinkTarget::Fd(cgroup_fd),
attach_type,
None,
flag.bpf_val(),
)
.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)?;
let link = ProgAttachLink::attach(prog_fd, cgroup_fd, attach_type, flag)?;

self.data
.links
Expand Down
31 changes: 21 additions & 10 deletions aya/src/programs/cgroup_sock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ pub use aya_obj::programs::CgroupSockAttachType;
use crate::{
generated::bpf_prog_type::BPF_PROG_TYPE_CGROUP_SOCK,
programs::{
define_link_wrapper, load_program, FdLink, Link, ProgAttachLink, ProgramData, ProgramError,
define_link_wrapper, load_program, CgroupAttachMode, FdLink, Link, ProgAttachLink,
ProgramData, ProgramError,
},
sys::{bpf_link_create, LinkTarget, SyscallError},
util::KernelVersion,
Expand Down Expand Up @@ -41,12 +42,12 @@ use crate::{
/// # }
/// # let mut bpf = aya::Ebpf::load(&[])?;
/// use std::fs::File;
/// use aya::programs::{CgroupSock, CgroupSockAttachType};
/// use aya::programs::{CgroupAttachMode, CgroupSock, CgroupSockAttachType};
///
/// let file = File::open("/sys/fs/cgroup/unified")?;
/// let bind: &mut CgroupSock = bpf.program_mut("bind").unwrap().try_into()?;
/// bind.load()?;
/// bind.attach(file)?;
/// bind.attach(file, CgroupAttachMode::Single)?;
/// # Ok::<(), Error>(())
/// ```
#[derive(Debug)]
Expand All @@ -66,24 +67,34 @@ impl CgroupSock {
/// Attaches the program to the given cgroup.
///
/// The returned value can be used to detach, see [CgroupSock::detach].
pub fn attach<T: AsFd>(&mut self, cgroup: T) -> Result<CgroupSockLinkId, ProgramError> {
pub fn attach<T: AsFd>(
&mut self,
cgroup: T,
flag: CgroupAttachMode,
) -> Result<CgroupSockLinkId, ProgramError> {
let prog_fd = self.fd()?;
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, 0)
.map_err(|(_, io_error)| SyscallError {
call: "bpf_link_create",
io_error,
})?;
let link_fd = bpf_link_create(
prog_fd,
LinkTarget::Fd(cgroup_fd),
attach_type,
None,
flag.bpf_val(),
)
.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)?;
let link = ProgAttachLink::attach(prog_fd, cgroup_fd, attach_type, flag)?;

self.data
.links
Expand Down
31 changes: 21 additions & 10 deletions aya/src/programs/cgroup_sock_addr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ pub use aya_obj::programs::CgroupSockAddrAttachType;
use crate::{
generated::bpf_prog_type::BPF_PROG_TYPE_CGROUP_SOCK_ADDR,
programs::{
define_link_wrapper, load_program, FdLink, Link, ProgAttachLink, ProgramData, ProgramError,
define_link_wrapper, load_program, CgroupAttachMode, FdLink, Link, ProgAttachLink,
ProgramData, ProgramError,
},
sys::{bpf_link_create, LinkTarget, SyscallError},
util::KernelVersion,
Expand Down Expand Up @@ -42,12 +43,12 @@ use crate::{
/// # }
/// # let mut bpf = aya::Ebpf::load(&[])?;
/// use std::fs::File;
/// use aya::programs::{CgroupSockAddr, CgroupSockAddrAttachType};
/// use aya::programs::{CgroupAttachMode, CgroupSockAddr, CgroupSockAddrAttachType};
///
/// let file = File::open("/sys/fs/cgroup/unified")?;
/// let egress: &mut CgroupSockAddr = bpf.program_mut("connect4").unwrap().try_into()?;
/// egress.load()?;
/// egress.attach(file)?;
/// egress.attach(file, CgroupAttachMode::Single)?;
/// # Ok::<(), Error>(())
/// ```
#[derive(Debug)]
Expand All @@ -67,24 +68,34 @@ impl CgroupSockAddr {
/// Attaches the program to the given cgroup.
///
/// The returned value can be used to detach, see [CgroupSockAddr::detach].
pub fn attach<T: AsFd>(&mut self, cgroup: T) -> Result<CgroupSockAddrLinkId, ProgramError> {
pub fn attach<T: AsFd>(
&mut self,
cgroup: T,
flag: CgroupAttachMode,
) -> Result<CgroupSockAddrLinkId, ProgramError> {
let prog_fd = self.fd()?;
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, 0)
.map_err(|(_, io_error)| SyscallError {
call: "bpf_link_create",
io_error,
})?;
let link_fd = bpf_link_create(
prog_fd,
LinkTarget::Fd(cgroup_fd),
attach_type,
None,
flag.bpf_val(),
)
.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)?;
let link = ProgAttachLink::attach(prog_fd, cgroup_fd, attach_type, flag)?;

self.data.links.insert(CgroupSockAddrLink::new(
CgroupSockAddrLinkInner::ProgAttach(link),
Expand Down
31 changes: 21 additions & 10 deletions aya/src/programs/cgroup_sockopt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ pub use aya_obj::programs::CgroupSockoptAttachType;
use crate::{
generated::bpf_prog_type::BPF_PROG_TYPE_CGROUP_SOCKOPT,
programs::{
define_link_wrapper, load_program, FdLink, Link, ProgAttachLink, ProgramData, ProgramError,
define_link_wrapper, load_program, CgroupAttachMode, FdLink, Link, ProgAttachLink,
ProgramData, ProgramError,
},
sys::{bpf_link_create, LinkTarget, SyscallError},
util::KernelVersion,
Expand Down Expand Up @@ -39,12 +40,12 @@ use crate::{
/// # }
/// # let mut bpf = aya::Ebpf::load(&[])?;
/// use std::fs::File;
/// use aya::programs::CgroupSockopt;
/// use aya::programs::{CgroupAttachMode, CgroupSockopt};
///
/// let file = File::open("/sys/fs/cgroup/unified")?;
/// let program: &mut CgroupSockopt = bpf.program_mut("cgroup_sockopt").unwrap().try_into()?;
/// program.load()?;
/// program.attach(file)?;
/// program.attach(file, CgroupAttachMode::Single)?;
/// # Ok::<(), Error>(())
/// ```
#[derive(Debug)]
Expand All @@ -64,24 +65,34 @@ impl CgroupSockopt {
/// Attaches the program to the given cgroup.
///
/// The returned value can be used to detach, see [CgroupSockopt::detach].
pub fn attach<T: AsFd>(&mut self, cgroup: T) -> Result<CgroupSockoptLinkId, ProgramError> {
pub fn attach<T: AsFd>(
&mut self,
cgroup: T,
flag: CgroupAttachMode,
) -> Result<CgroupSockoptLinkId, ProgramError> {
let prog_fd = self.fd()?;
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, 0)
.map_err(|(_, io_error)| SyscallError {
call: "bpf_link_create",
io_error,
})?;
let link_fd = bpf_link_create(
prog_fd,
LinkTarget::Fd(cgroup_fd),
attach_type,
None,
flag.bpf_val(),
)
.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)?;
let link = ProgAttachLink::attach(prog_fd, cgroup_fd, attach_type, flag)?;

self.data
.links
Expand Down
17 changes: 11 additions & 6 deletions aya/src/programs/cgroup_sysctl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ use std::{hash::Hash, os::fd::AsFd};
use crate::{
generated::{bpf_attach_type::BPF_CGROUP_SYSCTL, bpf_prog_type::BPF_PROG_TYPE_CGROUP_SYSCTL},
programs::{
define_link_wrapper, load_program, FdLink, Link, ProgAttachLink, ProgramData, ProgramError,
define_link_wrapper, load_program, CgroupAttachMode, FdLink, Link, ProgAttachLink,
ProgramData, ProgramError,
},
sys::{bpf_link_create, LinkTarget, SyscallError},
util::KernelVersion,
Expand Down Expand Up @@ -36,12 +37,12 @@ use crate::{
/// # }
/// # let mut bpf = aya::Ebpf::load(&[])?;
/// use std::fs::File;
/// use aya::programs::CgroupSysctl;
/// use aya::programs::{CgroupAttachMode, CgroupSysctl};
///
/// let file = File::open("/sys/fs/cgroup/unified")?;
/// let program: &mut CgroupSysctl = bpf.program_mut("cgroup_sysctl").unwrap().try_into()?;
/// program.load()?;
/// program.attach(file)?;
/// program.attach(file, CgroupAttachMode::Single)?;
/// # Ok::<(), Error>(())
/// ```
#[derive(Debug)]
Expand All @@ -59,7 +60,11 @@ impl CgroupSysctl {
/// Attaches the program to the given cgroup.
///
/// The returned value can be used to detach, see [CgroupSysctl::detach].
pub fn attach<T: AsFd>(&mut self, cgroup: T) -> Result<CgroupSysctlLinkId, ProgramError> {
pub fn attach<T: AsFd>(
&mut self,
cgroup: T,
flag: CgroupAttachMode,
) -> Result<CgroupSysctlLinkId, ProgramError> {
let prog_fd = self.fd()?;
let prog_fd = prog_fd.as_fd();
let cgroup_fd = cgroup.as_fd();
Expand All @@ -70,7 +75,7 @@ impl CgroupSysctl {
LinkTarget::Fd(cgroup_fd),
BPF_CGROUP_SYSCTL,
None,
0,
flag.bpf_val(),
)
.map_err(|(_, io_error)| SyscallError {
call: "bpf_link_create",
Expand All @@ -82,7 +87,7 @@ impl CgroupSysctl {
FdLink::new(link_fd),
)))
} else {
let link = ProgAttachLink::attach(prog_fd, cgroup_fd, BPF_CGROUP_SYSCTL)?;
let link = ProgAttachLink::attach(prog_fd, cgroup_fd, BPF_CGROUP_SYSCTL, flag)?;

self.data
.links
Expand Down
Loading

0 comments on commit 4103691

Please sign in to comment.