bpf.rs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. use std::{
  2. cell::{Ref, RefCell, RefMut},
  3. collections::HashMap,
  4. };
  5. use thiserror::Error;
  6. use crate::{
  7. generated::bpf_insn,
  8. maps::{Map, MapError},
  9. obj::{relocate, Object, ParseError, RelocationError},
  10. programs::{KProbe, Program, ProgramData, ProgramError, SocketFilter, TracePoint, UProbe, Xdp},
  11. syscalls::bpf_map_update_elem_ptr,
  12. };
  13. unsafe impl object::Pod for bpf_insn {}
  14. pub(crate) const BPF_OBJ_NAME_LEN: usize = 16;
  15. /* FIXME: these are arch dependent */
  16. pub(crate) const PERF_EVENT_IOC_ENABLE: libc::c_ulong = 9216;
  17. pub(crate) const PERF_EVENT_IOC_DISABLE: libc::c_ulong = 9217;
  18. pub(crate) const PERF_EVENT_IOC_SET_BPF: libc::c_ulong = 1074013192;
  19. pub unsafe trait Pod: Copy + 'static {}
  20. macro_rules! unsafe_impl_pod {
  21. ($($struct_name:ident),+ $(,)?) => {
  22. $(
  23. unsafe impl Pod for $struct_name { }
  24. )+
  25. }
  26. }
  27. unsafe_impl_pod!(i8, u8, i16, u16, i32, u32, i64, u64);
  28. #[repr(C)]
  29. #[derive(Copy, Clone, Debug)]
  30. pub(crate) struct bpf_map_def {
  31. pub(crate) map_type: u32,
  32. pub(crate) key_size: u32,
  33. pub(crate) value_size: u32,
  34. pub(crate) max_entries: u32,
  35. pub(crate) map_flags: u32,
  36. }
  37. unsafe impl object::Pod for bpf_map_def {}
  38. #[derive(Debug)]
  39. pub struct Bpf {
  40. maps: HashMap<String, RefCell<Map>>,
  41. programs: HashMap<String, Program>,
  42. }
  43. impl Bpf {
  44. pub fn load(data: &[u8]) -> Result<Bpf, BpfError> {
  45. let mut obj = Object::parse(data)?;
  46. let mut maps = Vec::new();
  47. for (_, obj) in obj.maps.drain() {
  48. let mut map = Map { obj, fd: None };
  49. let fd = map.create()?;
  50. if !map.obj.data.is_empty() && map.obj.name != ".bss" {
  51. bpf_map_update_elem_ptr(fd, &0 as *const _, map.obj.data.as_ptr(), 0)
  52. .map_err(|(code, io_error)| MapError::UpdateElementFailed { code, io_error })?;
  53. }
  54. maps.push(map);
  55. }
  56. relocate(&mut obj, maps.as_slice())?;
  57. let programs = obj
  58. .programs
  59. .drain()
  60. .map(|(name, obj)| {
  61. let kind = obj.kind;
  62. let data = ProgramData {
  63. obj,
  64. name: name.clone(),
  65. fd: None,
  66. links: Vec::new(),
  67. };
  68. let program = match kind {
  69. crate::obj::ProgramKind::KProbe => Program::KProbe(KProbe { data }),
  70. crate::obj::ProgramKind::UProbe => Program::UProbe(UProbe { data }),
  71. crate::obj::ProgramKind::TracePoint => Program::TracePoint(TracePoint { data }),
  72. crate::obj::ProgramKind::Xdp => Program::Xdp(Xdp { data }),
  73. };
  74. (name, program)
  75. })
  76. .collect();
  77. Ok(Bpf {
  78. maps: maps
  79. .drain(..)
  80. .map(|map| (map.obj.name.clone(), RefCell::new(map)))
  81. .collect(),
  82. programs,
  83. })
  84. }
  85. pub fn map(&self, name: &str) -> Option<Ref<'_, Map>> {
  86. self.maps.get(name).map(|cell| cell.borrow())
  87. }
  88. pub fn map_mut(&self, name: &str) -> Option<RefMut<'_, Map>> {
  89. self.maps.get(name).map(|cell| cell.borrow_mut())
  90. }
  91. pub fn program(&self, name: &str) -> Option<&Program> {
  92. self.programs.get(name)
  93. }
  94. pub fn program_mut(&mut self, name: &str) -> Option<&mut Program> {
  95. self.programs.get_mut(name)
  96. }
  97. pub fn kprobe(&self, name: &str) -> Option<&KProbe> {
  98. match self.programs.get(name) {
  99. Some(Program::KProbe(kprobe)) => Some(kprobe),
  100. _ => None,
  101. }
  102. }
  103. pub fn kprobe_mut(&mut self, name: &str) -> Option<&mut KProbe> {
  104. match self.programs.get_mut(name) {
  105. Some(Program::KProbe(kprobe)) => Some(kprobe),
  106. _ => None,
  107. }
  108. }
  109. pub fn uprobe(&self, name: &str) -> Option<&UProbe> {
  110. match self.programs.get(name) {
  111. Some(Program::UProbe(uprobe)) => Some(uprobe),
  112. _ => None,
  113. }
  114. }
  115. pub fn uprobe_mut(&mut self, name: &str) -> Option<&mut UProbe> {
  116. match self.programs.get_mut(name) {
  117. Some(Program::UProbe(uprobe)) => Some(uprobe),
  118. _ => None,
  119. }
  120. }
  121. pub fn trace_point(&self, name: &str) -> Option<&TracePoint> {
  122. match self.programs.get(name) {
  123. Some(Program::TracePoint(trace_point)) => Some(trace_point),
  124. _ => None,
  125. }
  126. }
  127. pub fn trace_point_mut(&mut self, name: &str) -> Option<&mut TracePoint> {
  128. match self.programs.get_mut(name) {
  129. Some(Program::TracePoint(trace_point)) => Some(trace_point),
  130. _ => None,
  131. }
  132. }
  133. pub fn socket_filter(&self, name: &str) -> Option<&SocketFilter> {
  134. match self.programs.get(name) {
  135. Some(Program::SocketFilter(socket_filter)) => Some(socket_filter),
  136. _ => None,
  137. }
  138. }
  139. pub fn socket_filter_mut(&mut self, name: &str) -> Option<&mut SocketFilter> {
  140. match self.programs.get_mut(name) {
  141. Some(Program::SocketFilter(socket_filter)) => Some(socket_filter),
  142. _ => None,
  143. }
  144. }
  145. pub fn xdp(&self, name: &str) -> Option<&Xdp> {
  146. match self.programs.get(name) {
  147. Some(Program::Xdp(xdp)) => Some(xdp),
  148. _ => None,
  149. }
  150. }
  151. pub fn xdp_mut(&mut self, name: &str) -> Option<&mut Xdp> {
  152. match self.programs.get_mut(name) {
  153. Some(Program::Xdp(xdp)) => Some(xdp),
  154. _ => None,
  155. }
  156. }
  157. }
  158. #[derive(Debug, Error)]
  159. pub enum BpfError {
  160. #[error("error parsing BPF object: {0}")]
  161. ParseError(#[from] ParseError),
  162. #[error("error relocating BPF object: {0}")]
  163. RelocationError(#[from] RelocationError),
  164. #[error("map error: {0}")]
  165. MapError(#[from] MapError),
  166. #[error("program error: {0}")]
  167. ProgramError(#[from] ProgramError),
  168. }