eBPF Talk: XDP 解析所有 TCP options
文章目录
使用 fentry
能解析到 TOA option,eBPF Talk: BPF 读取 TOA 的 4 种方式。
上难度,如何使用 XDP 解析所有的 TCP options 呢?
太长不读:使用 freplace
解析 TCP option,使用 XDP
遍历所有 TCP options。
这儿为什么要用上 freplace
呢?因为对于 verifier 来说,解析 TCP option 的函数过于复杂;如果为了通过 verifier,就无法解析所有的 TCP options 了。
因而,将遍历 TCP options 的逻辑和解析 TCP option 的逻辑分开,从而规避 verifier 的限制。
效果
跑起来,看看效果再说:
|
|
对比 Wireshark 的结果:
TCP options
先来看看内核支持哪些 TCP options:
|
|
似乎不够全面,找找其它资料:IANA Transmission Control Protocol (TCP) Parameters。
整理一下,得到如下 TCP options:
|
|
freplace 解析 TCP option
在解析 TCP option 时,需要按需去判断 packet range,因为可能会遇到 TCPOPT_NOP
、TCPOPT_EOL
等 option。
|
|
其中,parse_option()
返回 -1 时表示解析结束,返回其它值时表示解析成功后得到的当前 option 的长度。
parse_option()
处理逻辑:
- 读取
opcode
。 - 判断
opcode
是否为TCPOPT_EOL
或TCPOPT_NOP
。 - 读取
opsize
。 - 判断
opsize
是否小于 2;如果小于 2,遇到的是畸形 option。 - 特殊处理
TCPOPT_TOA_AKAMAI
和TCPOPT_TOA_COMPAT
。 - 查表
tcp_options
,打印 option 的名称、长度和值。
XDP 遍历所有 TCP options
遍历所有 TCP options 的逻辑比较简单:
|
|
其中:
option_parser()
是提供给freplace
的桩函数,用于解析 TCP option。for
循环遍历所有 TCP options,即使全部 option 都是TCPOPT_NOP
。length
为剩余需要解析的 TCP options 的数据长度。offset
为当前需要解析的 TCP option 相对于xdp->data
的偏移量。length <= 0
时表示已经解析完所有 TCP options。option_parser()
返回值小于等于 0 时表示解析结束,无需继续解析。
注意:option_parser()
不能使用 static
修饰,否则在加载 freplace
程序时 verifier 会报错。
总结
为了在 XDP 里解析所有的 TCP options,需要将遍历逻辑和解析逻辑分开,并将解析逻辑放到 freplace
程序里,从而规避 verifier 的限制。
文章作者 Leon Hwang
上次更新 2024-08-18