This repository was archived by the owner on Aug 26, 2024. It is now read-only.
This repository was archived by the owner on Aug 26, 2024. It is now read-only.
Detaching program hangs when using SKB mode #28
Open
Description
Hi!
I've noticed that when I explicitly set XDP_FLAGS_SKB_MODE
in xdp.DefaultXdpFlags
, removing a program from an interface never completes. I've tracked the issue down to here:
Lines 257 to 259 in 56d7123
If I change the call from netlink.LinkSetXdpFd()
to netlink.LinkSetXdpFdWithFlags()
and pass in xdp.DefaultXdpFlags
, then the detach works:
@@ -254,8 +254,8 @@ func removeProgram(Ifindex int) error {
if !isXdpAttached(link) {
return nil
}
- if err = netlink.LinkSetXdpFd(link, -1); err != nil {
- return fmt.Errorf("netlink.LinkSetXdpFd(link, -1) failed: %v", err)
+ if err = netlink.LinkSetXdpFdWithFlags(link, -1, int(DefaultXdpFlags)); err != nil {
+ return fmt.Errorf("netlink.LinkSetXdpFdWithFlags(link, -1, int(DefaultXdpFlags)) failed: %v", err)
}
for {
link, err = netlink.LinkByIndex(Ifindex)
I don't know if this is an artifact of my system, or if this is a more general issue, but if you think it's worth it I can make a PR.
MVP
I took this from one of the examples and modified/commented it to show the issue I'm seeing.
package main
import (
"flag"
"fmt"
"net"
"github.com/asavie/xdp"
"golang.org/x/sys/unix"
)
func main() {
var linkName string
var queueID int
flag.StringVar(&linkName, "linkname", "enp0s6f1", "The network link on which rebroadcast should run on.")
flag.IntVar(&queueID, "queueid", 0, "The ID of the Rx queue to which to attach to on the network link.")
flag.Parse()
interfaces, err := net.Interfaces()
if err != nil {
fmt.Printf("error: failed to fetch the list of network interfaces on the system: %v\n", err)
return
}
Ifindex := -1
for _, iface := range interfaces {
if iface.Name == linkName {
Ifindex = iface.Index
break
}
}
if Ifindex == -1 {
fmt.Printf("error: couldn't find a suitable network interface to attach to\n")
return
}
// NOTE: The important bit!
xdp.DefaultXdpFlags = unix.XDP_FLAGS_SKB_MODE
fmt.Println("creating new program")
program, err := xdp.NewProgram(queueID + 1)
if err != nil {
fmt.Printf("error: failed to create xdp program: %v\n", err)
return
}
defer func() {
fmt.Println("closing program")
program.Close()
}()
fmt.Printf("attaching program to ifidx %d\n", Ifindex)
if err := program.Attach(Ifindex); err != nil {
fmt.Printf("error: failed to attach xdp program to interface: %v\n", err)
return
}
defer func() {
fmt.Println("detaching program")
// NOTE: Without the diff above, this call hangs indefinitely
program.Detach(Ifindex)
}()
fmt.Println("creating new XDP socket")
xsk, err := xdp.NewSocket(Ifindex, queueID, nil)
if err != nil {
fmt.Printf("error: failed to create an XDP socket: %v\n", err)
return
}
fmt.Println("registering socket with program")
if err := program.Register(queueID, xsk.FD()); err != nil {
fmt.Printf("error: failed to register socket in BPF map: %v\n", err)
return
}
defer func() {
fmt.Println("unregistering socket")
program.Unregister(queueID)
}()
fmt.Println("done")
}
Metadata
Metadata
Assignees
Labels
No labels