socket_filter.rs 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. use proc_macro2::TokenStream;
  2. use proc_macro2_diagnostics::{Diagnostic, SpanDiagnosticExt as _};
  3. use quote::quote;
  4. use syn::{ItemFn, spanned::Spanned as _};
  5. pub(crate) struct SocketFilter {
  6. item: ItemFn,
  7. }
  8. impl SocketFilter {
  9. pub(crate) fn parse(attrs: TokenStream, item: TokenStream) -> Result<Self, Diagnostic> {
  10. if !attrs.is_empty() {
  11. return Err(attrs.span().error("unexpected attribute"));
  12. }
  13. let item = syn::parse2(item)?;
  14. Ok(Self { item })
  15. }
  16. pub(crate) fn expand(&self) -> TokenStream {
  17. let Self { item } = self;
  18. let ItemFn {
  19. attrs: _,
  20. vis,
  21. sig,
  22. block: _,
  23. } = item;
  24. let fn_name = &sig.ident;
  25. quote! {
  26. #[unsafe(no_mangle)]
  27. #[unsafe(link_section = "socket")]
  28. #vis fn #fn_name(ctx: *mut ::aya_ebpf::bindings::__sk_buff) -> i64 {
  29. return #fn_name(::aya_ebpf::programs::SkBuffContext::new(ctx));
  30. #item
  31. }
  32. }
  33. }
  34. }
  35. #[cfg(test)]
  36. mod tests {
  37. use syn::parse_quote;
  38. use super::*;
  39. #[test]
  40. fn test_socket_filter() {
  41. let prog = SocketFilter::parse(
  42. parse_quote! {},
  43. parse_quote! {
  44. fn prog(ctx: &mut ::aya_ebpf::programs::SkBuffContext) -> i64 {
  45. 0
  46. }
  47. },
  48. )
  49. .unwrap();
  50. let expanded = prog.expand();
  51. let expected = quote! {
  52. #[unsafe(no_mangle)]
  53. #[unsafe(link_section = "socket")]
  54. fn prog(ctx: *mut ::aya_ebpf::bindings::__sk_buff) -> i64 {
  55. return prog(::aya_ebpf::programs::SkBuffContext::new(ctx));
  56. fn prog(ctx: &mut ::aya_ebpf::programs::SkBuffContext) -> i64 {
  57. 0
  58. }
  59. }
  60. };
  61. assert_eq!(expected.to_string(), expanded.to_string());
  62. }
  63. }