如何通过bpf_trace获取进程信息,实现nc进程指定UDP端口的XDP过滤?
问题解答
直接在XDP程序中获取报文归属进程信息的需求无法实现:XDP的Hook点位于网卡驱动收包的最早期链路,此时内核尚未完成报文与对应socket的关联流程,没有进程归属的相关元数据可以读取。你在当前trace日志中看到的nc进程信息,只是执行bpf_trace_printk函数时当前CPU上运行的进程,和报文本身的归属没有对应关系,不能用作判断依据。
可行实现方案
- 方案1:替换为TC eBPF Hook实现
TC的Ingress/Egress Hook执行时机晚于XDP,此时报文已经和socket完成绑定,可以通过内核提供的eBPF辅助函数直接获取进程信息,核心逻辑参考如下:
// 需引入额外头文件 <linux/sched.h> int udpfilter(struct __sk_buff *skb) { void *data = (void *)(long)skb->data; void *data_end = (void *)(long)skb->data_end; struct ethhdr *eth = data; if ((void*)eth + sizeof(*eth) > data_end) return TC_ACT_OK; struct iphdr *ip = data + sizeof(*eth); if ((void*)ip + sizeof(*ip) > data_end) return TC_ACT_OK; if (ip->protocol == IPPROTO_UDP) { struct udphdr *udp = (void*)ip + sizeof(*ip); if ((void*)udp + sizeof(*udp) <= data_end && udp->dest == ntohs(7999)) { char comm[16] = {0}; bpf_get_current_comm(&comm, sizeof(comm)); // 判断当前报文归属进程名是否为nc if (comm[0] == 'n' && comm[1] == 'c' && comm[2] == '\0') { bpf_trace_printk("drop nc port 7999 packet\n"); return TC_ACT_SHOT; } } } return TC_ACT_OK; }
- 方案2:XDP配合BPF映射实现
如果需要保留XDP的高性能特性,可以额外挂载一个hook在socket收包路径的eBPF程序,将nc进程的五元组信息实时写入BPF哈希映射,XDP程序收到目标端口为7999的UDP报文时,查询映射匹配对应规则即可执行DROP操作,性能损耗极低。
你代码中出现的KBUILD_MODNAME重定义警告不影响功能运行,删除代码第一行的宏定义即可消除警告。
内容的提问来源于stack exchange,提问作者zexapod
相关产品推荐
相关产品推荐

