1use aya::{
2 Ebpf, Pod,
3 maps::{Array, Map, MapData},
4 programs::Xdp,
5};
6
7use crate::{Loader, error::Error};
8
9pub struct EbpfVar<T: Pod> {
10 value: T,
11 map: Array<MapData, T>,
12 name: String,
13}
14
15impl<T: Pod> EbpfVar<T> {
16 pub fn update(&mut self, value: T) -> Result<(), Error> {
18 self.value = value;
19 self.map
20 .set(0, value, 0)
21 .map_err(|e| Error::map(&self.name, e))
22 }
23 pub fn get(&self) -> &T {
25 &self.value
26 }
27 pub fn new(ebpf: &mut Ebpf, name: &str, value: T) -> Result<Self, Error> {
29 let mut map = array_owned(ebpf, name)?;
30 map.set(0, value, 0).map_err(|e| Error::map(name, e))?;
31 Ok(Self {
32 value,
33 map,
34 name: name.into(),
35 })
36 }
37}
38
39impl<T: Pod> Loader for (T, &str) {
40 type Component = EbpfVar<T>;
41 fn load(self, ebpf: &mut Ebpf) -> Result<Self::Component, Error> {
42 EbpfVar::new(ebpf, self.1, self.0)
43 }
44}
45
46pub(crate) fn map_owned<T>(ebpf: &mut Ebpf, name: &str) -> Result<T, Error>
47where
48 T: TryFrom<Map, Error = aya::maps::MapError>,
49{
50 let map = ebpf
51 .take_map(name)
52 .ok_or_else(|| Error::MissingMap(name.into()))?;
53 T::try_from(map).map_err(|e| Error::map(name, e))
54}
55
56pub(crate) fn array_owned<T: Pod>(ebpf: &mut Ebpf, name: &str) -> Result<Array<MapData, T>, Error> {
57 map_owned(ebpf, name)
58}
59
60pub(crate) fn xdp_program<'a>(ebpf: &'a mut Ebpf, name: &str) -> Result<&'a mut Xdp, Error> {
62 ebpf.program_mut(name)
63 .ok_or_else(|| Error::MissingProgram(name.into()))?
64 .try_into()
65 .map_err(|e| Error::InvalidProgramType {
66 program_name: name.into(),
67 e,
68 })
69}
70
71pub(crate) fn load_xdp_program<'a>(ebpf: &'a mut Ebpf, name: &str) -> Result<&'a mut Xdp, Error> {
73 let program = xdp_program(ebpf, name)?;
74 program.load().map_err(|e| Error::load_program(name, e))?;
75 Ok(program)
76}