Skip to content

Commit aaa170a

Browse files
committed
Use Aya in the userspace
This change replaces libbpf-rs with Aya as a loader of eBPF programs in the userspace part in lockc. eBPF programs still remain written in C and are going to be rewritten in Rust in separate changes. Another change is change of logging library to tracing. Fixes: #135 Fixes: #106 Signed-off-by: Michal Rostecki <[email protected]>
1 parent 2e4b839 commit aaa170a

File tree

15 files changed

+785
-990
lines changed

15 files changed

+785
-990
lines changed

Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
[workspace]
22
members = [
33
"lockc",
4-
"lockc-uprobes",
54
"xtask",
65
]

lockc-uprobes/Cargo.toml

Lines changed: 0 additions & 9 deletions
This file was deleted.

lockc-uprobes/src/lib.rs

Lines changed: 0 additions & 13 deletions
This file was deleted.

lockc/Cargo.toml

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,38 +12,31 @@ license = "Apache-2.0 AND GPL-2.0-or-later"
1212
[badges]
1313
maintenance = { status = "actively-developed" }
1414

15-
[lib]
16-
name = "lockc"
17-
1815
[dependencies]
1916
anyhow = "1.0"
17+
aya = { git = "https://github.com/aya-rs/aya", branch = "main", features=["async_tokio"] }
2018
bindgen = "0.59"
2119
byteorder = "1.4"
22-
chrono = { version = "0.4", default-features = false, features = ["clock"] }
20+
clap = { version = "3.0", features = ["derive"] }
2321
config = { version = "0.11", default-features = false, features = ["toml"] }
24-
ctrlc = "3.2"
2522
fanotify-rs = { git = "https://github.com/vadorovsky/fanotify-rs", branch = "fix-pid-type" }
2623
futures = "0.3"
27-
goblin = "0.4"
2824
kube = "0.67"
2925
k8s-openapi = { version = "0.14", default-features = false, features = ["v1_23"] }
3026
lazy_static = "1.4"
3127
libc = { version = "0.2", features = [ "extra_traits" ] }
32-
libbpf-rs = "0.14"
33-
lockc-uprobes = { path = "../lockc-uprobes" }
3428
log = "0.4"
3529
nix = "0.23"
36-
plain = "0.2"
3730
procfs = "0.12"
3831
regex = { version = "1.5", default-features = false, features = ["perf"] }
3932
scopeguard = "1.1"
4033
serde = "1.0"
4134
serde_json = "1.0"
42-
simplelog = "0.11"
43-
sysctl = "0.4"
4435
thiserror = "1.0"
4536
tokio = { version = "1.7", features = ["macros", "process", "rt-multi-thread"] }
46-
which = "4.2"
37+
tracing = "0.1"
38+
tracing-core = "0.1"
39+
tracing-subscriber = { version = "0.3", features = ["json"] }
4740

4841
[build-dependencies]
4942
anyhow = "1.0"
@@ -55,3 +48,6 @@ thiserror = "1.0"
5548

5649
[dev-dependencies]
5750
tempfile = "3.2.0"
51+
52+
[features]
53+
tests_bpf = []

lockc/src/bin/lockcd.rs

Lines changed: 0 additions & 42 deletions
This file was deleted.

lockc/src/bpfstructs.rs

Lines changed: 30 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -5,64 +5,52 @@
55
#![allow(non_snake_case)]
66
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
77

8-
use byteorder::{NativeEndian, WriteBytesExt};
8+
use std::ffi::CString;
99

