【问题标题】:how to forward packet between NIC and WIFI using XDP如何使用 XDP 在 NIC 和 WIFI 之间转发数据包
【发布时间】:2020-03-24 10:17:33
【问题描述】:

我正在尝试重定向 NIC 和 WIFI 之间的流量。我正在尝试从 eth0 转发数据包,通过 wlan0 发送偶数数据包,通过 wlan1 发送奇数数据包。

我无法成功地将数据包从一个接口重定向到另一个接口,除非这些接口是虚拟的(例如在 xdp 教程中创建的接口)。

是否有一个简单的示例将入口数据包从带有 MAC 28:f1:f1:f1:f1:f1 的 eth0 重定向到带有 MAC e4:f1:f1:f1:f1:f1 的 wlan0? (例如 MAC)所以如果我通过以太网端口连接第二台计算机(假设路由正确)并 ping 8.8.8.8,它会通过 wlan0 发送数据包?

我将不胜感激这方面的任何帮助。

编辑:

我使用的代码来自xdp-tutorial

逐步设置:

# Mount map directory
sudo mount -t bpf bpf /sys/fs/bpf/

# Load the programs
sudo ./xdp_loader -d eth0 -S --filename xdp_prog_kern_03.o --progsec xdp_redirect_map -F
sudo ./xdp_loader -d wlan0 -S --filename xdp_prog_kern_03.o --progsec xdp_pass -F

# Set up redirect map
sudo ./xdp_prog_user -d eth0 -r wlan0 --src-mac 28:f1:f1:f1:f1:f1 --dest-mac e4:f1:f1:f1:f1:f1

最后一条命令输出:

map dir: /sys/fs/bpf/eth0
redirect from ifnum=5 to ifnum=3
forward: 28:f1:f1:f1:f1:f1 -> e4:f1:f1:f1:f1:f1

相关的BPF代码是

struct bpf_map_def SEC("maps") tx_port = {
    .type = BPF_MAP_TYPE_DEVMAP,
    .key_size = sizeof(int),
    .value_size = sizeof(int),
    .max_entries = 256,
};

struct bpf_map_def SEC("maps") redirect_params = {
    .type = BPF_MAP_TYPE_HASH,
    .key_size = ETH_ALEN,
    .value_size = ETH_ALEN,
    .max_entries = 1,
};

SEC("xdp_redirect_map")                                                                                  
int xdp_redirect_map_func(struct xdp_md *ctx)                                                            
{                                                                                                        
        void *data_end = (void *)(long)ctx->data_end;                                                    
        void *data = (void *)(long)ctx->data;                                                            
        struct hdr_cursor nh;                                                                            
        struct ethhdr *eth;                                                                              
        int eth_type;                                                                                    
        int action = XDP_PASS;                                                                           
        unsigned char *dst;                                                                              

        /* These keep track of the next header type and iterator pointer */                              
        nh.pos = data;                                                                                   

        /* Parse Ethernet and IP/IPv6 headers */                                                         
        eth_type = parse_ethhdr(&nh, data_end, &eth);                                                    
        if (eth_type == -1)                                                                              
            return xdp_stats_record_action(ctx, XDP_DROP);                                               

        /* Do we know where to redirect this packet? */                                                                                                                                                         
        dst = bpf_map_lookup_elem(&redirect_params, eth->h_source);                                      

        if (!dst)                                                                                        
                goto out;                                                                                

        /* Set a proper destination address */                                                           
        memcpy(eth->h_dest, dst, ETH_ALEN);                                                              

        action = bpf_redirect_map(&tx_port, 0, 0);                                                       

out:                                                                                                     
        return xdp_stats_record_action(ctx, action);                                                     
} 

SEC("xdp_pass")                                       
int xdp_pass_func(struct xdp_md *ctx)                 
{                                                     
        return xdp_stats_record_action(ctx, XDP_PASS);
}    

地图的内容是:

# Output of redirect_params
sudo bpftool map dump id 33
key: 28 f1 f1 f1 f1 f1  value: e4 f1 f1 f1 f1 f1
Found 1 element

# Output of tx_port
key: 00 00 00 00  value: 03 00 00 00
key:
01 00 00 00
value:
No such file or directory

# And then the No such file or directory repeats with every key

【问题讨论】:

  • 您能详细说明您尝试了什么以及遇到的错误或问题吗? BPF程序没有加载成功?数据包是否被丢弃?重定向助手调用是否返回错误代码?
  • 我记得,从 NIC 重定向到 WLAN,还必须处理数据包格式 80211MAC,然后使用正确的 ifindex 调用 bpf_redirectbpf_redirect_map。分享您的代码 sn-p 并正如@pchaigno 正确指出的那样,确保您已正确加载到接口。
  • 请交叉检查 wlan0 是 NIC 还是无线设备。如果按照ip link show wlan0 对@pchaigno 的要求对 NIC 进行交叉检查。如果这是无线设备,请检查驱动程序代码是否支持 XDP。使用 bpftool sudo bpftool prog 获取地图 ID 并交叉检查 ip link show 以获得所需链接的 prog/xdp id
  • bpf_prog_run_xdp() 用于原生 XDP 支持。如果本机不可用,最近的内核将依赖通用 XDP 支持。以通用模式将 XDP 程序附加到无线接口应该可以工作。不过,我不知道重定向。 @Gef,你怎么知道事情不起作用?我认为您的情况应该是来自地图转储的No such file or directory
  • @Qeole,我还认为通用 XDP 应该与无线接口一起使用,而且似乎确实如此,支持 XDP_PASS 和 XDP_DROP 但 XDP_REDIRECT 需要驱动程序实现才能工作,或者至少我就是这样找到了。

标签: xdp-bpf


【解决方案1】:

截至目前,Linux Kernel 5.5 包含用于 TUN 和 NIC 驱动程序的 bpf_prog_run_xdp 函数调用。

drivers/net/tun.c
drivers/net/ethernet
/broadcom/bnxt/bnxt_xdp.c, line 144
cavium/thunder/nicvf_main.c, line 559
freescale/dpaa2/dpaa2-eth.c, line 305
intel/i40e/i40e_txrx.c, line 2212
intel/ice/ice_txrx.c, line 442
ixgbe/ixgbe_main.c, line 2213
marvell/mvneta.c, line 2099
mellanox/mlx4/en_rx.c, line 785
mellanox/mlx5/core/en/xdp.c, line 141
netronome/nfp/nfp_net_common.c, line 1917
qlogic/qede/qede_fp.c, line 1075
sfc/rx.c, line 700
socionext/netsec.c, line 890
ti/cpsw_priv.c, line 1337

因此,正如 cmets 中所讨论的,似乎没有本地对 wifi 驱动程序的 XDP 调用。

注意:Linux 内核版本、自定义驱动程序或ip 或 'bpftool` 的结果不共享以进行调试。我也找不到允许 802MAC 标头的 XDP 代码更改。

【讨论】:

  • 我已经找到了一些努力来实现对 wifi 驱动程序的 XDP 调用,如果有人和我有同样的问题,我会留下链接。 patchwork.kernel.org/cover/10701541
  • 但正如其中提到的,它不是主线的一部分。在 XDP 程序中,我也没有看到任何转换或附加 MAC wifi 空气头的代码。
  • 到目前为止,如果我能让 XDP_REDIRECT 在以太网和 WiFi 之间工作,我不介意尝试测试主线之外的任何东西。或任何其他有望如此快速的技术。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-02
相关资源
最近更新 更多