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