在 SKB 模式下加载 XDP 程序时,我无法从代码中删除任何地图和某些程序。我无法删除这些相同的 BPF 实体bpftool
。这是我清理实体的代码:
type BpfObjects struct {
CollectIpsProg *ebpf.Program `ebpf:"collect_ips_prog"`
HttpProg *ebpf.Program `ebpf:"http_prog"`
TlsProg *ebpf.Program `ebpf:"tls_prog"`
FlowRingBuffer *ebpf.Map `ebpf:"flow_ring_buf"`
JumpTable *ebpf.Map `ebpf:"jump_table"`
}
var objects BpfObjects
...
// None of these calls return an error
netlink.LinkSetXdpFdWithFlags(link, objects.CollectIpsProg.FD(), 2)
...
netlink.LinkSetXdpFd(link, -1)
objects.FlowRingBuffer.Unpin()
objects.JumpTable.Unpin()
objects.TlsProg.Unpin()
objects.HttpProg.Unpin()
objects.CollectIpsProg.Unpin()
objects.FlowRingBuffer.Close()
objects.JumpTable.Close()
objects.TlsProg.Close()
objects.HttpProg.Close()
objects.CollectIpsProg.Close()
在我用于开发的 VM 上,我只需要调用 donetlink.LinkSetXdpFd(link, -1)
来清理所有内容。但是,当我在目标服务器上运行时,我观察到该程序collect_ips_prog
仍在加载,并且没有删除任何地图:
# bpftool prog
117: xdp name collect_ips_pro tag 6f70925233787bae gpl
loaded_at 2022-02-09T19:40:06+0000 uid 0
xlated 1112B jited 785B memlock 4096B map_ids 148,149,150
btf_id 90
# bpftool map
148: percpu_array name bpf_context_tab flags 0x0
key 4B value 276B max_entries 1 memlock 24576B
149: prog_array name jump_table flags 0x0
key 4B value 4B max_entries 2 memlock 4096B
owner_prog_type xdp owner jited
150: ringbuf name flow_ring_buf flags 0x0
key 0B value 0B max_entries 16777216 memlock 0B
collect_ips_prog
是我使用加载到界面的唯一程序netlink.LinkSetXdpFdWithFlags
。我用代码填充其他两个程序jump_table
。程序退出后,jump_table 映射为空:
# bpftool map dump name jump_table
Found 0 elements
如果我这样做,程序仍然存在bpftool net detach xdp dev eth0
。没有错误/错误代码。
我在驱动程序模式下加载 XDP 程序时没有这个问题。
服务器运行的是 CentOS 7,我用 5.16.7-1.el7.elrepo.x86_64 替换了内核。我的 NIC 是 Mellanox MT28800 系列 [ConnectX-5 Ex]。