与套接字关联的BPF输入是什么?如何过滤NETLINK_KOBJECT_UEVENT中/eventXX后缀消息
问题解答
1. 套接字关联BPF程序的输入说明
附加到PF_NETLINK套接字上的套接字过滤器类BPF程序(包括cBPF和eBPF),不需要你手动传递buf_str,内核会直接把完整的netlink数据包payload作为BPF的输入,也就是你代码中UeventBuffer.raw数组的全部内容,会在数据包递送到用户空间之前自动交给BPF程序处理。
2. 内核示例sock_example.c的BPF操作对象
你参考的内核示例中,BPF指令操作的是完整的链路层数据包 payload(以太网帧头+IP头+TCP头+传输层payload),和你当前场景的逻辑完全一致:对应到netlink uevent场景,就是完整的uevent netlink消息内容,即buf.raw的全部数据。
3. 实现/eventXX后缀过滤的操作方法
你可以直接在BPF程序中解析uevent内容完成过滤,不需要修改现有用户态的接收逻辑,仅需额外完成以下步骤:
- 编写BPF过滤程序:
- 先校验数据包长度,跳过
struct nlmsghdr头部,拿到uevent字符串的起始偏移 - uevent的首行就是
action@/sys/path格式的路径字符串,以\0结尾,遍历找到首行的结束位置 - 检查首行最后6个字符是否为
/event,最后2个字符是否为数字,符合条件则保留数据包,否则直接丢弃
- 先校验数据包长度,跳过
- 将编译好的BPF程序附加到你的netlink套接字上:
如果使用eBPF,调用如下代码完成绑定:
如果使用经典cBPF,构造int prog_fd; // 已经加载完成的eBPF程序的文件描述符 setsockopt(sock, SOL_SOCKET, SO_ATTACH_BPF, &prog_fd, sizeof(prog_fd));sock_fprog结构体后使用SO_ATTACH_FILTER参数调用setsockopt即可。
绑定完成后,内核会自动过滤不符合规则的数据包,你调用recvmsg收到的就只有符合/eventXX后缀要求的uevent消息。
内容的提问来源于stack exchange,提问作者Edward Chamberlain
相关产品推荐
相关产品推荐

