Hi, On Tue, Jan 09, 2018 at 03:59:07PM +0900, Chris Mi wrote: [...] > diff --git a/lib/libnetlink.c b/lib/libnetlink.c > index 00e6ce0c..ae0059f9 100644 > --- a/lib/libnetlink.c > +++ b/lib/libnetlink.c > @@ -581,39 +581,43 @@ static void rtnl_talk_error(struct nlmsghdr *h, struct > nlmsgerr *err, > strerror(-err->error)); > } > > -static int __rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, > - struct nlmsghdr **answer, > - bool show_rtnl_err, nl_ext_ack_fn_t errfn) > +static int __rtnl_talk_msg(struct rtnl_handle *rtnl, struct msghdr *m, > + struct nlmsghdr **answer, > + bool show_rtnl_err, nl_ext_ack_fn_t errfn) > { > - int status; > - unsigned int seq; > - struct nlmsghdr *h; > struct sockaddr_nl nladdr = { .nl_family = AF_NETLINK }; > - struct iovec iov = { > - .iov_base = n, > - .iov_len = n->nlmsg_len > - }; > + int i, status, iovlen = m->msg_iovlen; > + struct iovec iov; > struct msghdr msg = { > .msg_name = &nladdr, > .msg_namelen = sizeof(nladdr), > .msg_iov = &iov, > .msg_iovlen = 1, > }; > - char *buf; > - > - n->nlmsg_seq = seq = ++rtnl->seq; > + unsigned int seq = 0; > + struct nlmsghdr *h; > > - if (answer == NULL) > - n->nlmsg_flags |= NLM_F_ACK; > + for (i = 0; i < iovlen; i++) { > + struct iovec *v; > + v = &m->msg_iov[i]; > + h = v->iov_base; > + h->nlmsg_seq = seq = ++rtnl->seq; > + if (answer == NULL) > + h->nlmsg_flags |= NLM_F_ACK; > + } > > - status = sendmsg(rtnl->fd, &msg, 0); > + status = sendmsg(rtnl->fd, m, 0); > if (status < 0) { > perror("Cannot talk to rtnetlink"); > return -1; > } > > + i = 0; > while (1) {
for (i = 1; ; i++) ? > + char *buf; Why did you move this declaration? > +next: Drop this and use 'continue' instead of 'goto next' below? > status = rtnl_recvmsg(rtnl->fd, &msg, &buf); > + ++i; > > if (status < 0) > return status; > @@ -642,7 +646,7 @@ static int __rtnl_talk(struct rtnl_handle *rtnl, struct > nlmsghdr *n, > > if (nladdr.nl_pid != 0 || > h->nlmsg_pid != rtnl->local.nl_pid || > - h->nlmsg_seq != seq) { > + h->nlmsg_seq > seq || h->nlmsg_seq < seq - iovlen) { > /* Don't forget to skip that message. */ > status -= NLMSG_ALIGN(len); > h = (struct nlmsghdr *)((char *)h + > NLMSG_ALIGN(len)); > @@ -662,7 +666,10 @@ static int __rtnl_talk(struct rtnl_handle *rtnl, struct > nlmsghdr *n, > *answer = (struct nlmsghdr > *)buf; > else > free(buf); > - return 0; > + if (h->nlmsg_seq == seq) > + return 0; > + else > + goto next; > } > > if (rtnl->proto != NETLINK_SOCK_DIAG && Cheers, Phil