This implements the userspace binding for RingBuf.
Instead of streaming the samples as heap buffers, the process_ring
function takes a callback to which we pass the event's byte region,
roughly following [libbpf]'s API design. This avoids a copy and allows
marking the consumer pointer in a timely manner.
[libbpf]: https://github.com/libbpf/libbpf/blob/master/src/ringbuf.c
Additionally, integration tests are added to demonstrate the usage
of the new APIs and to ensure that they work end-to-end.
Co-authored-by: William Findlay <william@williamfindlay.com>
Co-authored-by: Tatsuyuki Ishi <ishitatsuyuki@gmail.com>
- Adds new `maps_mut()` API to the BpfManager to allow us to iterate though
and pin all of maps at the same time.
- Adds new pin(Path)/unpin(Path) api to Maps so they
can be generically pinned AFTER load.
- Adds macro for pinning explicit map types in aya.
Convert all explicit map types "inner" field to be
pub crate in order to facilitate this.
Signed-off-by: astoycos <astoycos@redhat.com>
Aligns with libbpf for the special LIBBPF_PIN_BY_NAME
map flag. Specifically if the flag is provided without a pin path
default to "/sys/fs/bpf".
Signed-off-by: astoycos <astoycos@redhat.com>
On startup, the kernel is probed for support of chained program ids for
CpuMap, DevMap and DevMapHash, and will patch maps at load time to have
the proper size. Then, at runtime, the support is checked and will error
out if a program id is passed when the kernel does not support it.
This commit adds implementations for:
- xskmap
- devmap
- devmap_hash
- cpumap
Which can all be used to redirect XDP packets to various different
locations
Signed-off-by: Dave Tucker <dave@dtucker.co.uk>
This is to solve a use-case where a user (in this case bpfd) may want
to:
- MapData::from_pin to open a pinned map from bpffs
- MapData::pin to pin that object into another bpffs
Both operations should be easily accomplished without needing to cast
a MapData into a concrete Map type - e.g aya::maps::HashMap.
Signed-off-by: Dave Tucker <dave@dtucker.co.uk>
BPF objects can be pinned multiple times, to multiple different places.
Tracking whether or not a map is pinned in a bool is therefore not sufficient.
We could track this in a HashSet<PathBuf>, but there is really no reason
to track it at all.
Signed-off-by: Dave Tucker <dave@dtucker.co.uk>
`MapData::fd` is now a `MapFd`. This means that `MapData` now closes the
file descriptor on drop. In the future we might consider making `MapFd`
hold a `BorrowedFd` but this requires API design work due to overlapping
borrows.
Since `SockMapFd` is no longer `Copy`, attach methods to take it by
reference to allow callers to use it multiple times as they are
accustomed to doing.
`SockMapFd` implements `try_clone`. `MapFd` and `SockMapFd` are now
returned by reference to allow callers to avoid file descriptor cloning
when desired.
This is an API breaking change.
Updates #612.
The macro to implement TryFrom for MapData didn't have the ability to
specify that more than one variant of MapData can be valid for a single
map implementation. Support for new syntax was added to the macro so that
the implementation can succeed for both valid variants in the HashMap
and PerCpuHashMap impl.
Fixes#636
The old macros were repetitive and inflexible. This unifies the various
macros used to generate TryFrom implementations for map implementations
from the relevant map enum variants.
Cleanup in anticipation of fixing #636.
The API changes are just about renaming the return to Self and
Self::Error; they are not real changes.
This is a breaking change but adds another level of safety to ensure
the file descriptor we receive is valid. Additionally, this allows
aya to internally easily duplicate this file descriptor using std
library methods instead of manually calling `dup` which doesn't
duplicate with the CLOSE_ON_EXEC flag that is standard pratice to
avoid leaking the file descriptor when exec'ing.
Notably:
- clippy::use_self: replaced many T with Self.
- single_use_lifetimes: removed some single use lifetimes.
- unreachable_pub: removed some unreachable pub items.
- unused_crate_dependencies: removed unused futures,parking_lot deps.
- unused_qualifications: found a potential `crate` vs `$crate` bug.
- let_underscore_drop: not enabled, seems to trigger false positives.
- missing_copy_implementations: not enabled, unclear if we want this.
- unsafe_op_in_unsafe_fn: not enabled, unclear if we want this.
- unused_results: not enabled, needs many fixes (but I think wanted).
The primary driver of change here is that `MapData::create` is now a
factory function that returns `Result<Self, _>` rather than mutating
`&mut self`. The remaining changes are consequences of that change, the
most notable of which is the removal of several errors which are no
longer possible.
`ProgramData::fd` is now a `ProgramFd`. This means that `ProgramData`
now closes the file descriptor on drop. In the future we might consider
making `ProgramFd` hold a `BorrowedFd` but this requires API design work
due to overlapping borrows.
Since `ProgramFd` is no longer `Copy`, update methods to take it by
reference to allow callers to use it multiple times as they are
accustomed to doing.
`ProgramFd` is now returned by reference and implements `try_clone` to
allow callers to avoid file descriptor cloning when desired.
This is an API breaking change.
Updates #612.
This fixes an existing file descriptor leak when there is BTF data in
the loaded object.
To avoid lifetime issues while having minimal impact to UX the
`OwnedFd` returned from the BPF_BTF_LOAD syscall will be wrapped in an
`Arc` and shared accross the programs and maps of the loaded BPF
file.
This is just taking https://github.com/aya-rs/aya/pull/633 to its
logical conclusion. Because `std::os::fd` was only introduced as a
module in Rust v1.66.0 I have also updated the `Cargo.toml` of the
`aya` package to reflect the true MSRV. Note that this commit is *not*
the cause for this MSRV bump, that was done by a previous commit, this
commit is just making it explicit in the `Cargo.toml`
The matches crate has been archived now that `matches!` is in std.
However `assert_matches!` is still unstable in std, and the
assert_matches crate provides a more expressive form:
```
assert_matches!(foo, Ok(bar) => {
assert_eq!(bar, baz);
});
```
This feature is equivalent to async_tokio || async_std; removing it
avoids warnings emitted during `cargo hack check --feature-powerset`
where async is selected without either of the other features.
Use cargo hack to ensure clippy runs on the powerset of features.
Replace all `assert!(matches!(..))` with `assert_matches!(..)`.
Remove the now-unused build-integration-test xtask command whose logic
doesn't match that of the build-and-run command.
Based on the discussion in Discord we've decided to drop the
iter_key() API for LPM Trie. According to the kernel self-tests and
experimentation done in Aya, providing a key into bpf_map_get_next_id
will either:
- If key is an EXACT match, proceed iterating through all keys in the
trie from this point
- If key is NOT an EXACT match, proceed iterating through all keys in
the trie starting at the leftmost entry.
An API in Aya could be crafted that gets the LPM match + less specific
matches for a prefix using these semantics BUT it would only apply to
userspace. Therefore we've opted out of fixing this.
Signed-off-by: Dave Tucker <dave@dtucker.co.uk>
Move BpfError::UnsupportedMap into MapError and add a map_type field to
the error.
Update the `allow_unsupported_maps` function comment.
Update the logic to check if any unsupported maps are being used. More
specifically only search a program's maps if `allow_unsupported_maps` is
set and then use the iter function `try_for_each` with a match statement
which allows us to return the inner map type if it's unsupported.
Signed-off-by: Andrew Stoycos <astoycos@redhat.com>
Just because aya doesn't support working with some map
types doesn't mean we should't allow them to be loaded.
Add a new `Unsupported` map type to facilitate this,
Next add a user configurable option `allow_unsupported_maps()`
which can be called against the `bpfLoader`. Additionally
add a nice warning log message when a program is being loaded
by Aya and contains an unsupported map type.
Signed-off-by: Andrew Stoycos <astoycos@redhat.com>
Clearly split the code between `.maps`, `maps` and data maps (bss, data,
rodata). Sprinkle comments.
Remove MapKind which was effectively only needed since we used to have
one variant - BpfSectionKind::Data - to represent all data maps. Instead
add explicit BpfSectionKind::{Data, Rodata, Bss} variants and match on
those when we initialize maps.
Aya::obj depends on bindgen generated files, and we start
by migrating bindgen generated files.
This commit adds the new aya-obj crate to the workplace
and migrates generated files into the crate. We use core
instead of std in an effort to make the final crate no_std.
Bindgen was run against libbpf v1.0.1.
Refs: #473
Fix some broken rust doc links.
Make sure rustdoc build fail on warnings
so we catch these broken links in CI.
Signed-off-by: Andrew Stoycos <astoycos@redhat.com>
switch map() and map_mut() from returning a
`Result` to an `Option` since it's just getting
a value from a Hashmap, and to stay in line with
the Programs API.
Remove `MapError::MapNotFound`
Signed-off-by: Andrew Stoycos <astoycos@redhat.com>
Remove MapError::UnexpectedMapType
Add Macro for converting from aya::Map to
u32 (map type) for use in
`MapError::InvalidMapType { map_type: x }`
Signed-off-by: Andrew Stoycos <astoycos@redhat.com>
Respond to more review comments:
Revert to try_from in doctests so we don't need
to explicitly specify type parameters.
Fixup some documentation
Remove explit types in `try_from` methods
Signed-off-by: Andrew Stoycos <astoycos@redhat.com>
Implement Copy for MapData so that
when `take_map` is used we create a
1 to 1 mapping of MapData to internal
FileDescriptor. This will ensure
that when MapData is used in multiple
tasks that we don't drop the FD before
all tasks are done using it.
Signed-off-by: Andrew Stoycos <astoycos@redhat.com>
Create a new type called `SockMapFd` which is
solely used when a program needs to attach
to a socket map. In the future this same
tatic could be used for other use cases
so we may make this more generic.
Signed-off-by: Andrew Stoycos <astoycos@redhat.com>
Build completing tests passing
Refactor the Map API to better align
with the aya programs API. Specifically
remove all internal locking mechanisms
and custom Deref/DerefMut implementations.
They are replaced with a Map enum
and AsRef/AsMut implementations.
All Try_From implementations have been moved
to standardized enums, with a slightly
special one for PerfEventArray's.
Also cleanup/fix all associated tests and
documentation.
Signed-off-by: Andrew Stoycos <astoycos@redhat.com>
Following the lead of crates like tokio and nix, we now annotate APIs
that require optional features. This helps in cases where a user wants
to have an `AsyncPerfEventArray` which is documented on crates.io, but
it's not obvious that you have to enable the `async` feature.
Signed-off-by: Dave Tucker <dave@dtucker.co.uk>