فهرست منبع

aya: add support for BPF_PROG_TYPE_SCHED_CLS programs

Alessandro Decina 4 سال پیش
والد
کامیت
5effc972ac
5فایلهای تغییر یافته به همراه75 افزوده شده و 7 حذف شده
  1. 5 2
      aya/src/bpf.rs
  2. 9 2
      aya/src/obj/mod.rs
  3. 42 0
      aya/src/programs/cls.rs
  4. 18 2
      aya/src/programs/mod.rs
  5. 1 1
      xtask/src/codegen/aya_bpf_bindings.rs

+ 5 - 2
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)

+ 9 - 2
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(&section, ty, name)?);
                 if !section.relocations.is_empty() {

+ 42 - 0
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()
+    }
+}

+ 18 - 2
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
 );

+ 1 - 1
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);