xdp.rs 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. use std::borrow::Cow;
  2. use proc_macro2::TokenStream;
  3. use proc_macro_error::abort;
  4. use quote::quote;
  5. use syn::{Ident, ItemFn, Result};
  6. pub(crate) struct Xdp {
  7. item: ItemFn,
  8. frags: bool,
  9. }
  10. impl Xdp {
  11. pub(crate) fn parse(attrs: TokenStream, item: TokenStream) -> Result<Xdp> {
  12. let mut frags = false;
  13. let item = syn::parse2(item)?;
  14. if !attrs.is_empty() {
  15. let ident: Ident = syn::parse2(attrs)?;
  16. if ident != "frags" {
  17. abort!(ident, "unexpected attribute");
  18. }
  19. frags = true;
  20. }
  21. Ok(Xdp { item, frags })
  22. }
  23. pub(crate) fn expand(&self) -> Result<TokenStream> {
  24. let section_name: Cow<'_, _> = if self.frags {
  25. "xdp.frags".into()
  26. } else {
  27. "xdp".into()
  28. };
  29. let fn_vis = &self.item.vis;
  30. let fn_name = self.item.sig.ident.clone();
  31. let item = &self.item;
  32. Ok(quote! {
  33. #[no_mangle]
  34. #[link_section = #section_name]
  35. #fn_vis fn #fn_name(ctx: *mut ::aya_bpf::bindings::xdp_md) -> u32 {
  36. return #fn_name(::aya_bpf::programs::XdpContext::new(ctx));
  37. #item
  38. }
  39. })
  40. }
  41. }
  42. #[cfg(test)]
  43. mod tests {
  44. use super::*;
  45. use syn::parse_quote;
  46. #[test]
  47. fn test_xdp() {
  48. let prog = Xdp::parse(
  49. parse_quote! {},
  50. parse_quote! {
  51. fn prog(ctx: &mut ::aya_bpf::programs::XdpContext) -> i32 {
  52. 0
  53. }
  54. },
  55. )
  56. .unwrap();
  57. let expanded = prog.expand().unwrap();
  58. let expected = quote! {
  59. #[no_mangle]
  60. #[link_section = "xdp"]
  61. fn prog(ctx: *mut ::aya_bpf::bindings::xdp_md) -> u32 {
  62. return prog(::aya_bpf::programs::XdpContext::new(ctx));
  63. fn prog(ctx: &mut ::aya_bpf::programs::XdpContext) -> i32 {
  64. 0
  65. }
  66. }
  67. };
  68. assert_eq!(expected.to_string(), expanded.to_string());
  69. }
  70. #[test]
  71. fn test_xdp_frags() {
  72. let prog = Xdp::parse(
  73. parse_quote! { frags },
  74. parse_quote! {
  75. fn prog(ctx: &mut ::aya_bpf::programs::XdpContext) -> i32 {
  76. 0
  77. }
  78. },
  79. )
  80. .unwrap();
  81. let expanded = prog.expand().unwrap();
  82. let expected = quote! {
  83. #[no_mangle]
  84. #[link_section = "xdp.frags"]
  85. fn prog(ctx: *mut ::aya_bpf::bindings::xdp_md) -> u32 {
  86. return prog(::aya_bpf::programs::XdpContext::new(ctx));
  87. fn prog(ctx: &mut ::aya_bpf::programs::XdpContext) -> i32 {
  88. 0
  89. }
  90. }
  91. };
  92. assert_eq!(expected.to_string(), expanded.to_string());
  93. }
  94. }