@ -66,9 +66,9 @@ pub mod xdp;
 
		
	
		
			
				use   libc ::ENOSPC ;  
		
	
		
			
				use   std ::{  
		
	
		
			
				     ffi ::CString ,  
		
	
		
			
				     ,  
		
	
		
			
				     fs,    io,  
		
	
		
			
				     os ::unix ::io ::{ AsRawFd ,   RawFd } ,  
		
	
		
			
				     path ::Path ,  
		
	
		
			
				     path ::{ Path ,   PathBuf } ,  
		
	
		
			
				} ;  
		
	
		
			
				use   thiserror ::Error ;  
		
	
		
			
				
 
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -106,8 +106,9 @@ use crate::{
 
		
	
		
			
				     obj ::{ self ,   btf ::BtfError ,   Function ,   KernelVersion } ,  
		
	
		
			
				     pin ::PinError ,  
		
	
		
			
				     sys ::{  
		
	
		
			
				         bpf_get_object ,   bpf_load_program ,   bpf_pin_object ,   bpf_prog_get_fd_by_id ,  
		
	
		
			
				         bpf_prog_get_info_by_fd ,   bpf_prog_query ,   retry_with_verifier_logs ,   BpfLoadProgramAttrs ,  
		
	
		
			
				         bpf_btf_get_fd_by_id ,   bpf_get_object ,   bpf_load_program ,   bpf_pin_object ,  
		
	
		
			
				         bpf_prog_get_fd_by_id ,   bpf_prog_get_info_by_fd ,   bpf_prog_query ,   retry_with_verifier_logs ,  
		
	
		
			
				         BpfLoadProgramAttrs ,  
		
	
		
			
				     } ,  
		
	
		
			
				     util ::VerifierLog ,  
		
	
		
			
				} ;  
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -204,6 +205,10 @@ pub enum ProgramError {
 
		
	
		
			
				         /// program name
  
		
	
		
			
				         name : String ,  
		
	
		
			
				     } ,  
		
	
		
			
				
 
		
	
		
			
				     /// The program defintion is incomplete.
  
		
	
		
			
				     #[ error( " incomplete program defintion. {0} " ) ]  
		
	
		
			
				     IncompleteProgramDefinition ( String ) ,  
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				/// 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) ]  
		
	
		
			
				pub ( crate )   struct  ProgramData < T : Link >   {  
		
	
		
			
				     pub ( crate )   name : Option < String > ,  
		
	
		
			
				     pub ( crate )   obj : obj ::Program ,  
		
	
		
			
				     pub ( crate )   obj : Option < obj ::Program > ,  
		
	
		
			
				     pub ( crate )   fd : Option < RawFd > ,  
		
	
		
			
				     pub ( crate )   links : LinkMap < T > ,  
		
	
		
			
				     pub ( crate )   expected_attach_type : Option < bpf_attach_type > ,  
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
			
			@ -418,7 +622,7 @@ impl<T: Link> ProgramData<T> {
 
		
	
		
			
				     )   -> ProgramData < T >   {  
		
	
		
			
				         ProgramData   {  
		
	
		
			
				             name ,  
		
	
		
			
				             obj ,  
		
	
		
			
				             obj : Some ( obj )  ,  
		
	
		
			
				             fd : None ,  
		
	
		
			
				             links : LinkMap ::new ( ) ,  
		
	
		
			
				             expected_attach_type : None ,  
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
			
			@ -429,6 +633,42 @@ impl<T: Link> ProgramData<T> {
 
		
	
		
			
				             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 >   {  
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -481,6 +721,11 @@ fn load_program<T: Link>(
 
		
	
		
			
				     if   fd . is_some ( )   {  
		
	
		
			
				         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   {  
		
	
		
			
				         function : 
		
	
		
			
				             Function   {  
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -833,7 +1078,55 @@ impl ProgramInfo {
 
		
	
		
			
				         unsafe   {  
		
	
		
			
				             libc ::close ( fd ) ;  
		
	
		
			
				         }  
		
	
		
			
				
 
		
	
		
			
				         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_ )  
		
	
		
			
				     }  
		
	
		
			
				}