mirror of
https://git.proxmox.com/git/mirror_iproute2
synced 2025-10-24 22:23:08 +00:00
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__ */
|