4
0
Эх сурвалжийг харах

aya: programs: add support for SkMsg programs

Alessandro Decina 4 жил өмнө
parent
commit
144175434f

+ 2 - 1
aya/src/bpf.rs

@@ -19,7 +19,7 @@ use crate::{
         Object, ParseError, ProgramKind,
     },
     programs::{
-        KProbe, ProbeKind, Program, ProgramData, ProgramError, SkSkb, SkSkbKind, SockOps,
+        KProbe, ProbeKind, Program, ProgramData, ProgramError, SkMsg, SkSkb, SkSkbKind, SockOps,
         SocketFilter, TracePoint, UProbe, Xdp,
     },
     sys::bpf_map_update_elem_ptr,
@@ -173,6 +173,7 @@ impl Bpf {
                     ProgramKind::TracePoint => Program::TracePoint(TracePoint { data }),
                     ProgramKind::SocketFilter => Program::SocketFilter(SocketFilter { data }),
                     ProgramKind::Xdp => Program::Xdp(Xdp { data }),
+                    ProgramKind::SkMsg => Program::SkMsg(SkMsg { data }),
                     ProgramKind::SkSkbStreamParser => Program::SkSkb(SkSkb {
                         data,
                         kind: SkSkbKind::StreamParser,

+ 4 - 1
aya/src/obj/mod.rs

@@ -73,6 +73,7 @@ pub enum ProgramKind {
     TracePoint,
     SocketFilter,
     Xdp,
+    SkMsg,
     SkSkbStreamParser,
     SkSkbStreamVerdict,
     SockOps,
@@ -91,6 +92,7 @@ impl FromStr for ProgramKind {
             "xdp" => Xdp,
             "trace_point" => TracePoint,
             "socket_filter" => SocketFilter,
+            "sk_msg" => SkMsg,
             "sk_skb/stream_parser" => SkSkbStreamParser,
             "sk_skb/stream_verdict" => SkSkbStreamVerdict,
             "sockops" => SockOps,
@@ -257,7 +259,7 @@ impl Object {
         parts.reverse();
 
         if parts.len() == 1 {
-            if parts[0] == "xdp" || parts[0] == "sockops" {
+            if parts[0] == "xdp" || parts[0] == "sk_msg" || parts[0] == "sockops" {
                 parts.push(parts[0]);
             }
         }
@@ -283,6 +285,7 @@ impl Object {
             | &[ty @ "socket_filter", name]
             | &[ty @ "xdp", name]
             | &[ty @ "trace_point", name]
+            | &[ty @ "sk_msg", name]
             | &[ty @ "sk_skb/stream_parser", name]
             | &[ty @ "sk_skb/stream_verdict", name]
             | &[ty @ "sockops", name] => {

+ 8 - 1
aya/src/programs/mod.rs

@@ -47,6 +47,7 @@
 mod kprobe;
 mod perf_attach;
 mod probe;
+mod sk_msg;
 mod sk_skb;
 mod sock_ops;
 mod socket_filter;
@@ -61,6 +62,7 @@ use thiserror::Error;
 pub use kprobe::{KProbe, KProbeError};
 use perf_attach::*;
 pub use probe::ProbeKind;
+pub use sk_msg::SkMsg;
 pub use sk_skb::{SkSkb, SkSkbKind};
 pub use sock_ops::SockOps;
 pub use socket_filter::{SocketFilter, SocketFilterError};
@@ -142,6 +144,7 @@ pub enum Program {
     TracePoint(TracePoint),
     SocketFilter(SocketFilter),
     Xdp(Xdp),
+    SkMsg(SkMsg),
     SkSkb(SkSkb),
     SockOps(SockOps),
 }
@@ -170,6 +173,7 @@ impl Program {
             Program::TracePoint(_) => BPF_PROG_TYPE_TRACEPOINT,
             Program::SocketFilter(_) => BPF_PROG_TYPE_SOCKET_FILTER,
             Program::Xdp(_) => BPF_PROG_TYPE_XDP,
+            Program::SkMsg(_) => BPF_PROG_TYPE_SK_MSG,
             Program::SkSkb(_) => BPF_PROG_TYPE_SK_SKB,
             Program::SockOps(_) => BPF_PROG_TYPE_SOCK_OPS,
         }
@@ -187,6 +191,7 @@ impl Program {
             Program::TracePoint(p) => &p.data,
             Program::SocketFilter(p) => &p.data,
             Program::Xdp(p) => &p.data,
+            Program::SkMsg(p) => &p.data,
             Program::SkSkb(p) => &p.data,
             Program::SockOps(p) => &p.data,
         }
@@ -199,6 +204,7 @@ impl Program {
             Program::TracePoint(p) => &mut p.data,
             Program::SocketFilter(p) => &mut p.data,
             Program::Xdp(p) => &mut p.data,
+            Program::SkMsg(p) => &mut p.data,
             Program::SkSkb(p) => &mut p.data,
             Program::SockOps(p) => &mut p.data,
         }
@@ -410,7 +416,7 @@ macro_rules! impl_program_fd {
     }
 }
 
-impl_program_fd!(KProbe, UProbe, TracePoint, SocketFilter, Xdp, SkSkb);
+impl_program_fd!(KProbe, UProbe, TracePoint, SocketFilter, Xdp, SkMsg, SkSkb);
 
 macro_rules! impl_try_from_program {
     ($($ty:ident),+ $(,)?) => {
@@ -446,6 +452,7 @@ impl_try_from_program!(
     TracePoint,
     SocketFilter,
     Xdp,
+    SkMsg,
     SkSkb,
     SockOps
 );

+ 53 - 0
aya/src/programs/sk_msg.rs

@@ -0,0 +1,53 @@
+use std::ops::Deref;
+
+use crate::{
+    generated::{bpf_attach_type::BPF_SK_MSG_VERDICT, bpf_prog_type::BPF_PROG_TYPE_SK_MSG},
+    maps::{sock::SocketMap, Map, SockMap},
+    programs::{load_program, LinkRef, ProgAttachLink, ProgramData, ProgramError},
+    sys::bpf_prog_attach,
+};
+
+/// A socket buffer program.
+///
+/// Socket buffer programs are attached to [sockmaps], and can be used to
+/// redirect or drop packets. See the [`SockMap` documentation] for more info
+/// and examples.
+///
+/// [sockmaps]: crate::maps::SockMap
+/// [`SockMap` documentation]: crate::maps::SockMap
+#[derive(Debug)]
+pub struct SkMsg {
+    pub(crate) data: ProgramData,
+}
+
+impl SkMsg {
+    /// 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_SK_MSG, &mut self.data)
+    }
+
+    /// Returns the name of the program.
+    pub fn name(&self) -> String {
+        self.data.name.to_string()
+    }
+
+    /// Attaches the program to the given sockmap.
+    pub fn attach(&mut self, map: &dyn SocketMap) -> Result<LinkRef, ProgramError> {
+        let prog_fd = self.data.fd_or_err()?;
+        let map_fd = map.fd_or_err()?;
+
+        bpf_prog_attach(prog_fd, map_fd, BPF_SK_MSG_VERDICT).map_err(|(_, io_error)| {
+            ProgramError::SyscallError {
+                call: "bpf_link_create".to_owned(),
+                io_error,
+            }
+        })?;
+        Ok(self.data.link(ProgAttachLink {
+            prog_fd: Some(prog_fd),
+            target_fd: Some(map_fd),
+            attach_type: BPF_SK_MSG_VERDICT,
+        }))
+    }
+}