mirror of https://github.com/aya-rs/aya
Merge pull request #182 from dave-tucker/moar-tests
Regression Test Framework Improvementspull/183/head
commit
9f711e44fe
@ -0,0 +1,46 @@
|
||||
name: Aya test image
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "42 2 * * 0"
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
paths:
|
||||
- 'images/**'
|
||||
|
||||
env:
|
||||
REGISTRY: ghcr.io
|
||||
IMAGE_NAME: aya-rs/aya-test-rtf
|
||||
|
||||
jobs:
|
||||
rtf:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Log in to the Container registry
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Extract metadata (tags, labels) for Docker
|
||||
id: meta
|
||||
uses: docker/metadata-action@v3
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
path: ./images
|
||||
file: Dockerfile.rtf
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
@ -0,0 +1,38 @@
|
||||
FROM fedora:35
|
||||
|
||||
# Rust Nightly
|
||||
RUN curl https://sh.rustup.rs -sSf | sh -s -- \
|
||||
--default-toolchain nightly \
|
||||
--component rustfmt \
|
||||
--component clippy \
|
||||
--component rust-src \
|
||||
--target x86_64-unknown-linux-musl \
|
||||
-y
|
||||
|
||||
ENV PATH "/root/.cargo/bin:$PATH"
|
||||
|
||||
# Pre-requisites
|
||||
RUN dnf install \
|
||||
--setopt=install_weak_deps=False --best -qy \
|
||||
golang \
|
||||
qemu-system-x86 \
|
||||
cloud-utils \
|
||||
genisoimage \
|
||||
libbpf-devel \
|
||||
clang \
|
||||
openssl-devel \
|
||||
musl-libc \
|
||||
git && dnf clean all \
|
||||
&& rm -rf /var/cache/yum
|
||||
|
||||
RUN cargo install \
|
||||
bpf-linker \
|
||||
rust-script \
|
||||
sccache
|
||||
|
||||
RUN go install github.com/linuxkit/rtf@latest
|
||||
ENV PATH "/root/go/bin:$PATH"
|
||||
ENV RUSTC_WRAPPER "sccache"
|
||||
|
||||
ENTRYPOINT ["rtf"]
|
||||
CMD ["-vvv", "run"]
|
@ -0,0 +1,11 @@
|
||||
#include <linux/bpf.h>
|
||||
#include <bpf/bpf_helpers.h>
|
||||
#include <bpf/bpf_endian.h>
|
||||
|
||||
SEC("xdp/drop")
|
||||
int xdp_drop(struct xdp_md *ctx)
|
||||
{
|
||||
return XDP_DROP;
|
||||
}
|
||||
|
||||
char _license[] SEC("license") = "GPL";
|
@ -0,0 +1,24 @@
|
||||
//! ```cargo
|
||||
//! [dependencies]
|
||||
//! aya = { path = "../../../../aya" }
|
||||
//! ```
|
||||
|
||||
use aya::{
|
||||
Bpf, BpfLoader,
|
||||
programs::{Extension, ProgramFd, Xdp, XdpFlags},
|
||||
};
|
||||
use std::convert::TryInto;
|
||||
|
||||
fn main() {
|
||||
println!("Loading Root XDP program");
|
||||
let mut bpf = Bpf::load_file("main.o").unwrap();
|
||||
let pass: &mut Xdp = bpf.program_mut("pass").unwrap().try_into().unwrap();
|
||||
pass.load().unwrap();
|
||||
pass.attach("lo", XdpFlags::default()).unwrap();
|
||||
|
||||
println!("Loading Extension Program");
|
||||
let mut bpf = BpfLoader::new().extension("drop").load_file("ext.o").unwrap();
|
||||
let drop_: &mut Extension = bpf.program_mut("drop").unwrap().try_into().unwrap();
|
||||
drop_.load(pass.fd().unwrap(), "xdp_pass").unwrap();
|
||||
println!("Success...");
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
#include <linux/bpf.h>
|
||||
#include <bpf/bpf_helpers.h>
|
||||
#include <bpf/bpf_endian.h>
|
||||
|
||||
SEC("xdp/pass")
|
||||
int xdp_pass(struct xdp_md *ctx)
|
||||
{
|
||||
return XDP_PASS;
|
||||
}
|
||||
|
||||
char _license[] SEC("license") = "GPL";
|
@ -0,0 +1,33 @@
|
||||
#!/bin/sh
|
||||
# SUMMARY: Check that a simple XDP program an be loaded
|
||||
# LABELS:
|
||||
|
||||
set -e
|
||||
|
||||
# Source libraries. Uncomment if needed/defined
|
||||
#. "${RT_LIB}"
|
||||
. "${RT_PROJECT_ROOT}/_lib/lib.sh"
|
||||
|
||||
NAME=ext
|
||||
|
||||
clean_up() {
|
||||
rm -rf main.o ${NAME}.o ${NAME}
|
||||
exec_vm rm -f main.o ${NAME}.o ${NAME}
|
||||
}
|
||||
|
||||
trap clean_up EXIT
|
||||
|
||||
# Test code goes here
|
||||
min_kernel_version 5.9
|
||||
|
||||
compile_c_ebpf "$(pwd)/main.bpf.c"
|
||||
compile_c_ebpf "$(pwd)/${NAME}.bpf.c"
|
||||
compile_user "$(pwd)/${NAME}.rs"
|
||||
|
||||
scp_vm main.o
|
||||
scp_vm ${NAME}.o
|
||||
scp_vm ${NAME}
|
||||
|
||||
exec_vm sudo ./${NAME}
|
||||
|
||||
exit 0
|
@ -0,0 +1,85 @@
|
||||
//! ```cargo
|
||||
//! [dependencies]
|
||||
//! libbpf-sys = { version = "0.6.1-1" }
|
||||
//! anyhow = "1"
|
||||
//! ```
|
||||
|
||||
use std::{
|
||||
env,
|
||||
fs::{self, OpenOptions},
|
||||
io::Write,
|
||||
path::Path,
|
||||
process::Command,
|
||||
string::String,
|
||||
};
|
||||
use anyhow::{bail, Context, Result};
|
||||
static CLANG_DEFAULT: &str = "/usr/bin/clang";
|
||||
|
||||
/// Extract vendored libbpf headers from libbpf-sys.
|
||||
fn extract_libbpf_headers<P: AsRef<Path>>(include_path: P) -> Result<()> {
|
||||
let dir = include_path.as_ref().join("bpf");
|
||||
fs::create_dir_all(&dir)?;
|
||||
for (filename, contents) in libbpf_sys::API_HEADERS.iter() {
|
||||
let path = dir.as_path().join(filename);
|
||||
let mut file = OpenOptions::new().write(true).create(true).open(path)?;
|
||||
file.write_all(contents.as_bytes())?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Build eBPF programs with clang and libbpf headers.
|
||||
fn build_ebpf<P: Clone + AsRef<Path>>(in_file: P, out_file: P, include_path: P) -> Result<()> {
|
||||
extract_libbpf_headers(include_path.clone())?;
|
||||
let clang = match env::var("CLANG") {
|
||||
Ok(val) => val,
|
||||
Err(_) => String::from(CLANG_DEFAULT),
|
||||
};
|
||||
let arch = match std::env::consts::ARCH {
|
||||
"x86_64" => "x86",
|
||||
"aarch64" => "arm64",
|
||||
_ => std::env::consts::ARCH,
|
||||
};
|
||||
let mut cmd = Command::new(clang);
|
||||
cmd.arg(format!("-I{}", include_path.as_ref().to_string_lossy()))
|
||||
.arg("-g")
|
||||
.arg("-O2")
|
||||
.arg("-target")
|
||||
.arg("bpf")
|
||||
.arg("-c")
|
||||
.arg(format!("-D__TARGET_ARCH_{}", arch))
|
||||
.arg(in_file.as_ref().as_os_str())
|
||||
.arg("-o")
|
||||
.arg(out_file.as_ref().as_os_str());
|
||||
|
||||
let output = cmd.output().context("Failed to execute clang")?;
|
||||
if !output.status.success() {
|
||||
bail!(
|
||||
"Failed to compile eBPF programs\n \
|
||||
stdout=\n \
|
||||
{}\n \
|
||||
stderr=\n \
|
||||
{}\n",
|
||||
String::from_utf8(output.stdout).unwrap(),
|
||||
String::from_utf8(output.stderr).unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let args: Vec<String> = env::args().collect();
|
||||
if args.len() != 3 {
|
||||
bail!("requires 2 arguments. src and dst")
|
||||
}
|
||||
let path = env::current_dir()?;
|
||||
let src = Path::new(&args[1]);
|
||||
let dst = Path::new(&args[2]);
|
||||
|
||||
let include_path = path.join("include");
|
||||
fs::create_dir_all(include_path.clone())?;
|
||||
build_ebpf(src, dst, &include_path)?;
|
||||
|
||||
Ok(())
|
||||
}
|
Loading…
Reference in New Issue