Skip to content

Commit 8717bf1

Browse files
committed
aya: add Bpf::many_programs_mut
Store programs in a `hashbrown::HashMap` and expose `get_many_mut`. We can revisit this dependency when rust-lang/rust#97601 is resolved.
1 parent 5b872db commit 8717bf1

File tree

4 files changed

+92
-13
lines changed

4 files changed

+92
-13
lines changed

aya/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ async-io = { workspace = true, optional = true }
1616
aya-obj = { workspace = true, features = ["std"] }
1717
bitflags = { workspace = true }
1818
bytes = { workspace = true }
19+
hashbrown = { workspace = true, default-features = true }
1920
lazy_static = { workspace = true }
2021
libc = { workspace = true }
2122
log = { workspace = true }

aya/src/bpf.rs

+28-1
Original file line numberDiff line numberDiff line change
@@ -768,7 +768,9 @@ impl<'a> Default for BpfLoader<'a> {
768768
#[derive(Debug)]
769769
pub struct Bpf {
770770
maps: HashMap<String, Map>,
771-
programs: HashMap<String, Program>,
771+
// TODO(https://github.com/rust-lang/rust/issues/97601): use `HashMap` when `get_many_mut` is
772+
// stabilized.
773+
programs: hashbrown::HashMap<String, Program>,
772774
}
773775

774776
impl Bpf {
@@ -914,6 +916,31 @@ impl Bpf {
914916
self.programs.get_mut(name)
915917
}
916918

919+
/// Attempts to get mutable references to `N` programs in the map at once.
920+
///
921+
/// Returns an array of length `N` with the results of each query. For soundness, at most one
922+
/// mutable reference will be returned to any value. `None` will be returned if any of the
923+
/// keys are duplicates or missing.
924+
///
925+
/// # Examples
926+
///
927+
/// ```no_run
928+
/// # let mut bpf = aya::Bpf::load(&[])?;
929+
/// use aya::programs::UProbe;
930+
///
931+
/// let [ssl_read, ssl_write ]= bpf.many_programs_mut(["SSL_read", "SSL_write"]).unwrap();
932+
/// let ssl_read: &mut UProbe = ssl_read.try_into()?;
933+
/// let ssl_write: &mut UProbe = ssl_write.try_into()?;
934+
/// ssl_read.load()?;
935+
/// ssl_read.attach(Some("SSL_read"), 0, "libssl", None)?;
936+
/// ssl_write.load()?;
937+
/// ssl_write.attach(Some("SSL_write"), 0, "libssl", None)?;
938+
/// # Ok::<(), aya::BpfError>(())
939+
/// ```
940+
pub fn many_programs_mut<const N: usize>(&mut self, names: [&str; N]) -> Option<[&mut Program; N]> {
941+
self.programs.get_many_mut(names)
942+
}
943+
917944
/// An iterator over all the programs.
918945
///
919946
/// # Examples

aya/src/programs/extension.rs

+3-12
Original file line numberDiff line numberDiff line change
@@ -37,22 +37,13 @@ pub enum ExtensionError {
3737
/// use aya::{BpfLoader, programs::{Xdp, XdpFlags, Extension}};
3838
///
3939
/// let mut bpf = BpfLoader::new().extension("extension").load_file("app.o")?;
40-
/// let mut prog = None;
41-
/// let mut ext = None;
42-
/// for (name, program) in bpf.programs_mut() {
43-
/// match name {
44-
/// "main" => prog = Some(program),
45-
/// "extension" => ext = Some(program),
46-
/// _ => {},
47-
/// }
48-
/// }
49-
///
50-
/// let prog: &mut Xdp = prog.unwrap().try_into()?;
40+
/// let [prog, ext] = bpf.many_programs_mut(["main", "extension"]).unwrap();
41+
/// let prog: &mut Xdp = prog.try_into()?;
5142
/// prog.load()?;
5243
/// prog.attach("eth0", XdpFlags::default())?;
5344
///
5445
/// let prog_fd = prog.fd().unwrap();
55-
/// let ext: &mut Extension = ext.unwrap().try_into()?;
46+
/// let ext: &mut Extension = ext.try_into()?;
5647
/// ext.load(prog_fd, "function_to_replace")?;
5748
/// ext.attach()?;
5849
/// Ok::<(), aya::BpfError>(())

0 commit comments

Comments
 (0)