@ -1,22 +1,25 @@
use core ::{ mem, ptr ::NonNull } ;
use core ::{ cell::UnsafeCell , mem, ptr ::NonNull } ;
use aya_bpf_bindings ::bindings ::bpf_devmap_val ;
use aya_bpf_cty ::c_void ;
use aya_bpf_cty ::c_void ;
use crate ::{
use crate ::{
bindings ::{ bpf_map_def , bpf_map_type ::BPF_MAP_TYPE_DEVMAP_HASH } ,
bindings ::{ bpf_map_def , bpf_map_type ::BPF_MAP_TYPE_DEVMAP_HASH } ,
helpers ::bpf_map_lookup_elem ,
helpers ::{ bpf_map_lookup_elem , bpf_redirect_map } ,
maps ::PinningType ,
maps ::PinningType ,
} ;
} ;
#[ repr(transparent) ]
#[ repr(transparent) ]
pub struct DevMapHash {
pub struct DevMapHash {
def : bpf_map_def,
def : UnsafeCell< bpf_map_def> ,
}
}
unsafe impl Sync for DevMapHash { }
impl DevMapHash {
impl DevMapHash {
pub const fn with_max_entries ( max_entries : u32 , flags : u32 ) -> DevMapHash {
pub const fn with_max_entries ( max_entries : u32 , flags : u32 ) -> DevMapHash {
DevMapHash {
DevMapHash {
def : bpf_map_def {
def : UnsafeCell::new ( bpf_map_def {
type_ : BPF_MAP_TYPE_DEVMAP_HASH ,
type_ : BPF_MAP_TYPE_DEVMAP_HASH ,
key_size : mem ::size_of ::< u32 > ( ) as u32 ,
key_size : mem ::size_of ::< u32 > ( ) as u32 ,
value_size : mem ::size_of ::< u32 > ( ) as u32 ,
value_size : mem ::size_of ::< u32 > ( ) as u32 ,
@ -24,32 +27,40 @@ impl DevMapHash {
map_flags : flags ,
map_flags : flags ,
id : 0 ,
id : 0 ,
pinning : PinningType ::None as u32 ,
pinning : PinningType ::None as u32 ,
} ,
} ) ,
}
}
}
}
pub const fn pinned ( max_entries : u32 , flags : u32 ) -> DevMapHash {
pub const fn pinned ( max_entries : u32 , flags : u32 ) -> DevMapHash {
DevMapHash {
DevMapHash {
def : bpf_map_def {
def : UnsafeCell::new ( bpf_map_def {
type_ : BPF_MAP_TYPE_DEVMAP_HASH ,
type_ : BPF_MAP_TYPE_DEVMAP_HASH ,
key_size : mem ::size_of ::< u32 > ( ) as u32 ,
key_size : mem ::size_of ::< u32 > ( ) as u32 ,
value_size : mem ::size_of ::< u32 > ( ) as u32 ,
value_size : mem ::size_of ::< u32 > ( ) as u32 ,
max_entries ,
max_entries ,
map_flags : flags ,
map_flags : flags ,
id : 0 ,
id : 0 ,
pinning : PinningType ::Non e as u32 ,
pinning : PinningType ::ByNam e as u32 ,
} ,
} ) ,
}
}
}
}
pub fn get ( & mut self , index : u32 ) -> Option < & u32 > {
#[ inline(always) ]
unsafe {
pub unsafe fn get ( & self , index : u32 ) -> Option < & bpf_devmap_val > {
let value = bpf_map_lookup_elem (
let value = bpf_map_lookup_elem (
& mut self . def as * mut _ as * mut _ ,
self . def . get ( ) as * mut _ ,
& index as * const _ as * const c_void ,
& index as * const _ as * const c_void ,
) ;
) ;
// FIXME: alignment
NonNull ::new ( value as * mut bpf_devmap_val ) . map ( | p | p . as_ref ( ) )
NonNull ::new ( value as * mut u32 ) . map ( | p | p . as_ref ( ) )
}
#[ inline(always) ]
pub fn redirect ( & self , index : u32 , flags : u64 ) -> u32 {
unsafe {
// Return XDP_REDIRECT on success, or the value of the two lower bits of the flags
// argument on error. Thus I have no idea why it returns a long (i64) instead of
// something saner, hence the unsigned_abs.
bpf_redirect_map ( self . def . get ( ) as * mut _ , index . into ( ) , flags ) . unsigned_abs ( ) as u32
}
}
}
}
}
}