作者:wqiangwang,腾讯 TEG 后台开发工程师
本文通过“Kni 映射到内核的接口未能发送 LACP 报文导致 bond 不能聚合”这个问题,来探索内核调试中,对于正在运行的内核,通过 systemtap 获取关键数据结构的值的通用方法。
背景
DPDK 支持物理端口 通过 kni 映射到内核的虚拟接口作为内核的标准 net device,借助内核完善的生态处理相对复杂的网络协议,如 tcp 等,这样以后,无需在用户态实现这些协议。在 NGW 网关产品中,同样的,从物理端口接收的 LACP 报文则通过 kni 注入给内核;内核向外发送的 LACP 报文则通过 kni 处理并从物理口出。借助内核成熟的 LACP 协议和生态 而无需用户态自己实现 LACP,即可完成 bond 聚合。
但在升级 DPDK-20.11 版本时,出现 bond 未能聚合。通过 tcpdump 抓包发现,原来对端交换机已经发送了 LACP 报文,而本端一直未发送 LACP 报文,所以未能聚合:
分析
1、 既然是本端一直未发送 LACP 报文, 则内核协议栈没有调用 dev_queue_xmit 函数向外发送 skb->protocol 为 0x8809 的 skb。刚好手上有一台相同内核版本且 bond 已经聚合的设备,为了缩短 bond 内核模块的代码学习时间,因此看下这台设备当调用 dev_queue_xmit 函数发送 skb->protocol 为 0x8809 的 skb 的 backtrace。编写 systemtap 脚本如下:
2、 对于本设备,systemtap probe 函数 bond_3ad_state_machine_handler 发现其调用时 ad_lacpdu_send 未调用。看一下代码,发现 ad_lacpdu_send 若执行,需满足的条件离不开 port 的访问,为此必须知道 port 的地址