cgroup_device.rs 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. use proc_macro2::TokenStream;
  2. use proc_macro_error::abort;
  3. use quote::quote;
  4. use syn::{ItemFn, Result};
  5. pub(crate) struct CgroupDevice {
  6. item: ItemFn,
  7. }
  8. impl CgroupDevice {
  9. pub(crate) fn parse(attrs: TokenStream, item: TokenStream) -> Result<Self> {
  10. if !attrs.is_empty() {
  11. abort!(attrs, "unexpected attribute")
  12. }
  13. let item = syn::parse2(item)?;
  14. Ok(CgroupDevice { item })
  15. }
  16. pub(crate) fn expand(&self) -> Result<TokenStream> {
  17. let fn_vis = &self.item.vis;
  18. let fn_name = self.item.sig.ident.clone();
  19. let item = &self.item;
  20. Ok(quote! {
  21. #[no_mangle]
  22. #[link_section = "cgroup/dev"]
  23. #fn_vis fn #fn_name(ctx: *mut ::aya_ebpf::bindings::bpf_cgroup_dev_ctx) -> i32 {
  24. return #fn_name(::aya_ebpf::programs::DeviceContext::new(ctx));
  25. #item
  26. }
  27. })
  28. }
  29. }
  30. #[cfg(test)]
  31. mod tests {
  32. use syn::parse_quote;
  33. use super::*;
  34. #[test]
  35. fn test_cgroup_device() {
  36. let prog = CgroupDevice::parse(
  37. parse_quote!(),
  38. parse_quote!(
  39. fn foo(ctx: DeviceContext) -> i32 {
  40. 0
  41. }
  42. ),
  43. )
  44. .unwrap();
  45. let expanded = prog.expand().unwrap();
  46. let expected = quote! {
  47. #[no_mangle]
  48. #[link_section = "cgroup/dev"]
  49. fn foo(ctx: *mut ::aya_ebpf::bindings::bpf_cgroup_dev_ctx) -> i32 {
  50. return foo(::aya_ebpf::programs::DeviceContext::new(ctx));
  51. fn foo(ctx: DeviceContext) -> i32 {
  52. 0
  53. }
  54. }
  55. };
  56. assert_eq!(expected.to_string(), expanded.to_string());
  57. }
  58. }