как переслать пакет между NI C и WIFI, используя XDP - PullRequest
1 голос
/ 24 марта 2020

Я пытаюсь перенаправить трафик c между NI C и WIFI. Я пытаюсь пересылать пакеты из eth0, отправлять четные пакеты через wlan0 и нечетные пакеты через wlan1.

Я не смог успешно перенаправить пакеты с одного интерфейса на другой, если эти интерфейсы не являются виртуальными (например, созданные в xdp-руководстве).

Есть ли простой пример перенаправления входящих пакетов из eth0 с MA C 28: f1: f1: f1: f1: f1 на wlan0 с MA C e4: f1: f1: f1: f1: f1? (пример MAC) Так что если я подключу второй компьютер через порт ethe rnet (при условии правильной маршрутизации) и пинг 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

1 Ответ

0 голосов
/ 26 марта 2020

На сегодняшний день Linux Kernel 5.5 содержит bpf_prog_run_xdp функциональный вызов для драйверов TUN и NI C.

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

, следовательно, как обсуждалось в комментариях, исходные вызовы XDP к драйверу Wi-Fi не выглядят как исходные.

Примечание: версия ядра Linux, пользовательский драйвер или результаты ip или 'bpftool` не передается для отладки. Также я не могу найти изменение кода XDP для разрешения заголовков 802MA C.

...