mirror of
https://git.kernel.org/pub/scm/network/iproute2/iproute2.git
synced 2024-11-15 22:15:13 +08:00
f823f36012
Implement loading of .BTF section from object file and build up internal table for retrieving key/value id related to maps in the BPF program. Latter is done by setting up struct btf_type table. One of the issues is that there's a disconnect between the data types used in the map and struct bpf_elf_map, meaning the underlying types are unknown from the map description. One way to overcome this is to add a annotation such that the loader will recognize the relation to both. BPF_ANNOTATE_KV_PAIR(map_foo, struct key, struct val); has been added to the API that programs can use. The loader will then pick the corresponding key/value type ids and attach it to the maps for creation. This can later on be dumped via bpftool for introspection. Example with test_xdp_noinline.o from kernel selftests: [...] struct ctl_value { union { __u64 value; __u32 ifindex; __u8 mac[6]; }; }; struct bpf_map_def __attribute__ ((section("maps"), used)) ctl_array = { .type = BPF_MAP_TYPE_ARRAY, .key_size = sizeof(__u32), .value_size = sizeof(struct ctl_value), .max_entries = 16, .map_flags = 0, }; BPF_ANNOTATE_KV_PAIR(ctl_array, __u32, struct ctl_value); [...] Above could also further be wrapped in a macro. Compiling through LLVM and converting to BTF: # llc --version LLVM (http://llvm.org/): LLVM version 7.0.0svn Optimized build. Default target: x86_64-unknown-linux-gnu Host CPU: skylake Registered Targets: bpf - BPF (host endian) bpfeb - BPF (big endian) bpfel - BPF (little endian) [...] # clang [...] -O2 -target bpf -g -emit-llvm -c test_xdp_noinline.c -o - | llc -march=bpf -mcpu=probe -mattr=dwarfris -filetype=obj -o test_xdp_noinline.o # pahole -J test_xdp_noinline.o Checking pahole dump of BPF object file: # file test_xdp_noinline.o test_xdp_noinline.o: ELF 64-bit LSB relocatable, *unknown arch 0xf7* version 1 (SYSV), with debug_info, not stripped # pahole test_xdp_noinline.o [...] struct ctl_value { union { __u64 value; /* 0 8 */ __u32 ifindex; /* 0 4 */ __u8 mac[0]; /* 0 0 */ }; /* 0 8 */ /* size: 8, cachelines: 1, members: 1 */ /* last cacheline: 8 bytes */ }; Now loading into kernel and dumping the map via bpftool: # ip -force link set dev lo xdp obj test_xdp_noinline.o sec xdp-test # ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 xdpgeneric/id:227 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever [...] # bpftool prog show id 227 227: xdp tag a85e060c275c5616 gpl loaded_at 2018-07-17T14:41:29+0000 uid 0 xlated 8152B not jited memlock 12288B map_ids 381,385,386,382,384,383 # bpftool map dump id 386 [{ "key": 0, "value": { "": { "value": 0, "ifindex": 0, "mac": [] } } },{ "key": 1, "value": { "": { "value": 0, "ifindex": 0, "mac": [] } } },{ [...] Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Signed-off-by: David Ahern <dsahern@gmail.com>
54 lines
1.2 KiB
C
54 lines
1.2 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef __BPF_ELF__
|
|
#define __BPF_ELF__
|
|
|
|
#include <asm/types.h>
|
|
|
|
/* Note:
|
|
*
|
|
* Below ELF section names and bpf_elf_map structure definition
|
|
* are not (!) kernel ABI. It's rather a "contract" between the
|
|
* application and the BPF loader in tc. For compatibility, the
|
|
* section names should stay as-is. Introduction of aliases, if
|
|
* needed, are a possibility, though.
|
|
*/
|
|
|
|
/* ELF section names, etc */
|
|
#define ELF_SECTION_LICENSE "license"
|
|
#define ELF_SECTION_MAPS "maps"
|
|
#define ELF_SECTION_PROG "prog"
|
|
#define ELF_SECTION_CLASSIFIER "classifier"
|
|
#define ELF_SECTION_ACTION "action"
|
|
|
|
#define ELF_MAX_MAPS 64
|
|
#define ELF_MAX_LICENSE_LEN 128
|
|
|
|
/* Object pinning settings */
|
|
#define PIN_NONE 0
|
|
#define PIN_OBJECT_NS 1
|
|
#define PIN_GLOBAL_NS 2
|
|
|
|
/* ELF map definition */
|
|
struct bpf_elf_map {
|
|
__u32 type;
|
|
__u32 size_key;
|
|
__u32 size_value;
|
|
__u32 max_elem;
|
|
__u32 flags;
|
|
__u32 id;
|
|
__u32 pinning;
|
|
__u32 inner_id;
|
|
__u32 inner_idx;
|
|
};
|
|
|
|
#define BPF_ANNOTATE_KV_PAIR(name, type_key, type_val) \
|
|
struct ____btf_map_##name { \
|
|
type_key key; \
|
|
type_val value; \
|
|
}; \
|
|
struct ____btf_map_##name \
|
|
__attribute__ ((section(".maps." #name), used)) \
|
|
____btf_map_##name = { }
|
|
|
|
#endif /* __BPF_ELF__ */
|