据了解(未查证),从 clang12
开始,eBPF 代码中的变量声明不再要求写在函数体的最前方,而是可以按需声明并初始化。
写法一:一次性声明全部的变量
static __always_inline void
set_output_headers(struct __sk_buff *skb, struct event *ev)
{
struct ethhdr *eth;
struct vlan_hdr *vh;
struct iphdr *iph;
struct udphdr *udph;
struct tcphdr *tcph;
struct icmphdr *icmph;
int l3_off = 0, l4_off, var_off = 0, cpy_off = 0;
// ...
}
如上代码片段,将所有需要处理的协议头对应的 struct
变量放在一起声明。如果后续需要处理其它协议,则需要在此处添加对应的 struct
变量的声明。
先声明后使用
我不喜欢这种写法,不过这种写法能在编码的时候有一个好处:使用 typeof(hdr)
获取类型、使用 sizeof(*hdr)
获取协议头大小,而无需啰嗦地再写一遍 struct xxxhdr
。
写法二:按需声明并初始化
static __always_inline __u16
calc_l3_off(struct sk_buff *s