use sha2::{Digest, Sha256};
const SOURCE: &str = include_str!("../bpf/sandbox_nat.bpf.c");
const SOURCE_HASH: &str = include_str!("../bpf/sandbox_nat.bpf.c.sha256");
const OBJECT: &[u8] = include_bytes!("../bpf/sandbox_nat.bpf.o");
const OBJECT_HASH: &str = include_str!("../bpf/sandbox_nat.bpf.o.sha256");
#[test]
fn bpf_object_matches_source() {
let digest = format!("{:x}", Sha256::digest(SOURCE.as_bytes()));
assert_eq!(
digest,
SOURCE_HASH.trim(),
"bpf/sandbox_nat.bpf.c changed but the committed object was not \
rebuilt — run `cargo xtask dev bpf` and commit the result"
);
let object_digest = format!("{:x}", Sha256::digest(OBJECT));
assert_eq!(
object_digest,
OBJECT_HASH.trim(),
"bpf/sandbox_nat.bpf.o does not match its sidecar — run \
`cargo xtask dev bpf` and commit BOTH the object and the sidecars"
);
}
#[test]
fn bpf_object_is_a_little_endian_bpf_elf() {
assert_eq!(&OBJECT[..4], b"\x7fELF", "not an ELF object");
assert_eq!(OBJECT[4], 2, "must be ELFCLASS64");
assert_eq!(OBJECT[5], 1, "must be little-endian (bpfel)");
let machine = u16::from_le_bytes([OBJECT[18], OBJECT[19]]);
assert_eq!(machine, 247, "e_machine must be EM_BPF");
}
#[test]
fn bpf_object_carries_the_loader_contract_names() {
let contains = |needle: &[u8]| OBJECT.windows(needle.len()).any(|w| w == needle);
for name in [
"sandbox_nat_ingress",
"sandbox_nat_egress",
"SANDBOX_NAT",
"SANDBOX_NAT_POOL",
"classifier",
"maps",
"license",
] {
assert!(
contains(name.as_bytes()),
"object is missing the {name:?} loader contract name"
);
}
assert!(
contains(b"Dual MIT/GPL"),
"license string must stay GPL-compatible for kernel helpers"
);
}