diff --git a/aya-bpf-macros/src/expand.rs b/aya-bpf-macros/src/expand.rs index 506cfa89..b96db0fe 100644 --- a/aya-bpf-macros/src/expand.rs +++ b/aya-bpf-macros/src/expand.rs @@ -212,7 +212,7 @@ impl Xdp { frags = m } else { return Err(Error::new_spanned( - "mutlibuffer", + s, "invalid value. should be 'true' or 'false'", )); } @@ -613,18 +613,39 @@ impl RawTracePoint { pub struct Lsm { item: ItemFn, - name: String, + name: Option, + sleepable: bool, } impl Lsm { pub fn from_syn(mut args: Args, item: ItemFn) -> Result { - let name = name_arg(&mut args)?.unwrap_or_else(|| item.sig.ident.to_string()); - - Ok(Lsm { item, name }) + let name = pop_arg(&mut args, "name"); + let mut sleepable = false; + if let Some(s) = pop_arg(&mut args, "sleepable") { + if let Ok(m) = s.parse() { + sleepable = m + } else { + return Err(Error::new_spanned( + s, + "invalid value. should be 'true' or 'false'", + )); + } + } + err_on_unknown_args(&args)?; + Ok(Lsm { + item, + name, + sleepable, + }) } pub fn expand(&self) -> Result { - let section_name = format!("lsm/{}", self.name); + let section_prefix = if self.sleepable { "lsm.s" } else { "lsm" }; + let section_name = if let Some(name) = &self.name { + format!("{section_prefix}/{name}") + } else { + section_prefix.to_string() + }; let fn_vis = &self.item.vis; let fn_name = &self.item.sig.ident; let item = &self.item; diff --git a/aya-obj/src/obj.rs b/aya-obj/src/obj.rs index e0450d95..db1c50d9 100644 --- a/aya-obj/src/obj.rs +++ b/aya-obj/src/obj.rs @@ -161,7 +161,7 @@ pub struct Function { /// - `uprobe.s+` or `uretprobe.s+` /// - `usdt+` /// - `kprobe.multi+` or `kretprobe.multi+`: `BPF_TRACE_KPROBE_MULTI` -/// - `lsm_cgroup+` or `lsm.s+` +/// - `lsm_cgroup+` /// - `lwt_in`, `lwt_out`, `lwt_seg6local`, `lwt_xmit` /// - `raw_tp.w+`, `raw_tracepoint.w+` /// - `action` @@ -196,7 +196,7 @@ pub enum ProgramSection { }, Xdp { name: String, - frags_supported: bool, + frags: bool, }, SkMsg { name: String, @@ -244,6 +244,7 @@ pub enum ProgramSection { }, Lsm { name: String, + sleepable: bool, }, BtfTracePoint { name: String, @@ -294,7 +295,7 @@ impl ProgramSection { ProgramSection::LircMode2 { name } => name, ProgramSection::PerfEvent { name } => name, ProgramSection::RawTracePoint { name } => name, - ProgramSection::Lsm { name } => name, + ProgramSection::Lsm { name, .. } => name, ProgramSection::BtfTracePoint { name } => name, ProgramSection::FEntry { name } => name, ProgramSection::FExit { name } => name, @@ -326,14 +327,8 @@ impl FromStr for ProgramSection { "kretprobe" => KRetProbe { name }, "uprobe" => UProbe { name }, "uretprobe" => URetProbe { name }, - "xdp" => Xdp { - name, - frags_supported: false, - }, - "xdp.frags" => Xdp { - name, - frags_supported: true, - }, + "xdp" => Xdp { name, frags: false }, + "xdp.frags" => Xdp { name, frags: true }, "tp_btf" => BtfTracePoint { name }, _ if kind.starts_with("tracepoint") || kind.starts_with("tp") => { // tracepoint sections are named `tracepoint/category/event_name`, @@ -485,7 +480,14 @@ impl FromStr for ProgramSection { "lirc_mode2" => LircMode2 { name }, "perf_event" => PerfEvent { name }, "raw_tp" | "raw_tracepoint" => RawTracePoint { name }, - "lsm" => Lsm { name }, + "lsm" => Lsm { + name, + sleepable: false, + }, + "lsm.s" => Lsm { + name, + sleepable: true, + }, "fentry" => FEntry { name }, "fexit" => FExit { name }, "freplace" => Extension { name }, @@ -1876,7 +1878,7 @@ mod tests { assert_matches!( obj.programs.get("foo"), Some(Program { - section: ProgramSection::Xdp { .. }, + section: ProgramSection::Xdp { frags: false, .. }, .. }) ); @@ -1897,10 +1899,7 @@ mod tests { assert_matches!( obj.programs.get("foo"), Some(Program { - section: ProgramSection::Xdp { - frags_supported: true, - .. - }, + section: ProgramSection::Xdp { frags: true, .. }, .. }) ); @@ -1958,7 +1957,34 @@ mod tests { assert_matches!( obj.programs.get("foo"), Some(Program { - section: ProgramSection::Lsm { .. }, + section: ProgramSection::Lsm { + sleepable: false, + .. + }, + .. + }) + ); + } + + #[test] + fn test_parse_section_lsm_sleepable() { + let mut obj = fake_obj(); + + assert_matches!( + obj.parse_section(fake_section( + BpfSectionKind::Program, + "lsm.s/foo", + bytes_of(&fake_ins()) + )), + Ok(()) + ); + assert_matches!( + obj.programs.get("foo"), + Some(Program { + section: ProgramSection::Lsm { + sleepable: true, + .. + }, .. }) ); diff --git a/aya/src/bpf.rs b/aya/src/bpf.rs index 689674c7..859ee16d 100644 --- a/aya/src/bpf.rs +++ b/aya/src/bpf.rs @@ -9,7 +9,7 @@ use std::{ use aya_obj::{ btf::{BtfFeatures, BtfRelocationError}, - generated::BPF_F_XDP_HAS_FRAGS, + generated::{BPF_F_SLEEPABLE, BPF_F_XDP_HAS_FRAGS}, relocation::BpfRelocationError, BpfSectionKind, Features, }; @@ -477,12 +477,10 @@ impl<'a> BpfLoader<'a> { data: ProgramData::new(prog_name, obj, btf_fd, verifier_log_level), }) } - ProgramSection::Xdp { - frags_supported, .. - } => { + ProgramSection::Xdp { frags, .. } => { let mut data = ProgramData::new(prog_name, obj, btf_fd, verifier_log_level); - if *frags_supported { + if *frags { data.flags = BPF_F_XDP_HAS_FRAGS; } Program::Xdp(Xdp { data }) @@ -550,9 +548,14 @@ impl<'a> BpfLoader<'a> { data: ProgramData::new(prog_name, obj, btf_fd, verifier_log_level), }) } - ProgramSection::Lsm { .. } => Program::Lsm(Lsm { - data: ProgramData::new(prog_name, obj, btf_fd, verifier_log_level), - }), + ProgramSection::Lsm { sleepable, .. } => { + let mut data = + ProgramData::new(prog_name, obj, btf_fd, verifier_log_level); + if *sleepable { + data.flags = BPF_F_SLEEPABLE; + } + Program::Lsm(Lsm { data }) + } ProgramSection::BtfTracePoint { .. } => { Program::BtfTracePoint(BtfTracePoint { data: ProgramData::new(prog_name, obj, btf_fd, verifier_log_level),