@@ -83,6 +83,7 @@ use aya_obj::{
83
83
VerifierLog ,
84
84
btf:: BtfError ,
85
85
generated:: { bpf_attach_type, bpf_link_info, bpf_prog_info, bpf_prog_type} ,
86
+ programs:: XdpAttachType ,
86
87
} ;
87
88
use info:: impl_info;
88
89
pub use info:: { ProgramInfo , ProgramType , loaded_programs} ;
@@ -991,6 +992,212 @@ impl_from_pin!(
991
992
Iter ,
992
993
) ;
993
994
995
+ macro_rules! impl_from_prog_info {
996
+ ( $( ( $struct_name: ident, $prog_type: expr, $unsafe: ident $( , $var: ident, $var_ty: ty) ?) ) ,* $( , ) ?) => {
997
+ $(
998
+ impl_from_prog_info!( $struct_name, $prog_type, $unsafe $( , $var, $var_ty) ?) ;
999
+ ) *
1000
+ } ;
1001
+ ( $struct_name: ident, $prog_type: expr, false ) => {
1002
+ impl $struct_name {
1003
+ /// Constructs an instance of a Program from a [`ProgramInfo`].
1004
+ ///
1005
+ /// This allows the caller to get a handle to an already loaded
1006
+ /// program from the kernel without having to load it again.
1007
+ ///
1008
+ /// # Errors
1009
+ ///
1010
+ /// - If the program type reported by the kernel does not match
1011
+ /// that of the type you're converting to.
1012
+ /// - If the file descriptor of the program cannot be cloned.
1013
+ pub fn from_program_info(
1014
+ name: Option <& ' static str >,
1015
+ info: ProgramInfo ,
1016
+ ) -> Result <Self , ProgramError > {
1017
+ if info. program_type( ) ? != $prog_type {
1018
+ return Err ( ProgramError :: UnexpectedProgramType { } ) ;
1019
+ }
1020
+ let ProgramInfo { 0 : bpf_progam_info} = info;
1021
+ let fd = info. fd( ) ?;
1022
+ let fd = fd. as_fd( ) . try_clone_to_owned( ) ?;
1023
+
1024
+ Ok ( Self {
1025
+ data: ProgramData :: from_bpf_prog_info(
1026
+ name. map( |n| Cow :: Borrowed ( n) ) ,
1027
+ crate :: MockableFd :: from_fd( fd) ,
1028
+ Path :: new( "" ) ,
1029
+ bpf_progam_info,
1030
+ VerifierLogLevel :: default ( ) ,
1031
+ ) ?,
1032
+ } )
1033
+ }
1034
+ }
1035
+ } ;
1036
+ ( $struct_name: ident, $prog_type: expr, true ) => {
1037
+ impl $struct_name {
1038
+ /// Constructs an instance of a Program from a [`ProgramInfo`].
1039
+ ///
1040
+ /// This allows the caller to get a handle to an already loaded
1041
+ /// program from the kernel without having to load it again.
1042
+ ///
1043
+ /// # Errors
1044
+ ///
1045
+ /// - If the program type reported by the kernel does not match
1046
+ /// that of the type you're converting to.
1047
+ /// - If the file descriptor of the program cannot be cloned.
1048
+ ///
1049
+ /// # Safety
1050
+ ///
1051
+ /// We can't safely cast to `ProgramInfo` since we don't know the
1052
+ /// concrete type of the program. It's up to the caller to ensure
1053
+ /// that the program type matches the type you're converting to.
1054
+ /// Otherwise, the behavior is undefined.
1055
+ pub unsafe fn from_program_info(
1056
+ name: Option <& ' static str >,
1057
+ info: ProgramInfo ,
1058
+ ) -> Result <Self , ProgramError > {
1059
+ if info. program_type( ) ? != $prog_type {
1060
+ return Err ( ProgramError :: UnexpectedProgramType { } ) ;
1061
+ }
1062
+ let ProgramInfo { 0 : bpf_progam_info} = info;
1063
+ let fd = info. fd( ) ?;
1064
+ let fd = fd. as_fd( ) . try_clone_to_owned( ) ?;
1065
+
1066
+ Ok ( Self {
1067
+ data: ProgramData :: from_bpf_prog_info(
1068
+ name. map( |n| Cow :: Borrowed ( n) ) ,
1069
+ crate :: MockableFd :: from_fd( fd) ,
1070
+ Path :: new( "" ) ,
1071
+ bpf_progam_info,
1072
+ VerifierLogLevel :: default ( ) ,
1073
+ ) ?,
1074
+ } )
1075
+ }
1076
+ }
1077
+ } ;
1078
+ ( $struct_name: ident, $prog_type: expr, false , $var: ident, $var_ty: ty) => {
1079
+ impl $struct_name {
1080
+ /// Constructs an instance of a Program from a [`ProgramInfo`].
1081
+ ///
1082
+ /// This allows the caller to get a handle to an already loaded
1083
+ /// program from the kernel without having to load it again.
1084
+ ///
1085
+ /// # Errors
1086
+ ///
1087
+ /// - If the program type reported by the kernel does not match
1088
+ /// that of the type you're converting to.
1089
+ /// - If the file descriptor of the program cannot be cloned.
1090
+ pub fn from_program_info(
1091
+ name: Option <& ' static str >,
1092
+ info: ProgramInfo ,
1093
+ $var: $var_ty,
1094
+ ) -> Result <Self , ProgramError > {
1095
+ if info. program_type( ) ? != $prog_type {
1096
+ return Err ( ProgramError :: UnexpectedProgramType { } ) ;
1097
+ }
1098
+ let ProgramInfo { 0 : bpf_progam_info} = info;
1099
+ let fd = info. fd( ) ?;
1100
+ let fd = fd. as_fd( ) . try_clone_to_owned( ) ?;
1101
+
1102
+ Ok ( Self {
1103
+ data: ProgramData :: from_bpf_prog_info(
1104
+ name. map( |n| Cow :: Borrowed ( n) ) ,
1105
+ crate :: MockableFd :: from_fd( fd) ,
1106
+ Path :: new( "" ) ,
1107
+ bpf_progam_info,
1108
+ VerifierLogLevel :: default ( ) ,
1109
+ ) ?,
1110
+ $var,
1111
+ } )
1112
+ }
1113
+ }
1114
+ } ;
1115
+ ( $struct_name: ident, $prog_type: expr, true , $var: ident, $var_ty: ty) => {
1116
+ impl $struct_name {
1117
+ /// Constructs an instance of a Program from a [`ProgramInfo`].
1118
+ ///
1119
+ /// This allows the caller to get a handle to an already loaded
1120
+ /// program from the kernel without having to load it again.
1121
+ ///
1122
+ /// # Errors
1123
+ ///
1124
+ /// - If the program type reported by the kernel does not match
1125
+ /// that of the type you're converting to.
1126
+ /// - If the file descriptor of the program cannot be cloned.
1127
+ ///
1128
+ /// # Safety
1129
+ ///
1130
+ /// We can't safely cast to `ProgramInfo` since we don't know the
1131
+ /// concrete type of the program. It's up to the caller to ensure
1132
+ /// that the program type matches the type you're converting to.
1133
+ /// Otherwise, the behavior is undefined.
1134
+ pub unsafe fn from_program_info(
1135
+ name: Option <& ' static str >,
1136
+ info: ProgramInfo ,
1137
+ $var: $var_ty,
1138
+ ) -> Result <Self , ProgramError > {
1139
+ if info. program_type( ) ? != $prog_type {
1140
+ return Err ( ProgramError :: UnexpectedProgramType { } ) ;
1141
+ }
1142
+ let ProgramInfo { 0 : bpf_progam_info} = info;
1143
+ let fd = info. fd( ) ?;
1144
+ let fd = fd. as_fd( ) . try_clone_to_owned( ) ?;
1145
+
1146
+ Ok ( Self {
1147
+ data: ProgramData :: from_bpf_prog_info(
1148
+ name. map( |n| Cow :: Borrowed ( n) ) ,
1149
+ crate :: MockableFd :: from_fd( fd) ,
1150
+ Path :: new( "" ) ,
1151
+ bpf_progam_info,
1152
+ VerifierLogLevel :: default ( ) ,
1153
+ ) ?,
1154
+ $var,
1155
+ } )
1156
+ }
1157
+ }
1158
+ } ;
1159
+ }
1160
+
1161
+ // Order of arguments is as follows:
1162
+ // - Program, bpf_prog_type, unsafe
1163
+ // - Program, bpf_prog_type, unsafe, additional variable, variable type
1164
+ impl_from_prog_info ! (
1165
+ ( KProbe , ProgramType :: KProbe , true , kind, ProbeKind ) ,
1166
+ ( UProbe , ProgramType :: KProbe , true , kind, ProbeKind ) ,
1167
+ ( TracePoint , ProgramType :: TracePoint , false ) ,
1168
+ ( SocketFilter , ProgramType :: SocketFilter , false ) ,
1169
+ ( Xdp , ProgramType :: Xdp , false , attach_type, XdpAttachType ) ,
1170
+ ( SkMsg , ProgramType :: SkMsg , false ) ,
1171
+ ( SkSkb , ProgramType :: SkSkb , false , kind, SkSkbKind ) ,
1172
+ ( SockOps , ProgramType :: SockOps , false ) ,
1173
+ ( SchedClassifier , ProgramType :: SchedClassifier , false ) ,
1174
+ (
1175
+ CgroupSkb ,
1176
+ ProgramType :: CgroupSkb ,
1177
+ false ,
1178
+ attach_type,
1179
+ Option <CgroupSkbAttachType >
1180
+ ) ,
1181
+ ( CgroupSysctl , ProgramType :: CgroupSysctl , false ) ,
1182
+ (
1183
+ CgroupSockopt ,
1184
+ ProgramType :: CgroupSockopt ,
1185
+ false ,
1186
+ attach_type,
1187
+ CgroupSockoptAttachType
1188
+ ) ,
1189
+ ( LircMode2 , ProgramType :: LircMode2 , false ) ,
1190
+ ( PerfEvent , ProgramType :: PerfEvent , false ) ,
1191
+ ( Lsm , ProgramType :: Lsm , false ) ,
1192
+ ( RawTracePoint , ProgramType :: RawTracePoint , false ) ,
1193
+ ( BtfTracePoint , ProgramType :: Tracing , true ) ,
1194
+ ( FEntry , ProgramType :: Tracing , true ) ,
1195
+ ( FExit , ProgramType :: Tracing , true ) ,
1196
+ ( Extension , ProgramType :: Extension , false ) ,
1197
+ ( SkLookup , ProgramType :: SkLookup , false ) ,
1198
+ ( CgroupDevice , ProgramType :: CgroupDevice , false ) ,
1199
+ ) ;
1200
+
994
1201
macro_rules! impl_try_from_program {
995
1202
( $( $ty: ident) ,+ $( , ) ?) => {
996
1203
$(
0 commit comments