@ -12,6 +12,7 @@ use crate::{
maps ::{ check_kv_size , hash_map , IterableMap , MapData , MapError , MapIter , MapKeys } ,
maps ::{ check_kv_size , hash_map , IterableMap , MapData , MapError , MapIter , MapKeys } ,
programs ::ProgramFd ,
programs ::ProgramFd ,
sys ::{ bpf_map_lookup_elem , SyscallError } ,
sys ::{ bpf_map_lookup_elem , SyscallError } ,
FEATURES ,
} ;
} ;
use super ::dev_map ::DevMapValue ;
use super ::dev_map ::DevMapValue ;
@ -45,7 +46,12 @@ pub struct DevMapHash<T> {
impl < T : Borrow < MapData > > DevMapHash < T > {
impl < T : Borrow < MapData > > DevMapHash < T > {
pub ( crate ) fn new ( map : T ) -> Result < Self , MapError > {
pub ( crate ) fn new ( map : T ) -> Result < Self , MapError > {
let data = map . borrow ( ) ;
let data = map . borrow ( ) ;
check_kv_size ::< u32 , bpf_devmap_val > ( data ) ? ;
if FEATURES . devmap_hash_prog_id ( ) {
check_kv_size ::< u32 , bpf_devmap_val > ( data ) ? ;
} else {
check_kv_size ::< u32 , u32 > ( data ) ? ;
}
Ok ( Self { inner : map } )
Ok ( Self { inner : map } )
}
}
@ -57,18 +63,30 @@ impl<T: Borrow<MapData>> DevMapHash<T> {
/// Returns [`MapError::SyscallError`] if `bpf_map_lookup_elem` fails.
/// Returns [`MapError::SyscallError`] if `bpf_map_lookup_elem` fails.
pub fn get ( & self , key : u32 , flags : u64 ) -> Result < DevMapValue , MapError > {
pub fn get ( & self , key : u32 , flags : u64 ) -> Result < DevMapValue , MapError > {
let fd = self . inner . borrow ( ) . fd ( ) . as_fd ( ) ;
let fd = self . inner . borrow ( ) . fd ( ) . as_fd ( ) ;
let value = bpf_map_lookup_elem ( fd , & key , flags ) . map_err ( | ( _ , io_error ) | SyscallError {
call : "bpf_map_lookup_elem" ,
let value = if FEATURES . devmap_hash_prog_id ( ) {
io_error ,
bpf_map_lookup_elem ::< _ , bpf_devmap_val > ( fd , & key , flags ) . map ( | value | {
} ) ? ;
value . map ( | value | DevMapValue {
let value : bpf_devmap_val = value . ok_or ( MapError ::KeyNotFound ) ? ;
ifindex : value . ifindex ,
// SAFETY: map writes use fd, map reads use id.
// SAFETY: map writes use fd, map reads use id.
// https://github.com/torvalds/linux/blob/2dde18cd1d8fac735875f2e4987f11817cc0bc2c/include/uapi/linux/bpf.h#L6228
// https://github.com/torvalds/linux/blob/2dde18cd1d8fac735875f2e4987f11817cc0bc2c/include/uapi/linux/bpf.h#L6228
prog_id : NonZeroU32 ::new ( unsafe { value . bpf_prog . id } ) ,
Ok ( DevMapValue {
} )
ifindex : value . ifindex ,
} )
prog_id : NonZeroU32 ::new ( unsafe { value . bpf_prog . id } ) ,
} else {
} )
bpf_map_lookup_elem ::< _ , u32 > ( fd , & key , flags ) . map ( | value | {
value . map ( | ifindex | DevMapValue {
ifindex ,
prog_id : None ,
} )
} )
} ;
value
. map_err ( | ( _ , io_error ) | SyscallError {
call : "bpf_map_lookup_elem" ,
io_error ,
} ) ?
. ok_or ( MapError ::KeyNotFound )
}
}
/// An iterator over the elements of the devmap in arbitrary order.
/// An iterator over the elements of the devmap in arbitrary order.
@ -96,7 +114,9 @@ impl<T: BorrowMut<MapData>> DevMapHash<T> {
///
///
/// # Errors
/// # Errors
///
///
/// Returns [`MapError::SyscallError`] if `bpf_map_update_elem` fails.
/// Returns [`MapError::SyscallError`] if `bpf_map_update_elem` fails,
/// [`MapError::ProgIdNotSupported`] if the kernel does not support program ids and one is
/// provided.
pub fn insert (
pub fn insert (
& mut self ,
& mut self ,
key : u32 ,
key : u32 ,
@ -104,18 +124,25 @@ impl<T: BorrowMut<MapData>> DevMapHash<T> {
program : Option < & ProgramFd > ,
program : Option < & ProgramFd > ,
flags : u64 ,
flags : u64 ,
) -> Result < ( ) , MapError > {
) -> Result < ( ) , MapError > {
let value = bpf_devmap_val {
if FEATURES . devmap_hash_prog_id ( ) {
ifindex ,
let value = bpf_devmap_val {
bpf_prog : bpf_devmap_val__bindgen_ty_1 {
ifindex ,
// Default is valid as the kernel will only consider fd > 0:
bpf_prog : bpf_devmap_val__bindgen_ty_1 {
// https://github.com/torvalds/linux/blob/2dde18cd1d8fac735875f2e4987f11817cc0bc2c/kernel/bpf/devmap.c#L866
// Default is valid as the kernel will only consider fd > 0:
// https://github.com/torvalds/linux/blob/2dde18cd1d8fac735875f2e4987f11817cc0bc2c/kernel/bpf/devmap.c#L918
// https://github.com/torvalds/linux/blob/2dde18cd1d8fac735875f2e4987f11817cc0bc2c/kernel/bpf/devmap.c#L866
fd : program
// https://github.com/torvalds/linux/blob/2dde18cd1d8fac735875f2e4987f11817cc0bc2c/kernel/bpf/devmap.c#L918
. map ( | prog | prog . as_fd ( ) . as_raw_fd ( ) )
fd : program
. unwrap_or_default ( ) ,
. map ( | prog | prog . as_fd ( ) . as_raw_fd ( ) )
} ,
. unwrap_or_default ( ) ,
} ;
} ,
hash_map ::insert ( self . inner . borrow_mut ( ) , & key , & value , flags )
} ;
hash_map ::insert ( self . inner . borrow_mut ( ) , & key , & value , flags )
} else {
if program . is_some ( ) {
return Err ( MapError ::ProgIdNotSupported ) ;
}
hash_map ::insert ( self . inner . borrow_mut ( ) , & key , & ifindex , flags )
}
}
}
/// Removes a value from the map.
/// Removes a value from the map.