1pub mod attachments;
13pub mod context;
14pub mod fs;
15pub mod map;
16pub mod program;
17pub mod syscalls;
18
19use crate::bpf::attachments::EbpfAttachments;
20use crate::bpf::map::{BpfMapHandle, BpfMapId, WeakBpfMapHandle};
21use crate::bpf::program::{ProgramHandle, ProgramId, WeakProgramHandle};
22use starnix_sync::{EbpfStateLock, LockDepMutex};
23use starnix_uapi::{bpf_map_type, bpf_map_type_BPF_MAP_TYPE_SK_STORAGE};
24use std::collections::BTreeMap;
25use std::ops::Bound;
26use std::sync::Arc;
27use zerocopy::IntoBytes as _;
28
29struct WeakMapWithType {
30 map_type: bpf_map_type,
31 weak_map: WeakBpfMapHandle,
32}
33
34impl WeakMapWithType {
35 fn new(map: &BpfMapHandle) -> Self {
36 Self { map_type: map.schema.map_type, weak_map: Arc::downgrade(map) }
37 }
38}
39
40#[derive(Default)]
42pub struct EbpfState {
43 pub attachments: EbpfAttachments,
44
45 programs: LockDepMutex<BTreeMap<ProgramId, WeakProgramHandle>, EbpfStateLock>,
46 maps: LockDepMutex<BTreeMap<BpfMapId, WeakMapWithType>, EbpfStateLock>,
47}
48
49impl EbpfState {
50 fn register_program(&self, program: &ProgramHandle) {
51 self.programs.lock().insert(program.id(), Arc::downgrade(program));
52 }
53
54 fn unregister_program(&self, id: ProgramId) {
55 self.programs.lock().remove(&id).expect("Missing eBPF program");
56 }
57
58 fn get_next_program_id(&self, start_id: ProgramId) -> Option<ProgramId> {
59 self.programs
60 .lock()
61 .range((Bound::Excluded(start_id), Bound::Unbounded))
62 .next()
63 .map(|(k, _)| *k)
64 }
65
66 fn get_program_by_id(&self, id: ProgramId) -> Option<ProgramHandle> {
67 self.programs.lock().get(&id).map(|p| p.upgrade()).flatten()
68 }
69
70 fn register_map(&self, map: &BpfMapHandle) {
71 self.maps.lock().insert(map.id(), WeakMapWithType::new(map));
72 }
73
74 fn unregister_map(&self, id: BpfMapId) {
75 self.maps.lock().remove(&id).expect("Missing eBPF map");
76 }
77
78 fn get_next_map_id(&self, start_id: BpfMapId) -> Option<BpfMapId> {
79 self.maps
80 .lock()
81 .range((Bound::Excluded(start_id), Bound::Unbounded))
82 .next()
83 .map(|(k, _)| *k)
84 }
85
86 fn get_map_by_id(&self, id: BpfMapId) -> Option<BpfMapHandle> {
87 self.maps.lock().get(&id).map(|entry| entry.weak_map.upgrade()).flatten()
88 }
89
90 pub fn remove_sk_storage_entries(&self, cookie: u64) {
93 self.maps.lock().iter().for_each(|(_, entry)| {
94 if entry.map_type == bpf_map_type_BPF_MAP_TYPE_SK_STORAGE
95 && let Some(map) = entry.weak_map.upgrade()
96 {
97 let _ = map.delete(cookie.as_bytes());
98 }
99 });
100 }
101}