无法卸载BPF程序。

huangapple go评论81阅读模式
英文:

Unable to unload BPF program

问题

我无法从代码中卸载BPF程序。我正在使用Cilium eBPF库加载程序,并使用netlink将BPF函数添加到接口中。以下是我的操作步骤:

type BpfObjects struct {
	CollectIpsProg *ebpf.Program        `ebpf:"collect_ips_prog"`
}

var objects BpfObjects

// 加载BPF程序
spec, err := ebpf.LoadCollectionSpec("collect_ips.o")

if err != nil {
	log.Fatalln("ebpf.LoadCollectionSpec", err)
}

if err := spec.LoadAndAssign(objects, nil); err != nil {
	log.Fatalln("ebpf.LoadAndAssign", err)
}

// 加载到XDP
link, err := netlink.LinkByName("enp0s8")

if err != nil {
	log.Fatalln("netlink.LinkByName", err)
}

err = netlink.LinkSetXdpFdWithFlags(link, objects.CollectIpsProg.FD(), 2)

if err != nil {
	log.Fatalln("netlink.LinkSetXdpFdWithFlags:", err)
}
...

// 清理。这不会卸载BPF程序
objects.CollectIpsProg.Close()
objects.CollectIpsProg.Unpin()

尽管我关闭了程序,但是bpftool progxdp-loader status仍然显示BPF程序。我可以使用bpftoolxdp-loader卸载程序。

英文:

I am unable to unload a BPF program from code. I am using the Cilium eBPF library to load the program and netlink to add the BPF function to an interface. Here's what I'm doing:

type BpfObjects struct {
	CollectIpsProg *ebpf.Program        `ebpf:"collect_ips_prog"`
}

	var objects BpfObjects

    // Load the BPF program
	spec, err := ebpf.LoadCollectionSpec("collect_ips.o")

	if err != nil {
		log.Fatalln("ebpf.LoadCollectionSpec", err)
	}

	if err := spec.LoadAndAssign(objects, nil); err != nil {
		log.Fatalln("ebpf.LoadAndAssign", err)
	}

    // Load to XDP
	link, err := netlink.LinkByName("enp0s8")

	if err != nil {
		log.Fatalln("netlink.LinkByName", err)
	}

	err = netlink.LinkSetXdpFdWithFlags(link, objects.CollectIpsProg.FD(), 2)

	if err != nil {
		log.Fatalln("netlink.LinkSetXdpFdWithFlags:", err)
	}
    ...

    // Cleanup. This does not unload the BPF program
    objects.CollectIpsProg.Close()
	objects.CollectIpsProg.Unpin() 

Even though I am closing the program, bpftool prog and xdp-loader status still show the BPF program. I can unload the program using bpftool or xdp-loader.

答案1

得分: 3

eBPF程序只有在没有其他引用时(文件描述符、引用)才会卸载,但网络链接也会保留自己的引用。因此,要卸载程序,首先必须将其从网络链接中分离。

您可以通过将程序文件描述符设置为-1来实现:

err = netlink.LinkSetXdpFd(link, -1)
if err != nil {
    log.Fatalln("netlink.LinkSetXdpFd:", err)
}
英文:

eBPF programs only unload when there are no more references to it(File descriptors, pins), but network links also hold their own references. So to unload the program, you first have to detach it from your network link.

You can do so by setting the program fd to -1:

err = netlink.LinkSetXdpFd(link, -1)
if err != nil {
    log.Fatalln("netlink.LinkSetXdpFd:", err)
}

huangapple
  • 本文由 发表于 2022年2月9日 10:38:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/71043359.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定