1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
//! A library focused on detecting supported eBPF features on the current host
//!
//! # Background
//!
//! The approaches here taken are similar to the way [bpftool](https://github.com/libbpf/bpftool)
//! probes functionality on the host. We recommend users use the `bpftool feature`
//! subcommand for interactive display of eBPF feature support but we
//! developed this library for incorporating these detection techniques within Rust apps.
//!
//! ## Compatibility with bpftool
//!
//! This library is aimed to exactly match the detection features of `bpftool feature`. If
//! this is not the case, we consider [it a bug](https://github.com/bpfdeploy-io/bpf-rs/issues).
//!
//! As an example of this, we recreated the default output of `bpftool feature` here:
//! [`examples/feature-probe.rs`](https://github.com/bpfdeploy-io/bpf-rs/tree/main/bpf-feature/examples)
//!
//! # JSON
//!
//! We also support JSON output. This is powered by [Serde](https://github.com/serde-rs/serde),
//! a popular serialization crate. Note that the JSON output differs in structure
//! from the output of `bpftool feature probe --json` but semantically should be
//! identical.
//!
//! To see an example of JSON out, see the example
//! [`examples/json-dump.rs`](https://github.com/bpfdeploy-io/bpf-rs/tree/main/bpf-feature/examples).
//!
//! Serialization support is **NOT** enabled by default. Please pass in the `serde`
//! feature to enable.
//!
//! ## Other serialization formats
//!
//! Because of the abstraction Serde provides, we are not restricted to JSON and it
//! is possible to support other serialization formats. This should work out of the
//! box but if issues occur, please let us know.
//!
//! # Design
//!
//! For detecting all functionality, we've exported a singular function [`detect`]
//! that can be configured with options through [`DetectOpts`] (to pass in the
//! defaults you can use [`DetectOpts::default()`]):
//!
//! ```
//! use bpf_feature::{detect, DetectOpts};
//!
//! let features = detect(DetectOpts::default());
//! // ...
//! ```
//!
//! ## Modularity
//!
//! `detect` is not the only entrypoint publicly exported. We have organized
//! related features into modules that export specific detections through a
//! `features()` function:
//!
//! - [`bpf::features`]
//! - [`kernel_config::features`]
//! - [`runtime::features`]
//! - [`misc::features`]
//!
//! This means that in your application can choose which features to run:
//!
//! ```
//! use bpf_feature::kernel_config::{self, KERNEL_CONFIG_KEYS, KernelConfig};
//!
//! match kernel_config::features() {
//! Ok(KernelConfig { values }) => KERNEL_CONFIG_KEYS.iter().for_each(|&key| {
//! match values.get(key) {
//! Some(value) => println!("{} is set to {}", key, value),
//! None => println!("{} is not set", key),
//! };
//! }),
//! Err(err) => println!("skipping kernel config, {}", err),
//! }
//! ```
use Serialize;
/// Results of the entire feature detection set from [`detect`]
/// Options that can be passed into [`detect`]
/// Primary function to run entire feature detection set