diff --git a/.github/workflows/build-aya.yml b/.github/workflows/build-aya.yml index c16373a7..8f57b1de 100644 --- a/.github/workflows/build-aya.yml +++ b/.github/workflows/build-aya.yml @@ -31,11 +31,6 @@ jobs: toolchain: stable override: true - - uses: actions-rs/toolchain@v1 - with: - toolchain: nightly - override: false - - uses: Swatinem/rust-cache@v1 - name: Prereqs run: cargo install cross --git https://github.com/cross-rs/cross @@ -47,12 +42,7 @@ jobs: env: RUST_BACKTRACE: full run: | - cross test --verbose -p aya --target ${{matrix.arch}} - cross test --verbose -p aya-gen --target ${{matrix.arch}} - cross test --verbose -p aya-log --target ${{matrix.arch}} - cross test --verbose -p aya-log-ebpf-macros --target ${{matrix.arch}} - # aya-bpf-macros can only be tested on nightly since its tests depend on aya-bpf, which requires the never type - cross +nightly test --verbose -p aya-bpf-macros --target ${{matrix.arch}} + cross test --verbose --target ${{matrix.arch}} test: runs-on: ubuntu-20.04 diff --git a/bpf/aya-bpf/Cargo.toml b/bpf/aya-bpf/Cargo.toml index e8822cb4..03fedb59 100644 --- a/bpf/aya-bpf/Cargo.toml +++ b/bpf/aya-bpf/Cargo.toml @@ -8,3 +8,6 @@ edition = "2018" aya-bpf-cty = { path = "../aya-bpf-cty" } aya-bpf-macros = { path = "../../aya-bpf-macros" } aya-bpf-bindings = { path = "../aya-bpf-bindings" } + +[build-dependencies] +rustversion = "1.0" \ No newline at end of file diff --git a/bpf/aya-bpf/build.rs b/bpf/aya-bpf/build.rs index a8a2c261..8ae418f2 100644 --- a/bpf/aya-bpf/build.rs +++ b/bpf/aya-bpf/build.rs @@ -1,6 +1,7 @@ use std::env; fn main() { + check_rust_version(); println!("cargo:rerun-if-env-changed=CARGO_CFG_BPF_TARGET_ARCH"); if let Ok(arch) = env::var("CARGO_CFG_BPF_TARGET_ARCH") { println!("cargo:rustc-cfg=bpf_target_arch=\"{}\"", arch); @@ -10,3 +11,11 @@ fn main() { println!("cargo:rustc-cfg=bpf_target_arch=\"{}\"", arch); } } + +#[rustversion::nightly] +fn check_rust_version() { + println!("cargo:rustc-cfg=unstable"); +} + +#[rustversion::not(nightly)] +fn check_rust_version() {} diff --git a/bpf/aya-bpf/src/lib.rs b/bpf/aya-bpf/src/lib.rs index 8de7fc3b..d6855584 100644 --- a/bpf/aya-bpf/src/lib.rs +++ b/bpf/aya-bpf/src/lib.rs @@ -9,7 +9,7 @@ html_logo_url = "https://aya-rs.dev/assets/images/crabby.svg", html_favicon_url = "https://aya-rs.dev/assets/images/crabby.svg" )] -#![feature(never_type)] +#![cfg_attr(unstable, feature(never_type))] #![allow(clippy::missing_safety_doc)] #![no_std] diff --git a/bpf/aya-bpf/src/maps/program_array.rs b/bpf/aya-bpf/src/maps/program_array.rs index 62fa07d4..b7e54a6c 100644 --- a/bpf/aya-bpf/src/maps/program_array.rs +++ b/bpf/aya-bpf/src/maps/program_array.rs @@ -80,6 +80,30 @@ impl ProgramArray { /// /// On success, this function **does not return** into the original program. /// On failure, a negative error is returned, wrapped in `Err()`. + #[cfg(not(unstable))] + pub unsafe fn tail_call(&self, ctx: &C, index: u32) -> Result<(), c_long> { + let res = bpf_tail_call(ctx.as_ptr(), self.def.get() as *mut _, index); + if res != 0 { + Err(res) + } else { + unreachable_unchecked() + } + } + + /// Perform a tail call into a program indexed by this map. + /// + /// # Safety + /// + /// This function is inherently unsafe, since it causes control flow to jump into + /// another eBPF program. This can have side effects, such as drop methods not being + /// called. Note that tail calling into an eBPF program is not the same thing as + /// a function call -- control flow never returns to the caller. + /// + /// # Return Value + /// + /// On success, this function **does not return** into the original program. + /// On failure, a negative error is returned, wrapped in `Err()`. + #[cfg(unstable)] pub unsafe fn tail_call(&self, ctx: &C, index: u32) -> Result { let res = bpf_tail_call(ctx.as_ptr(), self.def.get() as *mut _, index); if res != 0 {