10-
#[derive(thiserror::Error, Debug)]
10+
use thiserror::Error;
11+
12+
#[derive(Error, Debug)]
1113
pub enum NewBpfstructError {
12-
#[error("FFI nul error")]
14+
#[error(transparent)]
1315
NulError(#[from] std::ffi::NulError),
14-
}
15-
16-
#[derive(thiserror::Error, Debug)]
17-
pub enum MapOperationError {
18-
#[error("could not convert the key to a byte array")]
19-
ByteWriteError(#[from] std::io::Error),
20-
21-
#[error("libbpf error")]
22-
LibbpfError(#[from] libbpf_rs::Error),
23-
}
2416

25-
/// Deletes an entry from the given map under the given key.
26-
pub fn map_delete(map: &mut libbpf_rs::Map, key: u32) -> Result<(), MapOperationError> {
27-
let mut key_b = vec![];
28-
key_b.write_u32::<NativeEndian>(key)?;
29-
30-
map.delete(&key_b)?;
31-
32-
Ok(())
17+
#[error("could not convert Vec<u8> to CString")]
18+
VecU8CStringConv,
3319
}
3420

35-
pub trait BpfStruct {
36-
/// Updates the given map with an entry under the given key and a value
37-
/// with a binary representation of the struct.
38-
fn map_update(&self, map: &mut libbpf_rs::Map, key: u32) -> Result<(), MapOperationError> {
39-
let mut key_b = vec![];
40-
key_b.write_u32::<NativeEndian>(key)?;
41-
42-
let val_b = unsafe { plain::as_bytes(self) };
43-
44-
map.update(&key_b, val_b, libbpf_rs::MapFlags::empty())?;
45-
46-
Ok(())
47-
}
48-
}
49-
50-
impl BpfStruct for container {}
51-
impl BpfStruct for process {}
52-
impl BpfStruct for accessed_path {}
53-
5421
impl accessed_path {
5522
/// Creates a new accessed_path instance and converts the given Rust string
5623
/// into C fixed-size char array.
5724
pub fn new(path: &str) -> Result<Self, NewBpfstructError> {
58-
let mut path_b = std::ffi::CString::new(path)?.into_bytes_with_nul();
25+
let mut path_b = CString::new(path)?.into_bytes_with_nul();
5926
path_b.resize(PATH_LEN as usize, 0);
6027
Ok(accessed_path {
61-
path: path_b.try_into().unwrap(),
28+
path: path_b
29+
.try_into()
30+
.map_err(|_| NewBpfstructError::VecU8CStringConv)?,
6231
})
6332
}
6433
}
6534

35+
impl container_id {
36+
/// Creates a new container_id instance and converts the given Rust string
37+
/// into C fixed size char array.
38+
pub fn new(id: &str) -> Result<Self, NewBpfstructError> {
39+
let mut id_b = CString::new(id)?.into_bytes_with_nul();
40+
id_b.resize(CONTAINER_ID_LIMIT as usize, 0);
41+
Ok(container_id {
42+
id: id_b
43+
.try_into()
44+
.map_err(|_| NewBpfstructError::VecU8CStringConv)?,
45+
})
46+
}
47+
}
48+
49+
unsafe impl aya::Pod for accessed_path {}
50+
unsafe impl aya::Pod for container {}
51+
unsafe impl aya::Pod for container_id {}
52+
unsafe impl aya::Pod for process {}
53+
6654
#[cfg(test)]
6755
mod tests {
6856
use super::*;

lockc/src/communication.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
use tokio::sync::oneshot;
2+
3+
use crate::{bpfstructs::container_policy_level, maps::MapOperationError};
4+
5+
/// Set of commands that the fanotify thread can send to the eBPF thread
6+
/// to request eBPF map operations.
7+
#[derive(Debug)]
8+
pub enum EbpfCommand {
9+
AddContainer {
10+
container_id: String,
11+
pid: i32,
12+
policy_level: container_policy_level,
13+
responder_tx: oneshot::Sender<Result<(), MapOperationError>>,
14+
},
15+
DeleteContainer {
16+
container_id: String,
17+
responder_tx: oneshot::Sender<Result<(), MapOperationError>>,
18+
},
19+
AddProcess {
20+
container_id: String,
21+
pid: i32,
22+
responder_tx: oneshot::Sender<Result<(), MapOperationError>>,
23+
},
24+
}

0 commit comments

Comments
 (0)