跳到正文
cccskills
免费在 GitHub 公开

af-xdp

Use when creating AF_XDP sockets, configuring UMEM and XSK rings, writing an XDP redirect program, or choosing copy versus zero-copy mode. Not for full kernel bypass: use dpdk.

中文简介正在准备中。当前显示原文说明。

查看安装方法

包含的文件(2)

  • SKILL.md7.3 KB
  • agents/openai.yaml198 B

SKILL.md(原文)

安装前可以查看交给 AI 代理的指令内容。

AF_XDP sockets

Contract

FieldBound contract
TriggerBuilding a userspace packet path on AF_XDP: UMEM and ring setup, an XDP redirect program, the RX loop, copy versus zero-copy mode, or an AF_XDP versus DPDK decision.
AuthorityRead-only. Writes nothing. Chat output only. No remote mutation.
Side effectReturns setup code, ring lifecycle rules, and a mode recommendation. No source files are modified.
DoneThe socket setup code, the fill-ring refill rule, the redirect program, and a mode choice tied to driver support are delivered.

Inputs

  1. Interface and queue (required): the interface name and the RX queue the socket serves. One socket per queue.
  2. Mode intent (optional): copy or zero-copy. Default to copy and confirm from the bind.
  3. Build setup (optional): libbpf installed (pkg-config --libs libbpf returns -lbpf; -lxdp when libxdp is installed separately).

