@ -66,9 +66,9 @@ pub mod xdp;
 
			
		
	
		
		
			
				
					
					use   libc ::ENOSPC ; use   libc ::ENOSPC ;  
			
		
	
		
		
			
				
					
					use   std ::{ use   std ::{  
			
		
	
		
		
			
				
					
					     ffi ::CString ,      ffi ::CString ,  
			
		
	
		
		
			
				
					
					     ,      fs,    io,  
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					     os ::unix ::io ::{ AsRawFd ,   RawFd } ,      os ::unix ::io ::{ AsRawFd ,   RawFd } ,  
			
		
	
		
		
			
				
					
					     path ::Path ,      path ::{ Path ,   PathBuf } ,  
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					} ; } ;  
			
		
	
		
		
			
				
					
					use   thiserror ::Error ; use   thiserror ::Error ;  
			
		
	
		
		
			
				
					
					
 
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -106,8 +106,9 @@ use crate::{
 
			
		
	
		
		
			
				
					
					     obj ::{ self ,   btf ::BtfError ,   Function ,   KernelVersion } ,      obj ::{ self ,   btf ::BtfError ,   Function ,   KernelVersion } ,  
			
		
	
		
		
			
				
					
					     pin ::PinError ,      pin ::PinError ,  
			
		
	
		
		
			
				
					
					     sys ::{      sys ::{  
			
		
	
		
		
			
				
					
					         bpf_get_object ,   bpf_load_program ,   bpf_pin_object ,   bpf_prog_get_fd_by_id ,          bpf_btf_get_fd_by_id ,   bpf_get_object ,   bpf_load_program ,   bpf_pin_object ,  
			
				
				
			
		
	
		
		
			
				
					
					         bpf_prog_get_info_by_fd ,   bpf_prog_query ,   retry_with_verifier_logs ,   BpfLoadProgramAttrs ,          bpf_prog_get_fd_by_id ,   bpf_prog_get_info_by_fd ,   bpf_prog_query ,   retry_with_verifier_logs ,  
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					         BpfLoadProgramAttrs ,  
			
		
	
		
		
			
				
					
					     } ,      } ,  
			
		
	
		
		
			
				
					
					     util ::VerifierLog ,      util ::VerifierLog ,  
			
		
	
		
		
			
				
					
					} ; } ;  
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -204,6 +205,10 @@ pub enum ProgramError {
 
			
		
	
		
		
			
				
					
					         /// program name
          /// program name
  
			
		
	
		
		
			
				
					
					         name : String ,          name : String ,  
			
		
	
		
		
			
				
					
					     } ,      } ,  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					     /// The program defintion is incomplete.
  
			
		
	
		
		
			
				
					
					     #[ error( " incomplete program defintion. {0} " ) ]  
			
		
	
		
		
			
				
					
					     IncompleteProgramDefinition ( String ) ,  
			
		
	
		
		
			
				
					
					} }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					/// A [`Program`] file descriptor.
 /// A [`Program`] file descriptor.
  
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -395,10 +400,209 @@ impl Drop for Program {
 
			
		
	
		
		
			
				
					
					     }      }  
			
		
	
		
		
			
				
					
					} }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					/// A Pinned Program.
  
			
		
	
		
		
			
				
					
					pub   struct  PinnedProgram   {  
			
		
	
		
		
			
				
					
					     path : PathBuf ,  
			
		
	
		
		
			
				
					
					     inner : Program ,  
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					impl   PinnedProgram   {  
			
		
	
		
		
			
				
					
					     /// Loads a program from a pinned entry on a bpffs.
  
			
		
	
		
		
			
				
					
					     ///
  
			
		
	
		
		
			
				
					
					     /// Not all programs can be loaded since we can't correctly convert them into a [`Program`] since
  
			
		
	
		
		
			
				
					
					     /// there is missing information in `bpf_prog_info`. Attempting to load an unsupported or
  
			
		
	
		
		
			
				
					
					     /// unimplemented program type will result in an error. You may use `ProgramInfo::from_pinned` which
  
			
		
	
		
		
			
				
					
					     /// offers limited interactions with these program types.
  
			
		
	
		
		
			
				
					
					     ///
  
			
		
	
		
		
			
				
					
					     /// Existing links will not be populated. To work with existing links you should use [`PinnedLink`].
  
			
		
	
		
		
			
				
					
					     ///
  
			
		
	
		
		
			
				
					
					     /// On drop, any managed links are detached and the program is unloaded. This will not result in
  
			
		
	
		
		
			
				
					
					     /// the program being unloaded from the kernel if it is still pinned.
  
			
		
	
		
		
			
				
					
					     pub   fn  from_pin < P : AsRef < Path > > ( path : P )   -> Result < Self ,   ProgramError >   {  
			
		
	
		
		
			
				
					
					         let   path_string   =   CString ::new ( path . as_ref ( ) . to_str ( ) . unwrap ( ) ) . unwrap ( ) ;  
			
		
	
		
		
			
				
					
					         let   fd   =  
			
		
	
		
		
			
				
					
					             bpf_get_object ( & path_string ) . map_err ( | ( _ ,   io_error ) |   ProgramError ::SyscallError   {  
			
		
	
		
		
			
				
					
					                 call : "bpf_obj_get" . to_owned ( ) ,  
			
		
	
		
		
			
				
					
					                 io_error ,  
			
		
	
		
		
			
				
					
					             } ) ?   as   RawFd ;  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					         let   info   =   bpf_prog_get_info_by_fd ( fd ) . map_err ( | io_error |   ProgramError ::SyscallError   {  
			
		
	
		
		
			
				
					
					             call : "bpf_prog_get_info_by_fd" . to_owned ( ) ,  
			
		
	
		
		
			
				
					
					             io_error ,  
			
		
	
		
		
			
				
					
					         } ) ? ;  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					         let   info   =   ProgramInfo ( info ) ;  
			
		
	
		
		
			
				
					
					         let   name   =   info . name_as_str ( ) . map ( | s |   s . to_string ( ) ) ;  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					         let   p   =   match   info . prog_type ( ) ?   {  
			
		
	
		
		
			
				
					
					             bpf_prog_type ::BPF_PROG_TYPE_UNSPEC   = >   {  
			
		
	
		
		
			
				
					
					                 return   Err ( ProgramError ::IncompleteProgramDefinition (  
			
		
	
		
		
			
				
					
					                     "unknown program type." . to_string ( ) ,  
			
		
	
		
		
			
				
					
					                 ) )  
			
		
	
		
		
			
				
					
					             }  
			
		
	
		
		
			
				
					
					             bpf_prog_type ::BPF_PROG_TYPE_SOCKET_FILTER   = >   Program ::SocketFilter ( SocketFilter   {  
			
		
	
		
		
			
				
					
					                 data : ProgramData ::from_bpf_prog_info ( name ,   fd ,   info . 0 ) ? ,  
			
		
	
		
		
			
				
					
					             } ) ,  
			
		
	
		
		
			
				
					
					             bpf_prog_type ::BPF_PROG_TYPE_KPROBE   = >   {  
			
		
	
		
		
			
				
					
					                 return   Err ( ProgramError ::IncompleteProgramDefinition (  
			
		
	
		
		
			
				
					
					                     "unable to determine probe kind." . to_string ( ) ,  
			
		
	
		
		
			
				
					
					                 ) )  
			
		
	
		
		
			
				
					
					             }  
			
		
	
		
		
			
				
					
					             bpf_prog_type ::BPF_PROG_TYPE_SCHED_CLS   = >   {  
			
		
	
		
		
			
				
					
					                 let   cname   =   CString ::new ( name . clone ( ) . unwrap_or_default ( ) )  
			
		
	
		
		
			
				
					
					                     . unwrap ( )  
			
		
	
		
		
			
				
					
					                     . into_boxed_c_str ( ) ;  
			
		
	
		
		
			
				
					
					                 Program ::SchedClassifier ( SchedClassifier   {  
			
		
	
		
		
			
				
					
					                     data : ProgramData ::from_bpf_prog_info ( name ,   fd ,   info . 0 ) ? ,  
			
		
	
		
		
			
				
					
					                     name : cname ,  
			
		
	
		
		
			
				
					
					                 } )  
			
		
	
		
		
			
				
					
					             }  
			
		
	
		
		
			
				
					
					             bpf_prog_type ::BPF_PROG_TYPE_SCHED_ACT   = >   {  
			
		
	
		
		
			
				
					
					                 return   Err ( ProgramError ::IncompleteProgramDefinition (  
			
		
	
		
		
			
				
					
					                     "not implemented." . to_string ( ) ,  
			
		
	
		
		
			
				
					
					                 ) )  
			
		
	
		
		
			
				
					
					             }  
			
		
	
		
		
			
				
					
					             bpf_prog_type ::BPF_PROG_TYPE_TRACEPOINT   = >   Program ::TracePoint ( TracePoint   {  
			
		
	
		
		
			
				
					
					                 data : ProgramData ::from_bpf_prog_info ( name ,   fd ,   info . 0 ) ? ,  
			
		
	
		
		
			
				
					
					             } ) ,  
			
		
	
		
		
			
				
					
					             bpf_prog_type ::BPF_PROG_TYPE_XDP   = >   Program ::Xdp ( Xdp   {  
			
		
	
		
		
			
				
					
					                 data : ProgramData ::from_bpf_prog_info ( name ,   fd ,   info . 0 ) ? ,  
			
		
	
		
		
			
				
					
					             } ) ,  
			
		
	
		
		
			
				
					
					             bpf_prog_type ::BPF_PROG_TYPE_PERF_EVENT   = >   Program ::PerfEvent ( PerfEvent   {  
			
		
	
		
		
			
				
					
					                 data : ProgramData ::from_bpf_prog_info ( name ,   fd ,   info . 0 ) ? ,  
			
		
	
		
		
			
				
					
					             } ) ,  
			
		
	
		
		
			
				
					
					             bpf_prog_type ::BPF_PROG_TYPE_CGROUP_SKB   = >   Program ::CgroupSkb ( CgroupSkb   {  
			
		
	
		
		
			
				
					
					                 data : ProgramData ::from_bpf_prog_info ( name ,   fd ,   info . 0 ) ? ,  
			
		
	
		
		
			
				
					
					                 expected_attach_type : None ,  
			
		
	
		
		
			
				
					
					             } ) ,  
			
		
	
		
		
			
				
					
					             bpf_prog_type ::BPF_PROG_TYPE_CGROUP_SOCK   = >   Program ::CgroupSock ( CgroupSock   {  
			
		
	
		
		
			
				
					
					                 data : ProgramData ::from_bpf_prog_info ( name ,   fd ,   info . 0 ) ? ,  
			
		
	
		
		
			
				
					
					                 attach_type : None ,   // pick one because we don't know for sure
  
			
		
	
		
		
			
				
					
					             } ) ,  
			
		
	
		
		
			
				
					
					             bpf_prog_type ::BPF_PROG_TYPE_LWT_IN   = >   {  
			
		
	
		
		
			
				
					
					                 return   Err ( ProgramError ::IncompleteProgramDefinition (  
			
		
	
		
		
			
				
					
					                     "not implemented." . to_string ( ) ,  
			
		
	
		
		
			
				
					
					                 ) )  
			
		
	
		
		
			
				
					
					             }  
			
		
	
		
		
			
				
					
					             bpf_prog_type ::BPF_PROG_TYPE_LWT_OUT   = >   {  
			
		
	
		
		
			
				
					
					                 return   Err ( ProgramError ::IncompleteProgramDefinition (  
			
		
	
		
		
			
				
					
					                     "not implemented." . to_string ( ) ,  
			
		
	
		
		
			
				
					
					                 ) )  
			
		
	
		
		
			
				
					
					             }  
			
		
	
		
		
			
				
					
					             bpf_prog_type ::BPF_PROG_TYPE_LWT_XMIT   = >   {  
			
		
	
		
		
			
				
					
					                 return   Err ( ProgramError ::IncompleteProgramDefinition (  
			
		
	
		
		
			
				
					
					                     "not implemented." . to_string ( ) ,  
			
		
	
		
		
			
				
					
					                 ) )  
			
		
	
		
		
			
				
					
					             }  
			
		
	
		
		
			
				
					
					             bpf_prog_type ::BPF_PROG_TYPE_SOCK_OPS   = >   Program ::SockOps ( SockOps   {  
			
		
	
		
		
			
				
					
					                 data : ProgramData ::from_bpf_prog_info ( name ,   fd ,   info . 0 ) ? ,  
			
		
	
		
		
			
				
					
					             } ) ,  
			
		
	
		
		
			
				
					
					             bpf_prog_type ::BPF_PROG_TYPE_SK_SKB   = >   {  
			
		
	
		
		
			
				
					
					                 return   Err ( ProgramError ::IncompleteProgramDefinition (  
			
		
	
		
		
			
				
					
					                     "unable to determine parser or verdict program." . to_string ( ) ,  
			
		
	
		
		
			
				
					
					                 ) )  
			
		
	
		
		
			
				
					
					             }  
			
		
	
		
		
			
				
					
					             bpf_prog_type ::BPF_PROG_TYPE_CGROUP_DEVICE   = >   {  
			
		
	
		
		
			
				
					
					                 return   Err ( ProgramError ::IncompleteProgramDefinition (  
			
		
	
		
		
			
				
					
					                     "not implemented." . to_string ( ) ,  
			
		
	
		
		
			
				
					
					                 ) )  
			
		
	
		
		
			
				
					
					             }  
			
		
	
		
		
			
				
					
					             bpf_prog_type ::BPF_PROG_TYPE_SK_MSG   = >   Program ::SkMsg ( SkMsg   {  
			
		
	
		
		
			
				
					
					                 data : ProgramData ::from_bpf_prog_info ( name ,   fd ,   info . 0 ) ? ,  
			
		
	
		
		
			
				
					
					             } ) ,  
			
		
	
		
		
			
				
					
					             bpf_prog_type ::BPF_PROG_TYPE_RAW_TRACEPOINT   = >   Program ::RawTracePoint ( RawTracePoint   {  
			
		
	
		
		
			
				
					
					                 data : ProgramData ::from_bpf_prog_info ( name ,   fd ,   info . 0 ) ? ,  
			
		
	
		
		
			
				
					
					             } ) ,  
			
		
	
		
		
			
				
					
					             bpf_prog_type ::BPF_PROG_TYPE_CGROUP_SOCK_ADDR   = >   {  
			
		
	
		
		
			
				
					
					                 return   Err ( ProgramError ::IncompleteProgramDefinition (  
			
		
	
		
		
			
				
					
					                     "unable to determine attach type." . to_string ( ) ,  
			
		
	
		
		
			
				
					
					                 ) )  
			
		
	
		
		
			
				
					
					             }  
			
		
	
		
		
			
				
					
					             bpf_prog_type ::BPF_PROG_TYPE_LWT_SEG6LOCAL   = >   {  
			
		
	
		
		
			
				
					
					                 return   Err ( ProgramError ::IncompleteProgramDefinition (  
			
		
	
		
		
			
				
					
					                     "not implemented." . to_string ( ) ,  
			
		
	
		
		
			
				
					
					                 ) )  
			
		
	
		
		
			
				
					
					             }  
			
		
	
		
		
			
				
					
					             bpf_prog_type ::BPF_PROG_TYPE_LIRC_MODE2   = >   Program ::LircMode2 ( LircMode2   {  
			
		
	
		
		
			
				
					
					                 data : ProgramData ::from_bpf_prog_info ( name ,   fd ,   info . 0 ) ? ,  
			
		
	
		
		
			
				
					
					             } ) ,  
			
		
	
		
		
			
				
					
					             bpf_prog_type ::BPF_PROG_TYPE_SK_REUSEPORT   = >   {  
			
		
	
		
		
			
				
					
					                 return   Err ( ProgramError ::IncompleteProgramDefinition (  
			
		
	
		
		
			
				
					
					                     "not implemented." . to_string ( ) ,  
			
		
	
		
		
			
				
					
					                 ) )  
			
		
	
		
		
			
				
					
					             }  
			
		
	
		
		
			
				
					
					             bpf_prog_type ::BPF_PROG_TYPE_FLOW_DISSECTOR   = >   {  
			
		
	
		
		
			
				
					
					                 return   Err ( ProgramError ::IncompleteProgramDefinition (  
			
		
	
		
		
			
				
					
					                     "not implemented." . to_string ( ) ,  
			
		
	
		
		
			
				
					
					                 ) )  
			
		
	
		
		
			
				
					
					             }  
			
		
	
		
		
			
				
					
					             bpf_prog_type ::BPF_PROG_TYPE_CGROUP_SYSCTL   = >   Program ::CgroupSysctl ( CgroupSysctl   {  
			
		
	
		
		
			
				
					
					                 data : ProgramData ::from_bpf_prog_info ( name ,   fd ,   info . 0 ) ? ,  
			
		
	
		
		
			
				
					
					             } ) ,  
			
		
	
		
		
			
				
					
					             bpf_prog_type ::BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE   = >   {  
			
		
	
		
		
			
				
					
					                 return   Err ( ProgramError ::IncompleteProgramDefinition (  
			
		
	
		
		
			
				
					
					                     "not implemented." . to_string ( ) ,  
			
		
	
		
		
			
				
					
					                 ) )  
			
		
	
		
		
			
				
					
					             }  
			
		
	
		
		
			
				
					
					             bpf_prog_type ::BPF_PROG_TYPE_CGROUP_SOCKOPT   = >   {  
			
		
	
		
		
			
				
					
					                 return   Err ( ProgramError ::IncompleteProgramDefinition (  
			
		
	
		
		
			
				
					
					                     "unable to determine attach type" . to_string ( ) ,  
			
		
	
		
		
			
				
					
					                 ) )  
			
		
	
		
		
			
				
					
					             }  
			
		
	
		
		
			
				
					
					             bpf_prog_type ::BPF_PROG_TYPE_TRACING   = >   {  
			
		
	
		
		
			
				
					
					                 return   Err ( ProgramError ::IncompleteProgramDefinition (  
			
		
	
		
		
			
				
					
					                     "unable to distinguish between fentry and fexit." . to_string ( ) ,  
			
		
	
		
		
			
				
					
					                 ) )  
			
		
	
		
		
			
				
					
					             }  
			
		
	
		
		
			
				
					
					             bpf_prog_type ::BPF_PROG_TYPE_STRUCT_OPS   = >   {  
			
		
	
		
		
			
				
					
					                 return   Err ( ProgramError ::IncompleteProgramDefinition (  
			
		
	
		
		
			
				
					
					                     "not implemented." . to_string ( ) ,  
			
		
	
		
		
			
				
					
					                 ) )  
			
		
	
		
		
			
				
					
					             }  
			
		
	
		
		
			
				
					
					             bpf_prog_type ::BPF_PROG_TYPE_EXT   = >   Program ::Extension ( Extension   {  
			
		
	
		
		
			
				
					
					                 data : ProgramData ::from_bpf_prog_info ( name ,   fd ,   info . 0 ) ? ,  
			
		
	
		
		
			
				
					
					             } ) ,  
			
		
	
		
		
			
				
					
					             bpf_prog_type ::BPF_PROG_TYPE_LSM   = >   Program ::Lsm ( Lsm   {  
			
		
	
		
		
			
				
					
					                 data : ProgramData ::from_bpf_prog_info ( name ,   fd ,   info . 0 ) ? ,  
			
		
	
		
		
			
				
					
					             } ) ,  
			
		
	
		
		
			
				
					
					             bpf_prog_type ::BPF_PROG_TYPE_SK_LOOKUP   = >   Program ::SkLookup ( SkLookup   {  
			
		
	
		
		
			
				
					
					                 data : ProgramData ::from_bpf_prog_info ( name ,   fd ,   info . 0 ) ? ,  
			
		
	
		
		
			
				
					
					             } ) ,  
			
		
	
		
		
			
				
					
					             bpf_prog_type ::BPF_PROG_TYPE_SYSCALL   = >   {  
			
		
	
		
		
			
				
					
					                 return   Err ( ProgramError ::IncompleteProgramDefinition (  
			
		
	
		
		
			
				
					
					                     "not implemented." . to_string ( ) ,  
			
		
	
		
		
			
				
					
					                 ) )  
			
		
	
		
		
			
				
					
					             }  
			
		
	
		
		
			
				
					
					         } ;  
			
		
	
		
		
			
				
					
					         Ok ( PinnedProgram   {  
			
		
	
		
		
			
				
					
					             path : PathBuf ::from ( path . as_ref ( ) ) ,  
			
		
	
		
		
			
				
					
					             inner : p ,  
			
		
	
		
		
			
				
					
					         } )  
			
		
	
		
		
			
				
					
					     }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					     /// Removes the pinned program from bpffs.
  
			
		
	
		
		
			
				
					
					     pub   fn  unpin ( self )   -> Result < Program ,   io ::Error >   {  
			
		
	
		
		
			
				
					
					         fs ::remove_file ( self . path . clone ( ) ) ? ;  
			
		
	
		
		
			
				
					
					         Ok ( self . inner )  
			
		
	
		
		
			
				
					
					     }  
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					impl   AsRef < Program >   for   PinnedProgram   {  
			
		
	
		
		
			
				
					
					     fn  as_ref ( & self )   -> & Program   {  
			
		
	
		
		
			
				
					
					         & self . inner  
			
		
	
		
		
			
				
					
					     }  
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					impl   AsMut < Program >   for   PinnedProgram   {  
			
		
	
		
		
			
				
					
					     fn  as_mut ( & mut   self )   -> & mut   Program   {  
			
		
	
		
		
			
				
					
					         & mut   self . inner  
			
		
	
		
		
			
				
					
					     }  
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					#[ derive(Debug) ] #[ derive(Debug) ]  
			
		
	
		
		
			
				
					
					pub ( crate )   struct  ProgramData < T : Link >   { pub ( crate )   struct  ProgramData < T : Link >   {  
			
		
	
		
		
			
				
					
					     pub ( crate )   name : Option < String > ,      pub ( crate )   name : Option < String > ,  
			
		
	
		
		
			
				
					
					     pub ( crate )   obj : obj ::Program ,      pub ( crate )   obj : Option < obj ::Program > ,  
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					     pub ( crate )   fd : Option < RawFd > ,      pub ( crate )   fd : Option < RawFd > ,  
			
		
	
		
		
			
				
					
					     pub ( crate )   links : LinkMap < T > ,      pub ( crate )   links : LinkMap < T > ,  
			
		
	
		
		
			
				
					
					     pub ( crate )   expected_attach_type : Option < bpf_attach_type > ,      pub ( crate )   expected_attach_type : Option < bpf_attach_type > ,  
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -418,7 +622,7 @@ impl<T: Link> ProgramData<T> {
 
			
		
	
		
		
			
				
					
					     )   -> ProgramData < T >   {      )   -> ProgramData < T >   {  
			
		
	
		
		
			
				
					
					         ProgramData   {          ProgramData   {  
			
		
	
		
		
			
				
					
					             name ,              name ,  
			
		
	
		
		
			
				
					
					             obj ,              obj : Some ( obj )  ,  
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					             fd : None ,              fd : None ,  
			
		
	
		
		
			
				
					
					             links : LinkMap ::new ( ) ,              links : LinkMap ::new ( ) ,  
			
		
	
		
		
			
				
					
					             expected_attach_type : None ,              expected_attach_type : None ,  
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -429,6 +633,42 @@ impl<T: Link> ProgramData<T> {
 
			
		
	
		
		
			
				
					
					             verifier_log_level ,              verifier_log_level ,  
			
		
	
		
		
			
				
					
					         }          }  
			
		
	
		
		
			
				
					
					     }      }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					     pub ( crate )   fn  from_bpf_prog_info (  
			
		
	
		
		
			
				
					
					         name : Option < String > ,  
			
		
	
		
		
			
				
					
					         fd : RawFd ,  
			
		
	
		
		
			
				
					
					         info : bpf_prog_info ,  
			
		
	
		
		
			
				
					
					     )   -> Result < ProgramData < T > ,   ProgramError >   {  
			
		
	
		
		
			
				
					
					         let   attach_btf_id   =   if   info . attach_btf_id   >   0   {  
			
		
	
		
		
			
				
					
					             Some ( info . attach_btf_id )  
			
		
	
		
		
			
				
					
					         }   else   {  
			
		
	
		
		
			
				
					
					             None  
			
		
	
		
		
			
				
					
					         } ;  
			
		
	
		
		
			
				
					
					         let   attach_btf_obj_fd   =   if   info . attach_btf_obj_id   >   0   {  
			
		
	
		
		
			
				
					
					             let   fd   =   bpf_btf_get_fd_by_id ( info . attach_btf_obj_id ) . map_err ( | io_error |   {  
			
		
	
		
		
			
				
					
					                 ProgramError ::SyscallError   {  
			
		
	
		
		
			
				
					
					                     call : "bpf_btf_get_fd_by_id" . to_string ( ) ,  
			
		
	
		
		
			
				
					
					                     io_error ,  
			
		
	
		
		
			
				
					
					                 }  
			
		
	
		
		
			
				
					
					             } ) ? ;  
			
		
	
		
		
			
				
					
					             Some ( fd   as   u32 )  
			
		
	
		
		
			
				
					
					         }   else   {  
			
		
	
		
		
			
				
					
					             None  
			
		
	
		
		
			
				
					
					         } ;  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					         Ok ( ProgramData   {  
			
		
	
		
		
			
				
					
					             name ,  
			
		
	
		
		
			
				
					
					             obj : None ,  
			
		
	
		
		
			
				
					
					             fd : Some ( fd ) ,  
			
		
	
		
		
			
				
					
					             links : LinkMap ::new ( ) ,  
			
		
	
		
		
			
				
					
					             expected_attach_type : None ,  
			
		
	
		
		
			
				
					
					             attach_btf_obj_fd ,  
			
		
	
		
		
			
				
					
					             attach_btf_id ,  
			
		
	
		
		
			
				
					
					             attach_prog_fd : None ,  
			
		
	
		
		
			
				
					
					             btf_fd : None ,  
			
		
	
		
		
			
				
					
					             verifier_log_level : 0 ,  
			
		
	
		
		
			
				
					
					         } )  
			
		
	
		
		
			
				
					
					     }  
			
		
	
		
		
			
				
					
					} }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					impl < T : Link >   ProgramData < T >   { impl < T : Link >   ProgramData < T >   {  
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -481,6 +721,11 @@ fn load_program<T: Link>(
 
			
		
	
		
		
			
				
					
					     if   fd . is_some ( )   {      if   fd . is_some ( )   {  
			
		
	
		
		
			
				
					
					         return   Err ( ProgramError ::AlreadyLoaded ) ;          return   Err ( ProgramError ::AlreadyLoaded ) ;  
			
		
	
		
		
			
				
					
					     }      }  
			
		
	
		
		
			
				
					
					     if   obj . is_none ( )   {  
			
		
	
		
		
			
				
					
					         // This program was loaded from a pin in bpffs
  
			
		
	
		
		
			
				
					
					         return   Err ( ProgramError ::AlreadyLoaded ) ;  
			
		
	
		
		
			
				
					
					     }  
			
		
	
		
		
			
				
					
					     let   obj   =   obj . as_ref ( ) . unwrap ( ) ;  
			
		
	
		
		
			
				
					
					     let   crate ::obj ::Program   {      let   crate ::obj ::Program   {  
			
		
	
		
		
			
				
					
					         function :         function : 
			
		
	
		
		
			
				
					
					             Function   {              Function   {  
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -833,7 +1078,55 @@ impl ProgramInfo {
 
			
		
	
		
		
			
				
					
					         unsafe   {          unsafe   {  
			
		
	
		
		
			
				
					
					             libc ::close ( fd ) ;              libc ::close ( fd ) ;  
			
		
	
		
		
			
				
					
					         }          }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					         Ok ( ProgramInfo ( info ) )          Ok ( ProgramInfo ( info ) )  
			
		
	
		
		
			
				
					
					     }      }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					     /// Returns the program type.
  
			
		
	
		
		
			
				
					
					     pub   fn  prog_type ( & self )   -> Result < bpf_prog_type ,   ProgramError >   {  
			
		
	
		
		
			
				
					
					         self . 0. type_ . try_into ( )  
			
		
	
		
		
			
				
					
					     }  
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					impl   TryFrom < u32 >   for   bpf_prog_type   {  
			
		
	
		
		
			
				
					
					     type  Error   =   ProgramError ;  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					     fn  try_from ( v : u32 )   -> Result < Self ,   Self ::Error >   {  
			
		
	
		
		
			
				
					
					         use   bpf_prog_type ::* ;  
			
		
	
		
		
			
				
					
					         let   type_   =   match   v   {  
			
		
	
		
		
			
				
					
					             0   = >   BPF_PROG_TYPE_UNSPEC ,  
			
		
	
		
		
			
				
					
					             1   = >   BPF_PROG_TYPE_SOCKET_FILTER ,  
			
		
	
		
		
			
				
					
					             2   = >   BPF_PROG_TYPE_KPROBE ,  
			
		
	
		
		
			
				
					
					             3   = >   BPF_PROG_TYPE_SCHED_CLS ,  
			
		
	
		
		
			
				
					
					             4   = >   BPF_PROG_TYPE_SCHED_ACT ,  
			
		
	
		
		
			
				
					
					             5   = >   BPF_PROG_TYPE_TRACEPOINT ,  
			
		
	
		
		
			
				
					
					             6   = >   BPF_PROG_TYPE_XDP ,  
			
		
	
		
		
			
				
					
					             7   = >   BPF_PROG_TYPE_PERF_EVENT ,  
			
		
	
		
		
			
				
					
					             8   = >   BPF_PROG_TYPE_CGROUP_SKB ,  
			
		
	
		
		
			
				
					
					             9   = >   BPF_PROG_TYPE_CGROUP_SOCK ,  
			
		
	
		
		
			
				
					
					             10   = >   BPF_PROG_TYPE_LWT_IN ,  
			
		
	
		
		
			
				
					
					             11   = >   BPF_PROG_TYPE_LWT_OUT ,  
			
		
	
		
		
			
				
					
					             12   = >   BPF_PROG_TYPE_LWT_XMIT ,  
			
		
	
		
		
			
				
					
					             13   = >   BPF_PROG_TYPE_SOCK_OPS ,  
			
		
	
		
		
			
				
					
					             14   = >   BPF_PROG_TYPE_SK_SKB ,  
			
		
	
		
		
			
				
					
					             15   = >   BPF_PROG_TYPE_CGROUP_DEVICE ,  
			
		
	
		
		
			
				
					
					             16   = >   BPF_PROG_TYPE_SK_MSG ,  
			
		
	
		
		
			
				
					
					             17   = >   BPF_PROG_TYPE_RAW_TRACEPOINT ,  
			
		
	
		
		
			
				
					
					             18   = >   BPF_PROG_TYPE_CGROUP_SOCK_ADDR ,  
			
		
	
		
		
			
				
					
					             19   = >   BPF_PROG_TYPE_LWT_SEG6LOCAL ,  
			
		
	
		
		
			
				
					
					             20   = >   BPF_PROG_TYPE_LIRC_MODE2 ,  
			
		
	
		
		
			
				
					
					             21   = >   BPF_PROG_TYPE_SK_REUSEPORT ,  
			
		
	
		
		
			
				
					
					             22   = >   BPF_PROG_TYPE_FLOW_DISSECTOR ,  
			
		
	
		
		
			
				
					
					             23   = >   BPF_PROG_TYPE_CGROUP_SYSCTL ,  
			
		
	
		
		
			
				
					
					             24   = >   BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE ,  
			
		
	
		
		
			
				
					
					             25   = >   BPF_PROG_TYPE_CGROUP_SOCKOPT ,  
			
		
	
		
		
			
				
					
					             26   = >   BPF_PROG_TYPE_TRACING ,  
			
		
	
		
		
			
				
					
					             27   = >   BPF_PROG_TYPE_STRUCT_OPS ,  
			
		
	
		
		
			
				
					
					             28   = >   BPF_PROG_TYPE_EXT ,  
			
		
	
		
		
			
				
					
					             29   = >   BPF_PROG_TYPE_LSM ,  
			
		
	
		
		
			
				
					
					             30   = >   BPF_PROG_TYPE_SK_LOOKUP ,  
			
		
	
		
		
			
				
					
					             31   = >   BPF_PROG_TYPE_SYSCALL ,  
			
		
	
		
		
			
				
					
					             _   = >   return   Err ( ProgramError ::UnexpectedProgramType ) ,  
			
		
	
		
		
			
				
					
					         } ;  
			
		
	
		
		
			
				
					
					         Ok ( type_ )  
			
		
	
		
		
			
				
					
					     }  
			
		
	
		
		
			
				
					
					} }