![](/img/trans.png)
[英]eBPF: How to use `bpf_map_update_elem` to send data from kernel space?
[英]Empty value from bpf_map_lookup_elem while 'bpftool map dump' does
我有一个 bpf 程序通过BPF_TYPE_MAP_ARRAY
在地图中存储一些统计信息。 代码的那一面似乎工作正常,我可以使用bpftool
来查看我的地图。
# bpftool map show
31: array name xdp_stats_map flags 0x0
key 4B value 16B max_entries 16 memlock 4096B
# bpftool map dump id 31
key: 00 00 00 00 value: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
key: 01 00 00 00 value: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
key: 02 00 00 00 value: e3 a6 00 00 00 00 00 00 99 38 b3 00 00 00 00 00
key: 03 00 00 00 value: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[...]
我们可以在 key 2 上看到一些数据,并且这些数据已正确更新。 但是,当我尝试使用 libbpf 在用户空间中收集这些数据时,我只有空值。 我不知道出了什么问题。
如果我伪造 fd,调用失败,如果我尝试获取超过 16 个元素,它稍后会失败,所以一切听起来都是正确的。
struct counters {
__u64 rx_packets;
__u64 rx_bytes;
};
void dies(char *str) {
fprintf(stderr, "[-] %s", str);
exit(EXIT_FAILURE);
}
int main(int argc, char *argv[]) {
struct counters value;
char *filename = "./xdp_pass.o";
int fd;
if(argc > 1)
filename = argv[1];
struct bpf_object *obj = bpf_object__open(filename);
if(libbpf_get_error(obj))
dies("could not open bpf object");
bpf_object__load(obj);
if(libbpf_get_error(obj))
dies("could not load bpf object");
if((fd = bpf_object__find_map_fd_by_name(obj, "xdp_stats_map")) < 0)
dies("could not find map in the object");
for(__u32 key = 0; key < 16; key++) {
if((bpf_map_lookup_elem(fd, &key, &value)) != 0)
dies("could not key in map");
printf("ID % 3d: %llu, %llu\n", key, value.rx_packets, value.rx_bytes);
}
return 0;
}
回报:
ID 0: 0, 0
ID 1: 0, 0
ID 2: 0, 0
ID 3: 0, 0
ID 4: 0, 0
[...] (all zero)
感谢@Qeole 在我原始帖子的评论中。 这是我解决问题的方法:
我使用ip link
将我的程序附加到我的界面。 在我的 bpf 映射的定义中,我添加了一个固定选项LIBBPF_PIN_BY_NAME
:
struct {
__uint(type, BPF_MAP_TYPE_ARRAY);
__uint(key_size, sizeof(__u32));
__uint(value_size, sizeof(struct xdp_stats));
__uint(pinning, LIBBPF_PIN_BY_NAME);
__uint(max_entries, 16);
} xdp_stats_map SEC(".maps");
通过这种方式, tc
将自动将映射pin
到/sys/fs/bpf/tc/globals/xdp_stats_map
。
在我的用户空间程序中,我现在可以直接获取该 fd:
int fd = bpf_obj_get("/sys/fs/bpf/tc/globals/xdp_stats_map");
for(__u32 key = 0; key < 16; key++) {
if((bpf_map_lookup_elem(fd, &key, &value)) != 0)
...
它有效!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.