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