@@ -201,13 +201,6 @@ struct reloc_desc {
201
201
};
202
202
};
203
203
204
- typedef int (* libbpf_prog_setup_fn_t )(struct bpf_program * prog , long cookie );
205
- typedef int (* libbpf_prog_prepare_load_fn_t )(struct bpf_program * prog ,
206
- struct bpf_prog_load_opts * opts , long cookie );
207
- /* If auto-attach is not supported, callback should return 0 and set link to NULL */
208
- typedef int (* libbpf_prog_attach_fn_t )(const struct bpf_program * prog , long cookie ,
209
- struct bpf_link * * link );
210
-
211
204
/* stored as sec_def->cookie for all libbpf-supported SEC()s */
212
205
enum sec_def_flags {
213
206
SEC_NONE = 0 ,
@@ -235,10 +228,11 @@ enum sec_def_flags {
235
228
};
236
229
237
230
struct bpf_sec_def {
238
- const char * sec ;
231
+ char * sec ;
239
232
enum bpf_prog_type prog_type ;
240
233
enum bpf_attach_type expected_attach_type ;
241
234
long cookie ;
235
+ int handler_id ;
242
236
243
237
libbpf_prog_setup_fn_t prog_setup_fn ;
244
238
libbpf_prog_prepare_load_fn_t prog_prepare_load_fn ;
@@ -8590,7 +8584,7 @@ int bpf_program__set_log_buf(struct bpf_program *prog, char *log_buf, size_t log
8590
8584
}
8591
8585
8592
8586
#define SEC_DEF (sec_pfx , ptype , atype , flags , ...) { \
8593
- .sec = sec_pfx, \
8587
+ .sec = (char *) sec_pfx, \
8594
8588
.prog_type = BPF_PROG_TYPE_##ptype, \
8595
8589
.expected_attach_type = atype, \
8596
8590
.cookie = (long)(flags), \
@@ -8683,61 +8677,167 @@ static const struct bpf_sec_def section_defs[] = {
8683
8677
SEC_DEF ("sk_lookup" , SK_LOOKUP , BPF_SK_LOOKUP , SEC_ATTACHABLE | SEC_SLOPPY_PFX ),
8684
8678
};
8685
8679
8686
- #define MAX_TYPE_NAME_SIZE 32
8680
+ static size_t custom_sec_def_cnt ;
8681
+ static struct bpf_sec_def * custom_sec_defs ;
8682
+ static struct bpf_sec_def custom_fallback_def ;
8683
+ static bool has_custom_fallback_def ;
8687
8684
8688
- static const struct bpf_sec_def * find_sec_def (const char * sec_name )
8685
+ static int last_custom_sec_def_handler_id ;
8686
+
8687
+ int libbpf_register_prog_handler (const char * sec ,
8688
+ enum bpf_prog_type prog_type ,
8689
+ enum bpf_attach_type exp_attach_type ,
8690
+ const struct libbpf_prog_handler_opts * opts )
8689
8691
{
8690
- const struct bpf_sec_def * sec_def ;
8691
- enum sec_def_flags sec_flags ;
8692
- int i , n = ARRAY_SIZE (section_defs ), len ;
8693
- bool strict = libbpf_mode & LIBBPF_STRICT_SEC_NAME ;
8692
+ struct bpf_sec_def * sec_def ;
8694
8693
8695
- for (i = 0 ; i < n ; i ++ ) {
8696
- sec_def = & section_defs [i ];
8697
- sec_flags = sec_def -> cookie ;
8698
- len = strlen (sec_def -> sec );
8694
+ if (!OPTS_VALID (opts , libbpf_prog_handler_opts ))
8695
+ return libbpf_err (- EINVAL );
8699
8696
8700
- /* "type/" always has to have proper SEC("type/extras") form */
8701
- if (sec_def -> sec [len - 1 ] == '/' ) {
8702
- if (str_has_pfx (sec_name , sec_def -> sec ))
8703
- return sec_def ;
8704
- continue ;
8705
- }
8697
+ if (last_custom_sec_def_handler_id == INT_MAX ) /* prevent overflow */
8698
+ return libbpf_err (- E2BIG );
8706
8699
8707
- /* "type+" means it can be either exact SEC("type") or
8708
- * well-formed SEC("type/extras") with proper '/' separator
8709
- */
8710
- if (sec_def -> sec [len - 1 ] == '+' ) {
8711
- len -- ;
8712
- /* not even a prefix */
8713
- if (strncmp (sec_name , sec_def -> sec , len ) != 0 )
8714
- continue ;
8715
- /* exact match or has '/' separator */
8716
- if (sec_name [len ] == '\0' || sec_name [len ] == '/' )
8717
- return sec_def ;
8718
- continue ;
8719
- }
8700
+ if (sec ) {
8701
+ sec_def = libbpf_reallocarray (custom_sec_defs , custom_sec_def_cnt + 1 ,
8702
+ sizeof (* sec_def ));
8703
+ if (!sec_def )
8704
+ return libbpf_err (- ENOMEM );
8720
8705
8721
- /* SEC_SLOPPY_PFX definitions are allowed to be just prefix
8722
- * matches, unless strict section name mode
8723
- * (LIBBPF_STRICT_SEC_NAME) is enabled, in which case the
8724
- * match has to be exact.
8725
- */
8726
- if ((sec_flags & SEC_SLOPPY_PFX ) && !strict ) {
8727
- if (str_has_pfx (sec_name , sec_def -> sec ))
8728
- return sec_def ;
8729
- continue ;
8730
- }
8706
+ custom_sec_defs = sec_def ;
8707
+ sec_def = & custom_sec_defs [custom_sec_def_cnt ];
8708
+ } else {
8709
+ if (has_custom_fallback_def )
8710
+ return libbpf_err (- EBUSY );
8731
8711
8732
- /* Definitions not marked SEC_SLOPPY_PFX (e.g.,
8733
- * SEC("syscall")) are exact matches in both modes.
8734
- */
8735
- if (strcmp (sec_name , sec_def -> sec ) == 0 )
8712
+ sec_def = & custom_fallback_def ;
8713
+ }
8714
+
8715
+ sec_def -> sec = sec ? strdup (sec ) : NULL ;
8716
+ if (sec && !sec_def -> sec )
8717
+ return libbpf_err (- ENOMEM );
8718
+
8719
+ sec_def -> prog_type = prog_type ;
8720
+ sec_def -> expected_attach_type = exp_attach_type ;
8721
+ sec_def -> cookie = OPTS_GET (opts , cookie , 0 );
8722
+
8723
+ sec_def -> prog_setup_fn = OPTS_GET (opts , prog_setup_fn , NULL );
8724
+ sec_def -> prog_prepare_load_fn = OPTS_GET (opts , prog_prepare_load_fn , NULL );
8725
+ sec_def -> prog_attach_fn = OPTS_GET (opts , prog_attach_fn , NULL );
8726
+
8727
+ sec_def -> handler_id = ++ last_custom_sec_def_handler_id ;
8728
+
8729
+ if (sec )
8730
+ custom_sec_def_cnt ++ ;
8731
+ else
8732
+ has_custom_fallback_def = true;
8733
+
8734
+ return sec_def -> handler_id ;
8735
+ }
8736
+
8737
+ int libbpf_unregister_prog_handler (int handler_id )
8738
+ {
8739
+ struct bpf_sec_def * sec_defs ;
8740
+ int i ;
8741
+
8742
+ if (handler_id <= 0 )
8743
+ return libbpf_err (- EINVAL );
8744
+
8745
+ if (has_custom_fallback_def && custom_fallback_def .handler_id == handler_id ) {
8746
+ memset (& custom_fallback_def , 0 , sizeof (custom_fallback_def ));
8747
+ has_custom_fallback_def = false;
8748
+ return 0 ;
8749
+ }
8750
+
8751
+ for (i = 0 ; i < custom_sec_def_cnt ; i ++ ) {
8752
+ if (custom_sec_defs [i ].handler_id == handler_id )
8753
+ break ;
8754
+ }
8755
+
8756
+ if (i == custom_sec_def_cnt )
8757
+ return libbpf_err (- ENOENT );
8758
+
8759
+ free (custom_sec_defs [i ].sec );
8760
+ for (i = i + 1 ; i < custom_sec_def_cnt ; i ++ )
8761
+ custom_sec_defs [i - 1 ] = custom_sec_defs [i ];
8762
+ custom_sec_def_cnt -- ;
8763
+
8764
+ /* try to shrink the array, but it's ok if we couldn't */
8765
+ sec_defs = libbpf_reallocarray (custom_sec_defs , custom_sec_def_cnt , sizeof (* sec_defs ));
8766
+ if (sec_defs )
8767
+ custom_sec_defs = sec_defs ;
8768
+
8769
+ return 0 ;
8770
+ }
8771
+
8772
+ static bool sec_def_matches (const struct bpf_sec_def * sec_def , const char * sec_name ,
8773
+ bool allow_sloppy )
8774
+ {
8775
+ size_t len = strlen (sec_def -> sec );
8776
+
8777
+ /* "type/" always has to have proper SEC("type/extras") form */
8778
+ if (sec_def -> sec [len - 1 ] == '/' ) {
8779
+ if (str_has_pfx (sec_name , sec_def -> sec ))
8780
+ return true;
8781
+ return false;
8782
+ }
8783
+
8784
+ /* "type+" means it can be either exact SEC("type") or
8785
+ * well-formed SEC("type/extras") with proper '/' separator
8786
+ */
8787
+ if (sec_def -> sec [len - 1 ] == '+' ) {
8788
+ len -- ;
8789
+ /* not even a prefix */
8790
+ if (strncmp (sec_name , sec_def -> sec , len ) != 0 )
8791
+ return false;
8792
+ /* exact match or has '/' separator */
8793
+ if (sec_name [len ] == '\0' || sec_name [len ] == '/' )
8794
+ return true;
8795
+ return false;
8796
+ }
8797
+
8798
+ /* SEC_SLOPPY_PFX definitions are allowed to be just prefix
8799
+ * matches, unless strict section name mode
8800
+ * (LIBBPF_STRICT_SEC_NAME) is enabled, in which case the
8801
+ * match has to be exact.
8802
+ */
8803
+ if (allow_sloppy && str_has_pfx (sec_name , sec_def -> sec ))
8804
+ return true;
8805
+
8806
+ /* Definitions not marked SEC_SLOPPY_PFX (e.g.,
8807
+ * SEC("syscall")) are exact matches in both modes.
8808
+ */
8809
+ return strcmp (sec_name , sec_def -> sec ) == 0 ;
8810
+ }
8811
+
8812
+ static const struct bpf_sec_def * find_sec_def (const char * sec_name )
8813
+ {
8814
+ const struct bpf_sec_def * sec_def ;
8815
+ int i , n ;
8816
+ bool strict = libbpf_mode & LIBBPF_STRICT_SEC_NAME , allow_sloppy ;
8817
+
8818
+ n = custom_sec_def_cnt ;
8819
+ for (i = 0 ; i < n ; i ++ ) {
8820
+ sec_def = & custom_sec_defs [i ];
8821
+ if (sec_def_matches (sec_def , sec_name , false))
8822
+ return sec_def ;
8823
+ }
8824
+
8825
+ n = ARRAY_SIZE (section_defs );
8826
+ for (i = 0 ; i < n ; i ++ ) {
8827
+ sec_def = & section_defs [i ];
8828
+ allow_sloppy = (sec_def -> cookie & SEC_SLOPPY_PFX ) && !strict ;
8829
+ if (sec_def_matches (sec_def , sec_name , allow_sloppy ))
8736
8830
return sec_def ;
8737
8831
}
8832
+
8833
+ if (has_custom_fallback_def )
8834
+ return & custom_fallback_def ;
8835
+
8738
8836
return NULL ;
8739
8837
}
8740
8838
8839
+ #define MAX_TYPE_NAME_SIZE 32
8840
+
8741
8841
static char * libbpf_get_type_names (bool attach_type )
8742
8842
{
8743
8843
int i , len = ARRAY_SIZE (section_defs ) * MAX_TYPE_NAME_SIZE ;
0 commit comments