xdp 是如何加载到内核并运行的

XDP framework

xdp在内核里的有三个关键步骤:

  • load: 加载到内核
  • attach: 绑定到一个网口
  • run:网口收包时候,调用并执行bpf prog

load加载: 通过ebpf系统调用, 把prog加载到内核

fd = sys_bpf(BPF_PROG_LOAD, attr, size);

  • 在内核里创建一个bfp_prog结构体用以存储bpf prog。
  • 通过bpf_check检查prog程序的安全性和合法性。
  • 通过bpf_prog_select_runtime指定bpf prog对应的执行函数
  • 这个函数指针保存在bpf_func这个字段里。这里的function最终指向通用的bfp run函数___bpf_prog_run
    关于___bpf_prog_run这个具体封装和实现见另外一篇文章。

attach绑定: 将prog程序绑定到一个特定的网口的struct net_device

libpf函数do_attach将上一步加载在内核里的prog跟一个网口绑定, 具体实现是通过下发netlink命令。
这是个generic类型的netlink命令,最终通过dev_change_xdp_fd将prog挂载到对应netdev下面。

Read More

how tcpdump work with vlan filter

问题场景

tcpdump在网口直接抓包和读取pcap文件两种场景下,同一个filter表达式icmp,对vlan报文有不同的处理结果。

  • 在网口上抓包可以看到vlan和非vlan两种流量
  • 读取pcap只能看到非vlan流量一种流量

【Q1】:在读取pcap文件时候,为什么不能读取到vlan报文呢?

分析结论

内核协议栈:

  1. 过滤条件 icmp:tcpdump 解析出来的 ebpf 指令,是要求报文是eth+IP+ICMP格式。通过ETH/IP 头里的协议类型分别做了限制: IPv4(0x0800)+ICMP(1)。

  2. 在网口上抓包:内核代码里,在tcpdump抓包过滤的钩子函数之前,会把报文的vlan解析并剔除掉。被剥离的vlan头信息,被保存到skb的metadata里了。所以 tcpdump(af_packet)在内核里,通过钩子函数运行过滤条件的 ebpf 指令时,被处理的报文已经不带vlan头了。因此只要满足icmp 头,带和不带 vlan头的报文都会被抓取到。

  3. 读取pcap文件:tcpdump 直接读取文件内容,vlan头并没有被剥离掉,所以vlan报文不满足过滤条件(eth+IP+ICMP),被丢弃了。

国外已经有人发现并分析过这个问题:BPF and tcpdump

Read More

tcpdump and ebpf

以内核v6.6代码,介绍tcpdump程序如何与内核交互,加载bpf程序的。

加载:

libpcap通过sockopt里的“SO_ATTACH_FILTER“,
在 packet socket下的”sk_filter“挂载prog呈现。

运行:

当skb报文到达packet_rcv时候, 通过调用___bpf_prog_run函数(注意,这个函数是3个下滑线,区别于2个下划线的函数)
运行”sk_filter“对应的prog。
其中prog的
==>packet_rcv
==> ==> run_filter
==> ==> ==>bpf_prog_run_clear_cb

Read More

how tcpdump work with cbpf

tcpdump通过libpcap库以及内核的af_packet对数据包问题进行抓取。
关于这两部分的如何协作抓包,之前blog里已经写过。
这里主要记录分析,在ebpf之前的内核(以v3.0)如何处理tcpdump里的filter的。

filter编译后,如何加载到内核里的:

在filter被翻译为一系列的指令后,这个指令buff被libpcap,
通过sockopt里的SO_ATTACH_FILTE选项,
最终挂载到AF_PACKET socket下的sk_filter上。

Read More

tcpdump如何实现参数-报文抓取长度

用法

tcpdump -s len

原理

tcpdump会把这个长度值编译到ebpf代码中。 ebpf代码执行完后,如果filter成功,则作为返回值(return)返回给调用方(内核协议栈),内核协议栈根据返回值,修改 skb报文到指定的长度,并借助 af socket 返回给用户空间。

tcpdump命令解析

tcpdump snaplen参数: ebpf指令对比

Read More

xfrm: configure xfrm state and policy with iproute2

测试环境

1
2
3
4
5
6
7
8
9
10
11
12
13
14
ip netns exec ns1 ip l s veth1 down
ip l delete veth0
ip netns delete ns1

ip l add type veth
ip netns add ns1

ip l s dev veth1 netns ns1
ip l set veth0 up
ip netns exec ns1 ip l set veth1 up

ip a a dev veth0 192.168.100.1/24
ip netns exec ns1 ip a a dev veth1 192.168.100.2/24
ip netns exec ns1 ip r a default via 192.168.100.1

Read More

WHAT is TFO

什么是tcp fast open(TFO)

背景

网络上有大量的短连接,传输的数据很少。google统计显示,其访问请求里有30%左右的流量是短连接。

原理

针对tcp 短连接的一个优化。在syn请求里携带请求数据,让server端尽早处理,进而降低一个RTT的延迟。
client端发送时候在syn报文里,增加一个tcp option选项(TFO),server端通过它校验client端的合法性。

Read More

How to use kpatch

搭建kpatch builder

以centos7.2为例。

默认centos7.2的安装的内核版本是3.10.0-327.el7.x86_64,这个内核版本当初是通过gcc 4.8.3编译的。
而centos7.2自带gcc rpm包的版本则是 4.8.5

kpatch build命令执行的时候,首先检查gcc的版本是否一致,
因为两者的版本不一致,所以kpatch build命令会失败。
当然我们可以使用--skip-gcc-check,跳过这个检查,我也测试发现在一些简单补丁下可以打包通过。
但是系统不推荐这样做的,会有一定的风险。

Read More