需要注意的问题是对于内核返回消息类型,及标志位的判断。
因为如果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 */
nlmsg_ptr = (struct nlmsghdr *) read_ptr;
if((nlmsg_ptr->nlmsg_type == NLMSG_ERROR) || (nlmsg_ptr->nlmsg_flags & NLM_F_DUMP_INTR) )
会打印一个不一致提示。
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;
}
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;
}
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