X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Ftap%2Ftap_netlink.c;h=ee92e2e7ed139bc36d03d73a1c413dbd2500e3b0;hb=13b1a5973552e5bf3edfe9986768510fece92361;hp=6de896ab17b67824cc982fa585544f0af612dd7b;hpb=c0bddd3a057f1ef34d2d5aa69e7338caa82de2bf;p=dpdk.git diff --git a/drivers/net/tap/tap_netlink.c b/drivers/net/tap/tap_netlink.c index 6de896ab17..ee92e2e7ed 100644 --- a/drivers/net/tap/tap_netlink.c +++ b/drivers/net/tap/tap_netlink.c @@ -159,7 +159,7 @@ nl_send(int nlsk_fd, struct nlmsghdr *nh) * The netlink socket file descriptor used for communication. * * @return - * 0 on success, -1 otherwise. + * 0 on success, -1 otherwise with errno set. */ int nl_recv_ack(int nlsk_fd) @@ -179,14 +179,13 @@ nl_recv_ack(int nlsk_fd) * Custom arguments for the callback. * * @return - * 0 on success, -1 otherwise. + * 0 on success, -1 otherwise with errno set. */ int nl_recv(int nlsk_fd, int (*cb)(struct nlmsghdr *, void *arg), void *arg) { /* man 7 netlink EXAMPLE */ struct sockaddr_nl sa; - struct nlmsghdr *nh; char buf[BUF_SIZE]; struct iovec iov = { .iov_base = buf, @@ -196,49 +195,43 @@ nl_recv(int nlsk_fd, int (*cb)(struct nlmsghdr *, void *arg), void *arg) .msg_name = &sa, .msg_namelen = sizeof(sa), .msg_iov = &iov, + /* One message at a time */ .msg_iovlen = 1, }; - int recv_bytes = 0, done = 0, multipart = 0, error = 0; + int multipart = 0; + int ret = 0; -read: - recv_bytes = recvmsg(nlsk_fd, &msg, 0); - if (recv_bytes < 0) - return -1; - for (nh = (struct nlmsghdr *)buf; - NLMSG_OK(nh, (unsigned int)recv_bytes); - nh = NLMSG_NEXT(nh, recv_bytes)) { - /* - * Multi-part messages and their following DONE message have the - * NLM_F_MULTI flag set. Make note, in order to read the DONE - * message afterwards. - */ - if (nh->nlmsg_flags & NLM_F_MULTI) - multipart = 1; - if (nh->nlmsg_type == NLMSG_ERROR) { - struct nlmsgerr *err_data = NLMSG_DATA(nh); + do { + struct nlmsghdr *nh; + int recv_bytes = 0; + + recv_bytes = recvmsg(nlsk_fd, &msg, 0); + if (recv_bytes < 0) + return -1; + for (nh = (struct nlmsghdr *)buf; + NLMSG_OK(nh, (unsigned int)recv_bytes); + nh = NLMSG_NEXT(nh, recv_bytes)) { + if (nh->nlmsg_type == NLMSG_ERROR) { + struct nlmsgerr *err_data = NLMSG_DATA(nh); - if (err_data->error == 0) - RTE_LOG(DEBUG, PMD, "%s() ack message recvd\n", - __func__); - else { - RTE_LOG(DEBUG, PMD, - "%s() error message recvd\n", __func__); - error = 1; + if (err_data->error < 0) { + errno = -err_data->error; + return -1; + } + /* Ack message. */ + return 0; } + /* Multi-part msgs and their trailing DONE message. */ + if (nh->nlmsg_flags & NLM_F_MULTI) { + if (nh->nlmsg_type == NLMSG_DONE) + return 0; + multipart = 1; + } + if (cb) + ret = cb(nh, arg); } - /* The end of multipart message. */ - if (nh->nlmsg_type == NLMSG_DONE) - /* No need to call the callback for a DONE message. */ - done = 1; - else if (cb) - if (cb(nh, arg) < 0) - error = 1; - } - if (multipart && !done) - goto read; - if (error) - return -1; - return 0; + } while (multipart); + return ret; } /**