eBPF Talk: 跟踪 ipv4 sysctl 配置变更
文章目录
实现了对 IRQ 绑核、RPS/XPS 配置变更后,接着是跟踪网卡的 net.ipv4.conf.*.* sysctl 的配置变更。
ipv4 sysctl 配置变更的内核函数
ipv4 sysctl 配置变更的方式如下:
echo 1 > /proc/sys/net/ipv4/conf/all/${devconf}
。echo 1 > /proc/sys/net/ipv4/conf/default/${devconf}
。echo 1 > /proc/sys/net/ipv4/conf/${NET_DEV}/${devconf}
。
直接查看对应的内核源代码 net/ipv4/devinet.c
吧。
找到如下源代码:
|
|
使用 bpftrace
确认一下:
|
|
分析其中的 devinet_conf_proc
函数:
- sysctl 配置变更的值是通过
ctl->data
获取的,类型是int
。 - sysctl 配置项的索引通过
(int *)ctl->data - cnf->data
获取的;需要+1
后才是正确的索引定义。 - sysctl 配置的 ifindex 是通过
devinet_conf_ifindex()
获取的,可能是ALL
/DEFAULT
/ifindex
。
跟踪 ipv4 sysctl 配置变更函数
直接对 devinet_conf_proc
、devinet_sysctl_forward
、ipv4_doint_and_flush
进行 fexit
跟踪,以便观测配置变更的情况。
|
|
其中,不要傻傻地在 bpf 里计算配置项索引,而留待用户态程序计算。
跑起来后:
|
|
完整的源代码:fexit_ipv4_sysctl。
总结
跟踪 ipv4 sysctl 配置变更的方式和跟踪 RPS/XPS 配置变更的方式类似,使用 fexit
而不是 kprobe
。
在 bpf 代码里,需要注意 ifindex 的获取,以及配置项索引的计算。
文章作者 Leon Hwang
上次更新 2024-07-07