[LTP] [PATCH v2 1/5] tst_rtnetlink: Refactor helper function for generic use

Martin Doucha
2023-11-14T12:32:54Z

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>
Reviewed-by: Petr Vorel <pvorel@suse.cz>
---

Changes since v1: Rebased

doc/C-Test-Network-API.asciidoc | 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/C-Test-Network-API.asciidoc b/doc/C-Test-Network-API.asciidoc
index 3bf2a1f8a..25e4bbd18 100644
--- a/doc/C-Test-Network-API.asciidoc
+++ b/doc/C-Test-Network-API.asciidoc
@@ -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 001056820..0fd254a92 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