XDP入门--eBPF之hello world

通过前文XDP, traffic control/tc/qdisc和netfilter在Linux的网络架构(packet flow in Netfilter and General Network)我们已经知道,XDP(eXpress Data Path)是与DPDK对应的一套快速数据处理框架,它是 Linux Kernel 中提供高性能、可编程的网络数据包处理框架。 它使得 Kernel 能够在数据报文到达 L2(网卡驱动层)时就对其进行针对性的高速处理,而无需再 “循规蹈矩” 地进入到 Linux内核的TCP/IP协议栈进行处理。

1、下面这二张图,能非常好的说明XDP在Linux内核里的网络数据处理架构上的位置。

在这里插入图片描述
在这里插入图片描述

2、XDP提供了可编程的灵活处理方式,XDP 程序可以通过 XDP action code来指定驱动程序对报文的后续处理方式:

  1. XDP_ABORTED:
    丢弃报文,与 XDP_DROP不同之处在于XDP_ABORTED会用 trace_xdp_exception 来记录错误行为。
  2. XDP_DROP:
    在网卡驱动层直接将报文丢弃,数据包将不再送到内核TCP/IP协议栈进行处理。
  3. XDP_PASS
    报文继续送往内核TCP/IP协议栈进行处理,此时的处理方式与传统方式一致。
  4. XDP_TX:
    将报文从接收到此报文的同一块网卡发送出去
  5. XDP_REDIRECT:
    将报文重定向到其他的网卡或CPU,结合AF_XDP可以将报文直接送往用户空间,接应用程度直接接管报文,类似DPDK。

3、一个将收到的报文在XDP里直接丢弃的例子

本例子在树莓派系统上验证通过。

3.1、安装clang

sudo apt install clang

3.2、编写XDP程序

每二个报文就丢弃一个报文,剩下的那个报文上送内核协议栈处理。

// file: xdp-helloworld.c

#include <linux/bpf.h>

#ifndef __section
# define __section(NAME)                  \
   __attribute__((section(NAME), used))
#endif



__section("prog")
int xdp_drop(struct xdp_md *ctx)
{
    
    
    static int example_count = 1;

    example_count++;

    if (example_count%2)
    {
    
    
        return XDP_DROP;
    }
    else
    {
    
    
        return XDP_PASS;
    }
}

char __license[] __section("license") = "GPL";


3.3、设置编译环境并编译XDP程度

注意依赖于你的环境是arm架构还是X86架构的不同,需要将/usr/include/xxxx/asm不同的xxxx下的asm目录软链接到/usr/include/asm目录。

cd /usr/include/

sudo ln -s ./arm-linux-gnueabihf/asm asm
sudo ln -s ./arm-linux-gnueabihf/bits/ bits

clang -O2 -Wall -target bpf -c xdp-helloworld.c -o xdp-helloworld.o

3.4、加载XDP程序和验证

我们的测试环境如下:

                                                     +- RPi -------+          +- old pc1----+
                                                     |         Eth0+----------+ Eth0        |    
                 +- Router ----+                     |  DHCP server|          | 10.0.0.10   |
                 | Firewall    |                     |   10.0.0.1  |          |             |
(Internet)---WAN-+ DHCP server +-WLAN AP-+-)))   (((-+ WLAN        |          +-------------+
                 | 192.168.3.1 |                     |             |          
                 +-------------+                     |             |          +- old pc2----+
                                                     |         Eth1+----------+ Eth0        |   
                                                     |             |          | 10.0.0.4    |                                                       
                                                     +-------------+          |             |
                                                                              +-------------+

我们在RPi的Eth1里加载XDP程序,并从old pc2(10.0.0.2) ping old pc1(10.0.0.4),在加载XDP的上述程序成功后,RPi的eth1会将收到的报文每间隔一个就丢弃一个。我们在old pc2上观察ping icmp报文,并用wireshark抓包,我们发现每间隔一个就有一个没有收到响应。说明RPi的Eth1已经将收到的报文每间隔一个就丢弃一个。

sudo ip link set dev eth1 xdp obj xdp-helloworld.o

在这里插入图片描述

3.5、卸载XDP程序

在卸载XDP的上述程序后,就会发现ping恢复正常。说明RPi的eth1恢复正常功能。

扫描二维码关注公众号,回复: 15401693 查看本文章
sudo ip link set dev eth1 xdp off

猜你喜欢

转载自blog.csdn.net/meihualing/article/details/130781598