diff --git a/link_linux.go b/link_linux.go index ed35c0d..79dbf5b 100644 --- a/link_linux.go +++ b/link_linux.go @@ -568,6 +568,12 @@ func (h *Handle) LinkSetNsFd(link Link, fd int) error { // LinkSetXdpFd adds a bpf function to the driver. The fd must be a bpf // program loaded with bpf(type=BPF_PROG_TYPE_XDP) func LinkSetXdpFd(link Link, fd int) error { + return LinkSetXdpFdWithFlags(link, fd, 0) +} + +// LinkSetXdpFdWithFlags adds a bpf function to the driver with the given +// options. The fd must be a bpf program loaded with bpf(type=BPF_PROG_TYPE_XDP) +func LinkSetXdpFdWithFlags(link Link, fd, flags int) error { base := link.Attrs() ensureIndex(base) req := nl.NewNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK) @@ -576,7 +582,7 @@ func LinkSetXdpFd(link Link, fd int) error { msg.Index = int32(base.Index) req.AddData(msg) - addXdpAttrs(&LinkXdp{Fd: fd}, req) + addXdpAttrs(&LinkXdp{Fd: fd, Flags: uint32(flags)}, req) _, err := req.Execute(syscall.NETLINK_ROUTE, 0) return err diff --git a/link_test.go b/link_test.go index 07d8090..f5850ab 100644 --- a/link_test.go +++ b/link_test.go @@ -10,6 +10,7 @@ import ( "testing" "time" + "github.com/vishvananda/netlink/nl" "github.com/vishvananda/netns" ) @@ -1157,6 +1158,9 @@ func TestLinkXdp(t *testing.T) { if err := LinkSetXdpFd(testXdpLink, fd); err != nil { t.Fatal(err) } + if err := LinkSetXdpFdWithFlags(testXdpLink, fd, nl.XDP_FLAGS_UPDATE_IF_NOEXIST); err != syscall.EBUSY { + t.Fatal(err) + } if err := LinkSetXdpFd(testXdpLink, -1); err != nil { t.Fatal(err) } diff --git a/nl/link_linux.go b/nl/link_linux.go index e4a192f..9ae65a1 100644 --- a/nl/link_linux.go +++ b/nl/link_linux.go @@ -443,6 +443,13 @@ func (msg *VfTrust) Serialize() []byte { return (*(*[SizeofVfTrust]byte)(unsafe.Pointer(msg)))[:] } +const ( + XDP_FLAGS_UPDATE_IF_NOEXIST = 1 << iota + XDP_FLAGS_SKB_MODE + XDP_FLAGS_DRV_MODE + XDP_FLAGS_MASK = XDP_FLAGS_UPDATE_IF_NOEXIST | XDP_FLAGS_SKB_MODE | XDP_FLAGS_DRV_MODE +) + const ( IFLA_XDP_UNSPEC = iota IFLA_XDP_FD /* fd of xdp program to attach, or -1 to remove */