aya: add support for BPF_PROG_TYPE_SCHED_CLS programs

pull/1/head
Alessandro Decina 3 years ago
parent 4222b140ec
commit 5effc972ac

@ -19,8 +19,8 @@ use crate::{
Object, ParseError, ProgramKind, Object, ParseError, ProgramKind,
}, },
programs::{ programs::{
KProbe, ProbeKind, Program, ProgramData, ProgramError, SkMsg, SkSkb, SkSkbKind, SockOps, KProbe, ProbeKind, Program, ProgramData, ProgramError, SchedClassifier, SkMsg, SkSkb,
SocketFilter, TracePoint, UProbe, Xdp, SkSkbKind, SockOps, SocketFilter, TracePoint, UProbe, Xdp,
}, },
sys::bpf_map_update_elem_ptr, sys::bpf_map_update_elem_ptr,
util::{possible_cpus, POSSIBLE_CPUS}, util::{possible_cpus, POSSIBLE_CPUS},
@ -182,6 +182,9 @@ impl Bpf {
kind: SkSkbKind::StreamVerdict, kind: SkSkbKind::StreamVerdict,
}), }),
ProgramKind::SockOps => Program::SockOps(SockOps { data }), ProgramKind::SockOps => Program::SockOps(SockOps { data }),
ProgramKind::SchedClassifier => {
Program::SchedClassifier(SchedClassifier { data })
}
}; };
(name, program) (name, program)

@ -77,6 +77,7 @@ pub enum ProgramKind {
SkSkbStreamParser, SkSkbStreamParser,
SkSkbStreamVerdict, SkSkbStreamVerdict,
SockOps, SockOps,
SchedClassifier,
} }
impl FromStr for ProgramKind { impl FromStr for ProgramKind {
@ -96,6 +97,7 @@ impl FromStr for ProgramKind {
"sk_skb/stream_parser" => SkSkbStreamParser, "sk_skb/stream_parser" => SkSkbStreamParser,
"sk_skb/stream_verdict" => SkSkbStreamVerdict, "sk_skb/stream_verdict" => SkSkbStreamVerdict,
"sockops" => SockOps, "sockops" => SockOps,
"classifier" => SchedClassifier,
_ => { _ => {
return Err(ParseError::InvalidProgramKind { return Err(ParseError::InvalidProgramKind {
kind: kind.to_string(), kind: kind.to_string(),
@ -259,7 +261,11 @@ impl Object {
parts.reverse(); parts.reverse();
if parts.len() == 1 { 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]); parts.push(parts[0]);
} }
} }
@ -288,7 +294,8 @@ impl Object {
| &[ty @ "sk_msg", name] | &[ty @ "sk_msg", name]
| &[ty @ "sk_skb/stream_parser", name] | &[ty @ "sk_skb/stream_parser", name]
| &[ty @ "sk_skb/stream_verdict", name] | &[ty @ "sk_skb/stream_verdict", name]
| &[ty @ "sockops", name] => { | &[ty @ "sockops", name]
| &[ty @ "classifier", name] => {
self.programs self.programs
.insert(name.to_string(), self.parse_program(&section, ty, name)?); .insert(name.to_string(), self.parse_program(&section, ty, name)?);
if !section.relocations.is_empty() { if !section.relocations.is_empty() {

@ -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()
}
}

@ -44,6 +44,7 @@
//! [`Bpf::program`]: crate::Bpf::program //! [`Bpf::program`]: crate::Bpf::program
//! [`Bpf::program_mut`]: crate::Bpf::program_mut //! [`Bpf::program_mut`]: crate::Bpf::program_mut
//! [maps]: crate::maps //! [maps]: crate::maps
mod cls;
mod kprobe; mod kprobe;
mod perf_attach; mod perf_attach;
mod probe; 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 std::{cell::RefCell, cmp, convert::TryFrom, ffi::CStr, io, os::unix::io::RawFd, rc::Rc};
use thiserror::Error; use thiserror::Error;
pub use cls::{SchedAction, SchedClassifier};
pub use kprobe::{KProbe, KProbeError}; pub use kprobe::{KProbe, KProbeError};
use perf_attach::*; use perf_attach::*;
pub use probe::ProbeKind; pub use probe::ProbeKind;
@ -147,6 +149,7 @@ pub enum Program {
SkMsg(SkMsg), SkMsg(SkMsg),
SkSkb(SkSkb), SkSkb(SkSkb),
SockOps(SockOps), SockOps(SockOps),
SchedClassifier(SchedClassifier),
} }
impl Program { impl Program {
@ -176,6 +179,7 @@ impl Program {
Program::SkMsg(_) => BPF_PROG_TYPE_SK_MSG, Program::SkMsg(_) => BPF_PROG_TYPE_SK_MSG,
Program::SkSkb(_) => BPF_PROG_TYPE_SK_SKB, Program::SkSkb(_) => BPF_PROG_TYPE_SK_SKB,
Program::SockOps(_) => BPF_PROG_TYPE_SOCK_OPS, 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::SkMsg(p) => &p.data,
Program::SkSkb(p) => &p.data, Program::SkSkb(p) => &p.data,
Program::SockOps(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::SkMsg(p) => &mut p.data,
Program::SkSkb(p) => &mut p.data, Program::SkSkb(p) => &mut p.data,
Program::SockOps(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 { macro_rules! impl_try_from_program {
($($ty:ident),+ $(,)?) => { ($($ty:ident),+ $(,)?) => {
@ -461,5 +476,6 @@ impl_try_from_program!(
Xdp, Xdp,
SkMsg, SkMsg,
SkSkb, SkSkb,
SockOps SockOps,
SchedClassifier
); );

@ -38,7 +38,7 @@ pub fn codegen(opts: &Options) -> Result<(), anyhow::Error> {
.constified_enum("BPF_FLOW_.*"); .constified_enum("BPF_FLOW_.*");
let types = ["bpf_map_.*", "sk_action", "pt_regs", "xdp_action"]; let types = ["bpf_map_.*", "sk_action", "pt_regs", "xdp_action"];
let vars = ["BPF_.*", "bpf_.*"]; let vars = ["BPF_.*", "bpf_.*", "TC_ACT_.*"];
for x in &types { for x in &types {
bindgen = bindgen.whitelist_type(x); bindgen = bindgen.whitelist_type(x);

Loading…
Cancel
Save