From: Christian Brauner Date: Sat, 11 Aug 2018 14:25:14 +0000 (+0200) Subject: netlink: add __netlink_{send,recv,transaction} X-Git-Tag: lxc-3.1.0~167^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F2521%2Fhead;p=thirdparty%2Flxc.git netlink: add __netlink_{send,recv,transaction} These allow to pass a struct nlmsghdr directly and are used in the higher level netlink_{send,rcv,transaction}. Signed-off-by: Christian Brauner --- diff --git a/src/lxc/network.c b/src/lxc/network.c index 53bc58111..dd294cd91 100644 --- a/src/lxc/network.c +++ b/src/lxc/network.c @@ -3192,93 +3192,6 @@ enum { __LXC_NETNSA_MAX, }; -static int nl_send(struct nl_handler *handler, struct nlmsghdr *nlmsghdr) -{ - struct sockaddr_nl nladdr; - struct iovec iov = { - .iov_base = nlmsghdr, - .iov_len = nlmsghdr->nlmsg_len, - }; - struct msghdr msg = { - .msg_name = &nladdr, - .msg_namelen = sizeof(nladdr), - .msg_iov = &iov, - .msg_iovlen = 1, - }; - int ret; - - memset(&nladdr, 0, sizeof(nladdr)); - nladdr.nl_family = AF_NETLINK; - nladdr.nl_pid = 0; - nladdr.nl_groups = 0; - - ret = sendmsg(handler->fd, &msg, MSG_NOSIGNAL); - if (ret < 0) - return -errno; - - return ret; -} - -static int nl_recv(struct nl_handler *handler, struct nlmsghdr *nlmsghdr) -{ - int ret; - struct sockaddr_nl nladdr; - struct iovec iov = { - .iov_base = nlmsghdr, - .iov_len = nlmsghdr->nlmsg_len, - }; - - struct msghdr msg = { - .msg_name = &nladdr, - .msg_namelen = sizeof(nladdr), - .msg_iov = &iov, - .msg_iovlen = 1, - }; - - memset(&nladdr, 0, sizeof(nladdr)); - nladdr.nl_family = AF_NETLINK; - nladdr.nl_pid = 0; - nladdr.nl_groups = 0; - -again: - ret = recvmsg(handler->fd, &msg, 0); - if (ret < 0) { - if (errno == EINTR) - goto again; - - return -1; - } - - if (!ret) - return 0; - - if (msg.msg_flags & MSG_TRUNC && (ret == nlmsghdr->nlmsg_len)) - return -EMSGSIZE; - - return ret; -} - -extern int nl_transaction(struct nl_handler *handler, struct nlmsghdr *request, - struct nlmsghdr *answer) -{ - int ret; - - ret = nl_send(handler, request); - if (ret < 0) - return ret; - - ret = nl_recv(handler, answer); - if (ret < 0) - return ret; - - if (answer->nlmsg_type == NLMSG_ERROR) { - struct nlmsgerr *err = (struct nlmsgerr *)NLMSG_DATA(answer); - return err->error; - } - - return 0; -} - int lxc_netns_set_nsid(int fd) { ssize_t ret; @@ -3309,7 +3222,7 @@ int lxc_netns_set_nsid(int fd) addattr(hdr, 1024, __LXC_NETNSA_FD, &netns_fd, sizeof(netns_fd)); addattr(hdr, 1024, __LXC_NETNSA_NSID, &ns_id, sizeof(ns_id)); - ret = nl_transaction(&nlh, hdr, hdr); + ret = __netlink_transaction(&nlh, hdr, hdr); netlink_close(&nlh); if (ret < 0) return -1; diff --git a/src/lxc/nl.c b/src/lxc/nl.c index c83c587e8..2e97efcca 100644 --- a/src/lxc/nl.c +++ b/src/lxc/nl.c @@ -171,20 +171,20 @@ extern void nlmsg_free(struct nlmsg *nlmsg) free(nlmsg); } -extern int netlink_rcv(struct nl_handler *handler, struct nlmsg *answer) +extern int __netlink_recv(struct nl_handler *handler, struct nlmsghdr *nlmsghdr) { int ret; struct sockaddr_nl nladdr; struct iovec iov = { - .iov_base = answer->nlmsghdr, - .iov_len = answer->nlmsghdr->nlmsg_len, + .iov_base = nlmsghdr, + .iov_len = nlmsghdr->nlmsg_len, }; struct msghdr msg = { - .msg_name = &nladdr, - .msg_namelen = sizeof(nladdr), - .msg_iov = &iov, - .msg_iovlen = 1, + .msg_name = &nladdr, + .msg_namelen = sizeof(nladdr), + .msg_iov = &iov, + .msg_iovlen = 1, }; memset(&nladdr, 0, sizeof(nladdr)); @@ -197,33 +197,38 @@ again: if (ret < 0) { if (errno == EINTR) goto again; - return -errno; + + return -1; } if (!ret) return 0; - if (msg.msg_flags & MSG_TRUNC && - ret == answer->nlmsghdr->nlmsg_len) + if (msg.msg_flags & MSG_TRUNC && (ret == nlmsghdr->nlmsg_len)) return -EMSGSIZE; return ret; } -extern int netlink_send(struct nl_handler *handler, struct nlmsg *nlmsg) +extern int netlink_rcv(struct nl_handler *handler, struct nlmsg *answer) { + return __netlink_recv(handler, answer->nlmsghdr); +} + +extern int __netlink_send(struct nl_handler *handler, struct nlmsghdr *nlmsghdr) +{ + int ret; struct sockaddr_nl nladdr; struct iovec iov = { - .iov_base = nlmsg->nlmsghdr, - .iov_len = nlmsg->nlmsghdr->nlmsg_len, + .iov_base = nlmsghdr, + .iov_len = nlmsghdr->nlmsg_len, }; struct msghdr msg = { - .msg_name = &nladdr, - .msg_namelen = sizeof(nladdr), - .msg_iov = &iov, - .msg_iovlen = 1, + .msg_name = &nladdr, + .msg_namelen = sizeof(nladdr), + .msg_iov = &iov, + .msg_iovlen = 1, }; - int ret; memset(&nladdr, 0, sizeof(nladdr)); nladdr.nl_family = AF_NETLINK; @@ -232,32 +237,45 @@ extern int netlink_send(struct nl_handler *handler, struct nlmsg *nlmsg) ret = sendmsg(handler->fd, &msg, MSG_NOSIGNAL); if (ret < 0) - return -errno; + return -1; return ret; } -extern int netlink_transaction(struct nl_handler *handler, - struct nlmsg *request, struct nlmsg *answer) +extern int netlink_send(struct nl_handler *handler, struct nlmsg *nlmsg) +{ + return __netlink_send(handler, nlmsg->nlmsghdr); +} + +extern int __netlink_transaction(struct nl_handler *handler, + struct nlmsghdr *request, + struct nlmsghdr *answer) { int ret; - ret = netlink_send(handler, request); + ret = __netlink_send(handler, request); if (ret < 0) return ret; - ret = netlink_rcv(handler, answer); + ret = __netlink_recv(handler, answer); if (ret < 0) return ret; - if (answer->nlmsghdr->nlmsg_type == NLMSG_ERROR) { - struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(answer->nlmsghdr); + if (answer->nlmsg_type == NLMSG_ERROR) { + struct nlmsgerr *err = (struct nlmsgerr *)NLMSG_DATA(answer); return err->error; } return 0; } +extern int netlink_transaction(struct nl_handler *handler, + struct nlmsg *request, struct nlmsg *answer) +{ + return __netlink_transaction(handler, request->nlmsghdr, + answer->nlmsghdr); +} + extern int netlink_open(struct nl_handler *handler, int protocol) { socklen_t socklen; diff --git a/src/lxc/nl.h b/src/lxc/nl.h index 0bf62d580..a00fc16df 100644 --- a/src/lxc/nl.h +++ b/src/lxc/nl.h @@ -98,6 +98,7 @@ int netlink_close(struct nl_handler *handler); * Returns 0 on success, < 0 otherwise */ int netlink_rcv(struct nl_handler *handler, struct nlmsg *nlmsg); +int __netlink_recv(struct nl_handler *handler, struct nlmsghdr *nlmsg); /* * netlink_send: send a netlink message to the kernel. It is up @@ -109,6 +110,7 @@ int netlink_rcv(struct nl_handler *handler, struct nlmsg *nlmsg); * Returns 0 on success, < 0 otherwise */ int netlink_send(struct nl_handler *handler, struct nlmsg *nlmsg); +int __netlink_send(struct nl_handler *handler, struct nlmsghdr *nlmsg); /* * netlink_transaction: send a request to the kernel and read the response. @@ -123,6 +125,8 @@ int netlink_send(struct nl_handler *handler, struct nlmsg *nlmsg); */ int netlink_transaction(struct nl_handler *handler, struct nlmsg *request, struct nlmsg *anwser); +int __netlink_transaction(struct nl_handler *handler, struct nlmsghdr *request, + struct nlmsghdr *anwser); /* * nla_put_string: copy a null terminated string to a netlink message