• netlink: 返回消息的处理;NLM_F_DUMP_INTR;NLMSG_ERROR


    注意的问题

    需要注意的问题是对于内核返回消息类型,及标志位的判断。

    因为如果netlink请求,内核处理出现错误,就可能返回消息类型是ERROR;
    如果在内核发生的多个返回消息直接,网络配置发生变化,可能会将标记位标记位NLM_F_DUMP_INTR;

    处理

    如果出现以上两个情况,都需要做特别处理;但是需要根据具体需求,具体处理。

    #define NLMSG_ERROR 0x2 /* Error */
    NLM_F_DUMP_INTR;
    #define NLM_F_DUMP_INTR 0x10 /* Dump was inconsistent due to sequence change */
    
    • 1
    • 2
    • 3

    nlmsg_ptr = (struct nlmsghdr *) read_ptr;
    if((nlmsg_ptr->nlmsg_type == NLMSG_ERROR) || (nlmsg_ptr->nlmsg_flags & NLM_F_DUMP_INTR) )

    iproute2的处理

    会打印一个不一致提示。

    if (h->nlmsg_flags & NLM_F_DUMP_INTR)
    	dump_intr = 1;
    if (found_done) {
    	if (dump_intr)
    		fprintf(stderr,
    			"Dump was interrupted and may be inconsistent.\n");
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    static int accept_msg(struct rtnl_ctrl_data *ctrl,
    		      struct nlmsghdr *n, void *arg)
    {
    	struct nlmsgerr *err = (struct nlmsgerr *)NLMSG_DATA(n);
    
    	if (n->nlmsg_type == NLMSG_ERROR &&
    	    (err->error == -EOPNOTSUPP || err->error == -EINVAL))
    		have_rtnl_newlink = 0;
    	else
    		have_rtnl_newlink = 1;
    	return -1;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    NLMSG_ERROR 两粒

    2176 recvmsg(13, {msg_name={sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, msg_namelen=12, msg_iov=[{iov_base={{len=36, type=NLMSG_ERROR, flags=NLM_F_CAPPED, seq=1665287797, pid=3474127294}, {error=0, msg={len=84, type=RTM_DELROUTE, flags=NLM_F_REQUEST|NLM_F_ACK, seq=1665287797, pid=0}}}, iov_len=1052}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 36

    2176 recvmsg(13, {msg_name={sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, msg_namelen=12, msg_iov=[{iov_base={{len=84, type=NLMSG_ERROR, flags=0, seq=1665287799, pid=4163225942}, {error=-EEXIST, msg={{len=64, type=RTM_NEWROUTE, flags=NLM_F_REQUEST|NLM_F_ACK|NLM_F_CREATE|NLM_F_APPEND, seq=1665287799, pid=0}, {rtm_family=AF_INET6, rtm_dst_len=64, rtm_src_len=0, rtm_tos=0, rtm_table=RT_TABLE_MAIN, rtm_protocol=RTPROT_BOOT, rtm_scope=RT_SCOPE_LINK, rtm_type=RTN_UNICAST, rtm_flags=0}, [{{nla_len=8, nla_type=RTA_PRIORITY}, 256}, {{nla_len=20, nla_type=RTA_DST}, inet_pton(AF_INET6, “26::”)}, {{nla_len=8, nla_type=RTA_OIF}, if_nametoindex(“abc”)}]}}}, iov_len=1052}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 84
    2176 close(13)

    类似问题

    https://github.com/golang/go/issues/52137

  • 相关阅读:
    flask SQLAlchemy
    算法基础:图
    Java小游戏之——贪吃蛇
    保证金服务数据一致性问题-大数据解决方案
    GPS定位与IP地址有什么区别?
    SNARK性能及安全——Prover篇
    【C语言】进阶——结构体+枚举+联合
    java毕业设计在线家教预约系统Mybatis+系统+数据库+调试部署
    基于Java毕业设计游泳馆管理平台源码+系统+mysql+lw文档+部署软件
    Nacos:服务注册及配置中心
  • 原文地址:https://blog.csdn.net/qq_36428903/article/details/127649129