3

I am trying to redirect the traffic between NIC and WIFI. I am trying to forwards packets from eth0, to send even packets through wlan0 and odd packets through wlan1.

I have not been able to successfully redirect packets from one interface to another unless those interfaces are virtual (such as the ones created in the xdp-tutorial).

Is there a simple example anywhere of redirecting ingress packets from eth0 with MAC 28:f1:f1:f1:f1:f1 to wlan0 with MAC e4:f1:f1:f1:f1:f1? (example MACs) So that if I connect a second computer through the ethernet port (assuming correct routing) and ping 8.8.8.8 it sends the packets through wlan0?

I would appreciate any help in this regard.

EDIT:

The code I am using is the one from xdp-tutorial

Step by step setup:

# 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

The last command outputs:

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

The relevant BPF code is

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);
}    

And the content of the maps is:

# 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
Vipin Varghese
  • 4,540
  • 2
  • 9
  • 25
Gef
  • 73
  • 8
  • 1
    Can you detail what you tried and the error or issue you get? Is the BPF program not successfully loaded? Are packets dropped? Is the redirect helper call returning an error code? – pchaigno Mar 24 '20 at 10:23
  • 2
    As I recollect, redirecting from NIC to WLAN, one also has to take care of packet format `80211MAC` then invoke `bpf_redirect` or `bpf_redirect_map` with the right ifindex. Share your code snippet and as correctly pointed out by @pchaigno ensure you have loaded to interface correctly. – Vipin Varghese Mar 24 '20 at 13:20
  • 1
    please cross-check wlan0 is NIC or wireless device. If NIC cross-check as asked @pchaigno by `ip link show wlan0`. if this is a wireless device, check the driver code if XDP is supported or not. Use bpftool `sudo bpftool prog` to get map id and cross check `ip link show ` for `prog/xdp id` of desired link. – Vipin Varghese Mar 25 '20 at 11:44
  • It is indeed a wireless device, so I guess I cannot achieve redirection between the NIC and the wireless device. – Gef Mar 26 '20 at 08:17
  • 1
    `bpf_prog_run_xdp()` is for native XDP support. Recent kernels fall back on generic XDP support if native is not available. Attaching XDP programs to a wireless interface in generic mode should work. I don't know about redirection, though. @Gef, how do you tell that things are not working? The `No such file or directory` from map dump is expected in your case I think. – Qeole Mar 26 '20 at 11:09
  • 1
    @Qeole, I thought also that generic XDP should work with wireless interfaces, and it seems that it does, XDP_PASS and XDP_DROP are supported but XDP_REDIRECT needs driver implementation to work, or at least that is what I found. – Gef Mar 26 '20 at 15:13
  • @Gef, could you please put the reference of your statement _XDP_PASS and XDP_DROP are supported but XDP_REDIRECT needs driver implementation to work, or at least that is what I found._ Thank you in a advance. – nav Aug 12 '20 at 15:29

1 Answers1

1

As of date, Linux Kernel 5.5 houses bpf_prog_run_xdp function call for TUN and NIC drivers.

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

hence as discussed in comments there looks like no XDP calls to wifi driver natively.

Note: the Linux kernel version, custom driver, or results of ip or 'bpftool` are not shared to debug. Also I am unable to find XDP code change for allowing 802MAC headers too.

Vipin Varghese
  • 4,540
  • 2
  • 9
  • 25
  • 1
    I have found some efforts to implement XDP calls to wifi driver, I will leave the link in case anyone has the same question as I did. https://patchwork.kernel.org/cover/10701541/ – Gef Mar 26 '20 at 08:54
  • 1
    But as mentioned in it is not part of mainline. In XDP program I do not see any code to convert or append MAC wifi air headers too. – Vipin Varghese Mar 26 '20 at 11:34
  • 1
    As of now, I would not mind to try and test anything outside mainline if I can get XDP_REDIRECT to work between Ethernet and WiFi. Or any other technology that is hopefully that fast. – Gef Mar 26 '20 at 15:16