lib.rs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. mod expand;
  2. use expand::{
  3. Args, BtfTracePoint, CgroupSkb, Lsm, Map, PerfEvent, Probe, ProbeKind, RawTracePoint,
  4. SchedClassifier, SkMsg, SkSkb, SkSkbKind, SockOps, SocketFilter, TracePoint, Xdp,
  5. };
  6. use proc_macro::TokenStream;
  7. use syn::{parse_macro_input, ItemFn, ItemStatic};
  8. #[proc_macro_attribute]
  9. pub fn map(attrs: TokenStream, item: TokenStream) -> TokenStream {
  10. let args = parse_macro_input!(attrs as Args);
  11. let item = parse_macro_input!(item as ItemStatic);
  12. Map::from_syn(args, item)
  13. .and_then(|u| u.expand())
  14. .unwrap_or_else(|err| err.to_compile_error())
  15. .into()
  16. }
  17. #[proc_macro_attribute]
  18. pub fn kprobe(attrs: TokenStream, item: TokenStream) -> TokenStream {
  19. probe(ProbeKind::KProbe, attrs, item)
  20. }
  21. #[proc_macro_attribute]
  22. pub fn kretprobe(attrs: TokenStream, item: TokenStream) -> TokenStream {
  23. probe(ProbeKind::KRetProbe, attrs, item)
  24. }
  25. #[proc_macro_attribute]
  26. pub fn uprobe(attrs: TokenStream, item: TokenStream) -> TokenStream {
  27. probe(ProbeKind::UProbe, attrs, item)
  28. }
  29. #[proc_macro_attribute]
  30. pub fn uretprobe(attrs: TokenStream, item: TokenStream) -> TokenStream {
  31. probe(ProbeKind::URetProbe, attrs, item)
  32. }
  33. #[proc_macro_attribute]
  34. pub fn sock_ops(attrs: TokenStream, item: TokenStream) -> TokenStream {
  35. let args = parse_macro_input!(attrs as Args);
  36. let item = parse_macro_input!(item as ItemFn);
  37. SockOps::from_syn(args, item)
  38. .and_then(|u| u.expand())
  39. .unwrap_or_else(|err| err.to_compile_error())
  40. .into()
  41. }
  42. #[proc_macro_attribute]
  43. pub fn sk_msg(attrs: TokenStream, item: TokenStream) -> TokenStream {
  44. let args = parse_macro_input!(attrs as Args);
  45. let item = parse_macro_input!(item as ItemFn);
  46. SkMsg::from_syn(args, item)
  47. .and_then(|u| u.expand())
  48. .unwrap_or_else(|err| err.to_compile_error())
  49. .into()
  50. }
  51. #[proc_macro_attribute]
  52. pub fn xdp(attrs: TokenStream, item: TokenStream) -> TokenStream {
  53. let args = parse_macro_input!(attrs as Args);
  54. let item = parse_macro_input!(item as ItemFn);
  55. Xdp::from_syn(args, item)
  56. .and_then(|u| u.expand())
  57. .unwrap_or_else(|err| err.to_compile_error())
  58. .into()
  59. }
  60. #[proc_macro_attribute]
  61. pub fn classifier(attrs: TokenStream, item: TokenStream) -> TokenStream {
  62. let args = parse_macro_input!(attrs as Args);
  63. let item = parse_macro_input!(item as ItemFn);
  64. SchedClassifier::from_syn(args, item)
  65. .and_then(|u| u.expand())
  66. .unwrap_or_else(|err| err.to_compile_error())
  67. .into()
  68. }
  69. #[proc_macro_attribute]
  70. pub fn cgroup_skb(attrs: TokenStream, item: TokenStream) -> TokenStream {
  71. let args = parse_macro_input!(attrs as Args);
  72. let item = parse_macro_input!(item as ItemFn);
  73. CgroupSkb::from_syn(args, item)
  74. .and_then(|u| u.expand())
  75. .unwrap_or_else(|err| err.to_compile_error())
  76. .into()
  77. }
  78. fn probe(kind: ProbeKind, attrs: TokenStream, item: TokenStream) -> TokenStream {
  79. let args = parse_macro_input!(attrs as Args);
  80. let item = parse_macro_input!(item as ItemFn);
  81. Probe::from_syn(kind, args, item)
  82. .and_then(|u| u.expand())
  83. .unwrap_or_else(|err| err.to_compile_error())
  84. .into()
  85. }
  86. #[proc_macro_attribute]
  87. pub fn tracepoint(attrs: TokenStream, item: TokenStream) -> TokenStream {
  88. let args = parse_macro_input!(attrs as Args);
  89. let item = parse_macro_input!(item as ItemFn);
  90. TracePoint::from_syn(args, item)
  91. .and_then(|u| u.expand())
  92. .unwrap_or_else(|err| err.to_compile_error())
  93. .into()
  94. }
  95. #[proc_macro_attribute]
  96. pub fn perf_event(attrs: TokenStream, item: TokenStream) -> TokenStream {
  97. let args = parse_macro_input!(attrs as Args);
  98. let item = parse_macro_input!(item as ItemFn);
  99. PerfEvent::from_syn(args, item)
  100. .and_then(|u| u.expand())
  101. .unwrap_or_else(|err| err.to_compile_error())
  102. .into()
  103. }
  104. /// Marks a function as a raw tracepoint eBPF program that can be attached at a
  105. /// pre-defined kernel trace point.
  106. ///
  107. /// The kernel provides a set of pre-defined trace points that eBPF programs can
  108. /// be attached to. See `/sys/kernel/debug/tracing/events` for a list of which
  109. /// events can be traced.
  110. ///
  111. /// # Minimum kernel version
  112. ///
  113. /// The minimum kernel version required to use this feature is 4.7.
  114. ///
  115. /// # Examples
  116. ///
  117. /// ```no_run
  118. /// use aya_bpf::{macros::raw_tracepoint, programs::RawTracePointContext};
  119. ///
  120. /// #[raw_tracepoint(name = "sys_enter")]
  121. /// pub fn sys_enter(ctx: RawTracePointContext) -> i32 {
  122. /// match unsafe { try_sys_enter(ctx) } {
  123. /// Ok(ret) => ret,
  124. /// Err(ret) => ret,
  125. /// }
  126. /// }
  127. ///
  128. /// unsafe fn try_sys_enter(_ctx: RawTracePointContext) -> Result<i32, i32> {
  129. /// Ok(0)
  130. /// }
  131. /// ```
  132. #[proc_macro_attribute]
  133. pub fn raw_tracepoint(attrs: TokenStream, item: TokenStream) -> TokenStream {
  134. let args = parse_macro_input!(attrs as Args);
  135. let item = parse_macro_input!(item as ItemFn);
  136. RawTracePoint::from_syn(args, item)
  137. .and_then(|u| u.expand())
  138. .unwrap_or_else(|err| err.to_compile_error())
  139. .into()
  140. }
  141. /// Marks a function as an LSM program that can be attached to Linux LSM hooks.
  142. /// Used to implement security policy and audit logging.
  143. ///
  144. /// LSM probes can be attached to the kernel's [security hooks][1] to implement mandatory
  145. /// access control policy and security auditing.
  146. ///
  147. /// LSM probes require a kernel compiled with `CONFIG_BPF_LSM=y` and `CONFIG_DEBUG_INFO_BTF=y`.
  148. /// In order for the probes to fire, you also need the BPF LSM to be enabled through your
  149. /// kernel's boot paramters (like `lsm=lockdown,yama,bpf`).
  150. ///
  151. /// # Minimum kernel version
  152. ///
  153. /// The minimum kernel version required to use this feature is 5.7.
  154. ///
  155. /// # Examples
  156. ///
  157. /// ```no_run
  158. /// use aya_bpf::{macros::lsm, programs::LsmContext};
  159. ///
  160. /// #[lsm(name = "file_open")]
  161. /// pub fn file_open(ctx: LsmContext) -> i32 {
  162. /// match unsafe { try_file_open(ctx) } {
  163. /// Ok(ret) => ret,
  164. /// Err(ret) => ret,
  165. /// }
  166. /// }
  167. ///
  168. /// unsafe fn try_file_open(_ctx: LsmContext) -> Result<i32, i32> {
  169. /// Ok(0)
  170. /// }
  171. /// ```
  172. #[proc_macro_attribute]
  173. pub fn lsm(attrs: TokenStream, item: TokenStream) -> TokenStream {
  174. let args = parse_macro_input!(attrs as Args);
  175. let item = parse_macro_input!(item as ItemFn);
  176. Lsm::from_syn(args, item)
  177. .and_then(|u| u.expand())
  178. .unwrap_or_else(|err| err.to_compile_error())
  179. .into()
  180. }
  181. /// Marks a function as a [BTF-enabled raw tracepoint][1] eBPF program that can be attached at
  182. /// a pre-defined kernel trace point.
  183. ///
  184. /// The kernel provides a set of pre-defined trace points that eBPF programs can
  185. /// be attached to. See `/sys/kernel/debug/tracing/events` for a list of which
  186. /// events can be traced.
  187. ///
  188. /// # Minimum kernel version
  189. ///
  190. /// The minimum kernel version required to use this feature is 5.5.
  191. ///
  192. /// # Examples
  193. ///
  194. /// ```no_run
  195. /// use aya_bpf::{macros::btf_tracepoint, programs::BtfTracePointContext};
  196. ///
  197. /// #[btf_tracepoint(name = "sched_process_fork")]
  198. /// pub fn sched_process_fork(ctx: BtfTracePointContext) -> u32 {
  199. /// match unsafe { try_sched_process_fork(ctx) } {
  200. /// Ok(ret) => ret,
  201. /// Err(ret) => ret,
  202. /// }
  203. /// }
  204. ///
  205. /// unsafe fn try_sched_process_fork(_ctx: BtfTracePointContext) -> Result<u32, u32> {
  206. /// Ok(0)
  207. /// }
  208. /// ```
  209. ///
  210. /// [1]: https://github.com/torvalds/linux/commit/9e15db66136a14cde3f35691f1d839d950118826
  211. #[proc_macro_attribute]
  212. pub fn btf_tracepoint(attrs: TokenStream, item: TokenStream) -> TokenStream {
  213. let args = parse_macro_input!(attrs as Args);
  214. let item = parse_macro_input!(item as ItemFn);
  215. BtfTracePoint::from_syn(args, item)
  216. .and_then(|u| u.expand())
  217. .unwrap_or_else(|err| err.to_compile_error())
  218. .into()
  219. }
  220. /// Marks a function as a SK_SKB Stream Parser eBPF program that can be attached
  221. /// to a SockMap
  222. ///
  223. /// # Minimum kernel version
  224. ///
  225. /// The minimum kernel version required to use this feature is 4.14
  226. ///
  227. /// # Examples
  228. ///
  229. /// ```no_run
  230. /// use aya_bpf::{macros::stream_parser, programs::SkSkbContext};
  231. ///
  232. ///
  233. ///#[stream_parser]
  234. ///fn stream_parser(ctx: SkSkbContext) -> u32 {
  235. /// match { try_stream_parser(ctx) } {
  236. /// Ok(ret) => ret,
  237. /// Err(ret) => ret,
  238. /// }
  239. ///}
  240. ///
  241. ///fn try_stream_parser(ctx: SkSkbContext) -> Result<u32, u32> {
  242. /// Ok(ctx.len())
  243. ///}
  244. /// ```
  245. #[proc_macro_attribute]
  246. pub fn stream_parser(attrs: TokenStream, item: TokenStream) -> TokenStream {
  247. sk_skb(SkSkbKind::StreamParser, attrs, item)
  248. }
  249. /// Marks a function as a SK_SKB Stream Verdict eBPF program that can be attached
  250. /// to a SockMap
  251. ///
  252. /// # Minimum kernel version
  253. ///
  254. /// The minimum kernel version required to use this feature is 4.14
  255. ///
  256. /// # Examples
  257. ///
  258. /// ```no_run
  259. /// use aya_bpf::{macros::stream_verdict, programs::SkSkbContext, bindings::sk_action};
  260. ///
  261. ///
  262. ///#[stream_verdict]
  263. ///fn stream_verdict(ctx: SkSkbContext) -> u32 {
  264. /// match { try_stream_verdict(ctx) } {
  265. /// Ok(ret) => ret,
  266. /// Err(ret) => ret,
  267. /// }
  268. ///}
  269. ///
  270. ///fn try_stream_verdict(_ctx: SkSkbContext) -> Result<u32, u32> {
  271. /// Ok(sk_action::SK_PASS)
  272. ///}
  273. /// ```
  274. #[proc_macro_attribute]
  275. pub fn stream_verdict(attrs: TokenStream, item: TokenStream) -> TokenStream {
  276. sk_skb(SkSkbKind::StreamVerdict, attrs, item)
  277. }
  278. fn sk_skb(kind: SkSkbKind, attrs: TokenStream, item: TokenStream) -> TokenStream {
  279. let args = parse_macro_input!(attrs as Args);
  280. let item = parse_macro_input!(item as ItemFn);
  281. SkSkb::from_syn(kind, args, item)
  282. .and_then(|u| u.expand())
  283. .unwrap_or_else(|err| err.to_compile_error())
  284. .into()
  285. }
  286. /// Marks a function as a eBPF Socket Filter program that can be attached to
  287. /// a socket.
  288. ///
  289. /// # Minimum kernel version
  290. ///
  291. /// The minimum kernel version required to use this feature is 3.19
  292. ///
  293. /// # Examples
  294. ///
  295. /// ```no_run
  296. /// use aya_bpf::{macros::socket_filter, programs::SkSkbContext};
  297. ///
  298. /// #[socket_filter(name = "accept_all")]
  299. /// pub fn accept_all(_ctx: SkSkbContext) -> i64 {
  300. /// return 0
  301. /// }
  302. /// ```
  303. #[proc_macro_attribute]
  304. pub fn socket_filter(attrs: TokenStream, item: TokenStream) -> TokenStream {
  305. let args = parse_macro_input!(attrs as Args);
  306. let item = parse_macro_input!(item as ItemFn);
  307. SocketFilter::from_syn(args, item)
  308. .and_then(|u| u.expand())
  309. .unwrap_or_else(|err| err.to_compile_error())
  310. .into()
  311. }