__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;
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;
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));
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;
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;
* 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
* 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.
*/
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