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

XDP_TX在veth接口L2转发场景下失效问题求助

XDP_TX转发失效问题排查与解决

问题场景

搭建了如下网络拓扑:

  • ns3作为路由器,开启IP转发并通过网桥br0桥接veth3_1、veth3_2
  • ns1通过veth1_3-veth3_1与ns3连通,ns2通过veth2_3-veth3_2与ns3连通
  • 将XDP程序部署在ns2的veth2_3接口ingress方向,目标是处理ns1发往ns2的UDP包:交换以太网帧源目MAC地址后返回XDP_TX
  • 实际测试中,仅能在ns3的veth3_2接口观测到发往ns2的包,但转发流量无法到达ns1;且在veth1_3的tc出口做了双层封装,将|IP|TCP|封装为|IP|UDP|IP|TCP|格式,已确认L2地址正确,bpf_printk显示程序执行到return XDP_TX

环境搭建脚本

ip link add veth1_3 type veth peer name veth3_1
ip link add veth2_3 type veth peer name veth3_2

# ns3 配置
ip link set veth3_1 netns ns3
ip link set veth3_2 netns ns3
ip netns exec ns3 sysctl -w net.ipv4.ip_forward=1
ip netns exec ns3 ip link add name br0 type bridge
ip netns exec ns3 ip link set br0 up
ip netns exec ns3 ip link set veth3_1 master br0
ip netns exec ns3 ip link set veth3_2 master br0
ip netns exec ns3 ip link set veth3_1 up
ip netns exec ns3 ip link set veth3_2 up
ip netns exec ns3 ip addr add 10.0.0.1/8 dev br0

# ns1 配置
ip link set veth1_3 netns ns1
ip netns exec ns1 ip addr add 10.0.0.2/8 dev veth1_3
ip netns exec ns1 ip link set veth1_3 up
ip netns exec ns1 ip link set lo up
ip netns exec ns1 ip route add default via 10.0.0.1

# ns2 配置
ip link set veth2_3 netns ns2
ip netns exec ns2 ip addr add 10.0.0.3/8 dev veth2_3
ip netns exec ns2 ip link set veth2_3 up
ip netns exec ns2 ip link set lo up
ip netns exec ns2 ip route add default via 10.0.0.1

原XDP程序代码

SEC("xdp_ingress")
int xdp_ingress_func(struct xdp_md* ctx) {
    void* data_end = (void*)(long)ctx->data_end;
    void* data = (void*)(long)ctx->data;
    struct ethhdr* eth = data;
    if ((void*)(eth + 1) > data_end) {
        return XDP_PASS;
    }
    if (eth->h_proto != __builtin_bswap16(ETH_P_IP)) {
        return XDP_PASS;
    }
    char tmp_mac[6];
    __builtin_memcpy(tmp_mac, eth->h_dest, ETH_ALEN);
    __builtin_memcpy(eth->h_dest, eth->h_source, ETH_ALEN);
    __builtin_memcpy(eth->h_source, tmp_mac, ETH_ALEN);
    return XDP_TX;
}

核心问题分析

  1. XDP_TX行为误解:XDP_TX仅将数据包从当前接口的egress方向发出,不支持跨接口转发。程序部署在ns2的veth2_3接口,执行XDP_TX后,包只会发回ns3的veth3_2,无法自动路由到ns1的接口。
  2. 双层封装头部未处理:实际数据包是嵌套的|ETH|IP|UDP|IP|TCP|结构,原XDP程序仅处理最外层以太网头,未解析内层IP/UDP头部。即使包回到ns3,内核IP转发逻辑会因内层TTL未递减、源目IP未调整等问题丢弃数据包。
  3. 网桥与XDP逻辑冲突:ns3中网桥br0的转发表无XDP交换MAC后的条目,导致包回到veth3_2后被网桥丢弃。

解决方案

1. 调整XDP部署位置与转发方式

将XDP程序部署在ns3的veth3_2接口ingress方向,使用bpf_redirect实现跨接口转发,示例代码如下:

#include <linux/bpf.h>
#include <linux/if_ether.h>
#include <bpf/bpf_helpers.h>

// 存储目标接口ifindex的map
struct bpf_map_def SEC("maps") ifindex_map = {
    .type = BPF_MAP_TYPE_ARRAY,
    .key_size = sizeof(int),
    .value_size = sizeof(int),
    .max_entries = 1,
};

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

    // 边界检查
    if ((void*)(eth + 1) > data_end) {
        return XDP_PASS;
    }
    // 仅处理外层IP包
    if (eth->h_proto != __builtin_bswap16(ETH_P_IP)) {
        return XDP_PASS;
    }

    // 交换源目MAC地址
    char tmp_mac[ETH_ALEN];
    __builtin_memcpy(tmp_mac, eth->h_dest, ETH_ALEN);
    __builtin_memcpy(eth->h_dest, eth->h_source, ETH_ALEN);
    __builtin_memcpy(eth->h_source, tmp_mac, ETH_ALEN);

    // 从map获取veth3_1的ifindex
    int key = 0;
    int *ifindex = bpf_map_lookup_elem(&ifindex_map, &key);
    if (!ifindex) {
        return XDP_PASS;
    }

    // 重定向到目标接口
    return bpf_redirect(*ifindex, 0);
}

2. 部署步骤

# 1. 获取ns3中veth3_1的ifindex
VETH3_1_IFINDEX=$(ip netns exec ns3 ip link show veth3_1 | grep -oP '^\d+')

# 2. 编译XDP程序
clang -O2 -target bpf -c xdp_redirect.c -o xdp_redirect.o

# 3. 加载程序并更新map
bpftool prog load xdp_redirect.o /sys/fs/bpf/xdp_redirect type xdp
bpftool map update name ifindex_map key 0 value $VETH3_1_IFINDEX

# 4. 将XDP程序绑定到ns3的veth3_2接口
ip netns exec ns3 ip link set veth3_2 xdp obj /sys/fs/bpf/xdp_redirect sec xdp_ingress

3. 额外优化

  • 移除网桥:使用XDP转发时无需保留br0网桥,直接配置veth3_1和veth3_2的IP,开启内核IP转发作为 fallback。
  • 处理内层头部:针对双层封装包,需解析内层IP头部,递减TTL,调整源目IP,并更新外层UDP校验和(或禁用校验和用于测试)。

内容的提问来源于stack exchange,提问作者JeremyGuo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 18:44:57