Replace proc-macro-error with proc-macro2-diagnostics

proc-macro-error is unmaintained.
reviewable/pr1109/r1
Tamir Duberstein 2 months ago committed by Michal Rostecki
parent dae394e199
commit 5a43bedc01

@ -81,8 +81,8 @@ nix = { version = "0.29.0", default-features = false }
num_enum = { version = "0.7", default-features = false }
object = { version = "0.36", default-features = false }
once_cell = { version = "1.20.1", default-features = false }
proc-macro-error = { version = "1.0", default-features = false }
proc-macro2 = { version = "1", default-features = false }
proc-macro2-diagnostics = { version = "0.10.1", default-features = false }
public-api = { version = "0.42.0", default-features = false }
quote = { version = "1", default-features = false }
rand = { version = "0.8", default-features = false }

@ -13,7 +13,7 @@ proc-macro = true
[dependencies]
proc-macro2 = { workspace = true }
proc-macro-error = { workspace = true }
proc-macro2-diagnostics = { workspace = true }
quote = { workspace = true }
syn = { workspace = true, default-features = true, features = ["full"] }

@ -18,28 +18,33 @@ impl BtfTracePoint {
let function = pop_string_arg(&mut args, "function");
err_on_unknown_args(&args)?;
Ok(BtfTracePoint { item, function })
Ok(Self { item, function })
}
pub(crate) fn expand(&self) -> Result<TokenStream> {
let section_name: Cow<'_, _> = if let Some(function) = &self.function {
pub(crate) fn expand(&self) -> TokenStream {
let Self { item, function } = self;
let ItemFn {
attrs: _,
vis,
sig,
block: _,
} = item;
let section_name: Cow<'_, _> = if let Some(function) = function {
format!("tp_btf/{}", function).into()
} else {
"tp_btf".into()
};
let fn_vis = &self.item.vis;
let fn_name = self.item.sig.ident.clone();
let item = &self.item;
Ok(quote! {
let fn_name = &sig.ident;
quote! {
#[no_mangle]
#[link_section = #section_name]
#fn_vis fn #fn_name(ctx: *mut ::core::ffi::c_void) -> i32 {
#vis fn #fn_name(ctx: *mut ::core::ffi::c_void) -> i32 {
let _ = #fn_name(::aya_ebpf::programs::BtfTracePointContext::new(ctx));
return 0;
#item
}
})
}
}
}
@ -60,7 +65,7 @@ mod tests {
),
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote!(
#[no_mangle]
#[link_section = "tp_btf"]
@ -87,7 +92,7 @@ mod tests {
),
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote!(
#[no_mangle]
#[link_section = "tp_btf/some_func"]

@ -1,34 +1,39 @@
use proc_macro2::TokenStream;
use proc_macro_error::abort;
use proc_macro2_diagnostics::{Diagnostic, SpanDiagnosticExt as _};
use quote::quote;
use syn::{ItemFn, Result};
use syn::{spanned::Spanned as _, ItemFn};
pub(crate) struct CgroupDevice {
item: ItemFn,
}
impl CgroupDevice {
pub(crate) fn parse(attrs: TokenStream, item: TokenStream) -> Result<Self> {
pub(crate) fn parse(attrs: TokenStream, item: TokenStream) -> Result<Self, Diagnostic> {
if !attrs.is_empty() {
abort!(attrs, "unexpected attribute")
return Err(attrs.span().error("unexpected attribute"));
}
let item = syn::parse2(item)?;
Ok(CgroupDevice { item })
Ok(Self { item })
}
pub(crate) fn expand(&self) -> Result<TokenStream> {
let fn_vis = &self.item.vis;
let fn_name = self.item.sig.ident.clone();
let item = &self.item;
Ok(quote! {
pub(crate) fn expand(&self) -> TokenStream {
let Self { item } = self;
let ItemFn {
attrs: _,
vis,
sig,
block: _,
} = item;
let fn_name = &sig.ident;
quote! {
#[no_mangle]
#[link_section = "cgroup/dev"]
#fn_vis fn #fn_name(ctx: *mut ::aya_ebpf::bindings::bpf_cgroup_dev_ctx) -> i32 {
#vis fn #fn_name(ctx: *mut ::aya_ebpf::bindings::bpf_cgroup_dev_ctx) -> i32 {
return #fn_name(::aya_ebpf::programs::DeviceContext::new(ctx));
#item
}
})
}
}
}
@ -49,7 +54,7 @@ mod tests {
),
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "cgroup/dev"]

@ -1,48 +1,52 @@
use std::borrow::Cow;
use proc_macro2::TokenStream;
use proc_macro_error::abort;
use proc_macro2_diagnostics::{Diagnostic, SpanDiagnosticExt as _};
use quote::quote;
use syn::{Ident, ItemFn, Result};
use syn::{Ident, ItemFn};
pub(crate) struct CgroupSkb {
item: ItemFn,
attach_type: Option<String>,
attach_type: Option<Ident>,
}
impl CgroupSkb {
pub(crate) fn parse(attrs: TokenStream, item: TokenStream) -> Result<CgroupSkb> {
pub(crate) fn parse(attrs: TokenStream, item: TokenStream) -> Result<Self, Diagnostic> {
let item: ItemFn = syn::parse2(item)?;
let mut attach_type = None;
if !attrs.is_empty() {
let attach_type = if attrs.is_empty() {
None
} else {
let ident: Ident = syn::parse2(attrs)?;
match ident.to_string().as_str() {
"ingress" | "egress" => (),
_ => abort!(ident, "invalid attach type"),
if ident != "ingress" && ident != "egress" {
return Err(ident.span().error("invalid attach type"));
}
attach_type = Some(ident.to_string());
}
Ok(CgroupSkb { item, attach_type })
Some(ident)
};
Ok(Self { item, attach_type })
}
pub(crate) fn expand(&self) -> Result<TokenStream> {
let section_name: Cow<'_, _> = if self.attach_type.is_some() {
format!("cgroup_skb/{}", self.attach_type.as_ref().unwrap()).into()
} else {
"cgroup/skb".into()
pub(crate) fn expand(&self) -> TokenStream {
let Self { item, attach_type } = self;
let ItemFn {
attrs: _,
vis,
sig,
block: _,
} = item;
let section_name: Cow<'_, _> = match attach_type {
Some(attach_type) => format!("cgroup_skb/{attach_type}").into(),
None => "cgroup/skb".into(),
};
let fn_vis = &self.item.vis;
let fn_name = self.item.sig.ident.clone();
let item = &self.item;
Ok(quote! {
let fn_name = &sig.ident;
quote! {
#[no_mangle]
#[link_section = #section_name]
#fn_vis fn #fn_name(ctx: *mut ::aya_ebpf::bindings::__sk_buff) -> i32 {
#vis fn #fn_name(ctx: *mut ::aya_ebpf::bindings::__sk_buff) -> i32 {
return #fn_name(::aya_ebpf::programs::SkBuffContext::new(ctx));
#item
}
})
}
}
}
@ -63,7 +67,7 @@ mod tests {
),
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "cgroup/skb"]
@ -89,7 +93,7 @@ mod tests {
),
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "cgroup_skb/egress"]
@ -115,7 +119,7 @@ mod tests {
),
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "cgroup_skb/ingress"]
@ -141,7 +145,7 @@ mod tests {
),
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "cgroup_skb/egress"]
@ -167,7 +171,7 @@ mod tests {
),
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "cgroup_skb/egress"]
@ -193,7 +197,7 @@ mod tests {
),
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "cgroup_skb/egress"]

@ -1,46 +1,51 @@
use std::borrow::Cow;
use proc_macro2::TokenStream;
use proc_macro_error::abort;
use proc_macro2_diagnostics::{Diagnostic, SpanDiagnosticExt as _};
use quote::quote;
use syn::{Ident, ItemFn, Result};
use syn::{spanned::Spanned as _, Ident, ItemFn};
pub(crate) struct CgroupSock {
item: ItemFn,
attach_type: String,
attach_type: Ident,
}
impl CgroupSock {
pub(crate) fn parse(attrs: TokenStream, item: TokenStream) -> Result<CgroupSock> {
pub(crate) fn parse(attrs: TokenStream, item: TokenStream) -> Result<Self, Diagnostic> {
if attrs.is_empty() {
abort!(attrs, "missing attach type")
return Err(attrs.span().error("missing attach type"));
}
let item: ItemFn = syn::parse2(item)?;
let attach_type: Ident = syn::parse2(attrs)?;
match attach_type.to_string().as_str() {
"post_bind4" | "post_bind6" | "sock_create" | "sock_release" => (),
_ => abort!(attach_type, "invalid attach type"),
if attach_type != "post_bind4"
&& attach_type != "post_bind6"
&& attach_type != "sock_create"
&& attach_type != "sock_release"
{
return Err(attach_type.span().error("invalid attach type"));
}
Ok(CgroupSock {
item,
attach_type: attach_type.to_string(),
})
Ok(Self { item, attach_type })
}
pub(crate) fn expand(&self) -> Result<TokenStream> {
let section_name: Cow<'_, _> = format!("cgroup/{}", self.attach_type).into();
let fn_vis = &self.item.vis;
let fn_name = self.item.sig.ident.clone();
let item = &self.item;
Ok(quote! {
pub(crate) fn expand(&self) -> TokenStream {
let Self { item, attach_type } = self;
let ItemFn {
attrs: _,
vis,
sig,
block: _,
} = item;
let section_name: Cow<'_, _> = format!("cgroup/{attach_type}").into();
let fn_name = &sig.ident;
quote! {
#[no_mangle]
#[link_section = #section_name]
#fn_vis fn #fn_name(ctx: *mut ::aya_ebpf::bindings::bpf_sock) -> i32 {
#vis fn #fn_name(ctx: *mut ::aya_ebpf::bindings::bpf_sock) -> i32 {
return #fn_name(::aya_ebpf::programs::SockContext::new(ctx));
#item
}
})
}
}
}
@ -61,7 +66,7 @@ mod tests {
),
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "cgroup/post_bind4"]
@ -87,7 +92,7 @@ mod tests {
),
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "cgroup/post_bind6"]
@ -112,7 +117,7 @@ mod tests {
),
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "cgroup/sock_create"]
@ -137,7 +142,7 @@ mod tests {
),
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "cgroup/sock_release"]

