众所周知,map可用于内核BPF程序和用户应用程序之间实现双向的数据交换,为BPF技术中的重要基础数据结构。
在BPF程序中可以通过声明structbpf_map_def结构完成创建,这其实带给我们一种错觉,感觉这和普通的C语言变量没有区别,然而事实真的是这样的吗?事情远没有这么简单,读完本文以后相信你会有更大的惊喜。
structbpf_map_defSEC("maps")my_map={.type=BPF_MAP_TYPE_ARRAY,//...};
我们知道最终BPF程序是需要在内核中执行,但是map数据结构是用于用户空间和内核BPF程序双向的数据结构,那么问题来了:
通过定义的变量究竟是如何创建的,是在用户空间创建还是内核中直接创建的?
如何实现创建后的map的结构,在用户空间与内核中BPF程序关联?你可能注意到在用户空间中对于map的访问是通过map文件句柄fd完成(类型为int),但是在BPF程序中是通过structbpf_map*结构完成的。
毕竟数据交换跨越了用户空间和内核空间,本文将从深入浅出为各位看官揭开map整个生命管理的"大瓜"。
2.简单的使用样例本样例来自于samples/bpf/sockex1_user.c和sockex1_kern.c,略有修改和删除。
sockex1_user.c用户空间程序主要内容如下(为方便展示,部分内容有删除和修改):
intmain(intargc,char**argv){structbpf_object*obj;intmap_fd,prog_fd;//...//加载BPF程序至bpf_object对象中,bpf_prog_load("sockex_kern.o",BPF_PROG_TYPE_SOCKET_FILTER,obj,prog_fd))//获取my_map对应的map_fd句柄map_fd=bpf_object__find_map_fd_by_name(obj,"my_map");//==本次