You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过netlink接收RTM_NEWTFILTER、RTM_DELTFILTER消息

问题解决方法

1. 无法接收TFILTER通知的根因

你当前代码的sa.nl_groups字段仅订阅了链路状态、IPv4地址、IPv4路由三类netlink事件组,TC(流量控制)相关的qdisc、分类器、过滤器事件都属于RTMGRP_TC事件组,未订阅该组自然无法接收RTM_NEWTFILTER/RTM_DELTFILTER通知。

2. 代码修改步骤

2.1 新增TC事件组订阅

修改main函数中sa.nl_groups的赋值逻辑,加入TC事件组:

// 原代码
// sa.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV4_ROUTE;
// 修改后
sa.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV4_ROUTE | RTMGRP_TC;

如果编译时提示RTMGRP_TC未定义,可以替换为原始宏计算值:

sa.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV4_ROUTE | (1 << (RTNLGRP_TC - 1));

2.2 修正消息解析逻辑

你当前代码默认把所有netlink消息的payload都当做struct ifinfomsg解析,TC类消息的payload结构是struct tcmsg,直接打印会出现字段错位问题,需要按消息类型做分支解析:

// read_msg函数中判断消息类型分支
if (nh->nlmsg_type >= RTM_NEWQDISC && nh->nlmsg_type <= RTM_DELACTION) {
    // TC类消息用tcmsg解析
    struct tcmsg *tcmsg = NLMSG_DATA(nh);
    printf("\ttcm_ifindex = %d, tcm_handle = 0x%x, tcm_parent = 0x%x\n",
        tcmsg->tcm_ifindex, tcmsg->tcm_handle, tcmsg->tcm_parent);
    print_type(nh->nlmsg_type);
} else if (nh->nlmsg_type >= RTM_NEWLINK && nh->nlmsg_type <= RTM_GETLINK) {
    // 链路类消息用ifinfomsg解析
    struct ifinfomsg *ifimsg = NLMSG_DATA(nh);
    printf("\tifi_family = %u, ifi_type = %u, ifi_index = %u, ifi_flags = 0x%X, ifi_change = 0x%X\n",
            ifimsg->ifi_family, ifimsg->ifi_type, ifimsg->ifi_index, ifimsg->ifi_flags, ifimsg->ifi_change);
    print_type(nh->nlmsg_type);
    print_flags(ifimsg->ifi_flags, ifimsg->ifi_change);
}

3. 其他接收TC过滤器变更的方式

  • 可以使用libnl、libmnl这类封装好的netlink开发库,无需手动处理消息对齐、属性解析等底层逻辑,开发效率更高
  • 也可以通过inotify监控tc配置相关的sysfs节点,不过该方式仅能感知变更事件,无法获取变更的具体内容,可靠性低于netlink通知

内容的提问来源于stack exchange,提问作者stanislav888

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 23:09:03