@ -1,48 +1,59 @@
use std::borrow::Cow;
use proc_macro2::TokenStream;
use proc_macro_error::abort;
use proc_macro2_diagnostics::{Diagnostic, SpanDiagnosticExt as _};
use quote::quote;
use syn::{Ident, ItemFn, Result};
use syn::{spanned::Spanned as _, Ident, ItemFn};
pub(crate) struct CgroupSockAddr {
item: ItemFn,
attach_type: String,
attach_type: Ident,
}
impl CgroupSockAddr {
pub(crate) fn parse(attrs: TokenStream, item: TokenStream) -> Result<Self> {
pub(crate) fn parse(attrs: TokenStream, item: TokenStream) -> Result<Self, Diagnostic> {
if attrs.is_empty() {
abort!(attrs, "missing attach type")
return Err(attrs.span().error("missing attach type"));
}
let item = syn::parse2(item)?;
let attach_type: Ident = syn::parse2(attrs)?;
match attach_type.to_string().as_str() {
"connect4" | "connect6" | "bind4" | "bind6" | "getpeername4" | "getpeername6"
| "getsockname4" | "getsockname6" | "sendmsg4" | "sendmsg6" | "recvmsg4"
| "recvmsg6" => (),
_ => abort!(attach_type, "invalid attach type"),
if attach_type != "connect4"
&& attach_type != "connect6"
&& attach_type != "bind4"
&& attach_type != "bind6"
&& attach_type != "getpeername4"
&& attach_type != "getpeername6"
&& attach_type != "getsockname4"
&& attach_type != "getsockname6"
&& attach_type != "sendmsg4"
&& attach_type != "sendmsg6"
&& attach_type != "recvmsg4"
&& attach_type != "recvmsg6"
{
return Err(attach_type.span().error("invalid attach type"));
}
Ok(CgroupSockAddr {
item,
attach_type: attach_type.to_string(),
})
Ok(Self { item, attach_type })
}
pub(crate) fn expand(&self) -> Result<TokenStream> {
let section_name: Cow<'_, _> = format!("cgroup/{}", self.attach_type).into();
let fn_vis = &self.item.vis;
let fn_name = self.item.sig.ident.clone();
let item = &self.item;
Ok(quote! {
pub(crate) fn expand(&self) -> TokenStream {
let Self { item, attach_type } = self;
let ItemFn {
attrs: _,
vis,
sig,
block: _,
} = item;
let section_name: Cow<'_, _> = format!("cgroup/{attach_type}").into();
let fn_name = &sig.ident;
quote! {
#[no_mangle]
#[link_section = #section_name]
#fn_vis fn #fn_name(ctx: *mut ::aya_ebpf::bindings::bpf_sock_addr) -> i32 {
#vis fn #fn_name(ctx: *mut ::aya_ebpf::bindings::bpf_sock_addr) -> i32 {
return #fn_name(::aya_ebpf::programs::SockAddrContext::new(ctx));
#item
}
})
}
}
}
@ -63,7 +74,7 @@ mod tests {
),
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "cgroup/connect4"]
@ -89,7 +100,7 @@ mod tests {
),
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "cgroup/connect6"]
@ -115,7 +126,7 @@ mod tests {
),
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "cgroup/bind4"]
@ -141,7 +152,7 @@ mod tests {
),
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "cgroup/bind6"]
@ -167,7 +178,7 @@ mod tests {
),
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "cgroup/getpeername4"]
@ -193,7 +204,7 @@ mod tests {
),
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "cgroup/getpeername6"]
@ -219,7 +230,7 @@ mod tests {
),
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "cgroup/getsockname4"]
@ -245,7 +256,7 @@ mod tests {
),
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "cgroup/getsockname6"]
@ -271,7 +282,7 @@ mod tests {
),
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "cgroup/sendmsg4"]
@ -297,7 +308,7 @@ mod tests {
),
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "cgroup/sendmsg6"]
@ -323,7 +334,7 @@ mod tests {
),
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "cgroup/recvmsg4"]
@ -349,7 +360,7 @@ mod tests {
),
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "cgroup/recvmsg6"]

