cgroup_sock_addr.rs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. use std::borrow::Cow;
  2. use proc_macro2::TokenStream;
  3. use proc_macro2_diagnostics::{Diagnostic, SpanDiagnosticExt as _};
  4. use quote::quote;
  5. use syn::{spanned::Spanned as _, Ident, ItemFn};
  6. pub(crate) struct CgroupSockAddr {
  7. item: ItemFn,
  8. attach_type: Ident,
  9. }
  10. impl CgroupSockAddr {
  11. pub(crate) fn parse(attrs: TokenStream, item: TokenStream) -> Result<Self, Diagnostic> {
  12. if attrs.is_empty() {
  13. return Err(attrs.span().error("missing attach type"));
  14. }
  15. let item = syn::parse2(item)?;
  16. let attach_type: Ident = syn::parse2(attrs)?;
  17. if attach_type != "connect4"
  18. && attach_type != "connect6"
  19. && attach_type != "bind4"
  20. && attach_type != "bind6"
  21. && attach_type != "getpeername4"
  22. && attach_type != "getpeername6"
  23. && attach_type != "getsockname4"
  24. && attach_type != "getsockname6"
  25. && attach_type != "sendmsg4"
  26. && attach_type != "sendmsg6"
  27. && attach_type != "recvmsg4"
  28. && attach_type != "recvmsg6"
  29. {
  30. return Err(attach_type.span().error("invalid attach type"));
  31. }
  32. Ok(Self { item, attach_type })
  33. }
  34. pub(crate) fn expand(&self) -> TokenStream {
  35. let Self { item, attach_type } = self;
  36. let ItemFn {
  37. attrs: _,
  38. vis,
  39. sig,
  40. block: _,
  41. } = item;
  42. let section_name: Cow<'_, _> = format!("cgroup/{attach_type}").into();
  43. let fn_name = &sig.ident;
  44. quote! {
  45. #[no_mangle]
  46. #[link_section = #section_name]
  47. #vis fn #fn_name(ctx: *mut ::aya_ebpf::bindings::bpf_sock_addr) -> i32 {
  48. return #fn_name(::aya_ebpf::programs::SockAddrContext::new(ctx));
  49. #item
  50. }
  51. }
  52. }
  53. }
  54. #[cfg(test)]
  55. mod tests {
  56. use syn::parse_quote;
  57. use super::*;
  58. #[test]
  59. fn cgroup_sock_addr_connect4() {
  60. let prog = CgroupSockAddr::parse(
  61. parse_quote!(connect4),
  62. parse_quote!(
  63. fn foo(ctx: CgroupSockAddrContext) -> i32 {
  64. 0
  65. }
  66. ),
  67. )
  68. .unwrap();
  69. let expanded = prog.expand();
  70. let expected = quote! {
  71. #[no_mangle]
  72. #[link_section = "cgroup/connect4"]
  73. fn foo(ctx: *mut ::aya_ebpf::bindings::bpf_sock_addr) -> i32 {
  74. return foo(::aya_ebpf::programs::SockAddrContext::new(ctx));
  75. fn foo(ctx: CgroupSockAddrContext) -> i32 {
  76. 0
  77. }
  78. }
  79. };
  80. assert_eq!(expected.to_string(), expanded.to_string());
  81. }
  82. #[test]
  83. fn cgroup_sock_addr_connect6() {
  84. let prog = CgroupSockAddr::parse(
  85. parse_quote!(connect6),
  86. parse_quote!(
  87. fn foo(ctx: CgroupSockAddrContext) -> i32 {
  88. 0
  89. }
  90. ),
  91. )
  92. .unwrap();
  93. let expanded = prog.expand();
  94. let expected = quote! {
  95. #[no_mangle]
  96. #[link_section = "cgroup/connect6"]
  97. fn foo(ctx: *mut ::aya_ebpf::bindings::bpf_sock_addr) -> i32 {
  98. return foo(::aya_ebpf::programs::SockAddrContext::new(ctx));
  99. fn foo(ctx: CgroupSockAddrContext) -> i32 {
  100. 0
  101. }
  102. }
  103. };
  104. assert_eq!(expected.to_string(), expanded.to_string());
  105. }
  106. #[test]
  107. fn cgroup_sock_addr_bind4() {
  108. let prog = CgroupSockAddr::parse(
  109. parse_quote!(bind4),
  110. parse_quote!(
  111. fn foo(ctx: CgroupSockAddrContext) -> i32 {
  112. 0
  113. }
  114. ),
  115. )
  116. .unwrap();
  117. let expanded = prog.expand();
  118. let expected = quote! {
  119. #[no_mangle]
  120. #[link_section = "cgroup/bind4"]
  121. fn foo(ctx: *mut ::aya_ebpf::bindings::bpf_sock_addr) -> i32 {
  122. return foo(::aya_ebpf::programs::SockAddrContext::new(ctx));
  123. fn foo(ctx: CgroupSockAddrContext) -> i32 {
  124. 0
  125. }
  126. }
  127. };
  128. assert_eq!(expected.to_string(), expanded.to_string());
  129. }
  130. #[test]
  131. fn cgroup_sock_addr_bind6() {
  132. let prog = CgroupSockAddr::parse(
  133. parse_quote!(bind6),
  134. parse_quote!(
  135. fn foo(ctx: CgroupSockAddrContext) -> i32 {
  136. 0
  137. }
  138. ),
  139. )
  140. .unwrap();
  141. let expanded = prog.expand();
  142. let expected = quote! {
  143. #[no_mangle]
  144. #[link_section = "cgroup/bind6"]
  145. fn foo(ctx: *mut ::aya_ebpf::bindings::bpf_sock_addr) -> i32 {
  146. return foo(::aya_ebpf::programs::SockAddrContext::new(ctx));
  147. fn foo(ctx: CgroupSockAddrContext) -> i32 {
  148. 0
  149. }
  150. }
  151. };
  152. assert_eq!(expected.to_string(), expanded.to_string());
  153. }
  154. #[test]
  155. fn cgroup_sock_addr_getpeername4() {
  156. let prog = CgroupSockAddr::parse(
  157. parse_quote!(getpeername4),
  158. parse_quote!(
  159. fn foo(ctx: CgroupSockAddrContext) -> i32 {
  160. 0
  161. }
  162. ),
  163. )
  164. .unwrap();
  165. let expanded = prog.expand();
  166. let expected = quote! {
  167. #[no_mangle]
  168. #[link_section = "cgroup/getpeername4"]
  169. fn foo(ctx: *mut ::aya_ebpf::bindings::bpf_sock_addr) -> i32 {
  170. return foo(::aya_ebpf::programs::SockAddrContext::new(ctx));
  171. fn foo(ctx: CgroupSockAddrContext) -> i32 {
  172. 0
  173. }
  174. }
  175. };
  176. assert_eq!(expected.to_string(), expanded.to_string());
  177. }
  178. #[test]
  179. fn cgroup_sock_addr_getpeername6() {
  180. let prog = CgroupSockAddr::parse(
  181. parse_quote!(getpeername6),
  182. parse_quote!(
  183. fn foo(ctx: CgroupSockAddrContext) -> i32 {
  184. 0
  185. }
  186. ),
  187. )
  188. .unwrap();
  189. let expanded = prog.expand();
  190. let expected = quote! {
  191. #[no_mangle]
  192. #[link_section = "cgroup/getpeername6"]
  193. fn foo(ctx: *mut ::aya_ebpf::bindings::bpf_sock_addr) -> i32 {
  194. return foo(::aya_ebpf::programs::SockAddrContext::new(ctx));
  195. fn foo(ctx: CgroupSockAddrContext) -> i32 {
  196. 0
  197. }
  198. }
  199. };
  200. assert_eq!(expected.to_string(), expanded.to_string());
  201. }
  202. #[test]
  203. fn cgroup_sock_addr_getsockname4() {
  204. let prog = CgroupSockAddr::parse(
  205. parse_quote!(getsockname4),
  206. parse_quote!(
  207. fn foo(ctx: CgroupSockAddrContext) -> i32 {
  208. 0
  209. }
  210. ),
  211. )
  212. .unwrap();
  213. let expanded = prog.expand();
  214. let expected = quote! {
  215. #[no_mangle]
  216. #[link_section = "cgroup/getsockname4"]
  217. fn foo(ctx: *mut ::aya_ebpf::bindings::bpf_sock_addr) -> i32 {
  218. return foo(::aya_ebpf::programs::SockAddrContext::new(ctx));
  219. fn foo(ctx: CgroupSockAddrContext) -> i32 {
  220. 0
  221. }
  222. }
  223. };
  224. assert_eq!(expected.to_string(), expanded.to_string());
  225. }
  226. #[test]
  227. fn cgroup_sock_addr_getsockname6() {
  228. let prog = CgroupSockAddr::parse(
  229. parse_quote!(getsockname6),
  230. parse_quote!(
  231. fn foo(ctx: CgroupSockAddrContext) -> i32 {
  232. 0
  233. }
  234. ),
  235. )
  236. .unwrap();
  237. let expanded = prog.expand();
  238. let expected = quote! {
  239. #[no_mangle]
  240. #[link_section = "cgroup/getsockname6"]
  241. fn foo(ctx: *mut ::aya_ebpf::bindings::bpf_sock_addr) -> i32 {
  242. return foo(::aya_ebpf::programs::SockAddrContext::new(ctx));
  243. fn foo(ctx: CgroupSockAddrContext) -> i32 {
  244. 0
  245. }
  246. }
  247. };
  248. assert_eq!(expected.to_string(), expanded.to_string());
  249. }
  250. #[test]
  251. fn cgroup_sock_addr_sendmsg4() {
  252. let prog = CgroupSockAddr::parse(
  253. parse_quote!(sendmsg4),
  254. parse_quote!(
  255. fn foo(ctx: CgroupSockAddrContext) -> i32 {
  256. 0
  257. }
  258. ),
  259. )
  260. .unwrap();
  261. let expanded = prog.expand();
  262. let expected = quote! {
  263. #[no_mangle]
  264. #[link_section = "cgroup/sendmsg4"]
  265. fn foo(ctx: *mut ::aya_ebpf::bindings::bpf_sock_addr) -> i32 {
  266. return foo(::aya_ebpf::programs::SockAddrContext::new(ctx));
  267. fn foo(ctx: CgroupSockAddrContext) -> i32 {
  268. 0
  269. }
  270. }
  271. };
  272. assert_eq!(expected.to_string(), expanded.to_string());
  273. }
  274. #[test]
  275. fn cgroup_sock_addr_sendmsg6() {
  276. let prog = CgroupSockAddr::parse(
  277. parse_quote!(sendmsg6),
  278. parse_quote!(
  279. fn foo(ctx: CgroupSockAddrContext) -> i32 {
  280. 0
  281. }
  282. ),
  283. )
  284. .unwrap();
  285. let expanded = prog.expand();
  286. let expected = quote! {
  287. #[no_mangle]
  288. #[link_section = "cgroup/sendmsg6"]
  289. fn foo(ctx: *mut ::aya_ebpf::bindings::bpf_sock_addr) -> i32 {
  290. return foo(::aya_ebpf::programs::SockAddrContext::new(ctx));
  291. fn foo(ctx: CgroupSockAddrContext) -> i32 {
  292. 0
  293. }
  294. }
  295. };
  296. assert_eq!(expected.to_string(), expanded.to_string());
  297. }
  298. #[test]
  299. fn cgroup_sock_addr_recvmsg4() {
  300. let prog = CgroupSockAddr::parse(
  301. parse_quote!(recvmsg4),
  302. parse_quote!(
  303. fn foo(ctx: CgroupSockAddrContext) -> i32 {
  304. 0
  305. }
  306. ),
  307. )
  308. .unwrap();
  309. let expanded = prog.expand();
  310. let expected = quote! {
  311. #[no_mangle]
  312. #[link_section = "cgroup/recvmsg4"]
  313. fn foo(ctx: *mut ::aya_ebpf::bindings::bpf_sock_addr) -> i32 {
  314. return foo(::aya_ebpf::programs::SockAddrContext::new(ctx));
  315. fn foo(ctx: CgroupSockAddrContext) -> i32 {
  316. 0
  317. }
  318. }
  319. };
  320. assert_eq!(expected.to_string(), expanded.to_string());
  321. }
  322. #[test]
  323. fn cgroup_sock_addr_recvmsg6() {
  324. let prog = CgroupSockAddr::parse(
  325. parse_quote!(recvmsg6),
  326. parse_quote!(
  327. fn foo(ctx: CgroupSockAddrContext) -> i32 {
  328. 0
  329. }
  330. ),
  331. )
  332. .unwrap();
  333. let expanded = prog.expand();
  334. let expected = quote! {
  335. #[no_mangle]
  336. #[link_section = "cgroup/recvmsg6"]
  337. fn foo(ctx: *mut ::aya_ebpf::bindings::bpf_sock_addr) -> i32 {
  338. return foo(::aya_ebpf::programs::SockAddrContext::new(ctx));
  339. fn foo(ctx: CgroupSockAddrContext) -> i32 {
  340. 0
  341. }
  342. }
  343. };
  344. assert_eq!(expected.to_string(), expanded.to_string());
  345. }
  346. }