* [LTP] [PATCH 0/3] Netlink helper functions refactoring
@ 2023-10-13 15:17 Martin Doucha
2023-10-13 15:17 ` [LTP] [PATCH 1/3] tst_rtnetlink: Refactor helper function for generic use Martin Doucha
` (3 more replies)
0 siblings, 4 replies; 8+ messages in thread
From: Martin Doucha @ 2023-10-13 15:17 UTC (permalink / raw)
To: ltp
Let's refactor the rtnetlink helper functions for generic use where possible.
The Netlink context structure can be used for other Netlink protocols like
NETLINK_CRYPTO or NETLINK_NETFILTER. One of the exceptions is
the NETLINK_KOBJECT_UEVENT protocol which returns raw data without the usual
headers.
The first patch replaces the tst_rtnl_* and RTNL_* prefix with tst_netlink_*
and NETLINK_* respectively to signify that the functions can be used
for generic netlink communication. The attribute handling functions are
specific to the NETLINK_ROUTE protocol so they keep the old prefix.
The last patch then replaces old netlink send/receive helper functions
with the context-based helpers in crypto test code.
Coming soon is a new netfilter CVE test which will also use the refactored
code.
Martin Doucha (3):
tst_rtnetlink: Refactor helper function for generic use
tst_netlink_destroy_context(): Allow safely passing NULL context
crypto: Replace old netlink helper functions with netlink contexts
doc/network-c-api.txt | 159 +++++++++++-----------
include/tst_crypto.h | 67 +---------
include/tst_netdevice.h | 2 +-
include/tst_netlink.h | 171 ++++++++++++++----------
include/tst_rtnetlink.h | 108 ---------------
lib/tst_crypto.c | 90 +++----------
lib/tst_netdevice.c | 95 ++++++-------
lib/{tst_rtnetlink.c => tst_netlink.c} | 88 ++++++------
testcases/cve/tcindex01.c | 4 +-
testcases/kernel/crypto/crypto_user01.c | 58 +++-----
testcases/kernel/crypto/crypto_user02.c | 17 +--
testcases/kernel/crypto/pcrypt_aead01.c | 10 +-
12 files changed, 331 insertions(+), 538 deletions(-)
delete mode 100644 include/tst_rtnetlink.h
rename lib/{tst_rtnetlink.c => tst_netlink.c} (77%)
--
2.42.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 8+ messages in thread
* [LTP] [PATCH 1/3] tst_rtnetlink: Refactor helper function for generic use
2023-10-13 15:17 [LTP] [PATCH 0/3] Netlink helper functions refactoring Martin Doucha
@ 2023-10-13 15:17 ` Martin Doucha
2023-10-24 8:41 ` Petr Vorel
2023-10-13 15:17 ` [LTP] [PATCH 2/3] tst_netlink_destroy_context(): Allow safely passing NULL context Martin Doucha
` (2 subsequent siblings)
3 siblings, 1 reply; 8+ messages in thread
From: Martin Doucha @ 2023-10-13 15:17 UTC (permalink / raw)
To: ltp
The netlink context structure can be used for any netlink protocol,
not just for NETLINK_ROUTE. Change the RTNL prefix to NETLINK on
all helper functions which don't use NETLINK_ROUTE features and
add a new protocol parameter to tst_netlink_create_context().
Signed-off-by: Martin Doucha <mdoucha@suse.cz>
---
doc/network-c-api.txt | 155 +++++++++++++++++++-------------------
include/tst_rtnetlink.h | 85 ++++++++++-----------
lib/tst_netdevice.c | 93 ++++++++++++-----------
lib/tst_rtnetlink.c | 83 ++++++++++----------
testcases/cve/tcindex01.c | 2 +-
5 files changed, 212 insertions(+), 206 deletions(-)
diff --git a/doc/network-c-api.txt b/doc/network-c-api.txt
index 3bf2a1f8a..25e4bbd18 100644
--- a/doc/network-c-api.txt
+++ b/doc/network-c-api.txt
@@ -143,7 +143,7 @@ static void setup(void)
When opening a localhost socket isn't enough and the test needs special device
or routing configuration, the netdevice library can create the required network
setup without calling external programs. Internally, the netdevice functions
-use a rtnetlink socket to communicate with the kernel.
+use a netlink socket to communicate with the kernel.
All of these functions will call +tst_brk()+ on failure, unless stated
otherwise. Error values described below are returned only during test cleanup
@@ -274,12 +274,12 @@ static void setup(void)
}
-------------------------------------------------------------------------------
-3 rtnetlink API
+3 Netlink API
---------------
+#include "tst_rtnetlink.h"+
-The rtnetlink library provides helper functions for constructing and sending
+The netlink library provides helper functions for constructing and sending
arbitrary messages and parsing kernel responses.
All of the functions below will call +tst_brk()+ on failure, unless stated
@@ -291,7 +291,7 @@ stage.
[source,c]
-------------------------------------------------------------------------------
-struct tst_rtnl_context;
+struct tst_netlink_context;
struct tst_rtnl_attr_list {
unsigned short type;
@@ -300,7 +300,7 @@ struct tst_rtnl_attr_list {
const struct tst_rtnl_attr_list *sublist;
};
-struct tst_rtnl_message {
+struct tst_netlink_message {
struct nlmsghdr *header;
struct nlmsgerr *err;
void *payload;
@@ -308,10 +308,10 @@ struct tst_rtnl_message {
};
-------------------------------------------------------------------------------
-+struct tst_rtnl_context+ is an opaque rtnetlink socket with buffer for
++struct tst_netlink_context+ is an opaque netlink socket with buffer for
constructing and sending arbitrary messages using the functions described
-below. Create a new context using +RTNL_CREATE_CONTEXT()+, then free it using
-+RTNL_DESTROY_CONTEXT()+ when you're done with it.
+below. Create a new context using +NETLINK_CREATE_CONTEXT()+, then free it
+using +NETLINK_DESTROY_CONTEXT()+ when you're done with it.
+struct tst_rtnl_attr_list+ is a helper structure for defining complex
rtnetlink message attribute payloads, including nested attribute lists. Every
@@ -331,10 +331,10 @@ negative +len+.
to the +len+ field. If you do not want to add nested attributes, set
+sublist+ to +NULL+.
-+struct tst_rtnl_message+ is a structure holding partially parsed rtnetlink
-messages received from the kernel. +RTNL_RECV()+ returns an array of these
++struct tst_netlink_message+ is a structure holding partially parsed netlink
+messages received from the kernel. +NETLINK_RECV()+ returns an array of these
structures with the last item having +NULL+ in the +header+ field. Call
-+RTNL_FREE_MESSAGE()+ to free a message list returned by +RTNL_RECV()+.
++NETLINK_FREE_MESSAGE()+ to free a message list returned by +NETLINK_RECV()+.
- +header+ is the netlink header structure of the message. +NULL+ in the header
field terminates a list of messages.
@@ -349,83 +349,86 @@ structures with the last item having +NULL+ in the +header+ field. Call
3.2 Sending and receiving messages
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- +struct tst_rtnl_context *RTNL_CREATE_CONTEXT(void)+ – Creates a new
- rtnetlink communication context for use with the functions described below.
- Returns +NULL+ on error.
+- +struct tst_netlink_context *NETLINK_CREATE_CONTEXT(int protocol)+ – Creates
+ a new netlink communication context with given netlink protocol for use
+ with the functions described below. Returns +NULL+ on error.
-- +void RTNL_FREE_MESSAGE(struct tst_rtnl_message *msg)+ – Frees an array of
- messages returned by +RTNL_RECV()+.
+- +void NETLINK_FREE_MESSAGE(struct tst_netlink_message *msg)+ – Frees
+ an array of messages returned by +NETLINK_RECV()+.
-- +void RTNL_DESTROY_CONTEXT(struct tst_rtnl_context *ctx)+ – Closes a
- communication context created by +RTNL_CREATE_CONTEXT()+.
+- +void NETLINK_DESTROY_CONTEXT(struct tst_netlink_context *ctx)+ – Closes a
+ communication context created by +NETLINK_CREATE_CONTEXT()+.
-- +int RTNL_SEND(struct tst_rtnl_context *ctx)+ – Sends all messages waiting
- in +ctx+ buffer to the kernel. If there are multiple messages to send, a new
- +NLMSG_DONE+ message will be added automatically. Returns the number of
- bytes sent on success. Return 0 or negative value on error.
+- +int NETLINK_SEND(struct tst_netlink_context *ctx)+ – Sends all messages
+ waiting in +ctx+ buffer to the kernel. If there are multiple messages
+ to send, a new +NLMSG_DONE+ message will be added automatically. Returns
+ the number of bytes sent on success. Return 0 or negative value on error.
-- +int RTNL_SEND_VALIDATE(struct tst_rtnl_context *ctx)+ – Sends all messages
- just like +RTNL_SEND()+, then receives the response from the kernel and
- validates results of requests sent with the +NLM_F_ACK+ flag. This function
- calls +tst_brk()+ as usual if communication fails but it will return error
- status without terminating the test if one of the received messages contains
- error code. See +RTNL_CHECK_ACKS()+ below for explanation of the return
- value.
+- +int NETLINK_SEND_VALIDATE(struct tst_netlink_context *ctx)+ – Sends all
+ messages just like +NETLINK_SEND()+, then receives the response from
+ the kernel and validates results of requests sent with the +NLM_F_ACK+ flag.
+ This function calls +tst_brk()+ as usual if communication fails but it will
+ return error status without terminating the test if one of the received
+ messages contains error code. See +NETLINK_CHECK_ACKS()+ below for
+ explanation of the return value.
-- +int RTNL_WAIT(struct tst_rtnl_context *ctx)+ – Waits until data becomes
- available to read from the rtnetlink socket (timeout: 1 second). Returns 1
+- +int NETLINK_WAIT(struct tst_netlink_context *ctx)+ – Waits until data becomes
+ available to read from the netlink socket (timeout: 1 second). Returns 1
if there is data to read, 0 on timeout or -1 on error.
-- +struct tst_rtnl_message *RTNL_RECV(struct tst_rtnl_context *ctx)+ – Receives
- rtnetlink messages from the kernel. The messages are received in non-blocking
- mode so calling +RTNL_WAIT()+ first is recommended. Returns an array of
- partially parsed messages terminated by an item with +NULL+ in the +header+
- field. On error or when there are no messages to receive, returns +NULL+.
- Call +RTNL_FREE_MESSAGE()+ to free the returned data.
-
-- +int RTNL_CHECK_ACKS(struct tst_rtnl_context *ctx, struct tst_rtnl_message
- *response)+ – Validate results of requests sent with the +NLM_F_ACK+ flag.
- Do not call +RTNL_ADD_MESSAGE()+ between +RTNL_SEND()+ and
- +RTNL_CHECK_ACKS()+ because it will reset the state of +ctx+ and prevent
- result validation. Returns 1 if all messages sent with the +NLM_F_ACK+ flag
- have a corresponding message in +response+ and the error code is 0. If any
- of the expected response messages is missing, this function will call
- +tst_brk()+ (or return 0 during test cleanup phase). If any of the response
- messages has non-zero error code, this function will return 0 and store the
- first non-zero error code in global variable +tst_rtnl_errno+ (sign-flipped
- just like regular libc +errno+).
+- +struct tst_netlink_message *NETLINK_RECV(struct tst_netlink_context *ctx)+ –
+ Receives netlink messages from the kernel. The messages are received
+ in non-blocking mode so calling +NETLINK_WAIT()+ first is recommended.
+ Returns an array of partially parsed messages terminated by an item with
+ +NULL+ in the +header+ field. On error or when there are no messages
+ to receive, returns +NULL+. Call +NETLINK_FREE_MESSAGE()+ to free
+ the returned data.
+
+- +int NETLINK_CHECK_ACKS(struct tst_netlink_context *ctx,
+ struct tst_netlink_message *response)+ – Validate results of requests sent
+ with the +NLM_F_ACK+ flag. Do not call +NETLINK_ADD_MESSAGE()+ between
+ +NETLINK_SEND()+ and +NETLINK_CHECK_ACKS()+ because it will reset the state
+ of +ctx+ and prevent result validation. Returns 1 if all messages sent
+ with the +NLM_F_ACK+ flag have a corresponding message in +response+ and
+ the error code is 0. If any of the expected response messages is missing,
+ this function will call +tst_brk()+ (or return 0 during test cleanup phase).
+ If any of the response messages has non-zero error code, this function will
+ return 0 and store the first non-zero error code in global variable
+ +tst_netlink_errno+ (sign-flipped just like regular libc +errno+).
3.3 Creating messages
~~~~~~~~~~~~~~~~~~~~~
-- +int RTNL_ADD_MESSAGE(struct tst_rtnl_context *ctx, const struct nlmsghdr
- *header, const void *payload, size_t payload_size)+ – Adds new rtnetlink
- message to +ctx+ buffer. You need to provide message +header+ and optional
- +payload+. +payload_size+ is the size of +payload+ data in bytes. If you
- don't want to add any payload data, set +payload+ to +NULL+ and
+- +int NETLINK_ADD_MESSAGE(struct tst_netlink_context *ctx, const struct
+ nlmsghdr *header, const void *payload, size_t payload_size)+ – Adds new
+ netlink message to +ctx+ buffer. You need to provide message +header+ and
+ optional +payload+. +payload_size+ is the size of +payload+ data in bytes.
+ If you don't want to add any payload data, set +payload+ to +NULL+ and
+payload_size+ to 0. This function will automatically fill the +nlmsg_len+,
+nlmsg_seq+ and +nlmsg_pid+ fields of the new message header. You don't need
to set those. It'll also automatically add +NLM_F_MULTI+ flag when needed.
Returns 1 on success, 0 on error. Note that the first call of
- +RTNL_ADD_MESSAGE()+ after +RTNL_SEND()+ will reset the state of +ctx+
- and +RTNL_CHECK_ACKS()+ will not work correctly until the next +RTNL_SEND()+.
-
-- +int RTNL_ADD_ATTR(struct tst_rtnl_context *ctx, unsigned short type, const
- void *data, unsigned short len)+ – Adds new attribute to the last message
- in +ctx+ buffer. See +RTNL_ADD_MESSAGE()+. You need to provide attribute
- +type+ which will be stored in +struct rtattr.rta_type+, optional payload
- +data+ and payload size +len+ in bytes. If you don't want to add any payload,
- set +data+ to +NULL+ and +len+ to 0. Returns 1 on success, 0 on error.
-
-- +int RTNL_ADD_ATTR_STRING(struct tst_rtnl_context *ctx, unsigned short type,
- const char *data)+ – Adds new string attribute to the last message in +ctx+
- buffer. Parameters and return value are the same as for +RTNL_ADD_ATTR()+,
- except the payload length is calculated using +strlen()+.
-
-- +int RTNL_ADD_ATTR_LIST(struct tst_rtnl_context *ctx, const struct
+ +NETLINK_ADD_MESSAGE()+ after +NETLINK_SEND()+ will reset the state of +ctx+
+ and +NETLINK_CHECK_ACKS()+ will not work correctly until the next
+ +NETLINK_SEND()+.
+
+- +int RTNL_ADD_ATTR(struct tst_netlink_context *ctx, unsigned short type,
+ const void *data, unsigned short len)+ – Adds new attribute to the last
+ message in +ctx+ buffer. See +NETLINK_ADD_MESSAGE()+. You need to provide
+ attribute +type+ which will be stored in +struct rtattr.rta_type+, optional
+ payload +data+ and payload size +len+ in bytes. If you don't want to add any
+ payload, set +data+ to +NULL+ and +len+ to 0. Returns 1 on success,
+ 0 on error.
+
+- +int RTNL_ADD_ATTR_STRING(struct tst_netlink_context *ctx, unsigned short
+ type, const char *data)+ – Adds new string attribute to the last message
+ in +ctx+ buffer. Parameters and return value are the same as for
+ +RTNL_ADD_ATTR()+, except the payload length is calculated using +strlen()+.
+
+- +int RTNL_ADD_ATTR_LIST(struct tst_netlink_context *ctx, const struct
tst_rtnl_attr_list *list)+ – Adds a list of attributes to the last message
in +ctx+ buffer. See description of +struct tst_rtnl_attr_list+ and
- +RTNL_ADD_MESSAGE()+ above. Returns the number of added attributes on
+ +NETLINK_ADD_MESSAGE()+ above. Returns the number of added attributes on
success (nested attributes are not counted), -1 on error.
Example Usage
@@ -447,7 +450,7 @@ Example Usage
void setup(void)
{
- struct tst_rtnl_context *ctx;
+ struct tst_netlink_context *ctx;
int index, ret;
in_addr_t addr;
@@ -465,12 +468,12 @@ void setup(void)
index = NETDEV_INDEX_BY_NAME("ltp_veth1");
info.ifa_index = index;
- ctx = RTNL_CREATE_CONTEXT();
- RTNL_ADD_MESSAGE(ctx, &header, &info, sizeof(info));
+ ctx = NETLINK_CREATE_CONTEXT(NETLINK_ROUTE);
+ NETLINK_ADD_MESSAGE(ctx, &header, &info, sizeof(info));
addr = inet_addr("192.168.123.45");
RTNL_ADD_ATTR(ctx, IFA_LOCAL, &addr, sizeof(addr));
- ret = RTNL_SEND_VALIDATE(ctx);
- RTNL_DESTROY_CONTEXT(ctx);
+ ret = NETLINK_SEND_VALIDATE(ctx);
+ NETLINK_DESTROY_CONTEXT(ctx);
if (!ret) {
tst_brk(TBROK, "Failed to set ltp_veth1 address");
diff --git a/include/tst_rtnetlink.h b/include/tst_rtnetlink.h
index 6a0c53df4..c5f295a38 100644
--- a/include/tst_rtnetlink.h
+++ b/include/tst_rtnetlink.h
@@ -5,7 +5,7 @@
#ifndef TST_RTNETLINK_H
#define TST_RTNETLINK_H
-struct tst_rtnl_context;
+struct tst_netlink_context;
struct tst_rtnl_attr_list {
unsigned short type;
@@ -14,71 +14,72 @@ struct tst_rtnl_attr_list {
const struct tst_rtnl_attr_list *sublist;
};
-struct tst_rtnl_message {
+struct tst_netlink_message {
struct nlmsghdr *header;
struct nlmsgerr *err;
void *payload;
size_t payload_size;
};
-extern int tst_rtnl_errno;
+extern int tst_netlink_errno;
/* Open a netlink socket */
-struct tst_rtnl_context *tst_rtnl_create_context(const char *file,
- const int lineno);
-#define RTNL_CREATE_CONTEXT() tst_rtnl_create_context(__FILE__, __LINE__)
+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_rtnl_message array returned by tst_rtnl_recv() */
-void tst_rtnl_free_message(struct tst_rtnl_message *msg);
-#define RTNL_FREE_MESSAGE tst_rtnl_free_message
+/* 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_rtnl_destroy_context(const char *file, const int lineno,
- struct tst_rtnl_context *ctx);
-#define RTNL_DESTROY_CONTEXT(ctx) \
- tst_rtnl_destroy_context(__FILE__, __LINE__, (ctx))
+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_rtnl_send(const char *file, const int lineno,
- struct tst_rtnl_context *ctx);
-#define RTNL_SEND(ctx) tst_rtnl_send(__FILE__, __LINE__, (ctx))
+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_rtnl_send_validate(const char *file, const int lineno,
- struct tst_rtnl_context *ctx);
-#define RTNL_SEND_VALIDATE(ctx) \
- tst_rtnl_send_validate(__FILE__, __LINE__, (ctx))
+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_rtnl_wait(struct tst_rtnl_context *ctx);
-#define RTNL_WAIT tst_rtnl_wait
+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.
*/
-struct tst_rtnl_message *tst_rtnl_recv(const char *file, const int lineno,
- struct tst_rtnl_context *ctx);
-#define RTNL_RECV(ctx) tst_rtnl_recv(__FILE__, __LINE__, (ctx))
+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_rtnl_add_message(const char *file, const int lineno,
- struct tst_rtnl_context *ctx, const struct nlmsghdr *header,
+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 RTNL_ADD_MESSAGE(ctx, header, payload, psize) \
- tst_rtnl_add_message(__FILE__, __LINE__, (ctx), (header), (payload), \
- (psize))
+#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_rtnl_context *ctx, unsigned short type, const void *data,
+ 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_rtnl_context *ctx, unsigned short type, const char *data);
+ 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))
@@ -87,22 +88,22 @@ int tst_rtnl_add_attr_string(const char *file, const int lineno,
* by attribute with negative length. Nested sublists are supported.
*/
int tst_rtnl_add_attr_list(const char *file, const int lineno,
- struct tst_rtnl_context *ctx, const struct tst_rtnl_attr_list *list);
+ 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:
*
- * tst_rtnl_send(ctx);
- * tst_rtnl_wait(ctx);
- * response = tst_rtnl_recv(ctx);
- * if (!tst_rtnl_check_acks(ctx, response)) { ... }
- * tst_rtnl_free_message(response);
+ * 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);
*/
-int tst_rtnl_check_acks(const char *file, const int lineno,
- struct tst_rtnl_context *ctx, struct tst_rtnl_message *response);
-#define RTNL_CHECK_ACKS(ctx, response) \
- tst_rtnl_context(__FILE__, __LINE__, (ctx), (response))
+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_RTNETLINK_H */
diff --git a/lib/tst_netdevice.c b/lib/tst_netdevice.c
index dba44c623..5873b3d58 100644
--- a/lib/tst_netdevice.c
+++ b/lib/tst_netdevice.c
@@ -15,23 +15,24 @@
#include "tst_rtnetlink.h"
#include "tst_netdevice.h"
-static struct tst_rtnl_context *create_request(const char *file,
+static struct tst_netlink_context *create_request(const char *file,
const int lineno, unsigned int type, unsigned int flags,
const void *payload, size_t psize)
{
- struct tst_rtnl_context *ctx;
+ struct tst_netlink_context *ctx;
struct nlmsghdr header = {
.nlmsg_type = type,
.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | flags,
};
- ctx = tst_rtnl_create_context(file, lineno);
+ ctx = tst_netlink_create_context(file, lineno, NETLINK_ROUTE);
if (!ctx)
return NULL;
- if (!tst_rtnl_add_message(file, lineno, ctx, &header, payload, psize)) {
- tst_rtnl_destroy_context(file, lineno, ctx);
+ if (!tst_netlink_add_message(file, lineno, ctx, &header, payload,
+ psize)) {
+ tst_netlink_destroy_context(file, lineno, ctx);
return NULL;
}
@@ -103,7 +104,7 @@ int tst_create_veth_pair(const char *file, const int lineno, int strict,
{
int ret;
struct ifinfomsg info = { .ifi_family = AF_UNSPEC };
- struct tst_rtnl_context *ctx;
+ struct tst_netlink_context *ctx;
struct tst_rtnl_attr_list peerinfo[] = {
{IFLA_IFNAME, ifname2, strlen(ifname2) + 1, NULL},
{0, NULL, -1, NULL}
@@ -141,17 +142,17 @@ int tst_create_veth_pair(const char *file, const int lineno, int strict,
return 0;
if (tst_rtnl_add_attr_list(file, lineno, ctx, attrs) != 2) {
- tst_rtnl_destroy_context(file, lineno, ctx);
+ tst_netlink_destroy_context(file, lineno, ctx);
return 0;
}
- ret = tst_rtnl_send_validate(file, lineno, ctx);
- tst_rtnl_destroy_context(file, lineno, ctx);
+ ret = tst_netlink_send_validate(file, lineno, ctx);
+ tst_netlink_destroy_context(file, lineno, ctx);
if (strict && !ret) {
tst_brk_(file, lineno, TBROK,
"Failed to create veth interfaces %s+%s: %s", ifname1,
- ifname2, tst_strerrno(tst_rtnl_errno));
+ ifname2, tst_strerrno(tst_netlink_errno));
}
return ret;
@@ -162,7 +163,7 @@ int tst_netdev_add_device(const char *file, const int lineno, int strict,
{
int ret;
struct ifinfomsg info = { .ifi_family = AF_UNSPEC };
- struct tst_rtnl_context *ctx;
+ struct tst_netlink_context *ctx;
struct tst_rtnl_attr_list attrs[] = {
{IFLA_IFNAME, ifname, strlen(ifname) + 1, NULL},
{IFLA_LINKINFO, NULL, 0, (const struct tst_rtnl_attr_list[]){
@@ -185,17 +186,17 @@ int tst_netdev_add_device(const char *file, const int lineno, int strict,
return 0;
if (tst_rtnl_add_attr_list(file, lineno, ctx, attrs) != 2) {
- tst_rtnl_destroy_context(file, lineno, ctx);
+ tst_netlink_destroy_context(file, lineno, ctx);
return 0;
}
- ret = tst_rtnl_send_validate(file, lineno, ctx);
- tst_rtnl_destroy_context(file, lineno, ctx);
+ ret = tst_netlink_send_validate(file, lineno, ctx);
+ tst_netlink_destroy_context(file, lineno, ctx);
if (strict && !ret) {
tst_brk_(file, lineno, TBROK,
"Failed to create %s device %s: %s", devtype, ifname,
- tst_strerrno(tst_rtnl_errno));
+ tst_strerrno(tst_netlink_errno));
}
return ret;
@@ -205,7 +206,7 @@ int tst_netdev_remove_device(const char *file, const int lineno, int strict,
const char *ifname)
{
struct ifinfomsg info = { .ifi_family = AF_UNSPEC };
- struct tst_rtnl_context *ctx;
+ struct tst_netlink_context *ctx;
int ret;
if (strlen(ifname) >= IFNAMSIZ) {
@@ -220,17 +221,17 @@ int tst_netdev_remove_device(const char *file, const int lineno, int strict,
return 0;
if (!tst_rtnl_add_attr_string(file, lineno, ctx, IFLA_IFNAME, ifname)) {
- tst_rtnl_destroy_context(file, lineno, ctx);
+ tst_netlink_destroy_context(file, lineno, ctx);
return 0;
}
- ret = tst_rtnl_send_validate(file, lineno, ctx);
- tst_rtnl_destroy_context(file, lineno, ctx);
+ ret = tst_netlink_send_validate(file, lineno, ctx);
+ tst_netlink_destroy_context(file, lineno, ctx);
if (strict && !ret) {
tst_brk_(file, lineno, TBROK,
"Failed to remove netdevice %s: %s", ifname,
- tst_strerrno(tst_rtnl_errno));
+ tst_strerrno(tst_netlink_errno));
}
return ret;
@@ -241,7 +242,7 @@ static int modify_address(const char *file, const int lineno, int strict,
unsigned int family, const void *address, unsigned int prefix,
size_t addrlen, uint32_t addr_flags)
{
- struct tst_rtnl_context *ctx;
+ struct tst_netlink_context *ctx;
int index, ret;
struct ifaddrmsg info = {
.ifa_family = family,
@@ -264,23 +265,23 @@ static int modify_address(const char *file, const int lineno, int strict,
if (!tst_rtnl_add_attr(file, lineno, ctx, IFA_FLAGS, &addr_flags,
sizeof(uint32_t))) {
- tst_rtnl_destroy_context(file, lineno, ctx);
+ tst_netlink_destroy_context(file, lineno, ctx);
return 0;
}
if (!tst_rtnl_add_attr(file, lineno, ctx, IFA_LOCAL, address,
addrlen)) {
- tst_rtnl_destroy_context(file, lineno, ctx);
+ tst_netlink_destroy_context(file, lineno, ctx);
return 0;
}
- ret = tst_rtnl_send_validate(file, lineno, ctx);
- tst_rtnl_destroy_context(file, lineno, ctx);
+ ret = tst_netlink_send_validate(file, lineno, ctx);
+ tst_netlink_destroy_context(file, lineno, ctx);
if (strict && !ret) {
tst_brk_(file, lineno, TBROK,
"Failed to modify %s network address: %s", ifname,
- tst_strerrno(tst_rtnl_errno));
+ tst_strerrno(tst_netlink_errno));
}
return ret;
@@ -322,7 +323,7 @@ static int change_ns(const char *file, const int lineno, int strict,
const char *ifname, unsigned short attr, uint32_t value)
{
struct ifinfomsg info = { .ifi_family = AF_UNSPEC };
- struct tst_rtnl_context *ctx;
+ struct tst_netlink_context *ctx;
int ret;
if (strlen(ifname) >= IFNAMSIZ) {
@@ -337,23 +338,23 @@ static int change_ns(const char *file, const int lineno, int strict,
return 0;
if (!tst_rtnl_add_attr_string(file, lineno, ctx, IFLA_IFNAME, ifname)) {
- tst_rtnl_destroy_context(file, lineno, ctx);
+ tst_netlink_destroy_context(file, lineno, ctx);
return 0;
}
if (!tst_rtnl_add_attr(file, lineno, ctx, attr, &value,
sizeof(uint32_t))) {
- tst_rtnl_destroy_context(file, lineno, ctx);
+ tst_netlink_destroy_context(file, lineno, ctx);
return 0;
}
- ret = tst_rtnl_send_validate(file, lineno, ctx);
- tst_rtnl_destroy_context(file, lineno, ctx);
+ ret = tst_netlink_send_validate(file, lineno, ctx);
+ tst_netlink_destroy_context(file, lineno, ctx);
if (strict && !ret) {
tst_brk_(file, lineno, TBROK,
"Failed to move %s to another namespace: %s", ifname,
- tst_strerrno(tst_rtnl_errno));
+ tst_strerrno(tst_netlink_errno));
}
return ret;
@@ -377,7 +378,7 @@ static int modify_route(const char *file, const int lineno, int strict,
size_t srclen, const void *dstaddr, unsigned int dstprefix,
size_t dstlen, const void *gateway, size_t gatewaylen)
{
- struct tst_rtnl_context *ctx;
+ struct tst_netlink_context *ctx;
int ret;
int32_t index;
struct rtmsg info = {
@@ -420,35 +421,35 @@ static int modify_route(const char *file, const int lineno, int strict,
if (srcaddr && !tst_rtnl_add_attr(file, lineno, ctx, RTA_SRC, srcaddr,
srclen)) {
- tst_rtnl_destroy_context(file, lineno, ctx);
+ tst_netlink_destroy_context(file, lineno, ctx);
return 0;
}
if (dstaddr && !tst_rtnl_add_attr(file, lineno, ctx, RTA_DST, dstaddr,
dstlen)) {
- tst_rtnl_destroy_context(file, lineno, ctx);
+ tst_netlink_destroy_context(file, lineno, ctx);
return 0;
}
if (gateway && !tst_rtnl_add_attr(file, lineno, ctx, RTA_GATEWAY,
gateway, gatewaylen)) {
- tst_rtnl_destroy_context(file, lineno, ctx);
+ tst_netlink_destroy_context(file, lineno, ctx);
return 0;
}
if (ifname && !tst_rtnl_add_attr(file, lineno, ctx, RTA_OIF, &index,
sizeof(index))) {
- tst_rtnl_destroy_context(file, lineno, ctx);
+ tst_netlink_destroy_context(file, lineno, ctx);
return 0;
}
- ret = tst_rtnl_send_validate(file, lineno, ctx);
- tst_rtnl_destroy_context(file, lineno, ctx);
+ ret = tst_netlink_send_validate(file, lineno, ctx);
+ tst_netlink_destroy_context(file, lineno, ctx);
if (strict && !ret) {
tst_brk_(file, lineno, TBROK,
"Failed to modify network route: %s",
- tst_strerrno(tst_rtnl_errno));
+ tst_strerrno(tst_netlink_errno));
}
return ret;
@@ -528,7 +529,7 @@ static int modify_qdisc(const char *file, const int lineno, int strict,
unsigned int handle, unsigned int info, const char *qd_kind,
const struct tst_rtnl_attr_list *config)
{
- struct tst_rtnl_context *ctx;
+ struct tst_netlink_context *ctx;
int ret;
struct tcmsg msg = {
.tcm_family = family,
@@ -560,22 +561,22 @@ static int modify_qdisc(const char *file, const int lineno, int strict,
return 0;
if (!tst_rtnl_add_attr_string(file, lineno, ctx, TCA_KIND, qd_kind)) {
- tst_rtnl_destroy_context(file, lineno, ctx);
+ tst_netlink_destroy_context(file, lineno, ctx);
return 0;
}
if (config && !tst_rtnl_add_attr_list(file, lineno, ctx, config)) {
- tst_rtnl_destroy_context(file, lineno, ctx);
+ tst_netlink_destroy_context(file, lineno, ctx);
return 0;
}
- ret = tst_rtnl_send_validate(file, lineno, ctx);
- tst_rtnl_destroy_context(file, lineno, ctx);
+ ret = tst_netlink_send_validate(file, lineno, ctx);
+ tst_netlink_destroy_context(file, lineno, ctx);
if (strict && !ret) {
tst_brk_(file, lineno, TBROK,
"Failed to modify %s: %s", object,
- tst_strerrno(tst_rtnl_errno));
+ tst_strerrno(tst_netlink_errno));
}
return ret;
diff --git a/lib/tst_rtnetlink.c b/lib/tst_rtnetlink.c
index a2411dfde..eacfdced1 100644
--- a/lib/tst_rtnetlink.c
+++ b/lib/tst_rtnetlink.c
@@ -15,7 +15,7 @@
#include "tst_test.h"
#include "tst_rtnetlink.h"
-struct tst_rtnl_context {
+struct tst_netlink_context {
int socket;
pid_t pid;
uint32_t seq;
@@ -24,10 +24,10 @@ struct tst_rtnl_context {
struct nlmsghdr *curmsg;
};
-int tst_rtnl_errno;
+int tst_netlink_errno;
-static int tst_rtnl_grow_buffer(const char *file, const int lineno,
- struct tst_rtnl_context *ctx, size_t size)
+static int netlink_grow_buffer(const char *file, const int lineno,
+ struct tst_netlink_context *ctx, size_t size)
{
size_t needed, offset, curlen = NLMSG_ALIGN(ctx->datalen);
char *buf;
@@ -52,21 +52,22 @@ static int tst_rtnl_grow_buffer(const char *file, const int lineno,
return 1;
}
-void tst_rtnl_destroy_context(const char *file, const int lineno,
- struct tst_rtnl_context *ctx)
+void tst_netlink_destroy_context(const char *file, const int lineno,
+ struct tst_netlink_context *ctx)
{
safe_close(file, lineno, NULL, ctx->socket);
free(ctx->buffer);
free(ctx);
}
-struct tst_rtnl_context *tst_rtnl_create_context(const char *file,
- const int lineno)
+struct tst_netlink_context *tst_netlink_create_context(const char *file,
+ const int lineno, int protocol)
{
- struct tst_rtnl_context *ctx;
+ struct tst_netlink_context *ctx;
struct sockaddr_nl addr = { .nl_family = AF_NETLINK };
- ctx = safe_malloc(file, lineno, NULL, sizeof(struct tst_rtnl_context));
+ ctx = safe_malloc(file, lineno, NULL,
+ sizeof(struct tst_netlink_context));
if (!ctx)
return NULL;
@@ -78,7 +79,7 @@ struct tst_rtnl_context *tst_rtnl_create_context(const char *file,
ctx->datalen = 0;
ctx->curmsg = NULL;
ctx->socket = safe_socket(file, lineno, NULL, AF_NETLINK,
- SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_ROUTE);
+ SOCK_DGRAM | SOCK_CLOEXEC, protocol);
if (ctx->socket < 0) {
free(ctx);
@@ -87,14 +88,14 @@ struct tst_rtnl_context *tst_rtnl_create_context(const char *file,
if (safe_bind(file, lineno, NULL, ctx->socket, (struct sockaddr *)&addr,
sizeof(addr))) {
- tst_rtnl_destroy_context(file, lineno, ctx);
+ tst_netlink_destroy_context(file, lineno, ctx);
return NULL;
}
ctx->buffer = safe_malloc(file, lineno, NULL, ctx->bufsize);
if (!ctx->buffer) {
- tst_rtnl_destroy_context(file, lineno, ctx);
+ tst_netlink_destroy_context(file, lineno, ctx);
return NULL;
}
@@ -103,7 +104,7 @@ struct tst_rtnl_context *tst_rtnl_create_context(const char *file,
return ctx;
}
-void tst_rtnl_free_message(struct tst_rtnl_message *msg)
+void tst_netlink_free_message(struct tst_netlink_message *msg)
{
if (!msg)
return;
@@ -114,8 +115,8 @@ void tst_rtnl_free_message(struct tst_rtnl_message *msg)
free(msg);
}
-int tst_rtnl_send(const char *file, const int lineno,
- struct tst_rtnl_context *ctx)
+int tst_netlink_send(const char *file, const int lineno,
+ struct tst_netlink_context *ctx)
{
int ret;
struct sockaddr_nl addr = { .nl_family = AF_NETLINK };
@@ -136,7 +137,7 @@ int tst_rtnl_send(const char *file, const int lineno,
if (ctx->curmsg->nlmsg_flags & NLM_F_MULTI) {
struct nlmsghdr eom = { .nlmsg_type = NLMSG_DONE };
- if (!tst_rtnl_add_message(file, lineno, ctx, &eom, NULL, 0))
+ if (!tst_netlink_add_message(file, lineno, ctx, &eom, NULL, 0))
return 0;
/* NLMSG_DONE message must not have NLM_F_MULTI flag */
@@ -153,7 +154,7 @@ int tst_rtnl_send(const char *file, const int lineno,
return ret;
}
-int tst_rtnl_wait(struct tst_rtnl_context *ctx)
+int tst_netlink_wait(struct tst_netlink_context *ctx)
{
struct pollfd fdinfo = {
.fd = ctx->socket,
@@ -163,11 +164,11 @@ int tst_rtnl_wait(struct tst_rtnl_context *ctx)
return poll(&fdinfo, 1, 1000);
}
-struct tst_rtnl_message *tst_rtnl_recv(const char *file, const int lineno,
- struct tst_rtnl_context *ctx)
+struct tst_netlink_message *tst_netlink_recv(const char *file,
+ const int lineno, struct tst_netlink_context *ctx)
{
char tmp, *tmpbuf, *buffer = NULL;
- struct tst_rtnl_message *ret;
+ struct tst_netlink_message *ret;
struct nlmsghdr *ptr;
size_t retsize, bufsize = 0;
ssize_t size;
@@ -215,7 +216,7 @@ struct tst_rtnl_message *tst_rtnl_recv(const char *file, const int lineno,
for (; size_left > 0 && NLMSG_OK(ptr, size_left); msgcount++)
ptr = NLMSG_NEXT(ptr, size_left);
- retsize = (msgcount + 1) * sizeof(struct tst_rtnl_message);
+ retsize = (msgcount + 1) * sizeof(struct tst_netlink_message);
ret = safe_malloc(file, lineno, NULL, retsize);
if (!ret) {
@@ -239,14 +240,14 @@ struct tst_rtnl_message *tst_rtnl_recv(const char *file, const int lineno,
return ret;
}
-int tst_rtnl_add_message(const char *file, const int lineno,
- struct tst_rtnl_context *ctx, const struct nlmsghdr *header,
+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)
{
size_t size;
unsigned int extra_flags = 0;
- if (!tst_rtnl_grow_buffer(file, lineno, ctx, NLMSG_SPACE(payload_size)))
+ if (!netlink_grow_buffer(file, lineno, ctx, NLMSG_SPACE(payload_size)))
return 0;
if (!ctx->curmsg) {
@@ -280,7 +281,7 @@ int tst_rtnl_add_message(const char *file, const int lineno,
}
int tst_rtnl_add_attr(const char *file, const int lineno,
- struct tst_rtnl_context *ctx, unsigned short type,
+ struct tst_netlink_context *ctx, unsigned short type,
const void *data, unsigned short len)
{
size_t size;
@@ -292,7 +293,7 @@ int tst_rtnl_add_attr(const char *file, const int lineno,
return 0;
}
- if (!tst_rtnl_grow_buffer(file, lineno, ctx, RTA_SPACE(len)))
+ if (!netlink_grow_buffer(file, lineno, ctx, RTA_SPACE(len)))
return 0;
size = NLMSG_ALIGN(ctx->curmsg->nlmsg_len);
@@ -307,7 +308,7 @@ int tst_rtnl_add_attr(const char *file, const int lineno,
}
int tst_rtnl_add_attr_string(const char *file, const int lineno,
- struct tst_rtnl_context *ctx, unsigned short type,
+ struct tst_netlink_context *ctx, unsigned short type,
const char *data)
{
return tst_rtnl_add_attr(file, lineno, ctx, type, data,
@@ -315,7 +316,7 @@ int tst_rtnl_add_attr_string(const char *file, const int lineno,
}
int tst_rtnl_add_attr_list(const char *file, const int lineno,
- struct tst_rtnl_context *ctx,
+ struct tst_netlink_context *ctx,
const struct tst_rtnl_attr_list *list)
{
int i, ret;
@@ -359,8 +360,8 @@ int tst_rtnl_add_attr_list(const char *file, const int lineno,
return i;
}
-int tst_rtnl_check_acks(const char *file, const int lineno,
- struct tst_rtnl_context *ctx, struct tst_rtnl_message *res)
+int tst_netlink_check_acks(const char *file, const int lineno,
+ struct tst_netlink_context *ctx, struct tst_netlink_message *res)
{
struct nlmsghdr *msg = (struct nlmsghdr *)ctx->buffer;
int size_left = ctx->datalen;
@@ -382,7 +383,7 @@ int tst_rtnl_check_acks(const char *file, const int lineno,
}
if (res->err->error) {
- tst_rtnl_errno = -res->err->error;
+ tst_netlink_errno = -res->err->error;
return 0;
}
}
@@ -390,25 +391,25 @@ int tst_rtnl_check_acks(const char *file, const int lineno,
return 1;
}
-int tst_rtnl_send_validate(const char *file, const int lineno,
- struct tst_rtnl_context *ctx)
+int tst_netlink_send_validate(const char *file, const int lineno,
+ struct tst_netlink_context *ctx)
{
- struct tst_rtnl_message *response;
+ struct tst_netlink_message *response;
int ret;
- tst_rtnl_errno = 0;
+ tst_netlink_errno = 0;
- if (tst_rtnl_send(file, lineno, ctx) <= 0)
+ if (tst_netlink_send(file, lineno, ctx) <= 0)
return 0;
- tst_rtnl_wait(ctx);
- response = tst_rtnl_recv(file, lineno, ctx);
+ tst_netlink_wait(ctx);
+ response = tst_netlink_recv(file, lineno, ctx);
if (!response)
return 0;
- ret = tst_rtnl_check_acks(file, lineno, ctx, response);
- tst_rtnl_free_message(response);
+ ret = tst_netlink_check_acks(file, lineno, ctx, response);
+ tst_netlink_free_message(response);
return ret;
}
diff --git a/testcases/cve/tcindex01.c b/testcases/cve/tcindex01.c
index 91bfafb53..eabad4188 100644
--- a/testcases/cve/tcindex01.c
+++ b/testcases/cve/tcindex01.c
@@ -95,7 +95,7 @@ static void run(void)
1, "tcindex");
ret = tst_netdev_add_traffic_filter(__FILE__, __LINE__, 0, DEVNAME,
qd_handle, 10, ETH_P_IP, 1, "tcindex", f_config);
- TST_ERR = tst_rtnl_errno;
+ TST_ERR = tst_netlink_errno;
NETDEV_REMOVE_QDISC(DEVNAME, AF_UNSPEC, TC_H_ROOT, qd_handle, "htb");
if (ret)
--
2.42.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [LTP] [PATCH 2/3] tst_netlink_destroy_context(): Allow safely passing NULL context
2023-10-13 15:17 [LTP] [PATCH 0/3] Netlink helper functions refactoring Martin Doucha
2023-10-13 15:17 ` [LTP] [PATCH 1/3] tst_rtnetlink: Refactor helper function for generic use Martin Doucha
@ 2023-10-13 15:17 ` Martin Doucha
2023-10-24 8:56 ` Petr Vorel
2023-10-13 15:17 ` [LTP] [PATCH 3/3] crypto: Replace old netlink helper functions with netlink contexts Martin Doucha
2023-10-24 8:35 ` [LTP] [PATCH 0/3] Netlink helper functions refactoring Petr Vorel
3 siblings, 1 reply; 8+ messages in thread
From: Martin Doucha @ 2023-10-13 15:17 UTC (permalink / raw)
To: ltp
Signed-off-by: Martin Doucha <mdoucha@suse.cz>
---
lib/tst_rtnetlink.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/lib/tst_rtnetlink.c b/lib/tst_rtnetlink.c
index eacfdced1..bf782ffb5 100644
--- a/lib/tst_rtnetlink.c
+++ b/lib/tst_rtnetlink.c
@@ -55,6 +55,9 @@ static int netlink_grow_buffer(const char *file, const int lineno,
void tst_netlink_destroy_context(const char *file, const int lineno,
struct tst_netlink_context *ctx)
{
+ if (!ctx)
+ return;
+
safe_close(file, lineno, NULL, ctx->socket);
free(ctx->buffer);
free(ctx);
--
2.42.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [LTP] [PATCH 3/3] crypto: Replace old netlink helper functions with netlink contexts
2023-10-13 15:17 [LTP] [PATCH 0/3] Netlink helper functions refactoring Martin Doucha
2023-10-13 15:17 ` [LTP] [PATCH 1/3] tst_rtnetlink: Refactor helper function for generic use Martin Doucha
2023-10-13 15:17 ` [LTP] [PATCH 2/3] tst_netlink_destroy_context(): Allow safely passing NULL context Martin Doucha
@ 2023-10-13 15:17 ` Martin Doucha
2023-11-13 15:40 ` Petr Vorel
2023-10-24 8:35 ` [LTP] [PATCH 0/3] Netlink helper functions refactoring Petr Vorel
3 siblings, 1 reply; 8+ messages in thread
From: Martin Doucha @ 2023-10-13 15:17 UTC (permalink / raw)
To: ltp
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.
Signed-off-by: Martin Doucha <mdoucha@suse.cz>
---
All three crypto tests have been verified on affected kernels.
doc/network-c-api.txt | 4 +-
include/tst_crypto.h | 67 +---------
include/tst_netdevice.h | 2 +-
include/tst_netlink.h | 171 ++++++++++++++----------
include/tst_rtnetlink.h | 109 ---------------
lib/tst_crypto.c | 90 +++----------
lib/tst_netdevice.c | 2 +-
lib/{tst_rtnetlink.c => tst_netlink.c} | 2 +-
testcases/cve/tcindex01.c | 2 +-
testcases/kernel/crypto/crypto_user01.c | 58 +++-----
testcases/kernel/crypto/crypto_user02.c | 17 +--
testcases/kernel/crypto/pcrypt_aead01.c | 10 +-
12 files changed, 159 insertions(+), 375 deletions(-)
delete mode 100644 include/tst_rtnetlink.h
rename lib/{tst_rtnetlink.c => tst_netlink.c} (99%)
diff --git a/doc/network-c-api.txt b/doc/network-c-api.txt
index 25e4bbd18..d04dd6aa3 100644
--- a/doc/network-c-api.txt
+++ b/doc/network-c-api.txt
@@ -277,7 +277,7 @@ static void setup(void)
3 Netlink API
---------------
-+#include "tst_rtnetlink.h"+
++#include "tst_netlink.h"+
The netlink library provides helper functions for constructing and sending
arbitrary messages and parsing kernel responses.
@@ -443,7 +443,7 @@ Example Usage
#include <arpa/inet.h>
#include "tst_test.h"
-#include "tst_rtnetlink.h"
+#include "tst_netlink.h"
#include "tst_netdevice.h"
...
diff --git a/include/tst_crypto.h b/include/tst_crypto.h
index ae406bd04..12321f86d 100644
--- a/include/tst_crypto.h
+++ b/include/tst_crypto.h
@@ -13,67 +13,13 @@
#define TST_CRYPTO_H
#include "lapi/cryptouser.h"
-
-/**
- * A reference to a crypto session and associated state.
- *
- * Holds state relevant to a netlink crypto connection. The seq_num is used
- * to tag each message sent to the netlink layer and is automatically
- * incremented by the tst_crypto_ functions. When the netlink layer sends a
- * response (ack) it will use the sequences number from the request.
- *
- * Some functions, such as delete ALG, may return EBUSY in which case it is
- * safe to retry them. The retries field allows you to set the number of
- * times this should be done. If set to zero the operation will only be tried
- * once. For operations which do not return EBUSY, the field is ignored.
- *
- * Use TST_CRYPTO_SESSION_INIT to statically initialize this struct with sane
- * defaults.
- */
-struct tst_crypto_session {
- /** File descriptor for the netlink socket */
- int fd;
- /** A sequence number used to identify responses from the kernel. */
- uint32_t seq_num;
- /** Number of times some operations will be retried. */
- uint32_t retries;
-};
-
-/**
- * Default static definition of tst_crypto_session.
- *
- * @relates tst_crypto_session
- */
-#define TST_CRYPTO_SESSION_INIT {\
- .fd = 0, \
- .seq_num = 0, \
- .retries = 1000 \
-}
-
-/**
- * Creates a crypto session.
- *
- * @relates tst_crypto_session
- * @param ses Session structure to use, it can be uninitialized.
- *
- * If some necessary feature is missing then it will call tst_brk() with
- * TCONF, for any other error it will use TBROK.
- */
-void tst_crypto_open(struct tst_crypto_session *ses);
-
-/**
- * Close a crypto session.
- *
- * @relates tst_crypto_session
- * @param ses The session to close.
- */
-void tst_crypto_close(struct tst_crypto_session *ses);
+#include "tst_netlink.h"
/**
* Add a crypto algorithm to a session.
*
* @relates tst_crypto_session
- * @param ses An open session.
+ * @param ctx Initialized netlink context
* @param alg The crypto algorithm or module to add.
*
* This requests a new crypto algorithm/engine/module to be initialized by the
@@ -84,15 +30,16 @@ void tst_crypto_close(struct tst_crypto_session *ses);
* @return On success it will return 0 otherwise it will return an inverted
* error code from the crypto layer.
*/
-int tst_crypto_add_alg(struct tst_crypto_session *ses,
+int tst_crypto_add_alg(struct tst_netlink_context *ctx,
const struct crypto_user_alg *alg);
/**
* Delete a crypto algorithm from a session.
*
* @relates tst_crypto_session
- * @param ses An open session.
+ * @param ctx Initialized netlink context
* @param alg The crypto algorithm to delete.
+ * @param retries Number of retries before giving up. Recommended value: 1000
*
* Request that the kernel remove an existing crypto algorithm. This behaves
* in a similar way to tst_crypto_add_alg() except that it is the inverse
@@ -106,7 +53,7 @@ int tst_crypto_add_alg(struct tst_crypto_session *ses,
* library, you don't need to log this error as it will already have
* been printed by tst_brk().
*/
-int tst_crypto_del_alg(struct tst_crypto_session *ses,
- const struct crypto_user_alg *alg);
+int tst_crypto_del_alg(struct tst_netlink_context *ctx,
+ const struct crypto_user_alg *alg, unsigned int retries);
#endif /* TST_CRYPTO_H */
diff --git a/include/tst_netdevice.h b/include/tst_netdevice.h
index 5e62ba065..4239d0960 100644
--- a/include/tst_netdevice.h
+++ b/include/tst_netdevice.h
@@ -5,7 +5,7 @@
#ifndef TST_NETDEVICE_H
#define TST_NETDEVICE_H
-#include "tst_rtnetlink.h"
+#include "tst_netlink.h"
/* Find device index for given network interface name. */
int tst_netdev_index_by_name(const char *file, const int lineno,
diff --git a/include/tst_netlink.h b/include/tst_netlink.h
index 2030ac30b..f10f1cf5d 100644
--- a/include/tst_netlink.h
+++ b/include/tst_netlink.h
@@ -1,11 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0-or-later
- * Copyright (c) 2018 Richard Palethorpe <rpalethorpe@suse.com>
- */
-
-/**
- * @file tst_netlink.h
- *
- * Library for communicating with the kernel over the netlink interface.
+ * Copyright (c) 2021 Linux Test Project
*/
#ifndef TST_NETLINK_H
@@ -13,76 +7,105 @@
#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 */
diff --git a/include/tst_rtnetlink.h b/include/tst_rtnetlink.h
deleted file mode 100644
index c5f295a38..000000000
--- a/include/tst_rtnetlink.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later
- * Copyright (c) 2021 Linux Test Project
- */
-
-#ifndef TST_RTNETLINK_H
-#define TST_RTNETLINK_H
-
-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.
- */
-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.
- */
-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:
- *
- * 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);
- */
-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_RTNETLINK_H */
diff --git a/lib/tst_crypto.c b/lib/tst_crypto.c
index c01632c2a..4495d0baa 100644
--- a/lib/tst_crypto.c
+++ b/lib/tst_crypto.c
@@ -10,102 +10,42 @@
#define TST_NO_DEFAULT_MAIN
#include "tst_test.h"
#include "tst_crypto.h"
-#include "tst_netlink.h"
-void tst_crypto_open(struct tst_crypto_session *ses)
-{
- const long ret = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_CRYPTO);
-
- if (ret < 0 && errno == EPROTONOSUPPORT)
- tst_brk(TCONF | TERRNO, "NETLINK_CRYPTO is probably disabled");
-
- if (ret < 0) {
- tst_brk(TBROK | TERRNO,
- "socket(AF_NETLINK, SOCK_DGRAM, NETLINK_CRYPTO)");
- }
-
- ses->fd = ret;
- ses->seq_num = 0;
-}
-
-void tst_crypto_close(struct tst_crypto_session *ses)
-{
- SAFE_CLOSE(ses->fd);
-}
-
-static int tst_crypto_recv_ack(struct tst_crypto_session *ses)
-{
- uint32_t len;
- char buf[BUFSIZ];
- struct nlmsghdr *nh;
-
- len = SAFE_NETLINK_RECV(ses->fd, buf, sizeof(buf));
-
- for (nh = (struct nlmsghdr *) buf;
- NLMSG_OK(nh, len);
- nh = NLMSG_NEXT(nh, len)) {
- if (nh->nlmsg_seq != ses->seq_num) {
- tst_brk(TBROK,
- "Message out of sequence; type=0%hx, seq_num=%u (not %u)",
- nh->nlmsg_type, nh->nlmsg_seq, ses->seq_num);
- }
-
- /* Acks use the error message type with error number set to
- * zero. Ofcourse we could also receive an actual error.
- */
- if (nh->nlmsg_type == NLMSG_ERROR)
- return ((struct nlmsgerr *)NLMSG_DATA(nh))->error;
-
- tst_brk(TBROK, "Unexpected message type; type=0x%hx, seq_num=%u",
- nh->nlmsg_type, nh->nlmsg_seq);
- }
-
- tst_brk(TBROK, "Empty message from netlink socket?");
-
- return ENODATA;
-}
-
-int tst_crypto_add_alg(struct tst_crypto_session *ses,
+int tst_crypto_add_alg(struct tst_netlink_context *ctx,
const struct crypto_user_alg *alg)
{
struct nlmsghdr nh = {
- .nlmsg_len = sizeof(struct nlmsghdr) + sizeof(*alg),
.nlmsg_type = CRYPTO_MSG_NEWALG,
.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK,
- .nlmsg_seq = ++(ses->seq_num),
- .nlmsg_pid = 0,
};
- SAFE_NETLINK_SEND(ses->fd, &nh, alg);
-
- return tst_crypto_recv_ack(ses);
+ NETLINK_ADD_MESSAGE(ctx, &nh, alg, sizeof(struct crypto_user_alg));
+ return NETLINK_SEND_VALIDATE(ctx) ? 0 : -tst_netlink_errno;
}
-int tst_crypto_del_alg(struct tst_crypto_session *ses,
- const struct crypto_user_alg *alg)
+int tst_crypto_del_alg(struct tst_netlink_context *ctx,
+ const struct crypto_user_alg *alg, unsigned int retries)
{
- long ret;
+ int ret;
unsigned int i = 0;
struct nlmsghdr nh = {
- .nlmsg_len = sizeof(struct nlmsghdr) + sizeof(*alg),
.nlmsg_type = CRYPTO_MSG_DELALG,
.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK,
- .nlmsg_pid = 0,
};
- while (1) {
- nh.nlmsg_seq = ++(ses->seq_num),
+ for (i = 0; i < retries; i++) {
+ NETLINK_ADD_MESSAGE(ctx, &nh, alg,
+ sizeof(struct crypto_user_alg));
- SAFE_NETLINK_SEND(ses->fd, &nh, alg);
+ if (NETLINK_SEND_VALIDATE(ctx))
+ return 0;
- ret = tst_crypto_recv_ack(ses);
- if (ret != -EBUSY || i >= ses->retries)
- break;
+ ret = -tst_netlink_errno;
- if (usleep(1) && errno != EINTR)
- tst_brk(TBROK | TERRNO, "usleep(1)");
+ if (ret != -EBUSY)
+ break;
- ++i;
+ usleep(1);
}
return ret;
diff --git a/lib/tst_netdevice.c b/lib/tst_netdevice.c
index 5873b3d58..6f86b8089 100644
--- a/lib/tst_netdevice.c
+++ b/lib/tst_netdevice.c
@@ -12,7 +12,7 @@
#define TST_NO_DEFAULT_MAIN
#include "tst_test.h"
-#include "tst_rtnetlink.h"
+#include "tst_netlink.h"
#include "tst_netdevice.h"
static struct tst_netlink_context *create_request(const char *file,
diff --git a/lib/tst_rtnetlink.c b/lib/tst_netlink.c
similarity index 99%
rename from lib/tst_rtnetlink.c
rename to lib/tst_netlink.c
index bf782ffb5..bd05df81a 100644
--- a/lib/tst_rtnetlink.c
+++ b/lib/tst_netlink.c
@@ -13,7 +13,7 @@
#include <sys/poll.h>
#define TST_NO_DEFAULT_MAIN
#include "tst_test.h"
-#include "tst_rtnetlink.h"
+#include "tst_netlink.h"
struct tst_netlink_context {
int socket;
diff --git a/testcases/cve/tcindex01.c b/testcases/cve/tcindex01.c
index eabad4188..c7dfbdee0 100644
--- a/testcases/cve/tcindex01.c
+++ b/testcases/cve/tcindex01.c
@@ -24,7 +24,7 @@
#include <linux/pkt_sched.h>
#include <linux/pkt_cls.h>
#include "tst_test.h"
-#include "tst_rtnetlink.h"
+#include "tst_netlink.h"
#include "tst_netdevice.h"
#include "lapi/sched.h"
#include "lapi/if_ether.h"
diff --git a/testcases/kernel/crypto/crypto_user01.c b/testcases/kernel/crypto/crypto_user01.c
index 47bf9f0d2..6f6036aed 100644
--- a/testcases/kernel/crypto/crypto_user01.c
+++ b/testcases/kernel/crypto/crypto_user01.c
@@ -17,7 +17,6 @@
#include "tst_test.h"
#include "tst_crypto.h"
-#include "tst_netlink.h"
/*
* include after <sys/socket.h> (via tst_test.h), to work around dependency bug
@@ -25,11 +24,11 @@
*/
#include <linux/rtnetlink.h>
-static struct tst_crypto_session ses = TST_CRYPTO_SESSION_INIT;
+static struct tst_netlink_context *ctx;
static void setup(void)
{
- tst_crypto_open(&ses);
+ ctx = NETLINK_CREATE_CONTEXT(NETLINK_CRYPTO);
}
static void do_check_for_leaks(const char *name, const char *value, size_t vlen)
@@ -131,25 +130,20 @@ static void validate_one_alg(const struct nlmsghdr *nh)
}
}
-static void validate_alg_list(const void *buf, size_t remaining)
+static void validate_alg_list(const struct tst_netlink_message *msg)
{
- const struct nlmsghdr *nh;
-
- for (nh = buf; NLMSG_OK(nh, remaining);
- nh = NLMSG_NEXT(nh, remaining)) {
- if (nh->nlmsg_seq != ses.seq_num) {
- tst_brk(TBROK,
- "Message out of sequence; type=0%hx, seq_num=%u (not %u)",
- nh->nlmsg_type, nh->nlmsg_seq, ses.seq_num);
- }
- if (nh->nlmsg_type == NLMSG_DONE)
+ for (; msg->header; msg++) {
+ if (msg->header->nlmsg_type == NLMSG_DONE)
return;
- if (nh->nlmsg_type != CRYPTO_MSG_GETALG) {
+
+ if (msg->header->nlmsg_type != CRYPTO_MSG_GETALG) {
tst_brk(TBROK,
"Unexpected message type; type=0x%hx, seq_num=%u",
- nh->nlmsg_type, nh->nlmsg_seq);
+ msg->header->nlmsg_type,
+ msg->header->nlmsg_seq);
}
- validate_one_alg(nh);
+
+ validate_one_alg(msg->header);
}
}
@@ -157,35 +151,23 @@ static void run(void)
{
struct crypto_user_alg payload = { 0 };
struct nlmsghdr nh = {
- .nlmsg_len = sizeof(payload),
.nlmsg_type = CRYPTO_MSG_GETALG,
.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP,
- .nlmsg_seq = ++(ses.seq_num),
- .nlmsg_pid = 0,
};
- /*
- * Due to an apparent kernel bug, this API cannot be used incrementally,
- * so we just use a large recvmsg() buffer. This is good enough since
- * we don't necessarily have to check every algorithm for this test to
- * be effective...
- */
- const size_t bufsize = 1048576;
- void *buf = SAFE_MALLOC(bufsize);
- size_t res;
-
- SAFE_NETLINK_SEND(ses.fd, &nh, &payload);
-
- res = SAFE_NETLINK_RECV(ses.fd, buf, bufsize);
-
- validate_alg_list(buf, res);
-
- free(buf);
+ struct tst_netlink_message *msg;
+
+ NETLINK_ADD_MESSAGE(ctx, &nh, &payload, sizeof(payload));
+ NETLINK_SEND(ctx);
+ NETLINK_WAIT(ctx);
+ msg = NETLINK_RECV(ctx);
+ validate_alg_list(msg);
+ NETLINK_FREE_MESSAGE(msg);
tst_res(TPASS, "No information leaks found");
}
static void cleanup(void)
{
- tst_crypto_close(&ses);
+ NETLINK_DESTROY_CONTEXT(ctx);
}
static struct tst_test test = {
diff --git a/testcases/kernel/crypto/crypto_user02.c b/testcases/kernel/crypto/crypto_user02.c
index afaff5d18..89cbb9bc5 100644
--- a/testcases/kernel/crypto/crypto_user02.c
+++ b/testcases/kernel/crypto/crypto_user02.c
@@ -52,7 +52,7 @@ static const char * const ALGORITHM_CANDIDATES[] = {
};
static const char* algorithm = NULL;
-static struct tst_crypto_session ses = TST_CRYPTO_SESSION_INIT;
+static struct tst_netlink_context *ctx;
static void setup(void)
@@ -60,7 +60,8 @@ static void setup(void)
int rc;
unsigned i;
struct crypto_user_alg alg;
- tst_crypto_open(&ses);
+
+ ctx = NETLINK_CREATE_CONTEXT(NETLINK_CRYPTO);
/* find an algorithm, that is not in use */
for (i = 0; i < ARRAY_SIZE(ALGORITHM_CANDIDATES); ++i) {
@@ -68,12 +69,12 @@ static void setup(void)
strcpy(alg.cru_driver_name, ALGORITHM_CANDIDATES[i]);
/* try to add it, to see if it is valid */
- rc = tst_crypto_add_alg(&ses, &alg);
+ rc = tst_crypto_add_alg(ctx, &alg);
if (rc != 0)
continue;
/* it also has to be deletable */
- rc = tst_crypto_del_alg(&ses, &alg);
+ rc = tst_crypto_del_alg(ctx, &alg, 1000);
if (rc == 0) {
algorithm = ALGORITHM_CANDIDATES[i];
break;
@@ -103,9 +104,9 @@ static void run(void)
if (pid == 0) {
/* Child process: execute CRYPTO_MSG_NEWALG. */
- tst_crypto_open(&ses);
+ ctx = NETLINK_CREATE_CONTEXT(NETLINK_CRYPTO);
for (;;) {
- TEST(tst_crypto_add_alg(&ses, &alg));
+ TEST(tst_crypto_add_alg(ctx, &alg));
if (TST_RET && TST_RET != -EEXIST)
tst_brk(TBROK | TRERRNO,
"unexpected error from tst_crypto_add_alg()");
@@ -123,7 +124,7 @@ static void run(void)
SAFE_WAIT(&status);
if (!WIFSIGNALED(status) || WTERMSIG(status) != SIGKILL)
tst_brk(TBROK, "child %s", tst_strstatus(status));
- TEST(tst_crypto_del_alg(&ses, &alg));
+ TEST(tst_crypto_del_alg(ctx, &alg, 1000));
if (TST_RET && TST_RET != -ENOENT)
tst_brk(TBROK | TRERRNO,
"unexpected error from tst_crypto_del_alg()");
@@ -134,7 +135,7 @@ static void run(void)
static void cleanup(void)
{
- tst_crypto_close(&ses);
+ NETLINK_DESTROY_CONTEXT(ctx);
}
static struct tst_test test = {
diff --git a/testcases/kernel/crypto/pcrypt_aead01.c b/testcases/kernel/crypto/pcrypt_aead01.c
index 3b4f5d8d1..3979f317a 100644
--- a/testcases/kernel/crypto/pcrypt_aead01.c
+++ b/testcases/kernel/crypto/pcrypt_aead01.c
@@ -26,11 +26,11 @@
#define ATTEMPTS 10000
-static struct tst_crypto_session ses = TST_CRYPTO_SESSION_INIT;
+static struct tst_netlink_context *ctx;
void setup(void)
{
- tst_crypto_open(&ses);
+ ctx = NETLINK_CREATE_CONTEXT(NETLINK_CRYPTO);
}
void run(void)
@@ -43,7 +43,7 @@ void run(void)
};
for (i = 0; i < ATTEMPTS; ++i) {
- TEST(tst_crypto_add_alg(&ses, &a));
+ TEST(tst_crypto_add_alg(ctx, &a));
if (TST_RET && TST_RET == -ENOENT) {
tst_brk(TCONF | TRERRNO,
"pcrypt, hmac, sha256, cbc or aes not supported");
@@ -51,7 +51,7 @@ void run(void)
if (TST_RET && TST_RET != -EEXIST)
tst_brk(TBROK | TRERRNO, "add_alg");
- TEST(tst_crypto_del_alg(&ses, &a));
+ TEST(tst_crypto_del_alg(ctx, &a, 1000));
if (TST_RET)
tst_brk(TBROK | TRERRNO, "del_alg");
@@ -67,7 +67,7 @@ void run(void)
void cleanup(void)
{
- tst_crypto_close(&ses);
+ NETLINK_DESTROY_CONTEXT(ctx);
}
static struct tst_test test = {
--
2.42.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [LTP] [PATCH 0/3] Netlink helper functions refactoring
2023-10-13 15:17 [LTP] [PATCH 0/3] Netlink helper functions refactoring Martin Doucha
` (2 preceding siblings ...)
2023-10-13 15:17 ` [LTP] [PATCH 3/3] crypto: Replace old netlink helper functions with netlink contexts Martin Doucha
@ 2023-10-24 8:35 ` Petr Vorel
3 siblings, 0 replies; 8+ messages in thread
From: Petr Vorel @ 2023-10-24 8:35 UTC (permalink / raw)
To: Martin Doucha; +Cc: ltp
Hi all,
> doc/network-c-api.txt | 159 +++++++++++-----------
Unfortunately, Martin based his patchset on the LTP before I merged my patchset
which renamed files in doc.
Therefore it's needed to download the patchset manually and modify it in order
to apply:
s/network-c-api.txt/C-Test-Network-API.asciidoc/g
Kind regards,
Petr
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [LTP] [PATCH 1/3] tst_rtnetlink: Refactor helper function for generic use
2023-10-13 15:17 ` [LTP] [PATCH 1/3] tst_rtnetlink: Refactor helper function for generic use Martin Doucha
@ 2023-10-24 8:41 ` Petr Vorel
0 siblings, 0 replies; 8+ messages in thread
From: Petr Vorel @ 2023-10-24 8:41 UTC (permalink / raw)
To: Martin Doucha; +Cc: ltp
Hi Martin,
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Kind regards,
Petr
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [LTP] [PATCH 2/3] tst_netlink_destroy_context(): Allow safely passing NULL context
2023-10-13 15:17 ` [LTP] [PATCH 2/3] tst_netlink_destroy_context(): Allow safely passing NULL context Martin Doucha
@ 2023-10-24 8:56 ` Petr Vorel
0 siblings, 0 replies; 8+ messages in thread
From: Petr Vorel @ 2023-10-24 8:56 UTC (permalink / raw)
To: Martin Doucha; +Cc: ltp
Hi Martin,
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Kind regards,
Petr
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [LTP] [PATCH 3/3] crypto: Replace old netlink helper functions with netlink contexts
2023-10-13 15:17 ` [LTP] [PATCH 3/3] crypto: Replace old netlink helper functions with netlink contexts Martin Doucha
@ 2023-11-13 15:40 ` Petr Vorel
0 siblings, 0 replies; 8+ messages in thread
From: Petr Vorel @ 2023-11-13 15:40 UTC (permalink / raw)
To: Martin Doucha; +Cc: ltp
Hi Martin,
...
> +++ b/include/tst_crypto.h
> @@ -13,67 +13,13 @@
> #define TST_CRYPTO_H
> #include "lapi/cryptouser.h"
> -
> -/**
> - * A reference to a crypto session and associated state.
> - *
> - * Holds state relevant to a netlink crypto connection. The seq_num is used
> - * to tag each message sent to the netlink layer and is automatically
> - * incremented by the tst_crypto_ functions. When the netlink layer sends a
> - * response (ack) it will use the sequences number from the request.
> - *
> - * Some functions, such as delete ALG, may return EBUSY in which case it is
> - * safe to retry them. The retries field allows you to set the number of
> - * times this should be done. If set to zero the operation will only be tried
> - * once. For operations which do not return EBUSY, the field is ignored.
> - *
> - * Use TST_CRYPTO_SESSION_INIT to statically initialize this struct with sane
> - * defaults.
> - */
> -struct tst_crypto_session {
> - /** File descriptor for the netlink socket */
> - int fd;
> - /** A sequence number used to identify responses from the kernel. */
> - uint32_t seq_num;
> - /** Number of times some operations will be retried. */
> - uint32_t retries;
> -};
include/tst_crypto.h still contains "@relates tst_crypto_session". I guess this
should be replaced with "@relates tst_netlink_context", right?
I can fix this before merge.
...
> -/**
> - * Default static definition of tst_crypto_session.
> - *
> - * @relates tst_crypto_session
> - */
> -#define TST_CRYPTO_SESSION_INIT {\
> - .fd = 0, \
> - .seq_num = 0, \
> - .retries = 1000 \
I quite like this macro which had the default values.
But atm only retries 1000 is what needs to be specified, thus understand that
you didn't introduce any macro wrapper).
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Kind regards,
Petr
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2023-11-13 15:41 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-10-13 15:17 [LTP] [PATCH 0/3] Netlink helper functions refactoring Martin Doucha
2023-10-13 15:17 ` [LTP] [PATCH 1/3] tst_rtnetlink: Refactor helper function for generic use Martin Doucha
2023-10-24 8:41 ` Petr Vorel
2023-10-13 15:17 ` [LTP] [PATCH 2/3] tst_netlink_destroy_context(): Allow safely passing NULL context Martin Doucha
2023-10-24 8:56 ` Petr Vorel
2023-10-13 15:17 ` [LTP] [PATCH 3/3] crypto: Replace old netlink helper functions with netlink contexts Martin Doucha
2023-11-13 15:40 ` Petr Vorel
2023-10-24 8:35 ` [LTP] [PATCH 0/3] Netlink helper functions refactoring Petr Vorel
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.