bpf: Support BPF_PROG_TYPE_SK_LOOKUP

Signed-off-by: Dave Tucker <dave@dtucker.co.uk>
pull/265/head
Dave Tucker 3 years ago
parent 2226b89ceb
commit 74704c3b28

@ -743,6 +743,38 @@ impl FExit {
} }
} }
pub struct SkLookup {
item: ItemFn,
name: Option<String>,
}
impl SkLookup {
pub fn from_syn(mut args: Args, item: ItemFn) -> Result<SkLookup> {
let name = name_arg(&mut args)?;
Ok(SkLookup { item, name })
}
pub fn expand(&self) -> Result<TokenStream> {
let section_name = if let Some(name) = &self.name {
format!("sk_lookup/{}", name)
} else {
"sk_lookup".to_owned()
};
let fn_name = &self.item.sig.ident;
let item = &self.item;
Ok(quote! {
#[no_mangle]
#[link_section = #section_name]
fn #fn_name(ctx: *mut ::aya_bpf::bindings::bpf_sk_lookup) -> u32 {
return #fn_name(::aya_bpf::programs::SkLookupContext::new(ctx));
#item
}
})
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use syn::parse_quote; use syn::parse_quote;

@ -2,8 +2,8 @@ mod expand;
use expand::{ use expand::{
Args, BtfTracePoint, CgroupSkb, CgroupSockAddr, CgroupSockopt, CgroupSysctl, FEntry, FExit, Args, BtfTracePoint, CgroupSkb, CgroupSockAddr, CgroupSockopt, CgroupSysctl, FEntry, FExit,
Lsm, Map, PerfEvent, Probe, ProbeKind, RawTracePoint, SchedClassifier, SkMsg, SkSkb, SkSkbKind, Lsm, Map, PerfEvent, Probe, ProbeKind, RawTracePoint, SchedClassifier, SkLookup, SkMsg, SkSkb,
SockAddrArgs, SockOps, SocketFilter, SockoptArgs, TracePoint, Xdp, SkSkbKind, SockAddrArgs, SockOps, SocketFilter, SockoptArgs, TracePoint, Xdp,
}; };
use proc_macro::TokenStream; use proc_macro::TokenStream;
use syn::{parse_macro_input, ItemFn, ItemStatic}; use syn::{parse_macro_input, ItemFn, ItemStatic};
@ -467,3 +467,32 @@ pub fn fexit(attrs: TokenStream, item: TokenStream) -> TokenStream {
.unwrap_or_else(|err| err.to_compile_error()) .unwrap_or_else(|err| err.to_compile_error())
.into() .into()
} }
/// Marks a function as an eBPF Socket Lookup program that can be attached to
/// a network namespace.
///
/// # Minimum kernel version
///
/// The minimum kernel version required to use this feature is 5.9
///
/// # Examples
///
/// ```no_run
/// use aya_bpf::{macros::sk_lookup, programs::SkLookupContext};
///
/// #[sk_lookup(name = "redirect")]
/// pub fn accept_all(_ctx: SkLookupContext) -> u32 {
/// // use sk_assign to redirect
/// return 0
/// }
/// ```
#[proc_macro_attribute]
pub fn sk_lookup(attrs: TokenStream, item: TokenStream) -> TokenStream {
let args = parse_macro_input!(attrs as Args);
let item = parse_macro_input!(item as ItemFn);
SkLookup::from_syn(args, item)
.and_then(|u| u.expand())
.unwrap_or_else(|err| err.to_compile_error())
.into()
}

