Skip to content

[rebase] feat(aya): add support for map-of-maps (HashOfMaps, ArrayOfMaps)#1564

Open
OliverGavin wants to merge 18 commits into
aya-rs:mainfrom
OliverGavin:hashmapofmaps-new
Open

[rebase] feat(aya): add support for map-of-maps (HashOfMaps, ArrayOfMaps)#1564
OliverGavin wants to merge 18 commits into
aya-rs:mainfrom
OliverGavin:hashmapofmaps-new

Conversation

@OliverGavin
Copy link
Copy Markdown

@OliverGavin OliverGavin commented May 9, 2026

Summary

Continuation of #1446 (by @Brskt), rebased onto current main to resolve conflicts.

It adds BTF-only support for BPF map-of-maps (BPF_MAP_TYPE_HASH_OF_MAPS and BPF_MAP_TYPE_ARRAY_OF_MAPS)

Conflict resolution notes

  • btf_map_def! macro syntax change (= $init for extra fields) required updating bloom_filter.rs in the first commit
  • alloc imports replaced with std equivalents (no_std was removed from aya-obj on main)
  • PERF_MAX_STACK_DEPTH uses the imported binding with as usize cast (local const was removed on main)
  • Added ReusePortSockArray arm to Map::fd() (new variant on main)
  • bool::then clippy fix (1 line change)
  • Public API fixtures need regeneration

Checklist

  • Rust code has been formatted with cargo +nightly fmt.
  • All clippy lints have been fixed.
    You can find failing lints with cargo xtask clippy.
  • Unit tests are passing locally with cargo test.
  • The [Integration tests] are passing locally.
  • I have blessed any API changes with cargo xtask public-api --bless.

This change is Reviewable

Brskt added 11 commits May 8, 2026 16:24
This adds support for BPF_MAP_TYPE_ARRAY_OF_MAPS and
BPF_MAP_TYPE_HASH_OF_MAPS on the eBPF side.

Implements:
- ArrayOfMaps and HashOfMaps for legacy maps
- ArrayOfMaps and HashOfMaps for BTF maps
- InnerMap sealed trait to mark types usable as inner maps
Adds the `inner` attribute to specify the inner map type for
map-of-maps (ArrayOfMaps and HashOfMaps).

Example usage:
  #[map]
  static OUTER: ArrayOfMaps<Array<u32>, 4> = ArrayOfMaps::new(0);

  #[map(inner = "OUTER")]
  static INNER: Array<u32> = Array::with_max_entries(1, 0);
Adds userspace support for BPF_MAP_TYPE_ARRAY_OF_MAPS and
BPF_MAP_TYPE_HASH_OF_MAPS.

Key changes:
- aya-obj: track inner map definitions and initial map FDs
- aya: Array and HashMap of_maps modules with get/set/iter
- aya: populate inner maps during EbpfLoader::load()
- Automatic inner map creation from BTF map definitions
Tests for ArrayOfMaps and HashOfMaps:
- Legacy maps with manual inner map setup
- BTF maps with automatic inner map creation
- Dynamic inner map allocation at runtime
- Also adds prog_array tests for ProgramArray
- Add sealed InnerMap trait; set()/insert() now take &impl InnerMap
  instead of &MapFd for compile-time validation
- Implement InnerMap for all kernel-supported inner map types,
  MapData, and MapFd
- Add pub(crate) map_fd() to PerfEventArray and RingBuf for
  InnerMap impls (different field layout than other map types)
- Remove fd()/map_data() from Array, HashMap; remove fd() from
  ArrayOfMaps, HashOfMaps
- Flatten nested if in bpf.rs inner_map_fd logic
- Update integration tests to pass &map instead of map.fd()
Enrich the sealed Map trait with Key and Value associated types so that
map-of-maps containers can perform fused two-level lookups without
intermediate struct indirection. This reduces BPF verifier state
explosion in tight loops.

eBPF side:
- Add Key/Value to private::Map and public Map with blanket forwarding.
- Introduce impl_private_map! macro to replace per-file boilerplate.
- Add get_value/get_value_ptr_mut to ArrayOfMaps and HashOfMaps.

Userspace side:
- Restructure inner map BTF/fallback logic in bpf.rs.
- Add V type parameter to ArrayOfMaps and HashOfMaps.
- Refactor impl_try_from_map! with @impl internal rule and add
  impl_try_from_map_of_maps! for unconstrained V.
Test fused lookups on both ArrayOfMaps and HashOfMaps: userspace
pre-populates inner maps, the eBPF program reads via get_value and
writes via get_value_ptr_mut, then userspace verifies the results.
Replace `map_fd()` with `map_data()` on `RingBuf` and `PerfEventArray`,
returning `&MapData`. Update sealed `InnerMap` impls to use
`map_data().fd()`.

Also clean up `of_maps` docs/tests:
- remove untyped-handle wording
- remove redundant type ascriptions/default type parameters
- use typed literals where inference needs help (`1u32`, `&1u32`)
Remove redundant `Key`/`Value` associated types from the public `Map` trait;
they resolve through the sealed `private::Map` supertrait.

Drop `impl_private_map!` in favor of explicit `private::Map` impls in map
modules, and simplify projections from `<T as Map>::Key` to `T::Key`
(and same for `Value`).
Simplify FromMapData and InnerMap into pure marker traits, moving
methods into their sealed supertraits. Rename inner_map_fd to fd
and error field name to outer_name for clarity.

Constrain V to InnerMap in map-of-maps TryFrom impls. Remove explicit
MapData type params from of_maps tests in favor of defaults.

In integration tests, rename OUTER to ARRAY_OF_MAPS, replace
Array<u32, 4> with Array<TestResult, 1> for named fields, and make
trigger functions const extern "C" fn.
@OliverGavin OliverGavin requested a review from a team as a code owner May 9, 2026 00:08
@netlify
Copy link
Copy Markdown

netlify Bot commented May 9, 2026

Deploy Preview for aya-rs-docs ready!

Built without sensitive environment variables

Name Link
🔨 Latest commit b4ed408
🔍 Latest deploy log https://app.netlify.com/projects/aya-rs-docs/deploys/69fe86e9f120c40008a43e60
😎 Deploy Preview https://deploy-preview-1564--aya-rs-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

Brskt and others added 7 commits May 9, 2026 00:44
- Drop legacy map-of-maps support
- Replace impl_create_map macro with a CreatableMap trait
- Unify PerfEventArray/RingBuf into impl_from_map_data via accessor arm
- Add fused lookups (get_value/get_value_ptr_mut) for BTF map-of-maps
- Rename tests to btf_map_of_maps
- Rename new_legacy to new_from_params to reflect actual usage
- Move CreatableMap into sealed module with public wrapper trait
- Replace impl_create_map macro and 8 manual trait impls with impl_creatable_map macro
- Remove CreatableMap trait, create() is now a direct inherent method
- Make lookup_inner generic over M: MapDef instead of separate K, V
- Revert ArrayOfMaps test annotations to turbofish form
…r turbofish

- Restore CreatableMap as a sealed trait with public wrapper and blanket
  impl, matching the FromMapData/InnerMap pattern
- Revert type ascription on lookup_inner/lookup_inner_ptr_mut callers
  now that inner_map is NonNull<M>
- Defer inner map template creation in the loader until we know the
  outer map needs to be created
- Change create_pinned_by_name to accept the inner map definition
  instead of a pre-created fd, creating it only when bpf_get_object
  fails
@OliverGavin OliverGavin force-pushed the hashmapofmaps-new branch from 2196567 to b4ed408 Compare May 9, 2026 00:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants