mirror of https://github.com/aya-rs/aya
aya: Support multiple maps in map sections
This commit uses the symbol table to discover all maps inside an ELF section. Instead of doing what libbpf does - divide the section data in to equal sized chunks - we read in to section data using the symbol address and offset, thus allowing us to support definitions of varying lengths. Signed-off-by: Dave Tucker <dave@dtucker.co.uk>pull/181/head
parent
2e494a1a29
commit
f357be7db4
@ -0,0 +1,47 @@
|
|||||||
|
#include <linux/bpf.h>
|
||||||
|
#include <bpf/bpf_helpers.h>
|
||||||
|
|
||||||
|
const int XDP_ACTION_MAX = (XDP_TX + 1);
|
||||||
|
|
||||||
|
struct datarec {
|
||||||
|
__u64 rx_packets;
|
||||||
|
};
|
||||||
|
|
||||||
|
// stats keyed by XDP Action
|
||||||
|
struct bpf_map_def SEC("maps") xdp_stats_map = {
|
||||||
|
.type = BPF_MAP_TYPE_ARRAY,
|
||||||
|
.key_size = sizeof(__u32),
|
||||||
|
.value_size = sizeof(struct datarec),
|
||||||
|
.max_entries = XDP_ACTION_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
|
// tracks number of times called
|
||||||
|
struct bpf_map_def SEC("maps") prog_stats_map = {
|
||||||
|
.type = BPF_MAP_TYPE_ARRAY,
|
||||||
|
.key_size = sizeof(__u32),
|
||||||
|
.value_size = sizeof(__u64),
|
||||||
|
.max_entries = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
SEC("xdp/stats")
|
||||||
|
int xdp_stats(struct xdp_md *ctx)
|
||||||
|
{
|
||||||
|
__u64 *stats;
|
||||||
|
struct datarec *rec;
|
||||||
|
__u32 key = XDP_PASS;
|
||||||
|
__u32 k1 = 0;
|
||||||
|
|
||||||
|
stats = bpf_map_lookup_elem(&prog_stats_map, &k1);
|
||||||
|
if (!stats)
|
||||||
|
return XDP_ABORTED;
|
||||||
|
__sync_fetch_and_add(stats, 1);
|
||||||
|
|
||||||
|
rec = bpf_map_lookup_elem(&xdp_stats_map, &key);
|
||||||
|
if (!rec)
|
||||||
|
return XDP_ABORTED;
|
||||||
|
__sync_fetch_and_add(&rec->rx_packets, 1);
|
||||||
|
|
||||||
|
return XDP_PASS;
|
||||||
|
}
|
||||||
|
|
||||||
|
char _license[] SEC("license") = "GPL";
|
@ -0,0 +1,33 @@
|
|||||||
|
//! ```cargo
|
||||||
|
//! [dependencies]
|
||||||
|
//! log = "0.4"
|
||||||
|
//! simplelog = "0.11"
|
||||||
|
//! aya = { path = "../../../../aya" }
|
||||||
|
//! ```
|
||||||
|
|
||||||
|
use aya::{
|
||||||
|
Bpf,
|
||||||
|
programs::{Xdp, XdpFlags},
|
||||||
|
};
|
||||||
|
use log::info;
|
||||||
|
use std::convert::TryInto;
|
||||||
|
|
||||||
|
use simplelog::{ColorChoice, ConfigBuilder, LevelFilter, TermLogger, TerminalMode};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
TermLogger::init(
|
||||||
|
LevelFilter::Debug,
|
||||||
|
ConfigBuilder::new()
|
||||||
|
.set_target_level(LevelFilter::Error)
|
||||||
|
.set_location_level(LevelFilter::Error)
|
||||||
|
.build(),
|
||||||
|
TerminalMode::Mixed,
|
||||||
|
ColorChoice::Auto,
|
||||||
|
).unwrap();
|
||||||
|
info!("Loading XDP program");
|
||||||
|
let mut bpf = Bpf::load_file("multimap.o").unwrap();
|
||||||
|
let pass: &mut Xdp = bpf.program_mut("stats").unwrap().try_into().unwrap();
|
||||||
|
pass.load().unwrap();
|
||||||
|
pass.attach("eth0", XdpFlags::default()).unwrap();
|
||||||
|
info!("Success...");
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# SUMMARY: Check that a program with multiple maps in the maps section loads
|
||||||
|
# LABELS:
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Source libraries. Uncomment if needed/defined
|
||||||
|
#. "${RT_LIB}"
|
||||||
|
. "${RT_PROJECT_ROOT}/_lib/lib.sh"
|
||||||
|
|
||||||
|
NAME=multimap
|
||||||
|
|
||||||
|
clean_up() {
|
||||||
|
rm -rf ${NAME}.o ${NAME}
|
||||||
|
exec_vm rm -f ${NAME}.o ${NAME}
|
||||||
|
}
|
||||||
|
|
||||||
|
trap clean_up EXIT
|
||||||
|
|
||||||
|
# Test code goes here
|
||||||
|
compile_c_ebpf "$(pwd)/${NAME}.bpf.c"
|
||||||
|
compile_user "$(pwd)/${NAME}.rs"
|
||||||
|
|
||||||
|
scp_vm ${NAME}.o
|
||||||
|
scp_vm ${NAME}
|
||||||
|
|
||||||
|
exec_vm sudo ./${NAME}
|
||||||
|
|
||||||
|
exit 0
|
Loading…
Reference in New Issue