linux协议栈中提供了一个trace kfree_skb的驱动drop_monitor,通过register_trace_kfree_skb注册trace回调,这样在kfree_skb的时候将丢包的地址传给drop_monitor,drop_monitor再将丢包的地址通过netlink传给应用程序dropwatch。
操作篇
1、将kernel的drop_monitor.c编译成模块ko;
2、系统启动后加载驱动insmod drop_monitor.ko
3、将dropwatch编译成可执行程序后,运行dropwatch,输入start后启动monitor;
4、获得丢包的地址后,通过addr2line查找对于的代码位置;
原理篇
kernel部分
1、首先需要向genl family中注册server端,常见的netlink family有NETLINK_GENERIC,NETLINK_ROUTE,NETLINK_KOBJECT_UEVENT等。
genl_register_family_with_ops(&net_drop_monitor_family,
dropmon_ops,
ARRAY_SIZE(dropmon_ops));
static struct genl_family net_drop_monitor_family = {
.id = GENL_ID_GENERATE,
.hdrsize = 0,
.name = "NET_DM",
.version = 2,
.maxattr = NET_DM_CMD_MAX,
};
2、申请空的genl message实体:
sk_buff *skb = genlmsg_new(al, GFP_KERNEL);//申请一个genl message
genlmsg_put(skb, 0, 0, &net_drop_monitor_family,
0, NET_DM_CM