bpf_map_lookup_elem的空值while' bpftool map dump'做
我有一个通过bpf_type_map_array
在地图中存储一些统计数据的BPF程序。代码的那一侧似乎可以正常工作,我可以使用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
[...]
我们可以看到有关密钥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)
I have a bpf program storing some stats in a map via BPF_TYPE_MAP_ARRAY
. That side of code seems to works correctly, I can use bpftool
to see my map.
# 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
[...]
We can see some data on key 2 and theses data are updated correctly.
However when I try to collect theses data in userspace with libbpf, I only have null values. I have no clue what's wrong.
If I fake the fd, call fails, if I try to fetch more than 16 elements, it fails later, so everything sounds correct.
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;
}
Returns:
ID 0: 0, 0
ID 1: 0, 0
ID 2: 0, 0
ID 3: 0, 0
ID 4: 0, 0
[...] (all zero)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
感谢@Qeole在我的原始帖子的评论中。这是解决问题的方法:
我使用
IP链接
将我的程序附加到接口。在我的BPF地图的定义中,我添加了一个固定选项libbpf_pin_by_name
:这样,
tc
将自动pin> pin> pin
将映射到>
/sys/fs/bpf/tc/globals/xdp_stats_map
。在我的用户空间程序中,我现在可以直接获取该FD:
它可以使用!
Thanks to @Qeole in the comment of my original post. Here is how I solved my problem:
I use
ip link
to attach my program to my interface. In the definition of my bpf map, I added a pinning optionLIBBPF_PIN_BY_NAME
:With this way,
tc
will automaticallypin
the map to/sys/fs/bpf/tc/globals/xdp_stats_map
.In my userspace program, I can directly fetch that fd now:
And it works !