Procedure

  1. Lay out the object model before writing code. UMEM is the shared frame pool. The fill ring carries empty frame addresses from user space to the kernel. The completion ring returns transmitted frames. The RX ring delivers received packets. The TX ring carries outgoing packets. Done when: each ring and the UMEM has a named struct in the design.

  2. Create the UMEM and the socket.

    #include <bpf/xsk.h>
    
    #define NUM_FRAMES    4096
    #define FRAME_SIZE    XSK_UMEM__DEFAULT_FRAME_SIZE
    #define RX_BATCH_SIZE 64
    
    /* mmap one anonymous region; the UMEM describes it to the kernel */
    void *buffer = mmap(NULL, NUM_FRAMES * FRAME_SIZE,
                        PROT_READ | PROT_WRITE,
                        MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    
    struct xsk_umem_config umem_cfg = {
        .fill_size = XSK_RING_PROD__DEFAULT_NUM_DESCS,
        .comp_size = XSK_RING_CONS__DEFAULT_NUM_DESCS,
        .frame_size = FRAME_SIZE,
        .frame_headroom = XSK_UMEM__DEFAULT_FRAME_HEADROOM,
        .flags = 0,
    };
    int ret = xsk_umem__create(&umem->umem, buffer, NUM_FRAMES * FRAME_SIZE,
                               &umem->fill, &umem->comp, &umem_cfg);
    
    struct xsk_socket_config xsk_cfg = {
        .rx_size = XSK_RING_CONS__DEFAULT_NUM_DESCS,
        .tx_size = XSK_RING_PROD__DEFAULT_NUM_DESCS,
        /* the skill loads its own program in step 4, so stop libbpf */
        .libbpf_flags = XSK_LIBBPF_FLAGS__INHIBIT_PROG_LOAD,
        .xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST,
        .bind_flags = XDP_COPY, /* or XDP_ZEROCOPY, see step 6 */
    };
    ret = xsk_socket__create(&xsk->xsk, ifname, queue_id, umem->umem,
                             &xsk->rx, &xsk->tx, &xsk_cfg);
    

    Done when: the UMEM covers the whole mmap region and each ring struct is wired into its create call.

  3. Keep the fill ring stocked. The kernel drops received packets when the fill ring holds no free frames. Reserve, fill frame offsets, submit.

    uint32_t idx;
    uint32_t n = xsk_ring_prod__reserve(&umem->fill, RX_BATCH_SIZE, &idx);
    for (uint32_t i = 0; i < n; i++)
        *xsk_ring_prod__fill_addr(&umem->fill, idx + i) = i * FRAME_SIZE;
    xsk_ring_prod__submit(&umem->fill, n);
    

    Done when: the refill runs after every consumed RX batch, not only at startup.

  4. Load an XDP program that redirects to the socket. A BPF_MAP_TYPE_XSKMAP maps queue index to socket fd.

    #include <linux/bpf.h>
    #include <bpf/bpf_helpers.h>
    
    struct {
        __uint(type, BPF_MAP_TYPE_XSKMAP);
        __uint(max_entries, 64);
        __type(key, int);
        __type(value, int);
    } xsks_map SEC(".maps");
    
    SEC("xdp")
    int xdp_redirect_prog(struct xdp_md *ctx)
    {
        return bpf_redirect_map(&xsks_map, ctx->rx_queue_index, 0);
    }
    
    ip link set dev eth0 xdp obj xdp_redirect.o sec xdp
    # hand the socket fd to the map for this queue
    

    Done when: the program is attached and the map holds xsk_socket__fd(xsk) at this queue's index.

  5. Run the RX loop. Peek a batch, resolve each descriptor to a packet pointer, release, refill.

    uint32_t idx_rx, rcvd;
    rcvd = xsk_ring_cons__peek(&xsk->rx, RX_BATCH_SIZE, &idx_rx);
    for (uint32_t i = 0; i < rcvd; i++) {
        const struct xdp_desc *d = xsk_ring_cons__rx_desc(&xsk->rx, idx_rx + i);
        uint8_t *pkt = xsk_umem__get_data(buffer, d->addr);
        process_packet(pkt, d->len);
    }
    xsk_ring_cons__release(&xsk->rx, rcvd);
    refill_fill_ring(umem, rcvd);
    

    Done when: every peeked batch is released and refilled, and the loop drains the completion ring for TX frame reuse.

  6. Choose copy versus zero-copy.

    ModeBind flagDriver requirement
    CopyXDP_COPY (default)Any driver; the kernel copies into UMEM frames.
    Zero-copyXDP_ZEROCOPYDriver support: i40e, ixgbe, mlx5, ice and others.

    Check support with ethtool -i eth0 and read the bind result in dmesg (dmesg | grep xsk). The bind falls back to copy mode when the driver lacks support. Zero-copy lets the NIC DMA straight into UMEM frames, which is the low-latency path; copy mode works everywhere at a copy cost. Done when: the chosen mode matches confirmed driver support.

  7. Decide AF_XDP versus DPDK for the workload.

    FactorAF_XDPDPDK
    SetupModerateHigh (hugepages, EAL)
    Kernel integrationXDP filter stays in kernelFull bypass
    ThroughputClose to DPDK in zero-copy mode, NIC and driver dependentHighest
    NIC bindingStays on the kernel driverBound to vfio-pci or uio
    FitFilter in kernel, selective traffic to user spaceFull dataplane takeover

    Throughput depends on NIC, driver, and CPU. No fixed number transfers between boards; measure with the real workload. Done when: the recommendation names the workload and the measured or expected traffic mix.

  8. Apply production rules. Run one socket per RX queue, pinned with taskset to the CPU that handles that queue's interrupts. AF_XDP needs CAP_NET_RAW. Route deeper work: ebpf for XDP program development (including C/libbpf and Rust/Aya), dpdk for full bypass. Done when: queue pinning, capability, and routing are stated in the delivered guidance.

Failure and recovery

SymptomCauseRecovery
RX ring stays emptyRedirect program missing or map entry unsetVerify the map entry for this queue index and that the program is attached.
EBUSY on socket createAn XDP program is already attachedDetach with ip link set dev eth0 xdp off, then bind.
Zero-copy bind silently falls backDriver lacks supportRead dmesg; use a supported driver or accept copy mode.
Packet drops under loadFill ring empty at packet arrivalRefill after each batch; grow NUM_FRAMES.
TX stopsCompletion ring never drainedPoll the completion ring to recycle transmitted frames.
Permission deniedCAP_NET_RAW missingRun with the capability.

Output

Setup code for UMEM, socket, and rings; the refill rule with its drop hazard; the redirect program and attach commands; the mode choice with driver evidence; the AF_XDP versus DPDK recommendation; the production checklist.

评价

还没有评价。欢迎分享你的使用感受。

评论

无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。

还没有评论。来写第一条吧。

提交后会立即公开。请勿填写邮箱、电话等个人信息。URL 最多 2 个。

0 / 1000 字

此表单受 reCAPTCHA 保护,适用 Google 的隐私权政策和服务条款。

同一仓库的技能

Use when explaining System V AMD64, ARM AAPCS, RISC-V psABI, stack frames, variadic calls, or FFI register rules. Not for the Rust FFI binding layer: use rust-ffi.

中文简介正在准备中。当前显示原文说明。

OutlineDriven/odin-claude-plugin372026年9月29日 更新

Use when configuring ADC sampling time, DMA-driven ADC, calibration, or DAC channel setup on bare-metal MCUs. Not for the DMA stream itself: use dma-baremetal.

中文简介正在准备中。当前显示原文说明。

OutlineDriven/odin-claude-plugin372026年9月29日 更新

Use when a completed session needs an agent-environment retrospective. Not for an engineering retrospective from telemetry: use engineering-retrospective.

中文简介正在准备中。当前显示原文说明。

OutlineDriven/odin-claude-plugin372026年9月29日 更新

Use when a redacted, trimmed agent transcript must be appended to a GitHub PR or issue body, with human approval and preview. Not for automated or model-initiated insertion.

中文简介正在准备中。当前显示原文说明。

OutlineDriven/odin-claude-plugin372026年9月29日 更新

agents-md

免费

Use when a repo needs agent setup, AGENTS.md added or made lean, CLAUDE.md audited, or agent instructions scored or pruned. Not for remote, credential, publish, deploy, or irreversible changes.

中文简介正在准备中。当前显示原文说明。

OutlineDriven/odin-claude-plugin372026年9月29日 更新

Use when the user describes an AI workflow gap or uses an ambiguous cross-session reference such as 'the PR Bob mentioned'. Not for tasks that require source or remote-system changes.

中文简介正在准备中。当前显示原文说明。

OutlineDriven/odin-claude-plugin372026年9月29日 更新

查看 OutlineDriven 的全部技能

报告此技能的问题