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

Reply via email to