@ -4,9 +4,12 @@ use aya_bpf_cty::c_void;
use crate::{ use crate::{
bindings::{bpf_map_def, bpf_map_type::BPF_MAP_TYPE_SOCKHASH, bpf_sock_ops}, bindings::{bpf_map_def, bpf_map_type::BPF_MAP_TYPE_SOCKHASH, bpf_sock_ops},
helpers::{bpf_msg_redirect_hash, bpf_sk_redirect_hash, bpf_sock_hash_update}, helpers::{
bpf_map_lookup_elem, bpf_msg_redirect_hash, bpf_sk_assign, bpf_sk_redirect_hash,
bpf_sk_release, bpf_sock_hash_update,
},
maps::PinningType, maps::PinningType,
programs::{SkBuffContext, SkMsgContext}, programs::{SkBuffContext, SkLookupContext, SkMsgContext},
BpfContext, BpfContext,
}; };
@ -85,4 +88,24 @@ impl<K> SockHash<K> {
) )
} }
} }
pub fn redirect_sk_lookup(
&mut self,
ctx: &SkLookupContext,
key: K,
flags: u64,
) -> Result<(), u32> {
unsafe {
let sk = bpf_map_lookup_elem(
&mut self.def as *mut _ as *mut _,
&key as *const _ as *const c_void,
);
if sk.is_null() {
return Err(1);
}
let ret = bpf_sk_assign(ctx.as_ptr() as *mut _, sk, flags);
bpf_sk_release(sk);
(ret >= 0).then(|| ()).ok_or(1)
}
}
} }

@ -4,9 +4,12 @@ use aya_bpf_cty::c_void;
use crate::{ use crate::{
bindings::{bpf_map_def, bpf_map_type::BPF_MAP_TYPE_SOCKMAP, bpf_sock_ops}, bindings::{bpf_map_def, bpf_map_type::BPF_MAP_TYPE_SOCKMAP, bpf_sock_ops},
helpers::{bpf_msg_redirect_map, bpf_sk_redirect_map, bpf_sock_map_update}, helpers::{
bpf_map_lookup_elem, bpf_msg_redirect_map, bpf_sk_assign, bpf_sk_redirect_map,
bpf_sk_release, bpf_sock_map_update,
},
maps::PinningType, maps::PinningType,
programs::{SkBuffContext, SkMsgContext}, programs::{SkBuffContext, SkLookupContext, SkMsgContext},
BpfContext, BpfContext,
}; };
@ -80,4 +83,24 @@ impl SockMap {
flags, flags,
) )
} }
pub fn redirect_sk_lookup(
&mut self,
ctx: &SkLookupContext,
index: u32,
flags: u64,
) -> Result<(), u32> {
unsafe {
let sk = bpf_map_lookup_elem(
&mut self.def as *mut _ as *mut _,
&index as *const _ as *const c_void,
);
if sk.is_null() {
return Err(1);
}
let ret = bpf_sk_assign(ctx.as_ptr() as *mut _, sk, flags);
bpf_sk_release(sk);
(ret >= 0).then(|| ()).ok_or(1)
}
}
} }

@ -5,6 +5,7 @@ pub mod perf_event;
pub mod probe; pub mod probe;
pub mod raw_tracepoint; pub mod raw_tracepoint;
pub mod sk_buff; pub mod sk_buff;
pub mod sk_lookup;
pub mod sk_msg; pub mod sk_msg;
pub mod sock_addr; pub mod sock_addr;
pub mod sock_ops; pub mod sock_ops;
@ -21,6 +22,7 @@ pub use perf_event::PerfEventContext;
pub use probe::ProbeContext; pub use probe::ProbeContext;
pub use raw_tracepoint::RawTracePointContext; pub use raw_tracepoint::RawTracePointContext;
pub use sk_buff::SkBuffContext; pub use sk_buff::SkBuffContext;
pub use sk_lookup::SkLookupContext;
pub use sk_msg::SkMsgContext; pub use sk_msg::SkMsgContext;
pub use sock_addr::SockAddrContext; pub use sock_addr::SockAddrContext;
pub use sock_ops::SockOpsContext; pub use sock_ops::SockOpsContext;

@ -0,0 +1,19 @@
use core::ffi::c_void;
use crate::{bindings::bpf_sk_lookup, BpfContext};
pub struct SkLookupContext {
pub lookup: *mut bpf_sk_lookup,
}
impl SkLookupContext {
pub fn new(lookup: *mut bpf_sk_lookup) -> SkLookupContext {
SkLookupContext { lookup }
}
}
impl BpfContext for SkLookupContext {
fn as_ptr(&self) -> *mut c_void {
self.lookup as *mut _
}
}
Loading…
Cancel
Save