1
+ //! Features derived from compile-time kernel configuration
2
+ //!
3
+ //! The Linux kernel accepts an assortment of flags that can be enabled or disabled
4
+ //! at compilation. These configuration flags are used to determine which eBPF
5
+ //! features are eventually available on the running kernel.
6
+ //!
7
+ //! Depending on your distribution, your kernel config can be available in a number
8
+ //! of locations such as:
9
+ //!
10
+ //! - `/proc/config.gz`
11
+ //! - `/boot/config`
12
+ //! - `/boot/config-$(uname -r)`
13
+ //!
14
+ //! This module will search for and read your kernel configuration for relevant
15
+ //! eBPF flags. If you believe a flag is missing or incorrectly added to
16
+ //! the set in [`KERNEL_CONFIG_KEYS`], please file [an issue](https://github.com/bpfdeploy-io/bpf-rs).
1
17
use flate2:: bufread:: GzDecoder ;
2
18
use nix:: sys:: utsname;
3
19
use std:: {
@@ -13,40 +29,7 @@ use bpf_rs_macros::SerializeFromDisplay;
13
29
#[ cfg( feature = "serde" ) ]
14
30
use serde:: Serialize ;
15
31
16
- #[ non_exhaustive]
17
- #[ derive( ThisError , Debug ) ]
18
- #[ cfg_attr( feature = "serde" , derive( Serialize ) ) ]
19
- pub enum KernelConfigError {
20
- #[ error( "can't open file" ) ]
21
- NotFound ,
22
- #[ error( "file data format unknown" ) ]
23
- ContentsUnknown ,
24
- #[ error( "can't read from file" ) ]
25
- ReadFail ,
26
- }
27
-
28
- #[ derive( Debug ) ]
29
- #[ cfg_attr( feature = "serde" , derive( SerializeFromDisplay ) ) ]
30
- pub enum ConfigValue {
31
- Y ,
32
- N ,
33
- M ,
34
- Other ( String ) ,
35
- }
36
-
37
- impl Display for ConfigValue {
38
- fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
39
- match self {
40
- ConfigValue :: Y => write ! ( f, "y" ) ,
41
- ConfigValue :: N => write ! ( f, "n" ) ,
42
- ConfigValue :: M => write ! ( f, "m" ) ,
43
- ConfigValue :: Other ( value) => write ! ( f, "{}" , value) ,
44
- }
45
- }
46
- }
47
-
48
- pub type KernelConfigValues = HashMap < & ' static str , ConfigValue > ;
49
-
32
+ /// Entire set of kernel config flags to determine support of
50
33
pub const KERNEL_CONFIG_KEYS : [ & ' static str ; 35 ] = [
51
34
"CONFIG_BPF" ,
52
35
"CONFIG_BPF_SYSCALL" ,
@@ -85,9 +68,63 @@ pub const KERNEL_CONFIG_KEYS: [&'static str; 35] = [
85
68
"CONFIG_HZ" ,
86
69
] ;
87
70
71
+
72
+ /// Possible errors when reading a kernel's config file
73
+ #[ non_exhaustive]
74
+ #[ derive( ThisError , Debug ) ]
75
+ #[ cfg_attr( feature = "serde" , derive( Serialize ) ) ]
76
+ pub enum KernelConfigError {
77
+ /// Kernel config file was not found
78
+ #[ error( "can't open file" ) ]
79
+ NotFound ,
80
+ /// Could not parse contents of config file
81
+ #[ error( "file data format unknown" ) ]
82
+ ContentsUnknown ,
83
+ /// IO error reading the config file
84
+ #[ error( "can't read from file" ) ]
85
+ ReadFail ,
86
+ }
87
+
88
+ /// Variant of possible config values (e.g. `y`, `n`, `m` etc.)
89
+ #[ derive( Debug ) ]
90
+ #[ cfg_attr( feature = "serde" , derive( SerializeFromDisplay ) ) ]
91
+ pub enum ConfigValue {
92
+ /// This kernel feature is available.
93
+ Y ,
94
+ /// This kernel feature is **NOT** available.
95
+ ///
96
+ /// This might mean that you need to upgrade your kernel, flag an issue
97
+ /// with your Linux distro or compile your own kernel to get the necessary
98
+ /// functionality.
99
+ N ,
100
+ /// This kernel feature is available *as a module only*.
101
+ ///
102
+ /// This means that the feature is available on your system as a kernel
103
+ /// module but might require privileged enabling of it to gain functionality.
104
+ M ,
105
+ /// This kernel flag is an unstructured value determined at compile time
106
+ Other ( String ) ,
107
+ }
108
+
109
+ impl Display for ConfigValue {
110
+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
111
+ match self {
112
+ ConfigValue :: Y => write ! ( f, "y" ) ,
113
+ ConfigValue :: N => write ! ( f, "n" ) ,
114
+ ConfigValue :: M => write ! ( f, "m" ) ,
115
+ ConfigValue :: Other ( value) => write ! ( f, "{}" , value) ,
116
+ }
117
+ }
118
+ }
119
+
120
+ type KernelConfigValues = HashMap < & ' static str , ConfigValue > ;
121
+
122
+ /// Primarily just a wrapper for kernel config values
88
123
#[ derive( Debug ) ]
89
124
#[ cfg_attr( feature = "serde" , derive( Serialize ) ) ]
90
125
pub struct KernelConfig {
126
+ /// A HashMap of kernel config values with the key being the
127
+ /// flag and the value derived from reading the kernel config file
91
128
#[ cfg_attr( feature = "serde" , serde( flatten) ) ]
92
129
pub values : KernelConfigValues ,
93
130
}
@@ -157,6 +194,8 @@ impl KernelConfig {
157
194
}
158
195
}
159
196
197
+ /// This module's main function to read and determine support of kernel config
198
+ /// flags
160
199
pub fn features ( ) -> Result < KernelConfig , KernelConfigError > {
161
200
return Ok ( KernelConfig {
162
201
values : KernelConfig :: probe_kernel_config ( ) ?,
0 commit comments