blob: 892ef8f78757a0528e5a5b437a606dcc33080171 [file] [log] [blame]
/*
* Copyright (c) 2018 Richard Palethorpe <rpalethorpe@suse.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file tst_netlink.h
*
* Library for communicating with the kernel over the netlink interface.
*/
#ifndef TST_NETLINK_H
#define TST_NETLINK_H
#include <linux/netlink.h>
#ifndef NETLINK_CRYPTO
/**
* The netlink-crypto socket protocol.
*/
#define NETLINK_CRYPTO 21
#endif
/** @private */
static inline ssize_t safe_netlink_send(const char *file, const int lineno,
int fd, const struct nlmsghdr *nh,
const void *payload)
{
struct sockaddr_nl sa = { .nl_family = AF_NETLINK };
struct iovec iov[2] = {
{(struct nlmsghdr *)nh, sizeof(*nh)},
{(void *)payload, nh->nlmsg_len - sizeof(*nh)}
};
struct msghdr msg = {
.msg_name = &sa,
.msg_namelen = sizeof(sa),
.msg_iov = iov,
.msg_iovlen = 2
};
return safe_sendmsg(file, lineno, nh->nlmsg_len, fd, &msg, 0);
}
/**
* Sends a netlink message using safe_sendmsg().
*
* @param fd netlink socket file descriptor.
* @param nl_header netlink header structure describing the message.
* @param payload an opaque object containing the message data.
*
* You should set the message length, type and flags to appropriate values
* within the nl_header object. See lib/tst_crypto.c for an example.
*
* @return The number of bytes sent.
*/
#define SAFE_NETLINK_SEND(fd, nl_header, payload) \
safe_netlink_send(__FILE__, __LINE__, fd, nl_header, payload)
/** @private */
static inline ssize_t safe_netlink_recv(const char *file, const int lineno,
int fd, char *nl_headers_buf,
size_t buf_len)
{
struct iovec iov = { nl_headers_buf, buf_len };
struct sockaddr_nl sa;
struct msghdr msg = {
.msg_name = &sa,
.msg_namelen = sizeof(sa),
.msg_iov = &iov,
.msg_iovlen = 1
};
return safe_recvmsg(file, lineno, 0, fd, &msg, 0);
}
/**
* Receives a netlink message using safe_recvmsg().
*
* @param fd netlink socket file descriptor.
* @param nl_header_buf buffer to contain the received netlink header structure.
* @param buf_len The length of the header buffer. Must be greater than the page
* size.
*
* @return The number of bytes received.
*/
#define SAFE_NETLINK_RECV(fd, nl_header_buf, buf_len) \
safe_netlink_recv(__FILE__, __LINE__, fd, nl_header_buf, buf_len)
#endif /* TST_NETLINK_H */