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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
use crate::{
error::{Error, LibbpfError},
libbpf::{BpfMapDef, BpfUpdateElemFlags, XdpAction},
utils::*,
};
use libbpf_sys as libbpf;
use std::{
mem,
option::Option,
os::raw::{c_int, c_void},
};
#[inline(always)]
pub fn bpf_map_lookup_elem<'a, 'b, T, U>(
map: &'a BpfMapDef<T, U>,
key: &'b T,
) -> Option<&'a mut U> {
type FPtrType = extern "C" fn(m: *const c_void, k: *const c_void) -> *mut c_void;
unsafe {
let f: FPtrType = mem::transmute(libbpf::BPF_FUNC_map_lookup_elem as usize);
let value = f(to_const_c_void(&map.map_def), to_const_c_void(key));
if value.is_null() {
None
} else {
Some(&mut *(value as *mut U))
}
}
}
#[inline(always)]
#[named]
pub fn bpf_map_update_elem<'a, 'b, T, U>(
map: &'a mut BpfMapDef<T, U>,
key: &'b T,
value: &'a U,
flags: BpfUpdateElemFlags,
) -> Result<(), Error> {
type FPtrType =
extern "C" fn(m: *mut c_void, k: *const c_void, v: *const c_void, f: u64) -> c_int;
let r = unsafe {
let f: FPtrType = mem::transmute(libbpf::BPF_FUNC_map_update_elem as usize);
f(
to_mut_c_void(&mut map.map_def),
to_const_c_void(key),
to_const_c_void(value),
flags.bits() as u64,
)
};
if r < 0 {
return map_libbpf_error(function_name!(), LibbpfError::LibbpfSys(r));
}
Ok(())
}
#[inline(always)]
pub fn bpf_redirect_map<'a, 'b, U>(
map: &'a BpfMapDef<u32, U>,
key: &'b u32,
default_action: XdpAction,
) -> XdpAction {
let flags: u32 = default_action as u32;
if flags > XdpAction::TX as u32 {
panic!("The default action must be one of ABORTED, DROP, PASS or TX");
}
type FPtrType = extern "C" fn(m: *const c_void, k: *const c_void, f: u64) -> c_int;
unsafe {
let f: FPtrType = mem::transmute(libbpf::BPF_FUNC_redirect_map as usize);
let r = f(
to_const_c_void(&map.map_def),
to_const_c_void(key),
flags as u64,
);
mem::transmute::<i32, XdpAction>(r)
}
}