aya_friday/programs/
cgroup_sysctl.rs1use std::{hash::Hash, os::fd::AsFd};
4
5use aya_obj::generated::{
6 bpf_attach_type::BPF_CGROUP_SYSCTL, bpf_prog_type::BPF_PROG_TYPE_CGROUP_SYSCTL,
7};
8
9use crate::{
10 programs::{
11 CgroupAttachMode, FdLink, Link, ProgAttachLink, ProgramData, ProgramError, ProgramType,
12 define_link_wrapper, id_as_key, load_program_with_attach_type,
13 },
14 sys::{LinkTarget, SyscallError, bpf_link_create},
15 util::KernelVersion,
16};
17
18#[derive(Debug)]
52#[doc(alias = "BPF_PROG_TYPE_CGROUP_SYSCTL")]
53pub struct CgroupSysctl {
54 pub(crate) data: ProgramData<CgroupSysctlLink>,
55}
56
57impl CgroupSysctl {
58 pub const PROGRAM_TYPE: ProgramType = ProgramType::CgroupSysctl;
60
61 pub fn load(&mut self) -> Result<(), ProgramError> {
63 let Self { data } = self;
64 load_program_with_attach_type(BPF_PROG_TYPE_CGROUP_SYSCTL, BPF_CGROUP_SYSCTL, data)
65 }
66
67 pub fn attach<T: AsFd>(
71 &mut self,
72 cgroup: T,
73 mode: CgroupAttachMode,
74 ) -> Result<CgroupSysctlLinkId, ProgramError> {
75 let prog_fd = self.fd()?;
76 let prog_fd = prog_fd.as_fd();
77 let cgroup_fd = cgroup.as_fd();
78 let attach_type = BPF_CGROUP_SYSCTL;
79 if KernelVersion::at_least(5, 7, 0) {
80 let link_fd = bpf_link_create(
81 prog_fd,
82 LinkTarget::Fd(cgroup_fd),
83 attach_type,
84 mode.into(),
85 None,
86 )
87 .map_err(|io_error| SyscallError {
88 call: "bpf_link_create",
89 io_error,
90 })?;
91 self.data
92 .links
93 .insert(CgroupSysctlLink::new(CgroupSysctlLinkInner::Fd(
94 FdLink::new(link_fd),
95 )))
96 } else {
97 let link = ProgAttachLink::attach(prog_fd, cgroup_fd, attach_type, mode)?;
98
99 self.data
100 .links
101 .insert(CgroupSysctlLink::new(CgroupSysctlLinkInner::ProgAttach(
102 link,
103 )))
104 }
105 }
106}
107
108#[derive(Debug, Hash, Eq, PartialEq)]
109enum CgroupSysctlLinkIdInner {
110 Fd(<FdLink as Link>::Id),
111 ProgAttach(<ProgAttachLink as Link>::Id),
112}
113
114#[derive(Debug)]
115enum CgroupSysctlLinkInner {
116 Fd(FdLink),
117 ProgAttach(ProgAttachLink),
118}
119
120impl Link for CgroupSysctlLinkInner {
121 type Id = CgroupSysctlLinkIdInner;
122
123 fn id(&self) -> Self::Id {
124 match self {
125 Self::Fd(fd) => CgroupSysctlLinkIdInner::Fd(fd.id()),
126 Self::ProgAttach(p) => CgroupSysctlLinkIdInner::ProgAttach(p.id()),
127 }
128 }
129
130 fn detach(self) -> Result<(), ProgramError> {
131 match self {
132 Self::Fd(fd) => fd.detach(),
133 Self::ProgAttach(p) => p.detach(),
134 }
135 }
136}
137
138id_as_key!(CgroupSysctlLinkInner, CgroupSysctlLinkIdInner);
139
140define_link_wrapper!(
141 CgroupSysctlLink,
142 CgroupSysctlLinkId,
143 CgroupSysctlLinkInner,
144 CgroupSysctlLinkIdInner,
145 CgroupSysctl,
146);