1 /* SPDX-License-Identifier: GPL-2.0-or-later
2 * Copyright (c) 2018 Richard Palethorpe <rpalethorpe@suse.com>
3 */
4
5 /**
6 * @file tst_netlink.h
7 *
8 * Library for communicating with the kernel over the netlink interface.
9 */
10
11 #ifndef TST_NETLINK_H
12 #define TST_NETLINK_H
13
14 #include <linux/netlink.h>
15
16 #ifndef NETLINK_CRYPTO
17 /**
18 * The netlink-crypto socket protocol.
19 */
20 #define NETLINK_CRYPTO 21
21 #endif
22
23 /** @private */
safe_netlink_send(const char * file,const int lineno,int fd,const struct nlmsghdr * nh,const void * payload)24 static inline ssize_t safe_netlink_send(const char *file, const int lineno,
25 int fd, const struct nlmsghdr *nh,
26 const void *payload)
27 {
28 struct sockaddr_nl sa = { .nl_family = AF_NETLINK };
29 struct iovec iov[2] = {
30 {(struct nlmsghdr *)nh, sizeof(*nh)},
31 {(void *)payload, nh->nlmsg_len - sizeof(*nh)}
32 };
33 struct msghdr msg = {
34 .msg_name = &sa,
35 .msg_namelen = sizeof(sa),
36 .msg_iov = iov,
37 .msg_iovlen = 2
38 };
39
40 return safe_sendmsg(file, lineno, nh->nlmsg_len, fd, &msg, 0);
41 }
42
43 /**
44 * Sends a netlink message using safe_sendmsg().
45 *
46 * @param fd netlink socket file descriptor.
47 * @param nl_header netlink header structure describing the message.
48 * @param payload an opaque object containing the message data.
49 *
50 * You should set the message length, type and flags to appropriate values
51 * within the nl_header object. See lib/tst_crypto.c for an example.
52 *
53 * @return The number of bytes sent.
54 */
55 #define SAFE_NETLINK_SEND(fd, nl_header, payload) \
56 safe_netlink_send(__FILE__, __LINE__, fd, nl_header, payload)
57
58 /** @private */
safe_netlink_recv(const char * file,const int lineno,int fd,char * nl_headers_buf,size_t buf_len)59 static inline ssize_t safe_netlink_recv(const char *file, const int lineno,
60 int fd, char *nl_headers_buf,
61 size_t buf_len)
62 {
63 struct iovec iov = { nl_headers_buf, buf_len };
64 struct sockaddr_nl sa;
65 struct msghdr msg = {
66 .msg_name = &sa,
67 .msg_namelen = sizeof(sa),
68 .msg_iov = &iov,
69 .msg_iovlen = 1
70 };
71
72 return safe_recvmsg(file, lineno, 0, fd, &msg, 0);
73 }
74
75 /**
76 * Receives a netlink message using safe_recvmsg().
77 *
78 * @param fd netlink socket file descriptor.
79 * @param nl_header_buf buffer to contain the received netlink header structure.
80 * @param buf_len The length of the header buffer. Must be greater than the page
81 * size.
82 *
83 * @return The number of bytes received.
84 */
85 #define SAFE_NETLINK_RECV(fd, nl_header_buf, buf_len) \
86 safe_netlink_recv(__FILE__, __LINE__, fd, nl_header_buf, buf_len)
87
88 #endif /* TST_NETLINK_H */
89