diff --git a/aya/src/bpf.rs b/aya/src/bpf.rs index bed764cd..f3b24a60 100644 --- a/aya/src/bpf.rs +++ b/aya/src/bpf.rs @@ -19,8 +19,8 @@ use crate::{ Object, ParseError, ProgramKind, }, programs::{ - KProbe, ProbeKind, Program, ProgramData, ProgramError, SkMsg, SkSkb, SkSkbKind, SockOps, - SocketFilter, TracePoint, UProbe, Xdp, + KProbe, ProbeKind, Program, ProgramData, ProgramError, SchedClassifier, SkMsg, SkSkb, + SkSkbKind, SockOps, SocketFilter, TracePoint, UProbe, Xdp, }, sys::bpf_map_update_elem_ptr, util::{possible_cpus, POSSIBLE_CPUS}, @@ -182,6 +182,9 @@ impl Bpf { kind: SkSkbKind::StreamVerdict, }), ProgramKind::SockOps => Program::SockOps(SockOps { data }), + ProgramKind::SchedClassifier => { + Program::SchedClassifier(SchedClassifier { data }) + } }; (name, program) diff --git a/aya/src/obj/mod.rs b/aya/src/obj/mod.rs index d240de96..00b8051a 100644 --- a/aya/src/obj/mod.rs +++ b/aya/src/obj/mod.rs @@ -77,6 +77,7 @@ pub enum ProgramKind { SkSkbStreamParser, SkSkbStreamVerdict, SockOps, + SchedClassifier, } impl FromStr for ProgramKind { @@ -96,6 +97,7 @@ impl FromStr for ProgramKind { "sk_skb/stream_parser" => SkSkbStreamParser, "sk_skb/stream_verdict" => SkSkbStreamVerdict, "sockops" => SockOps, + "classifier" => SchedClassifier, _ => { return Err(ParseError::InvalidProgramKind { kind: kind.to_string(), @@ -259,7 +261,11 @@ impl Object { parts.reverse(); if parts.len() == 1 { - if parts[0] == "xdp" || parts[0] == "sk_msg" || parts[0] == "sockops" { + if parts[0] == "xdp" + || parts[0] == "sk_msg" + || parts[0] == "sockops" + || parts[0] == "classifier" + { parts.push(parts[0]); } } @@ -288,7 +294,8 @@ impl Object { | &[ty @ "sk_msg", name] | &[ty @ "sk_skb/stream_parser", name] | &[ty @ "sk_skb/stream_verdict", name] - | &[ty @ "sockops", name] => { + | &[ty @ "sockops", name] + | &[ty @ "classifier", name] => { self.programs .insert(name.to_string(), self.parse_program(§ion, ty, name)?); if !section.relocations.is_empty() { diff --git a/aya/src/programs/cls.rs b/aya/src/programs/cls.rs new file mode 100644 index 00000000..08535183 --- /dev/null +++ b/aya/src/programs/cls.rs @@ -0,0 +1,42 @@ +use crate::{ + generated::bpf_prog_type::{BPF_PROG_TYPE_SCHED_ACT, BPF_PROG_TYPE_SCHED_CLS}, + programs::{load_program, ProgramData, ProgramError}, +}; + +#[derive(Debug)] +pub struct SchedClassifier { + pub(crate) data: ProgramData, +} + +impl SchedClassifier { + /// Loads the program inside the kernel. + /// + /// See also [`Program::load`](crate::programs::Program::load). + pub fn load(&mut self) -> Result<(), ProgramError> { + load_program(BPF_PROG_TYPE_SCHED_CLS, &mut self.data) + } + + /// Returns the name of the program. + pub fn name(&self) -> String { + self.data.name.to_string() + } +} + +#[derive(Debug)] +pub struct SchedAction { + pub(crate) data: ProgramData, +} + +impl SchedAction { + /// Loads the program inside the kernel. + /// + /// See also [`Program::load`](crate::programs::Program::load). + pub fn load(&mut self) -> Result<(), ProgramError> { + load_program(BPF_PROG_TYPE_SCHED_ACT, &mut self.data) + } + + /// Returns the name of the program. + pub fn name(&self) -> String { + self.data.name.to_string() + } +} diff --git a/aya/src/programs/mod.rs b/aya/src/programs/mod.rs index e2a4c1db..0ff7758f 100644 --- a/aya/src/programs/mod.rs +++ b/aya/src/programs/mod.rs @@ -44,6 +44,7 @@ //! [`Bpf::program`]: crate::Bpf::program //! [`Bpf::program_mut`]: crate::Bpf::program_mut //! [maps]: crate::maps +mod cls; mod kprobe; mod perf_attach; mod probe; @@ -59,6 +60,7 @@ use libc::{close, ENOSPC}; use std::{cell::RefCell, cmp, convert::TryFrom, ffi::CStr, io, os::unix::io::RawFd, rc::Rc}; use thiserror::Error; +pub use cls::{SchedAction, SchedClassifier}; pub use kprobe::{KProbe, KProbeError}; use perf_attach::*; pub use probe::ProbeKind; @@ -147,6 +149,7 @@ pub enum Program { SkMsg(SkMsg), SkSkb(SkSkb), SockOps(SockOps), + SchedClassifier(SchedClassifier), } impl Program { @@ -176,6 +179,7 @@ impl Program { Program::SkMsg(_) => BPF_PROG_TYPE_SK_MSG, Program::SkSkb(_) => BPF_PROG_TYPE_SK_SKB, Program::SockOps(_) => BPF_PROG_TYPE_SOCK_OPS, + Program::SchedClassifier(_) => BPF_PROG_TYPE_SCHED_CLS, } } @@ -194,6 +198,7 @@ impl Program { Program::SkMsg(p) => &p.data, Program::SkSkb(p) => &p.data, Program::SockOps(p) => &p.data, + Program::SchedClassifier(p) => &p.data, } } @@ -207,6 +212,7 @@ impl Program { Program::SkMsg(p) => &mut p.data, Program::SkSkb(p) => &mut p.data, Program::SockOps(p) => &mut p.data, + Program::SchedClassifier(p) => &mut p.data, } } } @@ -423,7 +429,16 @@ macro_rules! impl_program_fd { } } -impl_program_fd!(KProbe, UProbe, TracePoint, SocketFilter, Xdp, SkMsg, SkSkb); +impl_program_fd!( + KProbe, + UProbe, + TracePoint, + SocketFilter, + Xdp, + SkMsg, + SkSkb, + SchedClassifier +); macro_rules! impl_try_from_program { ($($ty:ident),+ $(,)?) => { @@ -461,5 +476,6 @@ impl_try_from_program!( Xdp, SkMsg, SkSkb, - SockOps + SockOps, + SchedClassifier ); diff --git a/xtask/src/codegen/aya_bpf_bindings.rs b/xtask/src/codegen/aya_bpf_bindings.rs index bdcf6d3f..a610ce68 100644 --- a/xtask/src/codegen/aya_bpf_bindings.rs +++ b/xtask/src/codegen/aya_bpf_bindings.rs @@ -38,7 +38,7 @@ pub fn codegen(opts: &Options) -> Result<(), anyhow::Error> { .constified_enum("BPF_FLOW_.*"); let types = ["bpf_map_.*", "sk_action", "pt_regs", "xdp_action"]; - let vars = ["BPF_.*", "bpf_.*"]; + let vars = ["BPF_.*", "bpf_.*", "TC_ACT_.*"]; for x in &types { bindgen = bindgen.whitelist_type(x);