-
Notifications
You must be signed in to change notification settings - Fork 1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
crypto: Replace old netlink helper functions with netlink contexts
Finish refactoring of netlink helper functions for generic use and replace the very limited netlink send/receive functions used by the crypto tests with the new context-based helpers. Reviewed-by: Petr Vorel <[email protected]> Signed-off-by: Martin Doucha <[email protected]>
- Loading branch information
Showing
12 changed files
with
159 additions
and
377 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,88 +1,111 @@ | ||
/* SPDX-License-Identifier: GPL-2.0-or-later | ||
* Copyright (c) 2018 Richard Palethorpe <[email protected]> | ||
*/ | ||
|
||
/** | ||
* @file tst_netlink.h | ||
* | ||
* Library for communicating with the kernel over the netlink interface. | ||
* Copyright (c) 2021 Linux Test Project | ||
*/ | ||
|
||
#ifndef TST_NETLINK_H | ||
#define TST_NETLINK_H | ||
|
||
#include <linux/netlink.h> | ||
|
||
#ifndef NETLINK_CRYPTO | ||
/** | ||
* The netlink-crypto socket protocol. | ||
struct tst_netlink_context; | ||
|
||
struct tst_rtnl_attr_list { | ||
unsigned short type; | ||
const void *data; | ||
ssize_t len; | ||
const struct tst_rtnl_attr_list *sublist; | ||
}; | ||
|
||
struct tst_netlink_message { | ||
struct nlmsghdr *header; | ||
struct nlmsgerr *err; | ||
void *payload; | ||
size_t payload_size; | ||
}; | ||
|
||
extern int tst_netlink_errno; | ||
|
||
/* Open a netlink socket */ | ||
struct tst_netlink_context *tst_netlink_create_context(const char *file, | ||
const int lineno, int protocol); | ||
#define NETLINK_CREATE_CONTEXT(protocol) \ | ||
tst_netlink_create_context(__FILE__, __LINE__, (protocol)) | ||
|
||
/* Free a tst_netlink_message array returned by tst_netlink_recv() */ | ||
void tst_netlink_free_message(struct tst_netlink_message *msg); | ||
#define NETLINK_FREE_MESSAGE tst_netlink_free_message | ||
|
||
/* Close netlink socket */ | ||
void tst_netlink_destroy_context(const char *file, const int lineno, | ||
struct tst_netlink_context *ctx); | ||
#define NETLINK_DESTROY_CONTEXT(ctx) \ | ||
tst_netlink_destroy_context(__FILE__, __LINE__, (ctx)) | ||
|
||
/* Send all messages in given buffer */ | ||
int tst_netlink_send(const char *file, const int lineno, | ||
struct tst_netlink_context *ctx); | ||
#define NETLINK_SEND(ctx) tst_netlink_send(__FILE__, __LINE__, (ctx)) | ||
|
||
/* Send all messages in given buffer and validate kernel response */ | ||
int tst_netlink_send_validate(const char *file, const int lineno, | ||
struct tst_netlink_context *ctx); | ||
#define NETLINK_SEND_VALIDATE(ctx) \ | ||
tst_netlink_send_validate(__FILE__, __LINE__, (ctx)) | ||
|
||
/* Wait until data is available for reading from the netlink socket */ | ||
int tst_netlink_wait(struct tst_netlink_context *ctx); | ||
#define NETLINK_WAIT tst_netlink_wait | ||
|
||
/* | ||
* Read from netlink socket and return an array of partially parsed messages. | ||
* header == NULL indicates end of array. | ||
*/ | ||
#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. | ||
struct tst_netlink_message *tst_netlink_recv(const char *file, const int lineno, | ||
struct tst_netlink_context *ctx); | ||
#define NETLINK_RECV(ctx) tst_netlink_recv(__FILE__, __LINE__, (ctx)) | ||
|
||
/* Add new message to buffer */ | ||
int tst_netlink_add_message(const char *file, const int lineno, | ||
struct tst_netlink_context *ctx, const struct nlmsghdr *header, | ||
const void *payload, size_t payload_size); | ||
#define NETLINK_ADD_MESSAGE(ctx, header, payload, psize) \ | ||
tst_netlink_add_message(__FILE__, __LINE__, (ctx), (header), \ | ||
(payload), (psize)) | ||
|
||
/* Add arbitrary attribute to last message */ | ||
int tst_rtnl_add_attr(const char *file, const int lineno, | ||
struct tst_netlink_context *ctx, unsigned short type, const void *data, | ||
unsigned short len); | ||
#define RTNL_ADD_ATTR(ctx, type, data, len) \ | ||
tst_rtnl_add_attr(__FILE__, __LINE__, (ctx), (type), (data), (len)) | ||
|
||
/* Add string attribute to last message */ | ||
int tst_rtnl_add_attr_string(const char *file, const int lineno, | ||
struct tst_netlink_context *ctx, unsigned short type, const char *data); | ||
#define RTNL_ADD_ATTR_STRING(ctx, type, data) \ | ||
tst_rtnl_add_attr_string(__FILE__, __LINE__, (ctx), (type), (data)) | ||
|
||
/* | ||
* Add list of arbitrary attributes to last message. The list is terminated | ||
* by attribute with negative length. Nested sublists are supported. | ||
*/ | ||
#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. | ||
int tst_rtnl_add_attr_list(const char *file, const int lineno, | ||
struct tst_netlink_context *ctx, const struct tst_rtnl_attr_list *list); | ||
#define RTNL_ADD_ATTR_LIST(ctx, list) \ | ||
tst_rtnl_add_attr_list(__FILE__, __LINE__, (ctx), (list)) | ||
|
||
/* Check that all sent messages with NLM_F_ACK flag have been acked without | ||
* error. Usage: | ||
* | ||
* @return The number of bytes received. | ||
* tst_netlink_send(ctx); | ||
* tst_netlink_wait(ctx); | ||
* response = tst_netlink_recv(ctx); | ||
* if (!tst_netlink_check_acks(ctx, response)) { ... } | ||
* tst_netlink_free_message(response); | ||
*/ | ||
#define SAFE_NETLINK_RECV(fd, nl_header_buf, buf_len) \ | ||
safe_netlink_recv(__FILE__, __LINE__, fd, nl_header_buf, buf_len) | ||
int tst_netlink_check_acks(const char *file, const int lineno, | ||
struct tst_netlink_context *ctx, struct tst_netlink_message *response); | ||
#define NETLINK_CHECK_ACKS(ctx, response) \ | ||
tst_netlink_check_acks(__FILE__, __LINE__, (ctx), (response)) | ||
|
||
#endif /* TST_NETLINK_H */ |
Oops, something went wrong.