@ -1,46 +1,50 @@
use std::borrow::Cow;
use proc_macro2::TokenStream;
use proc_macro_error::abort;
use proc_macro2_diagnostics::{Diagnostic, SpanDiagnosticExt as _};
use quote::quote;
use syn::{Ident, ItemFn, Result};
use syn::{spanned::Spanned as _, Ident, ItemFn};
pub(crate) struct CgroupSockopt {
item: ItemFn,
attach_type: String,
attach_type: Ident,
}
impl CgroupSockopt {
pub(crate) fn parse(attrs: TokenStream, item: TokenStream) -> Result<CgroupSockopt> {
pub(crate) fn parse(
attrs: TokenStream,
item: TokenStream,
) -> Result<CgroupSockopt, Diagnostic> {
if attrs.is_empty() {
abort!(attrs, "expected attach type");
return Err(attrs.span().error("missing attach type"));
}
let item = syn::parse2(item)?;
let attach_type: Ident = syn::parse2(attrs)?;
match attach_type.to_string().as_str() {
"getsockopt" | "setsockopt" => (),
_ => abort!(attach_type, "invalid attach type"),
if attach_type != "getsockopt" && attach_type != "setsockopt" {
return Err(attach_type.span().error("invalid attach type"));
}
Ok(CgroupSockopt {
item,
attach_type: attach_type.to_string(),
})
Ok(Self { item, attach_type })
}
pub(crate) fn expand(&self) -> Result<TokenStream> {
let section_name: Cow<'_, _> = format!("cgroup/{}", self.attach_type).into();
let fn_vis = &self.item.vis;
let fn_name = self.item.sig.ident.clone();
let item = &self.item;
Ok(quote! {
pub(crate) fn expand(&self) -> TokenStream {
let Self { item, attach_type } = self;
let ItemFn {
attrs: _,
vis,
sig,
block: _,
} = item;
let section_name: Cow<'_, _> = format!("cgroup/{attach_type}").into();
let fn_name = &sig.ident;
quote! {
#[no_mangle]
#[link_section = #section_name]
#fn_vis fn #fn_name(ctx: *mut ::aya_ebpf::bindings::bpf_sockopt) -> i32 {
#vis fn #fn_name(ctx: *mut ::aya_ebpf::bindings::bpf_sockopt) -> i32 {
return #fn_name(::aya_ebpf::programs::SockoptContext::new(ctx));
#item
}
})
}
}
}
@ -61,7 +65,7 @@ mod tests {
),
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote!(
#[no_mangle]
#[link_section = "cgroup/getsockopt"]
@ -87,7 +91,7 @@ mod tests {
),
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote!(
#[no_mangle]
#[link_section = "cgroup/setsockopt"]

@ -1,34 +1,39 @@
use proc_macro2::TokenStream;
use proc_macro_error::abort;
use proc_macro2_diagnostics::{Diagnostic, SpanDiagnosticExt as _};
use quote::quote;
use syn::{ItemFn, Result};
use syn::{spanned::Spanned as _, ItemFn};
pub(crate) struct CgroupSysctl {
item: ItemFn,
}
impl CgroupSysctl {
pub(crate) fn parse(attrs: TokenStream, item: TokenStream) -> Result<Self> {
pub(crate) fn parse(attrs: TokenStream, item: TokenStream) -> Result<Self, Diagnostic> {
if !attrs.is_empty() {
abort!(attrs, "unexpected attribute")
return Err(attrs.span().error("unexpected attribute"));
}
let item = syn::parse2(item)?;
Ok(CgroupSysctl { item })
Ok(Self { item })
}
pub(crate) fn expand(&self) -> Result<TokenStream> {
let fn_vis = &self.item.vis;
let fn_name = self.item.sig.ident.clone();
let item = &self.item;
Ok(quote! {
pub(crate) fn expand(&self) -> TokenStream {
let Self { item } = self;
let ItemFn {
attrs: _,
vis,
sig,
block: _,
} = item;
let fn_name = &sig.ident;
quote! {
#[no_mangle]
#[link_section = "cgroup/sysctl"]
#fn_vis fn #fn_name(ctx: *mut ::aya_ebpf::bindings::bpf_sysctl) -> i32 {
#vis fn #fn_name(ctx: *mut ::aya_ebpf::bindings::bpf_sysctl) -> i32 {
return #fn_name(::aya_ebpf::programs::SysctlContext::new(ctx));
#item
}
})
}
}
}
@ -49,7 +54,7 @@ mod tests {
),
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "cgroup/sysctl"]

@ -13,39 +13,48 @@ pub(crate) struct FEntry {
}
impl FEntry {
pub(crate) fn parse(attrs: TokenStream, item: TokenStream) -> Result<FEntry> {
pub(crate) fn parse(attrs: TokenStream, item: TokenStream) -> Result<Self> {
let item = syn::parse2(item)?;
let mut args = syn::parse2(attrs)?;
let function = pop_string_arg(&mut args, "function");
let sleepable = pop_bool_arg(&mut args, "sleepable");
err_on_unknown_args(&args)?;
Ok(FEntry {
Ok(Self {
item,
function,
sleepable,
})
}
pub(crate) fn expand(&self) -> Result<TokenStream> {
let section_prefix = if self.sleepable { "fentry.s" } else { "fentry" };
let section_name: Cow<'_, _> = if let Some(function) = &self.function {
pub(crate) fn expand(&self) -> TokenStream {
let Self {
item,
function,
sleepable,
} = self;
let ItemFn {
attrs: _,
vis,
sig,
block: _,
} = item;
let section_prefix = if *sleepable { "fentry.s" } else { "fentry" };
let section_name: Cow<'_, _> = if let Some(function) = function {
format!("{}/{}", section_prefix, function).into()
} else {
section_prefix.into()
};
let fn_vis = &self.item.vis;
let fn_name = self.item.sig.ident.clone();
let item = &self.item;
Ok(quote! {
let fn_name = &sig.ident;
quote! {
#[no_mangle]
#[link_section = #section_name]
#fn_vis fn #fn_name(ctx: *mut ::core::ffi::c_void) -> i32 {
#vis fn #fn_name(ctx: *mut ::core::ffi::c_void) -> i32 {
let _ = #fn_name(::aya_ebpf::programs::FEntryContext::new(ctx));
return 0;
#item
}
})
}
}
}
@ -66,7 +75,7 @@ mod tests {
},
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "fentry"]
@ -95,7 +104,7 @@ mod tests {
},
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "fentry/sys_clone"]
@ -124,7 +133,7 @@ mod tests {
},
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "fentry.s"]

@ -13,39 +13,48 @@ pub(crate) struct FExit {
}
impl FExit {
pub(crate) fn parse(attrs: TokenStream, item: TokenStream) -> Result<FExit> {
pub(crate) fn parse(attrs: TokenStream, item: TokenStream) -> Result<Self> {
let item = syn::parse2(item)?;
let mut args = syn::parse2(attrs)?;
let function = pop_string_arg(&mut args, "function");
let sleepable = pop_bool_arg(&mut args, "sleepable");
err_on_unknown_args(&args)?;
Ok(FExit {
Ok(Self {
item,
function,
sleepable,
})
}
pub(crate) fn expand(&self) -> Result<TokenStream> {
let section_prefix = if self.sleepable { "fexit.s" } else { "fexit" };
let section_name: Cow<'_, _> = if let Some(function) = &self.function {
pub(crate) fn expand(&self) -> TokenStream {
let Self {
item,
function,
sleepable,
} = self;
let ItemFn {
attrs: _,
vis,
sig,
block: _,
} = item;
let section_prefix = if *sleepable { "fexit.s" } else { "fexit" };
let section_name: Cow<'_, _> = if let Some(function) = function {
format!("{}/{}", section_prefix, function).into()
} else {
section_prefix.into()
};
let fn_vis = &self.item.vis;
let fn_name = self.item.sig.ident.clone();
let item = &self.item;
Ok(quote! {
let fn_name = &sig.ident;
quote! {
#[no_mangle]
#[link_section = #section_name]
#fn_vis fn #fn_name(ctx: *mut ::core::ffi::c_void) -> i32 {
#vis fn #fn_name(ctx: *mut ::core::ffi::c_void) -> i32 {
let _ = #fn_name(::aya_ebpf::programs::FExitContext::new(ctx));
return 0;
#item
}
})
}
}
}
@ -66,7 +75,7 @@ mod tests {
},
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "fexit"]
@ -95,7 +104,7 @@ mod tests {
},
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "fexit/sys_clone"]
@ -124,7 +133,7 @@ mod tests {
},
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "fexit.s/sys_clone"]

@ -1,8 +1,9 @@
use std::borrow::Cow;
use proc_macro2::TokenStream;
use proc_macro2_diagnostics::{Diagnostic, SpanDiagnosticExt as _};
use quote::quote;
use syn::{ItemFn, Result};
use syn::{spanned::Spanned as _, ItemFn};
use crate::args::{err_on_unknown_args, pop_string_arg};
@ -31,14 +32,23 @@ pub(crate) struct KProbe {
}
impl KProbe {
pub(crate) fn parse(kind: KProbeKind, attrs: TokenStream, item: TokenStream) -> Result<KProbe> {
pub(crate) fn parse(
kind: KProbeKind,
attrs: TokenStream,
item: TokenStream,
) -> Result<Self, Diagnostic> {
let item = syn::parse2(item)?;
let span = attrs.span();
let mut args = syn::parse2(attrs)?;
let function = pop_string_arg(&mut args, "function");
let offset = pop_string_arg(&mut args, "offset").map(|v| v.parse::<u64>().unwrap());
let offset = pop_string_arg(&mut args, "offset")
.as_deref()
.map(str::parse)
.transpose()
.map_err(|err| span.error(format!("failed to parse `offset` argument: {}", err)))?;
err_on_unknown_args(&args)?;
Ok(KProbe {
Ok(Self {
kind,
item,
function,
@ -46,39 +56,42 @@ impl KProbe {
})
}
pub(crate) fn expand(&self) -> Result<TokenStream> {
let section_name: Cow<'_, _> = if self.function.is_some() && self.offset.is_some() {
format!(
"{}/{}+{}",
self.kind,
self.function.as_ref().unwrap(),
self.offset.unwrap()
)
.into()
} else if self.function.is_some() {
format!("{}/{}", self.kind, self.function.as_ref().unwrap()).into()
} else {
format!("{}", self.kind).into()
pub(crate) fn expand(&self) -> TokenStream {
let Self {
kind,
function,
offset,
item,
} = self;
let ItemFn {
attrs: _,
vis,
sig,
block: _,
} = item;
let section_name: Cow<'_, _> = match function {
None => self.kind.to_string().into(),
Some(function) => match offset {
None => format!("{kind}/{function}").into(),
Some(offset) => format!("{kind}/{function}+{offset}").into(),
},
};
let probe_type = if section_name.as_ref().starts_with("kprobe") {
quote! { ProbeContext }
} else {
quote! { RetProbeContext }
};
let fn_vis = &self.item.vis;
let fn_name = self.item.sig.ident.clone();
let item = &self.item;
Ok(quote! {
let fn_name = &sig.ident;
quote! {
#[no_mangle]
#[link_section = #section_name]
#fn_vis fn #fn_name(ctx: *mut ::core::ffi::c_void) -> u32 {
#vis fn #fn_name(ctx: *mut ::core::ffi::c_void) -> u32 {
let _ = #fn_name(::aya_ebpf::programs::#probe_type::new(ctx));
return 0;
#item
}
})
}
}
}
@ -101,7 +114,7 @@ mod tests {
)
.unwrap();
assert_eq!(
kprobe.expand().unwrap().to_string(),
kprobe.expand().to_string(),
quote! {
#[no_mangle]
#[link_section = "kprobe"]
@ -133,7 +146,7 @@ mod tests {
)
.unwrap();
assert_eq!(
kprobe.expand().unwrap().to_string(),
kprobe.expand().to_string(),
quote! {
#[no_mangle]
#[link_section = "kprobe/fib_lookup"]
@ -166,7 +179,7 @@ mod tests {
)
.unwrap();
assert_eq!(
kprobe.expand().unwrap().to_string(),
kprobe.expand().to_string(),
quote! {
#[no_mangle]
#[link_section = "kprobe/fib_lookup+10"]
@ -196,7 +209,7 @@ mod tests {
)
.unwrap();
assert_eq!(
kprobe.expand().unwrap().to_string(),
kprobe.expand().to_string(),
quote! {
#[no_mangle]
#[link_section = "kretprobe"]

@ -37,7 +37,6 @@ use lsm::Lsm;
use map::Map;
use perf_event::PerfEvent;
use proc_macro::TokenStream;
use proc_macro_error::{abort, proc_macro_error};
use raw_tracepoint::RawTracePoint;
use sk_lookup::SkLookup;
use sk_msg::SkMsg;
@ -48,83 +47,69 @@ use tc::SchedClassifier;
use tracepoint::TracePoint;
use uprobe::{UProbe, UProbeKind};
use xdp::Xdp;
#[proc_macro_error]
#[proc_macro_attribute]
pub fn map(attrs: TokenStream, item: TokenStream) -> TokenStream {
match Map::parse(attrs.into(), item.into()) {
Ok(prog) => prog
.expand()
.unwrap_or_else(|err| abort!(err.span(), "{}", err))
.into(),
Err(err) => abort!(err.span(), "{}", err),
Ok(prog) => prog.expand(),
Err(err) => err.into_compile_error(),
}
.into()
}
#[proc_macro_error]
#[proc_macro_attribute]
pub fn kprobe(attrs: TokenStream, item: TokenStream) -> TokenStream {
match KProbe::parse(KProbeKind::KProbe, attrs.into(), item.into()) {
Ok(prog) => prog
.expand()
.unwrap_or_else(|err| abort!(err.span(), "{}", err))
.into(),
Err(err) => abort!(err.span(), "{}", err),
Ok(prog) => prog.expand(),
Err(err) => err.emit_as_expr_tokens(),
}
.into()
}
#[proc_macro_error]
#[proc_macro_attribute]
pub fn kretprobe(attrs: TokenStream, item: TokenStream) -> TokenStream {
match KProbe::parse(KProbeKind::KRetProbe, attrs.into(), item.into()) {
Ok(prog) => prog
.expand()
.unwrap_or_else(|err| abort!(err.span(), "{}", err))
.into(),
Err(err) => abort!(err.span(), "{}", err),
Ok(prog) => prog.expand(),
Err(err) => err.emit_as_expr_tokens(),
}
.into()
}
#[proc_macro_error]
#[proc_macro_attribute]
pub fn uprobe(attrs: TokenStream, item: TokenStream) -> TokenStream {
match UProbe::parse(UProbeKind::UProbe, attrs.into(), item.into()) {
Ok(prog) => prog
.expand()
.unwrap_or_else(|err| abort!(err.span(), "{}", err))
.into(),
Err(err) => abort!(err.span(), "{}", err),
Ok(prog) => match prog.expand() {
Ok(tokens) => tokens,
Err(err) => err.emit_as_expr_tokens(),
},
Err(err) => err.emit_as_expr_tokens(),
}
.into()
}
#[proc_macro_error]
#[proc_macro_attribute]
pub fn uretprobe(attrs: TokenStream, item: TokenStream) -> TokenStream {
match UProbe::parse(UProbeKind::URetProbe, attrs.into(), item.into()) {
Ok(prog) => prog
.expand()
.unwrap_or_else(|err| abort!(err.span(), "{}", err))
.into(),
Err(err) => abort!(err.span(), "{}", err),
Ok(prog) => match prog.expand() {
Ok(tokens) => tokens,
Err(err) => err.emit_as_expr_tokens(),
},
Err(err) => err.emit_as_expr_tokens(),
}
.into()
}
#[proc_macro_error]
#[proc_macro_attribute]
pub fn sock_ops(attrs: TokenStream, item: TokenStream) -> TokenStream {
match SockOps::parse(attrs.into(), item.into()) {
Ok(prog) => prog
.expand()
.unwrap_or_else(|err| abort!(err.span(), "{}", err))
.into(),
Err(err) => abort!(err.span(), "{}", err),
Ok(prog) => prog.expand(),
Err(err) => err.emit_as_expr_tokens(),
}
.into()
}
#[proc_macro_error]
#[proc_macro_attribute]
pub fn sk_msg(attrs: TokenStream, item: TokenStream) -> TokenStream {
match SkMsg::parse(attrs.into(), item.into()) {
Ok(prog) => prog
.expand()
.unwrap_or_else(|err| abort!(err.span(), "{}", err))
.into(),
Err(err) => abort!(err.span(), "{}", err),
Ok(prog) => prog.expand(),
Err(err) => err.emit_as_expr_tokens(),
}
.into()
}
/// Marks a function as an eBPF XDP program that can be attached to a network interface.
@ -149,60 +134,46 @@ pub fn sk_msg(attrs: TokenStream, item: TokenStream) -> TokenStream {
/// XDP_PASS
/// }
/// ```
#[proc_macro_error]
#[proc_macro_attribute]
pub fn xdp(attrs: TokenStream, item: TokenStream) -> TokenStream {
match Xdp::parse(attrs.into(), item.into()) {
Ok(prog) => prog
.expand()
.unwrap_or_else(|err| abort!(err.span(), "{}", err))
.into(),
Err(err) => abort!(err.span(), "{}", err),
Ok(prog) => prog.expand(),
Err(err) => err.emit_as_expr_tokens(),
}
.into()
}
#[proc_macro_error]
#[proc_macro_attribute]
pub fn classifier(attrs: TokenStream, item: TokenStream) -> TokenStream {
match SchedClassifier::parse(attrs.into(), item.into()) {
Ok(prog) => prog
.expand()
.unwrap_or_else(|err| abort!(err.span(), "{}", err))
.into(),
Err(err) => abort!(err.span(), "{}", err),
Ok(prog) => prog.expand(),
Err(err) => err.emit_as_expr_tokens(),
}
.into()
}
#[proc_macro_attribute]
pub fn cgroup_sysctl(attrs: TokenStream, item: TokenStream) -> TokenStream {
match CgroupSysctl::parse(attrs.into(), item.into()) {
Ok(prog) => prog
.expand()
.unwrap_or_else(|err| abort!(err.span(), "{}", err))
.into(),
Err(err) => abort!(err.span(), "{}", err),
Ok(prog) => prog.expand(),
Err(err) => err.emit_as_expr_tokens(),
}
.into()
}
#[proc_macro_error]
#[proc_macro_attribute]
pub fn cgroup_sockopt(attrs: TokenStream, item: TokenStream) -> TokenStream {
match CgroupSockopt::parse(attrs.into(), item.into()) {
Ok(prog) => prog
.expand()
.unwrap_or_else(|err| abort!(err.span(), "{}", err))
.into(),
Err(err) => abort!(err.span(), "{}", err),
Ok(prog) => prog.expand(),
Err(err) => err.emit_as_expr_tokens(),
}
.into()
}
#[proc_macro_error]
#[proc_macro_attribute]
pub fn cgroup_skb(attrs: TokenStream, item: TokenStream) -> TokenStream {
match CgroupSkb::parse(attrs.into(), item.into()) {
Ok(prog) => prog
.expand()
.unwrap_or_else(|err| abort!(err.span(), "{}", err))
.into(),
Err(err) => abort!(err.span(), "{}", err),
Ok(prog) => prog.expand(),
Err(err) => err.emit_as_expr_tokens(),
}
.into()
}
/// Marks a function as a [`CgroupSockAddr`] eBPF program.
@ -239,51 +210,39 @@ pub fn cgroup_skb(attrs: TokenStream, item: TokenStream) -> TokenStream {
/// Ok(0)
/// }
/// ```
#[proc_macro_error]
#[proc_macro_attribute]
pub fn cgroup_sock_addr(attrs: TokenStream, item: TokenStream) -> TokenStream {
match CgroupSockAddr::parse(attrs.into(), item.into()) {
Ok(prog) => prog
.expand()
.unwrap_or_else(|err| abort!(err.span(), "{}", err))
.into(),
Err(err) => abort!(err.span(), "{}", err),
Ok(prog) => prog.expand(),
Err(err) => err.emit_as_expr_tokens(),
}
.into()
}
#[proc_macro_error]
#[proc_macro_attribute]
pub fn cgroup_sock(attrs: TokenStream, item: TokenStream) -> TokenStream {
match CgroupSock::parse(attrs.into(), item.into()) {
Ok(prog) => prog
.expand()
.unwrap_or_else(|err| abort!(err.span(), "{}", err))
.into(),
Err(err) => abort!(err.span(), "{}", err),
Ok(prog) => prog.expand(),
Err(err) => err.emit_as_expr_tokens(),
}
.into()
}
#[proc_macro_error]
#[proc_macro_attribute]
pub fn tracepoint(attrs: TokenStream, item: TokenStream) -> TokenStream {
match TracePoint::parse(attrs.into(), item.into()) {
Ok(prog) => prog
.expand()
.unwrap_or_else(|err| abort!(err.span(), "{}", err))
.into(),
Err(err) => abort!(err.span(), "{}", err),
Ok(prog) => prog.expand(),
Err(err) => err.emit_as_expr_tokens(),
}
.into()
}
#[proc_macro_error]
#[proc_macro_attribute]
pub fn perf_event(attrs: TokenStream, item: TokenStream) -> TokenStream {
match PerfEvent::parse(attrs.into(), item.into()) {
Ok(prog) => prog
.expand()
.unwrap_or_else(|err| abort!(err.span(), "{}", err))
.into(),
Err(err) => abort!(err.span(), "{}", err),
Ok(prog) => prog.expand(),
Err(err) => err.emit_as_expr_tokens(),
}
.into()
}
/// Marks a function as a raw tracepoint eBPF program that can be attached at a
@ -314,16 +273,13 @@ pub fn perf_event(attrs: TokenStream, item: TokenStream) -> TokenStream {
/// Ok(0)
/// }
/// ```
#[proc_macro_error]
#[proc_macro_attribute]
pub fn raw_tracepoint(attrs: TokenStream, item: TokenStream) -> TokenStream {
match RawTracePoint::parse(attrs.into(), item.into()) {
Ok(prog) => prog
.expand()
.unwrap_or_else(|err| abort!(err.span(), "{}", err))
.into(),
Err(err) => abort!(err.span(), "{}", err),
Ok(prog) => prog.expand(),
Err(err) => err.into_compile_error(),
}
.into()
}
/// Marks a function as an LSM program that can be attached to Linux LSM hooks.
@ -361,16 +317,13 @@ pub fn raw_tracepoint(attrs: TokenStream, item: TokenStream) -> TokenStream {
/// Ok(0)
/// }
/// ```
#[proc_macro_error]
#[proc_macro_attribute]
pub fn lsm(attrs: TokenStream, item: TokenStream) -> TokenStream {
match Lsm::parse(attrs.into(), item.into()) {
Ok(prog) => prog
.expand()
.unwrap_or_else(|err| abort!(err.span(), "{}", err))
.into(),
Err(err) => abort!(err.span(), "{}", err),
Ok(prog) => prog.expand(),
Err(err) => err.into_compile_error(),
}
.into()
}
/// Marks a function as a [BTF-enabled raw tracepoint][1] eBPF program that can be attached at
@ -403,16 +356,13 @@ pub fn lsm(attrs: TokenStream, item: TokenStream) -> TokenStream {
/// ```
///
/// [1]: https://github.com/torvalds/linux/commit/9e15db66136a14cde3f35691f1d839d950118826
#[proc_macro_error]
#[proc_macro_attribute]
pub fn btf_tracepoint(attrs: TokenStream, item: TokenStream) -> TokenStream {
match BtfTracePoint::parse(attrs.into(), item.into()) {
Ok(prog) => prog
.expand()
.unwrap_or_else(|err| abort!(err.span(), "{}", err))
.into(),
Err(err) => abort!(err.span(), "{}", err),
Ok(prog) => prog.expand(),
Err(err) => err.into_compile_error(),
}
.into()
}
/// Marks a function as a SK_SKB Stream Parser eBPF program that can be attached
@ -440,7 +390,6 @@ pub fn btf_tracepoint(attrs: TokenStream, item: TokenStream) -> TokenStream {
/// Ok(ctx.len())
///}
/// ```
#[proc_macro_error]
#[proc_macro_attribute]
pub fn stream_parser(attrs: TokenStream, item: TokenStream) -> TokenStream {
sk_skb(SkSkbKind::StreamParser, attrs, item)
@ -471,7 +420,6 @@ pub fn stream_parser(attrs: TokenStream, item: TokenStream) -> TokenStream {
/// Ok(sk_action::SK_PASS)
///}
/// ```
#[proc_macro_error]
#[proc_macro_attribute]
pub fn stream_verdict(attrs: TokenStream, item: TokenStream) -> TokenStream {
sk_skb(SkSkbKind::StreamVerdict, attrs, item)
@ -479,12 +427,10 @@ pub fn stream_verdict(attrs: TokenStream, item: TokenStream) -> TokenStream {
fn sk_skb(kind: SkSkbKind, attrs: TokenStream, item: TokenStream) -> TokenStream {
match SkSkb::parse(kind, attrs.into(), item.into()) {
Ok(prog) => prog
.expand()
.unwrap_or_else(|err| abort!(err.span(), "{}", err))
.into(),
Err(err) => abort!(err.span(), "{}", err),
Ok(prog) => prog.expand(),
Err(err) => err.emit_as_expr_tokens(),
}
.into()
}
/// Marks a function as a eBPF Socket Filter program that can be attached to
@ -504,16 +450,13 @@ fn sk_skb(kind: SkSkbKind, attrs: TokenStream, item: TokenStream) -> TokenStream
/// return 0
/// }
/// ```
#[proc_macro_error]
#[proc_macro_attribute]
pub fn socket_filter(attrs: TokenStream, item: TokenStream) -> TokenStream {
match SocketFilter::parse(attrs.into(), item.into()) {
Ok(prog) => prog
.expand()
.unwrap_or_else(|err| abort!(err.span(), "{}", err))
.into(),
Err(err) => abort!(err.span(), "{}", err),
Ok(prog) => prog.expand(),
Err(err) => err.emit_as_expr_tokens(),
}
.into()
}
/// Marks a function as a fentry eBPF program that can be attached to almost
@ -548,16 +491,13 @@ pub fn socket_filter(attrs: TokenStream, item: TokenStream) -> TokenStream {
/// Ok(0)
/// }
/// ```
#[proc_macro_error]
#[proc_macro_attribute]
pub fn fentry(attrs: TokenStream, item: TokenStream) -> TokenStream {
match FEntry::parse(attrs.into(), item.into()) {
Ok(prog) => prog
.expand()
.unwrap_or_else(|err| abort!(err.span(), "{}", err))
.into(),
Err(err) => abort!(err.span(), "{}", err),
Ok(prog) => prog.expand(),
Err(err) => err.into_compile_error(),
}
.into()
}
/// Marks a function as a fexit eBPF program that can be attached to almost
@ -593,16 +533,13 @@ pub fn fentry(attrs: TokenStream, item: TokenStream) -> TokenStream {
/// Ok(0)
/// }
/// ```
#[proc_macro_error]
#[proc_macro_attribute]
pub fn fexit(attrs: TokenStream, item: TokenStream) -> TokenStream {
match FExit::parse(attrs.into(), item.into()) {
Ok(prog) => prog
.expand()
.unwrap_or_else(|err| abort!(err.span(), "{}", err))
.into(),
Err(err) => abort!(err.span(), "{}", err),
Ok(prog) => prog.expand(),
Err(err) => err.into_compile_error(),
}
.into()
}
/// Marks a function as an eBPF Socket Lookup program that can be attached to
@ -623,16 +560,13 @@ pub fn fexit(attrs: TokenStream, item: TokenStream) -> TokenStream {
/// return 0
/// }
/// ```
#[proc_macro_error]
#[proc_macro_attribute]
pub fn sk_lookup(attrs: TokenStream, item: TokenStream) -> TokenStream {
match SkLookup::parse(attrs.into(), item.into()) {
Ok(prog) => prog
.expand()
.unwrap_or_else(|err| abort!(err.span(), "{}", err))
.into(),
Err(err) => abort!(err.span(), "{}", err),
Ok(prog) => prog.expand(),
Err(err) => err.emit_as_expr_tokens(),
}
.into()
}
/// Marks a function as a cgroup device eBPF program that can be attached to a
@ -656,14 +590,11 @@ pub fn sk_lookup(attrs: TokenStream, item: TokenStream) -> TokenStream {
/// return 0;
/// }
/// ```
#[proc_macro_error]
#[proc_macro_attribute]
pub fn cgroup_device(attrs: TokenStream, item: TokenStream) -> TokenStream {
match CgroupDevice::parse(attrs.into(), item.into()) {
Ok(prog) => prog
.expand()
.unwrap_or_else(|err| abort!(err.span(), "{}", err))
.into(),
Err(err) => abort!(err.span(), "{}", err),
Ok(prog) => prog.expand(),
Err(err) => err.emit_as_expr_tokens(),
}
.into()
}

@ -13,41 +13,50 @@ pub(crate) struct Lsm {
}
impl Lsm {
pub(crate) fn parse(attrs: TokenStream, item: TokenStream) -> Result<Lsm> {
pub(crate) fn parse(attrs: TokenStream, item: TokenStream) -> Result<Self> {
let item = syn::parse2(item)?;
let mut args = syn::parse2(attrs)?;
let hook = pop_string_arg(&mut args, "hook");
let sleepable = pop_bool_arg(&mut args, "sleepable");
err_on_unknown_args(&args)?;
Ok(Lsm {
Ok(Self {
item,
hook,
sleepable,
})
}
pub(crate) fn expand(&self) -> Result<TokenStream> {
let section_prefix = if self.sleepable { "lsm.s" } else { "lsm" };
let section_name: Cow<'_, _> = if let Some(hook) = &self.hook {
pub(crate) fn expand(&self) -> TokenStream {
let Self {
item,
hook,
sleepable,
} = self;
let ItemFn {
attrs: _,
vis,
sig,
block: _,
} = item;
let section_prefix = if *sleepable { "lsm.s" } else { "lsm" };
let section_name: Cow<'_, _> = if let Some(hook) = hook {
format!("{}/{}", section_prefix, hook).into()
} else {
section_prefix.into()
};
let fn_vis = &self.item.vis;
let fn_name = self.item.sig.ident.clone();
let item = &self.item;
// LSM probes need to return an integer corresponding to the correct
// policy decision. Therefore we do not simply default to a return value
// of 0 as in other program types.
Ok(quote! {
let fn_name = &sig.ident;
quote! {
#[no_mangle]
#[link_section = #section_name]
#fn_vis fn #fn_name(ctx: *mut ::core::ffi::c_void) -> i32 {
#vis fn #fn_name(ctx: *mut ::core::ffi::c_void) -> i32 {
return #fn_name(::aya_ebpf::programs::LsmContext::new(ctx));
#item
}
})
}
}
}
@ -71,7 +80,7 @@ mod tests {
},
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "lsm.s/bprm_committed_creds"]
@ -99,7 +108,7 @@ mod tests {
},
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "lsm/bprm_committed_creds"]

@ -15,18 +15,18 @@ impl Map {
let item: ItemStatic = syn::parse2(item)?;
let mut args = syn::parse2(attrs)?;
let name = name_arg(&mut args).unwrap_or_else(|| item.ident.to_string());
Ok(Map { item, name })
Ok(Self { item, name })
}
pub(crate) fn expand(&self) -> Result<TokenStream> {
let section_name: Cow<'_, _> = "maps".to_string().into();
pub(crate) fn expand(&self) -> TokenStream {
let section_name: Cow<'_, _> = "maps".into();
let name = &self.name;
let item = &self.item;
Ok(quote! {
quote! {
#[link_section = #section_name]
#[export_name = #name]
#item
})
}
}
}
@ -45,7 +45,7 @@ mod tests {
),
)
.unwrap();
let expanded = map.expand().unwrap();
let expanded = map.expand();
let expected = quote!(
#[link_section = "maps"]
#[export_name = "foo"]
@ -63,7 +63,7 @@ mod tests {
),
)
.unwrap();
let expanded = map.expand().unwrap();
let expanded = map.expand();
let expected = quote!(
#[link_section = "maps"]
#[export_name = "BAR"]

@ -1,35 +1,40 @@
use proc_macro2::TokenStream;
use proc_macro_error::abort;
use proc_macro2_diagnostics::{Diagnostic, SpanDiagnosticExt as _};
use quote::quote;
use syn::{ItemFn, Result};
use syn::{spanned::Spanned as _, ItemFn};
pub(crate) struct PerfEvent {
item: ItemFn,
}
impl PerfEvent {
pub(crate) fn parse(attrs: TokenStream, item: TokenStream) -> Result<Self> {
pub(crate) fn parse(attrs: TokenStream, item: TokenStream) -> Result<Self, Diagnostic> {
if !attrs.is_empty() {
abort!(attrs, "unexpected attribute")
return Err(attrs.span().error("unexpected attribute"));
}
let item = syn::parse2(item)?;
Ok(PerfEvent { item })
Ok(Self { item })
}
pub(crate) fn expand(&self) -> Result<TokenStream> {
let fn_vis = &self.item.vis;
let fn_name = self.item.sig.ident.clone();
let item = &self.item;
Ok(quote! {
pub(crate) fn expand(&self) -> TokenStream {
let Self { item } = self;
let ItemFn {
attrs: _,
vis,
sig,
block: _,
} = item;
let fn_name = &sig.ident;
quote! {
#[no_mangle]
#[link_section = "perf_event"]
#fn_vis fn #fn_name(ctx: *mut ::core::ffi::c_void) -> u32 {
#vis fn #fn_name(ctx: *mut ::core::ffi::c_void) -> u32 {
let _ = #fn_name(::aya_ebpf::programs::PerfEventContext::new(ctx));
return 0;
#item
}
})
}
}
}
@ -50,7 +55,7 @@ mod tests {
),
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "perf_event"]

@ -12,33 +12,38 @@ pub(crate) struct RawTracePoint {
}
impl RawTracePoint {
pub(crate) fn parse(attrs: TokenStream, item: TokenStream) -> Result<RawTracePoint> {
pub(crate) fn parse(attrs: TokenStream, item: TokenStream) -> Result<Self> {
let item = syn::parse2(item)?;
let mut args = syn::parse2(attrs)?;
let tracepoint = pop_string_arg(&mut args, "tracepoint");
err_on_unknown_args(&args)?;
Ok(RawTracePoint { item, tracepoint })
Ok(Self { item, tracepoint })
}
pub(crate) fn expand(&self) -> Result<TokenStream> {
let section_name: Cow<'_, _> = if let Some(tracepoint) = &self.tracepoint {
pub(crate) fn expand(&self) -> TokenStream {
let Self { item, tracepoint } = self;
let ItemFn {
attrs: _,
vis,
sig,
block: _,
} = item;
let section_name: Cow<'_, _> = if let Some(tracepoint) = tracepoint {
format!("raw_tp/{}", tracepoint).into()
} else {
"raw_tp".into()
};
let fn_vis = &self.item.vis;
let fn_name = self.item.sig.ident.clone();
let item = &self.item;
Ok(quote! {
let fn_name = &sig.ident;
quote! {
#[no_mangle]
#[link_section = #section_name]
#fn_vis fn #fn_name(ctx: *mut ::core::ffi::c_void) -> u32 {
#vis fn #fn_name(ctx: *mut ::core::ffi::c_void) -> u32 {
let _ = #fn_name(::aya_ebpf::programs::RawTracePointContext::new(ctx));
return 0;
#item
}
})
}
}
}
@ -59,7 +64,7 @@ mod tests {
},
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "raw_tp/sys_enter"]

@ -1,34 +1,39 @@
use proc_macro2::TokenStream;
use proc_macro_error::abort;
use proc_macro2_diagnostics::{Diagnostic, SpanDiagnosticExt as _};
use quote::quote;
use syn::{ItemFn, Result};
use syn::{spanned::Spanned as _, ItemFn};
pub(crate) struct SkLookup {
item: ItemFn,
}
impl SkLookup {
pub(crate) fn parse(attrs: TokenStream, item: TokenStream) -> Result<Self> {
pub(crate) fn parse(attrs: TokenStream, item: TokenStream) -> Result<Self, Diagnostic> {
if !attrs.is_empty() {
abort!(attrs, "unexpected attribute")
return Err(attrs.span().error("unexpected attribute"));
}
let item = syn::parse2(item)?;
Ok(SkLookup { item })
Ok(Self { item })
}
pub(crate) fn expand(&self) -> Result<TokenStream> {
let fn_name = self.item.sig.ident.clone();
let fn_vis = &self.item.vis;
let item = &self.item;
Ok(quote! {
pub(crate) fn expand(&self) -> TokenStream {
let Self { item } = self;
let ItemFn {
attrs: _,
vis,
sig,
block: _,
} = item;
let fn_name = &sig.ident;
quote! {
#[no_mangle]
#[link_section = "sk_lookup"]
#fn_vis fn #fn_name(ctx: *mut ::aya_ebpf::bindings::bpf_sk_lookup) -> u32 {
#vis fn #fn_name(ctx: *mut ::aya_ebpf::bindings::bpf_sk_lookup) -> u32 {
return #fn_name(::aya_ebpf::programs::SkLookupContext::new(ctx));
#item
}
})
}
}
}
@ -49,7 +54,7 @@ mod tests {
},
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "sk_lookup"]

@ -1,34 +1,39 @@
use proc_macro2::TokenStream;
use proc_macro_error::abort;
use proc_macro2_diagnostics::{Diagnostic, SpanDiagnosticExt as _};
use quote::quote;
use syn::{ItemFn, Result};
use syn::{spanned::Spanned as _, ItemFn};
pub(crate) struct SkMsg {
item: ItemFn,
}
impl SkMsg {
pub(crate) fn parse(attrs: TokenStream, item: TokenStream) -> Result<Self> {
pub(crate) fn parse(attrs: TokenStream, item: TokenStream) -> Result<Self, Diagnostic> {
if !attrs.is_empty() {
abort!(attrs, "unexpected attribute")
return Err(attrs.span().error("unexpected attribute"));
}
let item = syn::parse2(item)?;
Ok(SkMsg { item })
Ok(Self { item })
}
pub(crate) fn expand(&self) -> Result<TokenStream> {
let fn_vis = &self.item.vis;
let fn_name = self.item.sig.ident.clone();
let item = &self.item;
Ok(quote! {
pub(crate) fn expand(&self) -> TokenStream {
let Self { item } = self;
let ItemFn {
attrs: _,
vis,
sig,
block: _,
} = item;
let fn_name = &sig.ident;
quote! {
#[no_mangle]
#[link_section = "sk_msg"]
#fn_vis fn #fn_name(ctx: *mut ::aya_ebpf::bindings::sk_msg_md) -> u32 {
#vis fn #fn_name(ctx: *mut ::aya_ebpf::bindings::sk_msg_md) -> u32 {
return #fn_name(::aya_ebpf::programs::SkMsgContext::new(ctx));
#item
}
})
}
}
}
@ -49,7 +54,7 @@ mod tests {
},
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "sk_msg"]

@ -1,9 +1,9 @@
use std::borrow::Cow;
use proc_macro2::TokenStream;
use proc_macro_error::abort;
use proc_macro2_diagnostics::{Diagnostic, SpanDiagnosticExt as _};
use quote::quote;
use syn::{ItemFn, Result};
use syn::{spanned::Spanned as _, ItemFn};
#[allow(clippy::enum_variant_names)]
#[derive(Debug, Copy, Clone)]
@ -28,29 +28,37 @@ pub(crate) struct SkSkb {
}
impl SkSkb {
pub(crate) fn parse(kind: SkSkbKind, attrs: TokenStream, item: TokenStream) -> Result<SkSkb> {
pub(crate) fn parse(
kind: SkSkbKind,
attrs: TokenStream,
item: TokenStream,
) -> Result<Self, Diagnostic> {
if !attrs.is_empty() {
abort!(attrs, "unexpected attribute");
return Err(attrs.span().error("unexpected attribute"));
}
let item = syn::parse2(item)?;
Ok(SkSkb { item, kind })
Ok(Self { item, kind })
}
pub(crate) fn expand(&self) -> Result<TokenStream> {
let kind = &self.kind;
pub(crate) fn expand(&self) -> TokenStream {
let Self { kind, item } = self;
let ItemFn {
attrs: _,
vis,
sig,
block: _,
} = item;
let section_name: Cow<'_, _> = format!("sk_skb/{kind}").into();
let fn_name = self.item.sig.ident.clone();
let fn_vis = &self.item.vis;
let item = &self.item;
Ok(quote! {
let fn_name = &sig.ident;
quote! {
#[no_mangle]
#[link_section = #section_name]
#fn_vis fn #fn_name(ctx: *mut ::aya_ebpf::bindings::__sk_buff) -> u32 {
#vis fn #fn_name(ctx: *mut ::aya_ebpf::bindings::__sk_buff) -> u32 {
return #fn_name(::aya_ebpf::programs::SkBuffContext::new(ctx));
#item
}
})
}
}
}
@ -72,7 +80,7 @@ mod tests {
},
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "sk_skb/stream_parser"]
@ -99,7 +107,7 @@ mod tests {
},
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "sk_skb/stream_verdict"]

@ -1,34 +1,39 @@
use proc_macro2::TokenStream;
use proc_macro_error::abort;
use proc_macro2_diagnostics::{Diagnostic, SpanDiagnosticExt as _};
use quote::quote;
use syn::{ItemFn, Result};
use syn::{spanned::Spanned as _, ItemFn};
pub(crate) struct SockOps {
item: ItemFn,
}
impl SockOps {
pub(crate) fn parse(attrs: TokenStream, item: TokenStream) -> Result<Self> {
pub(crate) fn parse(attrs: TokenStream, item: TokenStream) -> Result<Self, Diagnostic> {
if !attrs.is_empty() {
abort!(attrs, "unexpected attribute")
return Err(attrs.span().error("unexpected attribute"));
}
let item = syn::parse2(item)?;
Ok(SockOps { item })
Ok(Self { item })
}
pub(crate) fn expand(&self) -> Result<TokenStream> {
let fn_vis = &self.item.vis;
let fn_name = self.item.sig.ident.clone();
let item = &self.item;
Ok(quote! {
pub(crate) fn expand(&self) -> TokenStream {
let Self { item } = self;
let ItemFn {
attrs: _,
vis,
sig,
block: _,
} = item;
let fn_name = &sig.ident;
quote! {
#[no_mangle]
#[link_section = "sockops"]
#fn_vis fn #fn_name(ctx: *mut ::aya_ebpf::bindings::bpf_sock_ops) -> u32 {
#vis fn #fn_name(ctx: *mut ::aya_ebpf::bindings::bpf_sock_ops) -> u32 {
return #fn_name(::aya_ebpf::programs::SockOpsContext::new(ctx));
#item
}
})
}
}
}
@ -49,7 +54,7 @@ mod tests {
},
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "sockops"]

@ -1,34 +1,39 @@
use proc_macro2::TokenStream;
use proc_macro_error::abort;
use proc_macro2_diagnostics::{Diagnostic, SpanDiagnosticExt as _};
use quote::quote;
use syn::{ItemFn, Result};
use syn::{spanned::Spanned as _, ItemFn};
pub(crate) struct SocketFilter {
item: ItemFn,
}
impl SocketFilter {
pub(crate) fn parse(attrs: TokenStream, item: TokenStream) -> Result<Self> {
pub(crate) fn parse(attrs: TokenStream, item: TokenStream) -> Result<Self, Diagnostic> {
if !attrs.is_empty() {
abort!(attrs, "unexpected attribute")
return Err(attrs.span().error("unexpected attribute"));
}
let item = syn::parse2(item)?;
Ok(SocketFilter { item })
Ok(Self { item })
}
pub(crate) fn expand(&self) -> Result<TokenStream> {
let fn_name = self.item.sig.ident.clone();
let fn_vis = &self.item.vis;
let item = &self.item;
Ok(quote! {
pub(crate) fn expand(&self) -> TokenStream {
let Self { item } = self;
let ItemFn {
attrs: _,
vis,
sig,
block: _,
} = item;
let fn_name = &sig.ident;
quote! {
#[no_mangle]
#[link_section = "socket"]
#fn_vis fn #fn_name(ctx: *mut ::aya_ebpf::bindings::__sk_buff) -> i64 {
#vis fn #fn_name(ctx: *mut ::aya_ebpf::bindings::__sk_buff) -> i64 {
return #fn_name(::aya_ebpf::programs::SkBuffContext::new(ctx));
#item
}
})
}
}
}
@ -49,7 +54,7 @@ mod tests {
},
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "socket"]

@ -1,34 +1,39 @@
use proc_macro2::TokenStream;
use proc_macro_error::abort;
use proc_macro2_diagnostics::{Diagnostic, SpanDiagnosticExt as _};
use quote::quote;
use syn::{ItemFn, Result};
use syn::{spanned::Spanned as _, ItemFn};
pub(crate) struct SchedClassifier {
item: ItemFn,
}
impl SchedClassifier {
pub(crate) fn parse(attrs: TokenStream, item: TokenStream) -> Result<Self> {
pub(crate) fn parse(attrs: TokenStream, item: TokenStream) -> Result<Self, Diagnostic> {
if !attrs.is_empty() {
abort!(attrs, "unexpected attribute")
return Err(attrs.span().error("unexpected attribute"));
}
let item = syn::parse2(item)?;
Ok(SchedClassifier { item })
Ok(Self { item })
}
pub(crate) fn expand(&self) -> Result<TokenStream> {
let fn_vis = &self.item.vis;
let fn_name = self.item.sig.ident.clone();
let item = &self.item;
Ok(quote! {
pub(crate) fn expand(&self) -> TokenStream {
let Self { item } = self;
let ItemFn {
attrs: _,
vis,
sig,
block: _,
} = item;
let fn_name = &sig.ident;
quote! {
#[no_mangle]
#[link_section = "classifier"]
#fn_vis fn #fn_name(ctx: *mut ::aya_ebpf::bindings::__sk_buff) -> i32 {
#vis fn #fn_name(ctx: *mut ::aya_ebpf::bindings::__sk_buff) -> i32 {
return #fn_name(::aya_ebpf::programs::TcContext::new(ctx));
#item
}
})
}
}
}
@ -49,7 +54,7 @@ mod tests {
},
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "classifier"]

@ -1,52 +1,64 @@
use std::borrow::Cow;
use proc_macro2::TokenStream;
use proc_macro_error::abort;
use proc_macro2_diagnostics::{Diagnostic, SpanDiagnosticExt as _};
use quote::quote;
use syn::{ItemFn, Result};
use syn::{spanned::Spanned as _, ItemFn};
use crate::args::{err_on_unknown_args, pop_string_arg};
pub(crate) struct TracePoint {
item: ItemFn,
category: Option<String>,
name: Option<String>,
name_and_category: Option<(String, String)>,
}
impl TracePoint {
pub(crate) fn parse(attrs: TokenStream, item: TokenStream) -> Result<TracePoint> {
pub(crate) fn parse(attrs: TokenStream, item: TokenStream) -> Result<Self, Diagnostic> {
let item = syn::parse2(item)?;
let span = attrs.span();
let mut args = syn::parse2(attrs)?;
let name = pop_string_arg(&mut args, "name");
let category = pop_string_arg(&mut args, "category");
err_on_unknown_args(&args)?;
Ok(TracePoint {
item,
category,
name,
})
match (name, category) {
(None, None) => Ok(Self {
item,
name_and_category: None,
}),
(Some(name), Some(category)) => Ok(Self {
item,
name_and_category: Some((name, category)),
}),
_ => Err(span.error("expected `name` and `category` arguments")),
}
}
pub(crate) fn expand(&self) -> Result<TokenStream> {
let section_name: Cow<'_, _> = match (&self.category, &self.name) {
(Some(category), Some(name)) => format!("tracepoint/{}/{}", category, name).into(),
(Some(_), None) => abort!(self.item, "expected `name` and `category` arguments"),
(None, Some(_)) => abort!(self.item, "expected `name` and `category` arguments"),
_ => "tracepoint".into(),
pub(crate) fn expand(&self) -> TokenStream {
let Self {
item,
name_and_category,
} = self;
let section_name: Cow<'_, _> = match name_and_category {
Some((name, category)) => format!("tracepoint/{category}/{name}").into(),
None => "tracepoint".into(),
};
let fn_vis = &self.item.vis;
let fn_name = self.item.sig.ident.clone();
let item = &self.item;
Ok(quote! {
let ItemFn {
attrs: _,
vis,
sig,
block: _,
} = item;
let fn_name = &sig.ident;
quote! {
#[no_mangle]
#[link_section = #section_name]
#fn_vis fn #fn_name(ctx: *mut ::core::ffi::c_void) -> u32 {
#vis fn #fn_name(ctx: *mut ::core::ffi::c_void) -> u32 {
let _ = #fn_name(::aya_ebpf::programs::TracePointContext::new(ctx));
return 0;
#item
}
})
}
}
}
@ -67,7 +79,7 @@ mod tests {
},
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "tracepoint/syscalls/sys_enter_bind"]

@ -1,9 +1,9 @@
use std::borrow::Cow;
use proc_macro2::TokenStream;
use proc_macro_error::abort;
use proc_macro2_diagnostics::{Diagnostic, SpanDiagnosticExt as _};
use quote::quote;
use syn::{ItemFn, Result};
use syn::{spanned::Spanned as _, ItemFn};
use crate::args::{err_on_unknown_args, pop_bool_arg, pop_string_arg};
@ -34,15 +34,24 @@ pub(crate) struct UProbe {
}
impl UProbe {
pub(crate) fn parse(kind: UProbeKind, attrs: TokenStream, item: TokenStream) -> Result<UProbe> {
pub(crate) fn parse(
kind: UProbeKind,
attrs: TokenStream,
item: TokenStream,
) -> Result<Self, Diagnostic> {
let item = syn::parse2(item)?;
let span = attrs.span();
let mut args = syn::parse2(attrs)?;
let path = pop_string_arg(&mut args, "path");
let function = pop_string_arg(&mut args, "function");
let offset = pop_string_arg(&mut args, "offset").map(|v| v.parse::<u64>().unwrap());
let offset = pop_string_arg(&mut args, "offset")
.as_deref()
.map(str::parse)
.transpose()
.map_err(|err| span.error(format!("failed to parse `offset` argument: {}", err)))?;
let sleepable = pop_bool_arg(&mut args, "sleepable");
err_on_unknown_args(&args)?;
Ok(UProbe {
Ok(Self {
kind,
item,
path,
@ -52,39 +61,38 @@ impl UProbe {
})
}
pub(crate) fn expand(&self) -> Result<TokenStream> {
let prefix = if self.sleepable {
format!("{}.s", self.kind)
} else {
format!("{}", self.kind)
};
let section_name: Cow<'_, _> = if self.path.is_some() && self.offset.is_some() {
if self.function.is_none() {
abort!(self.item.sig.ident, "expected `function` attribute");
}
let mut path = self.path.as_ref().unwrap().clone();
if path.starts_with('/') {
path.remove(0);
}
format!(
"{}/{}:{}+{}",
prefix,
path,
self.function.as_ref().unwrap(),
self.offset.unwrap()
)
.into()
} else if self.path.is_some() {
if self.function.is_none() {
abort!(self.item.sig.ident, "expected `function` attribute");
}
let mut path = self.path.as_ref().unwrap().clone();
if path.starts_with('/') {
path.remove(0);
pub(crate) fn expand(&self) -> Result<TokenStream, Diagnostic> {
let Self {
kind,
path,
function,
offset,
item,
sleepable,
} = self;
let ItemFn {
attrs: _,
vis,
sig,
block: _,
} = item;
let mut prefix = kind.to_string();
if *sleepable {
prefix.push_str(".s");
}
let section_name: Cow<'_, _> = match path {
None => prefix.into(),
Some(path) => {
let path = path.strip_prefix("/").unwrap_or(path);
// TODO: check this in parse instead.
let function = function
.as_deref()
.ok_or(item.sig.span().error("expected `function` attribute"))?;
match offset {
None => format!("{prefix}/{path}:{function}").into(),
Some(offset) => format!("{prefix}/{path}:{function}+{offset}",).into(),
}
}
format!("{}/{}:{}", prefix, path, self.function.as_ref().unwrap()).into()
} else {
prefix.to_string().into()
};
let probe_type = if section_name.as_ref().starts_with("uprobe") {
@ -92,13 +100,11 @@ impl UProbe {
} else {
quote! { RetProbeContext }
};
let fn_vis = &self.item.vis;
let fn_name = self.item.sig.ident.clone();
let item = &self.item;
let fn_name = &sig.ident;
Ok(quote! {
#[no_mangle]
#[link_section = #section_name]
#fn_vis fn #fn_name(ctx: *mut ::core::ffi::c_void) -> u32 {
#vis fn #fn_name(ctx: *mut ::core::ffi::c_void) -> u32 {
let _ = #fn_name(::aya_ebpf::programs::#probe_type::new(ctx));
return 0;

@ -1,6 +1,7 @@
use proc_macro2::TokenStream;
use proc_macro2_diagnostics::{Diagnostic, SpanDiagnosticExt as _};
use quote::quote;
use syn::{Error, ItemFn, Result};
use syn::{spanned::Spanned as _, ItemFn};
use crate::args::{err_on_unknown_args, pop_bool_arg, pop_string_arg, Args};
@ -17,8 +18,9 @@ pub(crate) enum XdpMap {
}
impl Xdp {
pub(crate) fn parse(attrs: TokenStream, item: TokenStream) -> Result<Xdp> {
pub(crate) fn parse(attrs: TokenStream, item: TokenStream) -> Result<Self, Diagnostic> {
let item = syn::parse2(item)?;
let span = attrs.span();
let mut args: Args = syn::parse2(attrs)?;
let frags = pop_bool_arg(&mut args, "frags");
@ -26,39 +28,42 @@ impl Xdp {
Some("cpumap") => Some(XdpMap::CpuMap),
Some("devmap") => Some(XdpMap::DevMap),
Some(name) => {
return Err(Error::new_spanned(
"map",
format!("Invalid value. Expected 'cpumap' or 'devmap', found '{name}'"),
))
return Err(span.error(format!(
"Invalid value. Expected 'cpumap' or 'devmap', found '{name}'"
)))
}
None => None,
};
err_on_unknown_args(&args)?;
Ok(Xdp { item, frags, map })
Ok(Self { item, frags, map })
}
pub(crate) fn expand(&self) -> Result<TokenStream> {
let mut section_name = vec![if self.frags { "xdp.frags" } else { "xdp" }];
match self.map {
pub(crate) fn expand(&self) -> TokenStream {
let Self { item, frags, map } = self;
let ItemFn {
attrs: _,
vis,
sig,
block: _,
} = item;
let mut section_name = vec![if *frags { "xdp.frags" } else { "xdp" }];
match map {
Some(XdpMap::CpuMap) => section_name.push("cpumap"),
Some(XdpMap::DevMap) => section_name.push("devmap"),
None => (),
};
let section_name = section_name.join("/");
let fn_vis = &self.item.vis;
let fn_name = self.item.sig.ident.clone();
let item = &self.item;
Ok(quote! {
let fn_name = &sig.ident;
quote! {
#[no_mangle]
#[link_section = #section_name]
#fn_vis fn #fn_name(ctx: *mut ::aya_ebpf::bindings::xdp_md) -> u32 {
#vis fn #fn_name(ctx: *mut ::aya_ebpf::bindings::xdp_md) -> u32 {
return #fn_name(::aya_ebpf::programs::XdpContext::new(ctx));
#item
}
})
}
}
}
@ -79,7 +84,7 @@ mod tests {
},
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "xdp"]
@ -105,7 +110,7 @@ mod tests {
},
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "xdp.frags"]
@ -131,7 +136,7 @@ mod tests {
},
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "xdp/cpumap"]
@ -157,7 +162,7 @@ mod tests {
},
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "xdp/devmap"]
@ -197,7 +202,7 @@ mod tests {
},
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "xdp.frags/cpumap"]
@ -223,7 +228,7 @@ mod tests {
},
)
.unwrap();
let expanded = prog.expand().unwrap();
let expanded = prog.expand();
let expected = quote! {
#[no_mangle]
#[link_section = "xdp.frags/devmap"]

Loading…
Cancel
Save