For tests that do networking operations, this allows to have a
clean-state network namespace and interfaces for each test. Mainly, this
avoids "device or resource busy" errors when reusing the loopback
interface across tests.
Wrap verifier logs in a newtype whose `Debug` impl emits unescaped
newlines. This improves ergonomics in tests where we `Result::unwrap()`
those load errors; when these fail today they emit the errors with
newlines escaped, making them incredibly difficult to read.
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.
Implement TryFrom functions to convert Fdlink to PerfLink/TracePointLink/
KprobeLink, and UprobeLink and vice-versa.
This allows us to pin taken links for perf programs, ultimately
ensuring the link isn't dropped when the loading process exits.
Signed-off-by: Andrew Stoycos <astoycos@redhat.com>
- Add libbpf as a submodule. This prevents having to plumb its location
around (which can't be passed to Cargo build scripts) and also
controls the version against which codegen has run.
- Move bpf written in C to the integration-test crate and define
constants for each probe.
- Remove magic; each C source file must be directly enumerated in the
build script and in lib.rs.
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.
This commit adds a new probe for bpf_attach_cookie, which would be used
to implement USDT probes. Since USDT probes aren't currently supported,
we this triggers a dead_code warning in clippy.
There are cases where exposing FEATURES - our lazy static - is actually
helpful to users of the library. For example, they may wish to choose to
load a different version of their bytecode based on current features.
Or, in the case of an orchestrator like bpfd, we might want to allow
users to describe which features their program needs and return nice
error message is one or more nodes in their cluster doesn't support the
necessary feature set.
To do this without breaking the API, we make all the internal members of
the `Features` and `BtfFeatures` structs private, and add accessors for
them. We then add a `features()` API to avoid leaking the
lazy_static.
Signed-off-by: Dave Tucker <dave@dtucker.co.uk>
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>
These two functions are needed because kernel symbols representing
syscalls have architecture-specific prefixes.
These are the equivalent of bcc's get_syscall_fnname and
get_syscall_prefix.
Solves: #534
Fix map creation failure when a BPF have a data section on older
kernel. (< 5.2)
If the BPF uses that section, relocation will fail accordingly and
report an error.
This fixes `cargo build --all-features` by sidestepping the feature
unification problem described in The Cargo Book[0].
Add `cargo hack --feature-powerset` to CI to enforce that this doesn't
regress (and that all combinations of features work).
Since error_in_core is nightly-only, use core-error and a fake std
module to allow aya-obj to build without std on stable.
[0] https://doc.rust-lang.org/cargo/reference/features.html#feature-unification
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.
This was mistakenly comparing the exit code of the syscall, which is
always -1 and not the corresponding error-code. Added unit tests to
ensure we don't regress.
Signed-off-by: Dave Tucker <dave@dtucker.co.uk>
This adds support for loading XDP programs that are multi-buffer
capable, which is signalled using the xdp.frags section name. When this
is set, we should set the BPF_F_XDP_HAS_FRAGS flag when loading the
program into the kernel.
Signed-off-by: Dave Tucker <dave@dtucker.co.uk>
This commit adds from_pin() which allows the creation of a Program
from a path on bpffs. This is useful to be able to call `attach` or
other APIs for programs that are already loaded to the kernel.
This differs from #444 since it implements this on the concrete program
type, not the Program enum, allowing the user to pass in any additional
context that isn't available from bpf_prog_info.
Signed-off-by: Dave Tucker <dave@dtucker.co.uk>
Fix a bug which was resulting in `ENOTSUPP` following
the `BPF_MAP_CREATE` Syscall. This fix was initially
found by libbpf maintainers in:
https://github.com/libbpf/libbpf/issues/355.
Signed-off-by: Andrew Stoycos <astoycos@redhat.com>
- Rename `new_tc_link` to `attached`
- Simplified example for `attached`
The following was not requested in reviews:
- Moved example from `SchedClassifierLink` tor
`SchedClassifierLink::attached' since we're only showing an
example of that one method
Signed-off-by: Andre Fredette <afredette@redhat.com>
This is the proposed solution for Step 2 of issue #414
“For cases where you have done program.take_link() to manage
ownership of TcLink we need an API similar to PinnedLink::from_pin
that can reconstruct a TcLink”
As long as a user application continues to run after executing
`take_link()`, the `SchedClassifierLink` returned can be used to
detach the program. However, if we want to handle cases where the
application exits or crashes, we need a way to save and reconstruct
the link, and to do that, we also need to know the information
required for the reconstruction -- namely, the `interface`,
`attach_type`, `priority`, and `handle`. The user knows the first
two because they are required to execute `attach()` in the first
place; however, the user will not know the others if they let the
system choose them.
This pr solves the problems by adding an `impl` for
`SchedClassifierLink` with an accessor for `tc_options` and a `new()`
function.
Signed-off-by: Andre Fredette <afredette@redhat.com>
Currently aya will just report a standard outer level
error on failure. Ensure that we also report the inner
error condition back to the user
Signed-off-by: Andrew Stoycos <astoycos@redhat.com>
- Set the version number of `aya-obj` to `0.1.0`.
- Update the description of the `aya-obj` crate.
- Add a section in README and rustdoc warning about the unstable API.
To split the crate into two, several changes were made:
1. Most `pub(crate)` are now `pub` to allow access from Aya;
2. Parts of BpfError are merged into, for example, RelocationError;
3. BTF part of Features is moved into the new crate;
4. `#![deny(missing_docs)]` is removed temporarily;
5. Some other code gets moved into the new crate, mainly:
- aya::{bpf_map_def, BtfMapDef, PinningType},
- aya::programs::{CgroupSock*AttachType},
The new crate is currenly allowing missing_docs. Member visibility
will be adjusted later to minimize exposure of implementation details.
Refs: #473
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
Kernel 4.15 added a new eBPF program that can
be used with cgroup v2 to control & observe device
access (e.g. read, write, mknod) - `BPF_PROG_TYPE_CGROUP_DEVICE`.
We add the ability to create these programs with the `cgroup_device`
proc macro which creates the `cgroup/dev` link section. Device
details are available to the eBPF program in `DeviceContext`.
The userspace representation is provided with the `CgroupDevice`
structure.
Fixes: #212
Signed-off-by: Milan <milan@mdaverde.com>
Use a struct called TcOptions for setting priority and handle in SchedClassifier attach
struct TcOptions implements the Default trait, so for the simple use
case in which the defaults are acceptable, we can call attach as
follows:
attach(“eth0”, TcAttachType::Ingress, TcOptions::default())
To specify all options:
attach(“eth0”, TcAttachType::Ingress, TcOptions { priority: (50), handle: (3) })
Or, some options:
attach(“eth0”, TcAttachType::Ingress, TcOptions { priority: (50), ..Default::default() })
Signed-off-by: Andre Fredette <afredette@redhat.com>
Implements step 1 of https://github.com/aya-rs/aya/issues/414.
- Adds handle to the SchedClassifier attach API
- Saves handle in the TcLink sruct and uses it when detaching programs
NOTE: this changes the API, so it will require a bump in the Aya version.
Signed-off-by: Andre Fredette <afredette@redhat.com>
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>
`override_syscall` performs integer-to-pointer conversion. This is
considered harmful on the newest Rust nightly which provides
`ptr::from_exposed_addr`, but there is no other way on Rust stable than
doing `as *const T`, which is what miri is unhappy about.
Signed-off-by: Michal Rostecki <vadorovsky@gmail.com>
Add BpfLoader::set_max_entries, which sets the max_entries for the
specified map, as the load-time option.
The max_entries set at map initialization in the ebpf component can be
overwritten by this method called on the userspace component.
If you want to set max_entries for multiple maps in an ebpf component,
you can do so by calling set_max_entries in the form of a method chain.
Fixes: #308
Refs: #292
Add `from_pinned` to allow loading BPF maps
from pinned points in the bpffs and
`from_fd` to allow loading BPF maps from
RawFds aquired via some other means eg
a unix socket.
These functions return an
aya::Map which has not been used previously
but will be the future abstraction once
all bpf maps are represented as an enum.
Signed-off-by: Andrew Stoycos <astoycos@redhat.com>
This commit fixes a bug and adds some missing lifecycle APIs.
1. Adds PinnedLink::from_path to create a pinned link from bpffs
2. Adds From<PinnedLink> for FdLink to allow for ^ to be converted
3. Adds From<FdLink> for XdpLink
Signed-off-by: Dave Tucker <dave@dtucker.co.uk>
Files changed:\nM aya/src/generated/linux_bindings_aarch64.rs
M aya/src/generated/linux_bindings_armv7.rs
M aya/src/generated/linux_bindings_riscv64.rs
M aya/src/generated/linux_bindings_x86_64.rs
Files changed:\nM aya/src/generated/btf_internal_bindings.rs
M aya/src/generated/linux_bindings_aarch64.rs
M aya/src/generated/linux_bindings_armv7.rs
M aya/src/generated/linux_bindings_riscv64.rs
M aya/src/generated/linux_bindings_x86_64.rs
M bpf/aya-bpf-bindings/src/aarch64/bindings.rs
M bpf/aya-bpf-bindings/src/aarch64/helpers.rs
M bpf/aya-bpf-bindings/src/armv7/bindings.rs
M bpf/aya-bpf-bindings/src/armv7/helpers.rs
M bpf/aya-bpf-bindings/src/riscv64/bindings.rs
M bpf/aya-bpf-bindings/src/riscv64/helpers.rs
M bpf/aya-bpf-bindings/src/x86_64/bindings.rs
M bpf/aya-bpf-bindings/src/x86_64/helpers.rs
This commit removes reliance on generated BtfType structs, as
well as adding a dedicated struct for each BTF type. As such,
we can now add nice accessors like `bits()` and `encoding()`
for Int vs. inlined shift/mask operations.
Signed-off-by: Dave Tucker <dave@dtucker.co.uk>
1. Removes OwnedLink
2. Allows Links to be converted into FdLink
3. Introduces a PinnedLink type to handle wrap FdLink when pinned and
support un-pinning
Signed-off-by: Dave Tucker <dave@dtucker.co.uk>
This allows for FdLinks to also be pinned to BpfFs.
In order for it to be called, the user would first call
`take_link` to get the underlying link. This can then
be destructured to an FdLink where FdLink::pin() may be called.
Signed-off-by: Dave Tucker <dave@dtucker.co.uk>
This allows for `pin` to be called as `Xdp::pin()` or
Program::pin() - the same way that unload() can be used.
This simplifies the use of this API.
Signed-off-by: Dave Tucker <dave@dtucker.co.uk>