lib.rs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. //! [![](https://aya-rs.dev/assets/images/aya_logo_docs.svg)](https://aya-rs.dev)
  2. //!
  3. //! A library to write eBPF programs.
  4. //!
  5. //! Aya-bpf is an eBPF library built with a focus on operability and developer experience.
  6. //! It is the kernel-space counterpart of [Aya](https://docs.rs/aya)
  7. #![doc(
  8. html_logo_url = "https://aya-rs.dev/assets/images/crabby.svg",
  9. html_favicon_url = "https://aya-rs.dev/assets/images/crabby.svg"
  10. )]
  11. #![cfg_attr(
  12. feature = "const_assert",
  13. allow(incomplete_features),
  14. feature(generic_const_exprs)
  15. )]
  16. #![cfg_attr(unstable, feature(never_type))]
  17. #![cfg_attr(target_arch = "bpf", feature(asm_experimental_arch))]
  18. #![allow(clippy::missing_safety_doc)]
  19. #![deny(warnings)]
  20. #![warn(clippy::cast_lossless, clippy::cast_sign_loss)]
  21. #![no_std]
  22. pub use aya_ebpf_bindings::bindings;
  23. mod args;
  24. pub use args::PtRegs;
  25. pub mod helpers;
  26. pub mod maps;
  27. pub mod programs;
  28. use core::ffi::c_void;
  29. pub use aya_ebpf_cty as cty;
  30. pub use aya_ebpf_macros as macros;
  31. use cty::{c_int, c_long};
  32. use helpers::{bpf_get_current_comm, bpf_get_current_pid_tgid, bpf_get_current_uid_gid};
  33. pub const TASK_COMM_LEN: usize = 16;
  34. pub trait EbpfContext {
  35. fn as_ptr(&self) -> *mut c_void;
  36. #[inline]
  37. fn command(&self) -> Result<[u8; TASK_COMM_LEN], c_long> {
  38. bpf_get_current_comm()
  39. }
  40. fn pid(&self) -> u32 {
  41. bpf_get_current_pid_tgid() as u32
  42. }
  43. fn tgid(&self) -> u32 {
  44. (bpf_get_current_pid_tgid() >> 32) as u32
  45. }
  46. fn uid(&self) -> u32 {
  47. bpf_get_current_uid_gid() as u32
  48. }
  49. fn gid(&self) -> u32 {
  50. (bpf_get_current_uid_gid() >> 32) as u32
  51. }
  52. }
  53. #[no_mangle]
  54. pub unsafe extern "C" fn memset(s: *mut u8, c: c_int, n: usize) {
  55. #[allow(clippy::cast_sign_loss)]
  56. let b = c as u8;
  57. for i in 0..n {
  58. *s.add(i) = b;
  59. }
  60. }
  61. #[no_mangle]
  62. pub unsafe extern "C" fn memcpy(dest: *mut u8, src: *mut u8, n: usize) {
  63. copy_forward(dest, src, n);
  64. }
  65. #[no_mangle]
  66. pub unsafe extern "C" fn memmove(dest: *mut u8, src: *mut u8, n: usize) {
  67. let delta = (dest as usize).wrapping_sub(src as usize);
  68. if delta >= n {
  69. // We can copy forwards because either dest is far enough ahead of src,
  70. // or src is ahead of dest (and delta overflowed).
  71. copy_forward(dest, src, n);
  72. } else {
  73. copy_backward(dest, src, n);
  74. }
  75. }
  76. #[inline(always)]
  77. unsafe fn copy_forward(dest: *mut u8, src: *mut u8, n: usize) {
  78. for i in 0..n {
  79. *dest.add(i) = *src.add(i);
  80. }
  81. }
  82. #[inline(always)]
  83. unsafe fn copy_backward(dest: *mut u8, src: *mut u8, n: usize) {
  84. for i in (0..n).rev() {
  85. *dest.add(i) = *src.add(i);
  86. }
  87. }
  88. /// Check if a value is within a range, using conditional forms compatible with
  89. /// the verifier.
  90. #[inline(always)]
  91. pub fn check_bounds_signed(value: i64, lower: i64, upper: i64) -> bool {
  92. #[cfg(target_arch = "bpf")]
  93. unsafe {
  94. let mut in_bounds = 0u64;
  95. core::arch::asm!(
  96. "if {value} s< {lower} goto +2",
  97. "if {value} s> {upper} goto +1",
  98. "{i} = 1",
  99. i = inout(reg) in_bounds,
  100. lower = in(reg) lower,
  101. upper = in(reg) upper,
  102. value = in(reg) value,
  103. );
  104. in_bounds == 1
  105. }
  106. // We only need this for doc tests which are compiled for the host target
  107. #[cfg(not(target_arch = "bpf"))]
  108. {
  109. let _ = value;
  110. let _ = lower;
  111. let _ = upper;
  112. unimplemented!()
  113. }
  114. }