mirror of
https://git.proxmox.com/git/mirror_lxc
synced 2025-08-08 08:16:20 +00:00
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 <christian.brauner@ubuntu.com>
This commit is contained in:
parent
d813c8edf8
commit
9fbbc42791
@ -3192,93 +3192,6 @@ enum {
|
|||||||
__LXC_NETNSA_MAX,
|
__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)
|
int lxc_netns_set_nsid(int fd)
|
||||||
{
|
{
|
||||||
ssize_t ret;
|
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_FD, &netns_fd, sizeof(netns_fd));
|
||||||
addattr(hdr, 1024, __LXC_NETNSA_NSID, &ns_id, sizeof(ns_id));
|
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);
|
netlink_close(&nlh);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
88
src/lxc/nl.c
88
src/lxc/nl.c
@ -171,20 +171,20 @@ extern void nlmsg_free(struct nlmsg *nlmsg)
|
|||||||
free(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;
|
int ret;
|
||||||
struct sockaddr_nl nladdr;
|
struct sockaddr_nl nladdr;
|
||||||
struct iovec iov = {
|
struct iovec iov = {
|
||||||
.iov_base = answer->nlmsghdr,
|
.iov_base = nlmsghdr,
|
||||||
.iov_len = answer->nlmsghdr->nlmsg_len,
|
.iov_len = nlmsghdr->nlmsg_len,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct msghdr msg = {
|
struct msghdr msg = {
|
||||||
.msg_name = &nladdr,
|
.msg_name = &nladdr,
|
||||||
.msg_namelen = sizeof(nladdr),
|
.msg_namelen = sizeof(nladdr),
|
||||||
.msg_iov = &iov,
|
.msg_iov = &iov,
|
||||||
.msg_iovlen = 1,
|
.msg_iovlen = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
memset(&nladdr, 0, sizeof(nladdr));
|
memset(&nladdr, 0, sizeof(nladdr));
|
||||||
@ -197,33 +197,38 @@ again:
|
|||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
if (errno == EINTR)
|
if (errno == EINTR)
|
||||||
goto again;
|
goto again;
|
||||||
return -errno;
|
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ret)
|
if (!ret)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (msg.msg_flags & MSG_TRUNC &&
|
if (msg.msg_flags & MSG_TRUNC && (ret == nlmsghdr->nlmsg_len))
|
||||||
ret == answer->nlmsghdr->nlmsg_len)
|
|
||||||
return -EMSGSIZE;
|
return -EMSGSIZE;
|
||||||
|
|
||||||
return ret;
|
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 sockaddr_nl nladdr;
|
||||||
struct iovec iov = {
|
struct iovec iov = {
|
||||||
.iov_base = nlmsg->nlmsghdr,
|
.iov_base = nlmsghdr,
|
||||||
.iov_len = nlmsg->nlmsghdr->nlmsg_len,
|
.iov_len = nlmsghdr->nlmsg_len,
|
||||||
};
|
};
|
||||||
struct msghdr msg = {
|
struct msghdr msg = {
|
||||||
.msg_name = &nladdr,
|
.msg_name = &nladdr,
|
||||||
.msg_namelen = sizeof(nladdr),
|
.msg_namelen = sizeof(nladdr),
|
||||||
.msg_iov = &iov,
|
.msg_iov = &iov,
|
||||||
.msg_iovlen = 1,
|
.msg_iovlen = 1,
|
||||||
};
|
};
|
||||||
int ret;
|
|
||||||
|
|
||||||
memset(&nladdr, 0, sizeof(nladdr));
|
memset(&nladdr, 0, sizeof(nladdr));
|
||||||
nladdr.nl_family = AF_NETLINK;
|
nladdr.nl_family = AF_NETLINK;
|
||||||
@ -232,30 +237,43 @@ extern int netlink_send(struct nl_handler *handler, struct nlmsg *nlmsg)
|
|||||||
|
|
||||||
ret = sendmsg(handler->fd, &msg, MSG_NOSIGNAL);
|
ret = sendmsg(handler->fd, &msg, MSG_NOSIGNAL);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -errno;
|
return -1;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = __netlink_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;
|
||||||
|
}
|
||||||
|
|
||||||
extern int netlink_transaction(struct nl_handler *handler,
|
extern int netlink_transaction(struct nl_handler *handler,
|
||||||
struct nlmsg *request, struct nlmsg *answer)
|
struct nlmsg *request, struct nlmsg *answer)
|
||||||
{
|
{
|
||||||
int ret;
|
return __netlink_transaction(handler, request->nlmsghdr,
|
||||||
|
answer->nlmsghdr);
|
||||||
ret = netlink_send(handler, request);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
ret = netlink_rcv(handler, answer);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
if (answer->nlmsghdr->nlmsg_type == NLMSG_ERROR) {
|
|
||||||
struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(answer->nlmsghdr);
|
|
||||||
return err->error;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern int netlink_open(struct nl_handler *handler, int protocol)
|
extern int netlink_open(struct nl_handler *handler, int protocol)
|
||||||
|
@ -98,6 +98,7 @@ int netlink_close(struct nl_handler *handler);
|
|||||||
* Returns 0 on success, < 0 otherwise
|
* Returns 0 on success, < 0 otherwise
|
||||||
*/
|
*/
|
||||||
int netlink_rcv(struct nl_handler *handler, struct nlmsg *nlmsg);
|
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
|
* 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
|
* Returns 0 on success, < 0 otherwise
|
||||||
*/
|
*/
|
||||||
int netlink_send(struct nl_handler *handler, struct nlmsg *nlmsg);
|
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.
|
* 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,
|
int netlink_transaction(struct nl_handler *handler,
|
||||||
struct nlmsg *request, struct nlmsg *anwser);
|
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
|
* nla_put_string: copy a null terminated string to a netlink message
|
||||||
|
Loading…
Reference in New Issue
Block a user