Browse Source

bpf: Only use never type with rust nightly

Signed-off-by: Dave Tucker <[email protected]>
Dave Tucker 2 years ago
parent
commit
6ab7148731

+ 1 - 11
.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

+ 3 - 0
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"

+ 9 - 0
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() {}

+ 1 - 1
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]
 

+ 24 - 0
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<C: BpfContext>(&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<C: BpfContext>(&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 {