1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
use super::{skeleton::MapRef, kind};

pub struct ArrayPerCpuRef<const V: usize>(MapRef);

impl<const V: usize> kind::AppItem for ArrayPerCpuRef<V> {
    const MAP: usize = 1;
    const PROG: usize = 0;

    fn named(name: &'static str) -> Self {
        ArrayPerCpuRef(MapRef::named(name))
    }

    fn kind_mut(&mut self) -> kind::AppItemKindMut<'_> {
        kind::AppItemKindMut::Map(&mut self.0)
    }
}

pub struct HashMapRef<const K: usize, const V: usize>(MapRef);

impl<const K: usize, const V: usize> kind::AppItem for HashMapRef<K, V> {
    const MAP: usize = 1;
    const PROG: usize = 0;

    fn named(name: &'static str) -> Self {
        HashMapRef(MapRef::named(name))
    }

    fn kind_mut(&mut self) -> kind::AppItemKindMut<'_> {
        kind::AppItemKindMut::Map(&mut self.0)
    }
}

impl<const K: usize, const V: usize> HashMapRef<K, V> {
    pub fn insert(&mut self, key: [u8; K], value: [u8; V]) -> Result<(), i32> {
        let c = unsafe {
            libbpf_sys::bpf_map_update_elem(self.0.fd(), key.as_ptr() as _, value.as_ptr() as _, 0)
        };
        if c >= 0 {
            Ok(())
        } else {
            Err(c as _)
        }
    }

    pub fn get(&self, key: &[u8; K]) -> Option<[u8; V]> {
        let mut value = [0; V];
        let c = unsafe {
            libbpf_sys::bpf_map_lookup_elem(self.0.fd(), key.as_ptr() as _, value.as_mut_ptr() as _)
        };
        if c >= 0 {
            Some(value)
        } else {
            None
        }
    }

    pub fn remove(&self, key: &[u8; K]) -> Result<(), i32> {
        let c = unsafe {
            libbpf_sys::bpf_map_delete_elem(self.0.fd(), key.as_ptr() as _)
        };
        if c >= 0 {
            Ok(())
        } else {
            Err(c)
        }
    }
}