diff --git a/aya/src/bpf.rs b/aya/src/bpf.rs index bb2af41f..785c4e6d 100644 --- a/aya/src/bpf.rs +++ b/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, diff --git a/aya/src/obj/mod.rs b/aya/src/obj/mod.rs index 6c430a45..d240de96 100644 --- a/aya/src/obj/mod.rs +++ b/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] => { diff --git a/aya/src/programs/mod.rs b/aya/src/programs/mod.rs index ba43609d..c30fba12 100644 --- a/aya/src/programs/mod.rs +++ b/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 ); diff --git a/aya/src/programs/sk_msg.rs b/aya/src/programs/sk_msg.rs new file mode 100644 index 00000000..1332e8a8 --- /dev/null +++ b/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 { + 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, + })) + } +}