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