public inbox for ltp@lists.linux.it
 help / color / mirror / Atom feed
* [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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox