Skip to content

dwisiswant0/xdp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

xdp

XDP (eXpress Data Path) for Go, transpiled, CGo-free.

Can be built without CGo, system libxdp, system libbpf, pkg-config, clang, m4, bpftool, ccgo, or a C compiler.

go.dw1.io/xdp uses generated libxdp code from the pinned xdp-tools v1.6.3 source and forwards libbpf calls to go.dw1.io/bpf/abi. It is intended for Linux XDP control paths, not for hiding the operational risk of XDP. Many calls require elevated Linux capabilities and can change live packet processing on the selected interface.

CleanReferences(0) asks libxdp to clean stale dispatcher references for all interfaces. Pass a positive ifindex to restrict cleanup.

Supported Targets

Generated libxdp support is committed for:

  • linux/amd64
  • linux/arm64

Unsupported targets fail at compile time with a diagnostic that names go.dw1.io/bpf/abi as the target matrix source and lists the generated targets.

Quick Start

Install the module in the application that will manage XDP state:

go get go.dw1.io/xdp

Open an object file, attach its XDP program, and detach it when done:

prog, err := xdp.OpenProgramFile("xdp_prog.o", "xdp", xdp.OpenOptions{
	KernelLogSize:  64 << 10,
	KernelLogLevel: 1,
})
if err != nil {
	return err
}
defer prog.Close()

if logText := prog.KernelLog(); logText != "" {
	log.Printf("verifier log:\n%s", logText)
}

if err := prog.Attach(ifindex, xdp.AttachModeUnspecified, 0); err != nil {
	return err
}
defer func() {
	_ = prog.Detach(ifindex, xdp.AttachModeUnspecified, 0)
}()

Attach, detach, pin, cleanup, and AF_XDP socket setup calls can require CAP_BPF, CAP_NET_ADMIN, or root depending on the kernel and distribution. Use a test interface first.

Program Selection

OpenProgramFile, FindProgramFile, and ProgramFromBPFObject select a program by section name. Use CreateProgram with ProgramOptions.ProgramName when a BPF object should be searched by program name instead. ProgramOptions rejects conflicting sources and rejects selectors or open options that libxdp would not apply to the chosen source.

OpenOptions.KernelLogSize and OpenOptions.KernelLogLevel request libbpf verifier/BTF logging for file-backed program creation. Program.KernelLog returns the retained log while the program remains open.

Errors

Operations return Go errors that preserve errno matching where libxdp or the kernel provide one. Use errors.Is for errno checks and errors.As for the package error type when the operation or resource context matters:

var xerr *xdp.Error
if errors.As(err, &xerr) {
	log.Printf("%s %s: %s", xerr.Op, xerr.Resource, xerr.Message)
}
if errors.Is(err, syscall.EPERM) {
	log.Print("operation needs additional privileges")
}

Logging

SetLogHandler installs a process-wide handler for libxdp warning, info, and debug messages and returns a function that restores the previous handler:

restore := xdp.SetLogHandler(func(msg xdp.LogMessage) {
	log.Printf("libxdp %s: %s", msg.Level, strings.TrimSpace(msg.Message))
})
defer restore()

The handler receives copied Go strings. Generated callback pointers and C varargs remain internal.

Environment Behavior

The generated libxdp code preserves upstream environment handling. LIBXDP_OBJECT_PATH participates in FindProgramFile and CreateProgram object-name searches. LIBXDP_BPFFS selects the bpffs root used by libxdp, and LIBXDP_BPFFS_AUTOMOUNT controls libxdp's upstream automount behavior.

The package does not load, attach, detach, pin, unpin, clean, mount, or remove kernel or bpffs state on import. Those effects happen only when calling the corresponding APIs, such as Program.Attach, Program.Detach, Program.Pin, CleanReferences, CreateSocket, or setup helpers.

MultiProg Lifetime Notes

Programs returned from a MultiProg are borrowed views of that multiprog snapshot. Close those Program wrappers when done. If MultiProg.Close runs first, it marks the snapshot closed for new operations and releases the native snapshot after the outstanding borrowed program wrappers are closed.

AF_XDP Lifetime Notes

CreateUMEM keeps the supplied byte slice reachable until UMEM.Close succeeds. Use memory suitable for AF_XDP registration, normally page-aligned mmap-backed storage sized to whole frames. If UMEMOptions.Size is zero, the registered size is the length of that packet area.

UMEMOptions.FrameSize, UMEMOptions.FrameHeadroom, UMEMOptions.FillSize, UMEMOptions.CompletionSize, UMEMOptions.Flags, and UMEMOptions.TXMetadataLen are passed through to libxdp; zero values mean libxdp defaults. UMEM.Options returns those creation options with Size normalized to the registered byte length. UMEM.Data returns a borrowed, mutable slice into the retained packet area and must not be used after the UMEM is closed.

CreateUMEMWithFD and UMEMOptions.UseFD pass an existing UMEM fd to libxdp. After Go validation succeeds, libxdp owns that fd and may close it even if UMEM creation returns an error.

Sockets borrow the UMEM and ring handles supplied at creation. Keep shared UMEM, fill, completion, RX, and TX rings open while any socket that uses them remains open. UMEM.Close returns EBUSY while open sockets still depend on it; close sockets before closing the UMEM they use.

Socket.FillRing and Socket.CompletionRing return explicitly shared rings when supplied, otherwise they return the socket UMEM's fill and completion rings. Ring methods return ErrClosed for closed handles and structured errors for unattached rings.

Include SocketInhibitProgramLoad in SocketOptions.LibxdpFlags when another control plane has already loaded the XDP program and AF_XDP socket creation should not ask libxdp to load one automatically.

Development

Generated files and embedded BPF object assets are checked in. Regeneration is only needed when updating the pinned inputs:

make generate
make generate-check

Regeneration reads ABI metadata from the required go.dw1.io/bpf module. The Makefile uses scripts/prepare-bpf-source to provide libbpf source headers from GENXDP_BPF_SOURCE_DIR, a full local go.dw1.io/bpf checkout, sibling ../bpf, or a cached checkout of the required module tag. The generator then verifies that those source inputs match the required module ABI manifests.

Examples

The package examples compile during go test and skip runtime work unless environment variables are provided:

  • XDP_EXAMPLE_OBJECT, optional XDP_EXAMPLE_SECTION, and XDP_EXAMPLE_IFINDEX for program attach/detach and *bpf.Object interop.
  • XDP_EXAMPLE_IFINDEX for multiprog inspection.
  • XDP_EXAMPLE_IFNAME for AF_XDP UMEM/socket setup.

Optional Integration Tests

Privileged integration tests skip by default and can be enabled with explicit inputs:

  • XDP_INTEGRATION_OBJECT points to an XDP BPF object file.
  • XDP_INTEGRATION_SECTION optionally selects the object section.
  • XDP_INTEGRATION_IFINDEX optionally attaches the program to an interface.
  • XDP_INTEGRATION_IFNAME creates an AF_XDP socket on the named interface.

Run them with:

CGO_ENABLED=0 go test -run 'TestIntegration' -v .

License

This module is licensed under the Apache License 2.0. See the LICENSE.

About

XDP (eXpress Data Path) for Go, transpiled, CGo-free.

Resources

License

Stars

Watchers

Forks

Contributors