@ -4,25 +4,30 @@
 
		
	
		
			
				//! used to setup and share data with eBPF programs. When you call
  
		
	
		
			
				//! [`Bpf::load_file`](crate::Bpf::load_file) or
  
		
	
		
			
				//! [`Bpf::load`](crate::Bpf::load), all the maps defined in the eBPF code get
  
		
	
		
			
				//! initialized and can then be accessed using [`Bpf::map`](crate::Bpf::map)  and 
 
		
	
		
			
				//! [`Bpf::map_mut`](crate::Bpf::map_mut) .
 
		
	
		
			
				//! initialized and can then be accessed using [`Bpf::map`](crate::Bpf::map) , 
 
		
	
		
			
				//! [`Bpf::map_mut`](crate::Bpf::map_mut) , or [`Bpf::take_map`](crate::Bpf::take_map) .
 
		
	
		
			
				//!
  
		
	
		
			
				//! # Typed maps
  
		
	
		
			
				//!
  
		
	
		
			
				//! The eBPF API includes many map types each supporting different operations.
  
		
	
		
			
				//! [`Bpf::map`](crate::Bpf::map) and [`Bpf::map_mut`](crate::Bpf::map_mut) always return the
  
		
	
		
			
				//! opaque [`MapRef`] and [`MapRefMut`] types respectively. Those two types can be converted to
  
		
	
		
			
				//! *typed maps* using the [`TryFrom`](std::convert::TryFrom) trait. For example:
  
		
	
		
			
				//! [`Bpf::map`](crate::Bpf::map), [`Bpf::map_mut`](crate::Bpf::map_mut), and
  
		
	
		
			
				//! [`Bpf::take_map`](crate::Bpf::take_map) always return the
  
		
	
		
			
				//! opaque [`&Map`](crate::maps::Map), [`&mut Map`](crate::maps::Map), and [`Map`](crate::maps::Map)
  
		
	
		
			
				//! types respectively. Those three types can be converted to *typed maps* using
  
		
	
		
			
				//! the [`TryFrom`](std::convert::TryFrom) or [`TryInto`](std::convert::TryInto)
  
		
	
		
			
				//! trait. For example:
  
		
	
		
			
				//!
  
		
	
		
			
				//! ```no_run
  
		
	
		
			
				//! # let mut bpf = aya::Bpf::load(&[])?;
  
		
	
		
			
				//! use aya::maps::SockMap;
  
		
	
		
			
				//! use aya::programs::SkMsg;
  
		
	
		
			
				//!
  
		
	
		
			
				//! let intercept_egress = SockMap::try_from(bpf.map_mut("INTERCEPT_EGRESS")?)?;
  
		
	
		
			
				//! let intercept_egress = SockMap::try_from(bpf.map_mut("INTERCEPT_EGRESS").unwrap())?;
  
		
	
		
			
				//! let map_fd = intercept_egress.fd()?;
  
		
	
		
			
				//! let prog: &mut SkMsg = bpf.program_mut("intercept_egress_packet").unwrap().try_into()?;
  
		
	
		
			
				//! prog.load()?;
  
		
	
		
			
				//! prog.attach(&intercept_egress)?;
  
		
	
		
			
				//! prog.attach(map_fd)?;
  
		
	
		
			
				//!
  
		
	
		
			
				//! # Ok::<(), aya::BpfError>(())
  
		
	
		
			
				//! ```
  
		
	
		
			
				//!
  
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
			
			@ -32,6 +37,7 @@
 
		
	
		
			
				//! versa. Because of that, all map values must be plain old data and therefore
  
		
	
		
			
				//! implement the [Pod] trait.
  
		
	
		
			
				use   std ::{  
		
	
		
			
				     convert ::{ AsMut ,   AsRef } ,  
		
	
		
			
				     ffi ::CString ,  
		
	
		
			
				     fmt ,   io ,  
		
	
		
			
				     marker ::PhantomData ,  
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -58,8 +64,6 @@ use crate::{
 
		
	
		
			
				     PinningType ,   Pod ,  
		
	
		
			
				} ;  
		
	
		
			
				
 
		
	
		
			
				mod  map_lock ;  
		
	
		
			
				
 
		
	
		
			
				pub   mod  array ;  
		
	
		
			
				pub   mod  bloom_filter ;  
		
	
		
			
				pub   mod  hash_map ;  
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
			
			@ -71,8 +75,12 @@ pub mod stack;
 
		
	
		
			
				pub   mod  stack_trace ;  
		
	
		
			
				
 
		
	
		
			
				pub   use   array ::{ Array ,   PerCpuArray ,   ProgramArray } ;  
		
	
		
			
				pub   use   bloom_filter ::BloomFilter ;  
		
	
		
			
				pub   use   hash_map ::{ HashMap ,   PerCpuHashMap } ;  
		
	
		
			
				pub   use   map_lock ::* ;  
		
	
		
			
				pub   use   lpm_trie ::LpmTrie ;  
		
	
		
			
				#[ cfg(feature =  " async " ) ]  
		
	
		
			
				#[ cfg_attr(docsrs, doc(cfg(feature =  " async " ))) ]  
		
	
		
			
				pub   use   perf ::AsyncPerfEventArray ;  
		
	
		
			
				pub   use   perf ::PerfEventArray ;  
		
	
		
			
				pub   use   queue ::Queue ;  
		
	
		
			
				pub   use   sock ::{ SockHash ,   SockMap } ;  
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
			
			@ -82,13 +90,6 @@ pub use stack_trace::StackTraceMap;
 
		
	
		
			
				#[ derive(Error, Debug) ]  
		
	
		
			
				/// Errors occuring from working with Maps
  
		
	
		
			
				pub   enum  MapError   {  
		
	
		
			
				     /// Unable to find the map
  
		
	
		
			
				     #[ error( " map `{name}` not found  " ) ]  
		
	
		
			
				     MapNotFound   {  
		
	
		
			
				         /// Map name
  
		
	
		
			
				         name : String ,  
		
	
		
			
				     } ,  
		
	
		
			
				
 
		
	
		
			
				     /// Invalid map type encontered
  
		
	
		
			
				     #[ error( " invalid map type {map_type} " ) ]  
		
	
		
			
				     InvalidMapType   {  
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -174,20 +175,6 @@ pub enum MapError {
 
		
	
		
			
				         io_error : io ::Error ,  
		
	
		
			
				     } ,  
		
	
		
			
				
 
		
	
		
			
				     /// Map is borrowed mutably
  
		
	
		
			
				     #[ error( " map `{name}` is borrowed mutably " ) ]  
		
	
		
			
				     BorrowError   {  
		
	
		
			
				         /// Map name
  
		
	
		
			
				         name : String ,  
		
	
		
			
				     } ,  
		
	
		
			
				
 
		
	
		
			
				     /// Map is already borrowed
  
		
	
		
			
				     #[ error( " map `{name}` is already borrowed " ) ]  
		
	
		
			
				     BorrowMutError   {  
		
	
		
			
				         /// Map name
  
		
	
		
			
				         name : String ,  
		
	
		
			
				     } ,  
		
	
		
			
				
 
		
	
		
			
				     /// Could not pin map by name
  
		
	
		
			
				     #[ error( " map `{name:?}` requested pinning by name. pinning failed " ) ]  
		
	
		
			
				     PinError   {  
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -243,11 +230,234 @@ fn maybe_warn_rlimit() {
 
		
	
		
			
				     }  
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				/// eBPF map types.
  
		
	
		
			
				#[ derive(Debug) ]  
		
	
		
			
				pub   enum  Map   {  
		
	
		
			
				     /// A [`Array`] map
  
		
	
		
			
				     Array ( MapData ) ,  
		
	
		
			
				     /// A [`PerCpuArray`] map
  
		
	
		
			
				     PerCpuArray ( MapData ) ,  
		
	
		
			
				     /// A [`ProgramArray`] map
  
		
	
		
			
				     ProgramArray ( MapData ) ,  
		
	
		
			
				     /// A [`HashMap`] map
  
		
	
		
			
				     HashMap ( MapData ) ,  
		
	
		
			
				     /// A [`PerCpuHashMap`] map
  
		
	
		
			
				     PerCpuHashMap ( MapData ) ,  
		
	
		
			
				     /// A [`PerfEventArray`] map
  
		
	
		
			
				     PerfEventArray ( MapData ) ,  
		
	
		
			
				     /// A [`SockMap`] map
  
		
	
		
			
				     SockMap ( MapData ) ,  
		
	
		
			
				     /// A [`SockHash`] map
  
		
	
		
			
				     SockHash ( MapData ) ,  
		
	
		
			
				     /// A [`BloomFilter`] map
  
		
	
		
			
				     BloomFilter ( MapData ) ,  
		
	
		
			
				     /// A [`LpmTrie`] map
  
		
	
		
			
				     LpmTrie ( MapData ) ,  
		
	
		
			
				     /// A [`Stack`] map
  
		
	
		
			
				     Stack ( MapData ) ,  
		
	
		
			
				     /// A [`StackTraceMap`] map
  
		
	
		
			
				     StackTraceMap ( MapData ) ,  
		
	
		
			
				     /// A [`Queue`] map
  
		
	
		
			
				     Queue ( MapData ) ,  
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				impl   Map   {  
		
	
		
			
				     /// Returns the low level map type.
  
		
	
		
			
				     fn  map_type ( & self )   -> u32  {  
		
	
		
			
				         match   self   {  
		
	
		
			
				             Map ::Array ( map )   = >   map . obj . map_type ( ) ,  
		
	
		
			
				             Map ::PerCpuArray ( map )   = >   map . obj . map_type ( ) ,  
		
	
		
			
				             Map ::ProgramArray ( map )   = >   map . obj . map_type ( ) ,  
		
	
		
			
				             Map ::HashMap ( map )   = >   map . obj . map_type ( ) ,  
		
	
		
			
				             Map ::PerCpuHashMap ( map )   = >   map . obj . map_type ( ) ,  
		
	
		
			
				             Map ::PerfEventArray ( map )   = >   map . obj . map_type ( ) ,  
		
	
		
			
				             Map ::SockHash ( map )   = >   map . obj . map_type ( ) ,  
		
	
		
			
				             Map ::SockMap ( map )   = >   map . obj . map_type ( ) ,  
		
	
		
			
				             Map ::BloomFilter ( map )   = >   map . obj . map_type ( ) ,  
		
	
		
			
				             Map ::LpmTrie ( map )   = >   map . obj . map_type ( ) ,  
		
	
		
			
				             Map ::Stack ( map )   = >   map . obj . map_type ( ) ,  
		
	
		
			
				             Map ::StackTraceMap ( map )   = >   map . obj . map_type ( ) ,  
		
	
		
			
				             Map ::Queue ( map )   = >   map . obj . map_type ( ) ,  
		
	
		
			
				         }  
		
	
		
			
				     }  
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				macro_rules!   impl_try_from_map   {  
		
	
		
			
				     ( $( $tx :ident   from   Map ::$ty :ident ) , +   $(, ) ? )   = >   {  
		
	
		
			
				         $(  
		
	
		
			
				             impl < ' a >   TryFrom < & ' a   Map >   for   $tx < & ' a   MapData >   {  
		
	
		
			
				                 type  Error   =   MapError ;  
		
	
		
			
				
 
		
	
		
			
				                 fn  try_from ( map : & ' a  Map )   -> Result < $tx < & ' a   MapData > ,   MapError >   {  
		
	
		
			
				                     match   map   {  
		
	
		
			
				                         Map ::$ty ( m )   = >   {  
		
	
		
			
				                             $tx ::new ( m )  
		
	
		
			
				                         } ,  
		
	
		
			
				                         _   = >   Err ( MapError ::InvalidMapType {   map_type : map . map_type ( ) } ) ,  
		
	
		
			
				                     }  
		
	
		
			
				                 }  
		
	
		
			
				             }  
		
	
		
			
				
 
		
	
		
			
				             impl < ' a , >   TryFrom < & ' a   mut   Map >   for   $tx < & ' a   mut   MapData >   {  
		
	
		
			
				                 type  Error   =   MapError ;  
		
	
		
			
				
 
		
	
		
			
				                 fn  try_from ( map : & ' a  mut   Map )   -> Result < $tx < & ' a   mut   MapData > ,   MapError >   {  
		
	
		
			
				                     match   map   {  
		
	
		
			
				                         Map ::$ty ( m )   = >   {  
		
	
		
			
				                             $tx ::new ( m )  
		
	
		
			
				                         } ,  
		
	
		
			
				                         _   = >   Err ( MapError ::InvalidMapType {   map_type : map . map_type ( ) } ) ,  
		
	
		
			
				                     }  
		
	
		
			
				                 }  
		
	
		
			
				             }  
		
	
		
			
				
 
		
	
		
			
				             impl   TryFrom < Map >   for   $tx < MapData >   {  
		
	
		
			
				                 type  Error   =   MapError ;  
		
	
		
			
				
 
		
	
		
			
				                 fn  try_from ( map : Map )   -> Result < $tx < MapData > ,   MapError >   {  
		
	
		
			
				                     match   map   {  
		
	
		
			
				                         Map ::$ty ( m )   = >   {  
		
	
		
			
				                             $tx ::new ( m )  
		
	
		
			
				                         } ,  
		
	
		
			
				                         _   = >   Err ( MapError ::InvalidMapType {   map_type : map . map_type ( ) } ) ,  
		
	
		
			
				                     }  
		
	
		
			
				                 }  
		
	
		
			
				             }  
		
	
		
			
				        ) +  
		
	
		
			
				    }  
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				impl_try_from_map ! (  
		
	
		
			
				     ProgramArray   from   Map ::ProgramArray ,  
		
	
		
			
				     SockMap   from   Map ::SockMap ,  
		
	
		
			
				     PerfEventArray   from   Map ::PerfEventArray ,  
		
	
		
			
				     StackTraceMap   from   Map ::StackTraceMap ,  
		
	
		
			
				) ;  
		
	
		
			
				
 
		
	
		
			
				#[ cfg(feature =  " async " ) ]  
		
	
		
			
				#[ cfg_attr(docsrs, doc(cfg(feature =  " async " ))) ]  
		
	
		
			
				impl_try_from_map ! (  
		
	
		
			
				     AsyncPerfEventArray   from   Map ::PerfEventArray ,  
		
	
		
			
				) ;  
		
	
		
			
				
 
		
	
		
			
				macro_rules!   impl_try_from_map_generic_key_or_value   {  
		
	
		
			
				     ( $( $ty :ident ) , +   $(, ) ? )   = >   {  
		
	
		
			
				         $(  
		
	
		
			
				             impl < ' a ,   V :Pod >   TryFrom < & ' a   Map >   for   $ty < & ' a   MapData ,   V >   {  
		
	
		
			
				                 type  Error   =   MapError ;  
		
	
		
			
				
 
		
	
		
			
				                 fn  try_from ( map : & ' a  Map )   -> Result < $ty < & ' a   MapData   ,   V > ,   MapError >   {  
		
	
		
			
				                     match   map   {  
		
	
		
			
				                         Map ::$ty ( m )   = >   {  
		
	
		
			
				                             $ty ::new ( m )  
		
	
		
			
				                         } ,  
		
	
		
			
				                         _   = >   Err ( MapError ::InvalidMapType {   map_type : map . map_type ( ) } ) ,  
		
	
		
			
				                     }  
		
	
		
			
				                 }  
		
	
		
			
				             }  
		
	
		
			
				
 
		
	
		
			
				             impl < ' a , V : Pod >   TryFrom < & ' a   mut   Map >   for   $ty < & ' a   mut   MapData ,   V >   {  
		
	
		
			
				                 type  Error   =   MapError ;  
		
	
		
			
				
 
		
	
		
			
				                 fn  try_from ( map : & ' a  mut   Map )   -> Result < $ty < & ' a   mut   MapData ,   V > ,   MapError >   {  
		
	
		
			
				                     match   map   {  
		
	
		
			
				                         Map ::$ty ( m )   = >   {  
		
	
		
			
				                             $ty ::new ( m )  
		
	
		
			
				                         } ,  
		
	
		
			
				                         _   = >   Err ( MapError ::InvalidMapType {   map_type : map . map_type ( ) } ) ,  
		
	
		
			
				                     }  
		
	
		
			
				                 }  
		
	
		
			
				             }  
		
	
		
			
				
 
		
	
		
			
				             impl < V : Pod >   TryFrom < Map >   for   $ty < MapData ,   V >   {  
		
	
		
			
				                 type  Error   =   MapError ;  
		
	
		
			
				
 
		
	
		
			
				                 fn  try_from ( map : Map )   -> Result < $ty < MapData ,   V > ,   MapError >   {  
		
	
		
			
				                     match   map   {  
		
	
		
			
				                         Map ::$ty ( m )   = >   {  
		
	
		
			
				                             $ty ::new ( m )  
		
	
		
			
				                         } ,  
		
	
		
			
				                         _   = >   Err ( MapError ::InvalidMapType {   map_type : map . map_type ( ) } ) ,  
		
	
		
			
				                     }  
		
	
		
			
				                 }  
		
	
		
			
				             }  
		
	
		
			
				        ) +  
		
	
		
			
				    }  
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				impl_try_from_map_generic_key_or_value ! ( Array ,   PerCpuArray ,   SockHash ,   BloomFilter ,   Queue ,   Stack , ) ;  
		
	
		
			
				
 
		
	
		
			
				macro_rules!   impl_try_from_map_generic_key_and_value   {  
		
	
		
			
				     ( $( $ty :ident ) , +   $(, ) ? )   = >   {  
		
	
		
			
				         $(  
		
	
		
			
				             impl < ' a ,   V : Pod ,   K : Pod >   TryFrom < & ' a   Map >   for   $ty < & ' a   MapData ,   V ,   K >   {  
		
	
		
			
				                 type  Error   =   MapError ;  
		
	
		
			
				
 
		
	
		
			
				                 fn  try_from ( map : & ' a  Map )   -> Result < $ty < & ' a   MapData , V , K > ,   MapError >   {  
		
	
		
			
				                     match   map   {  
		
	
		
			
				                         Map ::$ty ( m )   = >   {  
		
	
		
			
				                             $ty ::new ( m )  
		
	
		
			
				                         } ,  
		
	
		
			
				                         _   = >   Err ( MapError ::InvalidMapType {   map_type : map . map_type ( ) } ) ,  
		
	
		
			
				                     }  
		
	
		
			
				                 }  
		
	
		
			
				             }  
		
	
		
			
				
 
		
	
		
			
				             impl < ' a , V : Pod , K : Pod >   TryFrom < & ' a   mut   Map >   for   $ty < & ' a   mut   MapData ,   V ,   K >   {  
		
	
		
			
				                 type  Error   =   MapError ;  
		
	
		
			
				
 
		
	
		
			
				                 fn  try_from ( map : & ' a  mut   Map )   -> Result < $ty < & ' a   mut   MapData ,   V ,   K > ,   MapError >   {  
		
	
		
			
				                     match   map   {  
		
	
		
			
				                         Map ::$ty ( m )   = >   {  
		
	
		
			
				                             $ty ::new ( m )  
		
	
		
			
				                         } ,  
		
	
		
			
				                         _   = >   Err ( MapError ::InvalidMapType {   map_type : map . map_type ( ) } ) ,  
		
	
		
			
				                 }  
		
	
		
			
				             }  
		
	
		
			
				             }  
		
	
		
			
				        ) +  
		
	
		
			
				    }  
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				impl_try_from_map_generic_key_and_value ! ( HashMap ,   PerCpuHashMap ,   LpmTrie ) ;  
		
	
		
			
				
 
		
	
		
			
				pub ( crate )   fn  check_bounds ( map : & MapData ,   index : u32 )   -> Result < ( ) ,   MapError >   {  
		
	
		
			
				     let   max_entries   =   map . obj . max_entries ( ) ;  
		
	
		
			
				     if   index   > =   max_entries   {  
		
	
		
			
				         Err ( MapError ::OutOfBounds   {   index ,   max_entries   } )  
		
	
		
			
				     }   else   {  
		
	
		
			
				         Ok ( ( ) )  
		
	
		
			
				     }  
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				pub ( crate )   fn  check_kv_size < K ,   V > ( map : & MapData )   -> Result < ( ) ,   MapError >   {  
		
	
		
			
				     let   size   =   mem ::size_of ::< K > ( ) ;  
		
	
		
			
				     let   expected   =   map . obj . key_size ( )   as   usize ;  
		
	
		
			
				     if   size   ! =   expected   {  
		
	
		
			
				         return   Err ( MapError ::InvalidKeySize   {   size ,   expected   } ) ;  
		
	
		
			
				     }  
		
	
		
			
				     let   size   =   mem ::size_of ::< V > ( ) ;  
		
	
		
			
				     let   expected   =   map . obj . value_size ( )   as   usize ;  
		
	
		
			
				     if   size   ! =   expected   {  
		
	
		
			
				         return   Err ( MapError ::InvalidValueSize   {   size ,   expected   } ) ;  
		
	
		
			
				     } ;  
		
	
		
			
				     Ok ( ( ) )  
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				pub ( crate )   fn  check_v_size < V > ( map : & MapData )   -> Result < ( ) ,   MapError >   {  
		
	
		
			
				     let   size   =   mem ::size_of ::< V > ( ) ;  
		
	
		
			
				     let   expected   =   map . obj . value_size ( )   as   usize ;  
		
	
		
			
				     if   size   ! =   expected   {  
		
	
		
			
				         return   Err ( MapError ::InvalidValueSize   {   size ,   expected   } ) ;  
		
	
		
			
				     } ;  
		
	
		
			
				     Ok ( ( ) )  
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				/// A generic handle to a BPF map.
  
		
	
		
			
				///
  
		
	
		
			
				/// You should never need to use this unless you're implementing a new map type.
  
		
	
		
			
				#[ derive(Debug) ]  
		
	
		
			
				pub   struct  Map   {  
		
	
		
			
				pub   struct  Map Data   {  
		
	
		
			
				     pub ( crate )   obj : obj ::Map ,  
		
	
		
			
				     pub ( crate )   fd : Option < RawFd > ,  
		
	
		
			
				     pub ( crate )   btf_fd : Option < RawFd > ,  
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
			
			@ -255,7 +465,19 @@ pub struct Map {
 
		
	
		
			
				     pub   pinned : bool ,  
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				impl   Map   {  
		
	
		
			
				impl   AsRef < MapData >   for   MapData   {  
		
	
		
			
				     fn  as_ref ( & self )   -> & MapData   {  
		
	
		
			
				         self  
		
	
		
			
				     }  
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				impl   AsMut < MapData >   for   MapData   {  
		
	
		
			
				     fn  as_mut ( & mut   self )   -> & mut   MapData   {  
		
	
		
			
				         self  
		
	
		
			
				     }  
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				impl   MapData   {  
		
	
		
			
				     /// Creates a new map with the provided `name`
  
		
	
		
			
				     pub   fn  create ( & mut   self ,   name : & str )   -> Result < RawFd ,   MapError >   {  
		
	
		
			
				         if   self . fd . is_some ( )   {  
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -303,7 +525,7 @@ impl Map {
 
		
	
		
			
				     }  
		
	
		
			
				
 
		
	
		
			
				     /// Loads a map from a pinned path in bpffs.
  
		
	
		
			
				     pub   fn  from_pin < P : AsRef < Path > > ( path : P )   -> Result < Map ,   MapError >   {  
		
	
		
			
				     pub   fn  from_pin < P : AsRef < Path > > ( path : P )   -> Result < Map Data ,   MapError >   {  
		
	
		
			
				         let   path_string   =  
		
	
		
			
				             CString ::new ( path . as_ref ( ) . to_string_lossy ( ) . into_owned ( ) ) . map_err ( | e |   {  
		
	
		
			
				                 MapError ::PinError   {  
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
			
			@ -324,7 +546,7 @@ impl Map {
 
		
	
		
			
				             io_error ,  
		
	
		
			
				         } ) ? ;  
		
	
		
			
				
 
		
	
		
			
				         Ok ( Map   {  
		
	
		
			
				         Ok ( Map Data   {  
		
	
		
			
				             obj : parse_map_info ( info ,   PinningType ::ByName ) ,  
		
	
		
			
				             fd : Some ( fd ) ,  
		
	
		
			
				             btf_fd : None ,  
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
			
			@ -334,16 +556,16 @@ impl Map {
 
		
	
		
			
				
 
		
	
		
			
				     /// Loads a map from a [`RawFd`].
  
		
	
		
			
				     ///
  
		
	
		
			
				     /// If loading from a BPF Filesystem (bpffs) you should use [`Map::from_pin`] .
 
		
	
		
			
				     /// If loading from a BPF Filesystem (bpffs) you should use [`Map::from_pin`] (crate::maps::MapData::from_pin) .
 
		
	
		
			
				     /// This API is intended for cases where you have received a valid BPF FD from some other means.
  
		
	
		
			
				     /// For example, you received an FD over Unix Domain Socket.
  
		
	
		
			
				     pub   fn  from_fd ( fd : RawFd )   -> Result < Map ,   MapError >   {  
		
	
		
			
				     pub   fn  from_fd ( fd : RawFd )   -> Result < Map Data ,   MapError >   {  
		
	
		
			
				         let   info   =   bpf_map_get_info_by_fd ( fd ) . map_err ( | io_error |   MapError ::SyscallError   {  
		
	
		
			
				             call : "BPF_OBJ_GET" . to_owned ( ) ,  
		
	
		
			
				             io_error ,  
		
	
		
			
				         } ) ? ;  
		
	
		
			
				
 
		
	
		
			
				         Ok ( Map   {  
		
	
		
			
				         Ok ( Map Data   {  
		
	
		
			
				             obj : parse_map_info ( info ,   PinningType ::None ) ,  
		
	
		
			
				             fd : Some ( fd ) ,  
		
	
		
			
				             btf_fd : None ,  
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
			
			@ -351,11 +573,6 @@ impl Map {
 
		
	
		
			
				         } )  
		
	
		
			
				     }  
		
	
		
			
				
 
		
	
		
			
				     /// Returns the [`bpf_map_type`] of this map
  
		
	
		
			
				     pub   fn  map_type ( & self )   -> Result < bpf_map_type ,   MapError >   {  
		
	
		
			
				         bpf_map_type ::try_from ( self . obj . map_type ( ) )  
		
	
		
			
				     }  
		
	
		
			
				
 
		
	
		
			
				     pub ( crate )   fn  fd_or_err ( & self )   -> Result < RawFd ,   MapError >   {  
		
	
		
			
				         self . fd . ok_or ( MapError ::NotCreated )  
		
	
		
			
				     }  
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -389,7 +606,7 @@ impl Map {
 
		
	
		
			
				     }  
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				impl   Drop   for   Map   {  
		
	
		
			
				impl   Drop   for   Map Data   {  
		
	
		
			
				     fn  drop ( & mut   self )   {  
		
	
		
			
				         // TODO: Replace this with an OwnedFd once that is stabilized.
  
		
	
		
			
				         if   let   Some ( fd )   =   self . fd . take ( )   {  
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
			
			@ -398,10 +615,26 @@ impl Drop for Map {
 
		
	
		
			
				     }  
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				impl   Clone   for   MapData   {  
		
	
		
			
				     fn  clone ( & self )   -> MapData   {  
		
	
		
			
				         MapData   {  
		
	
		
			
				             obj : self . obj . clone ( ) ,  
		
	
		
			
				             fd : {  
		
	
		
			
				                 if   let   Some ( fd )   =   self . fd   {  
		
	
		
			
				                     unsafe   {   Some ( libc ::dup ( fd ) )   } ;  
		
	
		
			
				                 }  
		
	
		
			
				                 None  
		
	
		
			
				             } ,  
		
	
		
			
				             btf_fd : self . btf_fd ,  
		
	
		
			
				             pinned : self . pinned ,  
		
	
		
			
				         }  
		
	
		
			
				     }  
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				/// An iterable map
  
		
	
		
			
				pub   trait   IterableMap < K : Pod ,   V >   {  
		
	
		
			
				     /// Get a generic map handle
  
		
	
		
			
				     fn  map ( & self )   -> & Map ;  
		
	
		
			
				     fn  map ( & self )   -> & Map Data ;  
		
	
		
			
				
 
		
	
		
			
				     /// Get the value for the provided `key`
  
		
	
		
			
				     fn  get ( & self ,   key : & K )   -> Result < V ,   MapError > ;  
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
			
			@ -409,13 +642,13 @@ pub trait IterableMap<K: Pod, V> {
 
		
	
		
			
				
 
		
	
		
			
				/// Iterator returned by `map.keys()`.
  
		
	
		
			
				pub   struct  MapKeys < ' coll ,   K : Pod >   {  
		
	
		
			
				     map : & ' coll  Map ,  
		
	
		
			
				     map : & ' coll  Map Data ,  
		
	
		
			
				     err : bool ,  
		
	
		
			
				     key : Option < K > ,  
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				impl < ' coll ,   K : Pod >   MapKeys < ' coll ,   K >   {  
		
	
		
			
				     fn  new ( map : & ' coll  Map )   -> MapKeys < ' coll ,   K >   {  
		
	
		
			
				     fn  new ( map : & ' coll  Map Data )   -> MapKeys < ' coll ,   K >   {  
		
	
		
			
				         MapKeys   {  
		
	
		
			
				             map ,  
		
	
		
			
				             err : false ,  
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -538,6 +771,7 @@ impl TryFrom<u32> for bpf_map_type {
 
		
	
		
			
				         } )  
		
	
		
			
				     }  
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				pub ( crate )   struct  PerCpuKernelMem   {  
		
	
		
			
				     bytes : Vec < u8 > ,  
		
	
		
			
				}  
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -643,6 +877,7 @@ mod tests {
 
		
	
		
			
				     use   crate ::{  
		
	
		
			
				         bpf_map_def ,  
		
	
		
			
				         generated ::{ bpf_cmd ,   bpf_map_type ::BPF_MAP_TYPE_HASH } ,  
		
	
		
			
				         maps ::MapData ,  
		
	
		
			
				         obj ::MapKind ,  
		
	
		
			
				         sys ::{ override_syscall ,   Syscall } ,  
		
	
		
			
				     } ;  
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
			
			@ -665,8 +900,8 @@ mod tests {
 
		
	
		
			
				         } )  
		
	
		
			
				     }  
		
	
		
			
				
 
		
	
		
			
				     fn  new_map ( )   -> Map   {  
		
	
		
			
				         Map   {  
		
	
		
			
				     fn  new_map ( )   -> Map Data   {  
		
	
		
			
				         Map Data   {  
		
	
		
			
				             obj : new_obj_map ( ) ,  
		
	
		
			
				             fd : None ,  
		
	
		
			
				             pinned : false ,