You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于XDP实现双向数据包转发失败的技术求助

XDP双向转发失效问题排查与修复

1. 语法错误直接导致ARP回复转发逻辑失效

你提供的代码里,ARP分支的第二个return语句缺少分号:

} else if (ctx->ingress_ifindex == IFINDEX_3) {
    return bpf_redirect(IFINDEX_2, 0)  // 这里没有分号,语法错误
}

这个错误会让编译器无法正确解析这段逻辑,要么程序加载失败,要么ARP回复的转发逻辑被直接跳过,数据包走到return XDP_PASS,而server2内核默认没开转发,导致ARP回复无法到达server1。

2. 接口索引与实际设备不匹配

根据你的网络拓扑,server2用于转发的接口是enp129s0f0np0和enp129s0f1np1,但代码里的宏定义写的是对应enp129s0f0和enp129s0f1的ifindex(2和3),这明显和实际接口名不符,对应的ifindex大概率不是2和3。

你可以用以下命令查看实际接口的ifindex:

ip link show

必须把宏定义的IFINDEX值替换成实际查到的数值,否则转发逻辑根本不会触发。

3. XDP重定向Flags可能存在问题

bpf_redirect的第二个参数用0(XDP_REDIRECT_FLAGS_NONE)在多队列接口场景下可能转发失败,建议换成XDP_REDIRECT_FLAGS_TX(值为1)强制走TX路径:

return bpf_redirect(目标IFINDEX, XDP_REDIRECT_FLAGS_TX);

4. 内核转发兜底配置(可选)

虽然XDP转发不需要内核IP转发,但如果XDP程序没覆盖所有数据包类型,可以临时开启内核转发作为兜底:

sysctl -w net.ipv4.ip_forward=1

修复后的完整代码

#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
#include <linux/if_ether.h>
#include <linux/ip.h>
#include <linux/icmp.h>
#include <linux/udp.h>
#include <linux/in.h>
#include <linux/if_arp.h>

// 替换成ip link show查到的实际ifindex
#define IFINDEX_LEFT  实际值  // 对应enp129s0f0np0
#define IFINDEX_RIGHT 实际值  // 对应enp129s0f1np1

SEC("xdp_redirect")
int xdp_redirect_prog(struct xdp_md *ctx)
{
    void *data = (void *)(long)ctx->data;
    void *data_end = (void *)(long)ctx->data_end;
    struct ethhdr *eth = data;

    if ((void *)(eth + 1) > data_end)
        return XDP_DROP;

    // 处理ARP数据包
    if (eth->h_proto == bpf_htons(ETH_P_ARP)) {
        if (ctx->ingress_ifindex == IFINDEX_LEFT) {
            return bpf_redirect(IFINDEX_RIGHT, XDP_REDIRECT_FLAGS_TX);
        } else if (ctx->ingress_ifindex == IFINDEX_RIGHT) {
            return bpf_redirect(IFINDEX_LEFT, XDP_REDIRECT_FLAGS_TX);
        }
    }

    // 处理IP类数据包(TCP/UDP/ICMP都包含在内)
    if (eth->h_proto == bpf_htons(ETH_P_IP)) {
        if (ctx->ingress_ifindex == IFINDEX_LEFT) {
            return bpf_redirect(IFINDEX_RIGHT, XDP_REDIRECT_FLAGS_TX); 
        } else if (ctx->ingress_ifindex == IFINDEX_RIGHT) {
            return bpf_redirect(IFINDEX_LEFT, XDP_REDIRECT_FLAGS_TX);
        }
    }

    return XDP_PASS; 
}

char _license[] SEC("license") = "GPL";

内容的提问来源于stack exchange,提问作者테스트입니다

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 08:55:56