xref: /aosp_15_r20/external/ltp/include/tst_netlink.h (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1*49cdfc7eSAndroid Build Coastguard Worker /* SPDX-License-Identifier: GPL-2.0-or-later
2*49cdfc7eSAndroid Build Coastguard Worker  * Copyright (c) 2021 Linux Test Project
3*49cdfc7eSAndroid Build Coastguard Worker  */
4*49cdfc7eSAndroid Build Coastguard Worker 
5*49cdfc7eSAndroid Build Coastguard Worker #ifndef TST_NETLINK_H
6*49cdfc7eSAndroid Build Coastguard Worker #define TST_NETLINK_H
7*49cdfc7eSAndroid Build Coastguard Worker 
8*49cdfc7eSAndroid Build Coastguard Worker #include <linux/netlink.h>
9*49cdfc7eSAndroid Build Coastguard Worker 
10*49cdfc7eSAndroid Build Coastguard Worker struct tst_netlink_context;
11*49cdfc7eSAndroid Build Coastguard Worker 
12*49cdfc7eSAndroid Build Coastguard Worker struct tst_netlink_attr_list {
13*49cdfc7eSAndroid Build Coastguard Worker 	unsigned short type;
14*49cdfc7eSAndroid Build Coastguard Worker 	const void *data;
15*49cdfc7eSAndroid Build Coastguard Worker 	ssize_t len;
16*49cdfc7eSAndroid Build Coastguard Worker 	const struct tst_netlink_attr_list *sublist;
17*49cdfc7eSAndroid Build Coastguard Worker };
18*49cdfc7eSAndroid Build Coastguard Worker 
19*49cdfc7eSAndroid Build Coastguard Worker struct tst_netlink_message {
20*49cdfc7eSAndroid Build Coastguard Worker 	struct nlmsghdr *header;
21*49cdfc7eSAndroid Build Coastguard Worker 	struct nlmsgerr *err;
22*49cdfc7eSAndroid Build Coastguard Worker 	void *payload;
23*49cdfc7eSAndroid Build Coastguard Worker 	size_t payload_size;
24*49cdfc7eSAndroid Build Coastguard Worker };
25*49cdfc7eSAndroid Build Coastguard Worker 
26*49cdfc7eSAndroid Build Coastguard Worker extern int tst_netlink_errno;
27*49cdfc7eSAndroid Build Coastguard Worker 
28*49cdfc7eSAndroid Build Coastguard Worker /* Open a netlink socket */
29*49cdfc7eSAndroid Build Coastguard Worker struct tst_netlink_context *tst_netlink_create_context(const char *file,
30*49cdfc7eSAndroid Build Coastguard Worker 	const int lineno, int protocol);
31*49cdfc7eSAndroid Build Coastguard Worker #define NETLINK_CREATE_CONTEXT(protocol) \
32*49cdfc7eSAndroid Build Coastguard Worker 	tst_netlink_create_context(__FILE__, __LINE__, (protocol))
33*49cdfc7eSAndroid Build Coastguard Worker 
34*49cdfc7eSAndroid Build Coastguard Worker /* Free a tst_netlink_message array returned by tst_netlink_recv() */
35*49cdfc7eSAndroid Build Coastguard Worker void tst_netlink_free_message(struct tst_netlink_message *msg);
36*49cdfc7eSAndroid Build Coastguard Worker #define NETLINK_FREE_MESSAGE tst_netlink_free_message
37*49cdfc7eSAndroid Build Coastguard Worker 
38*49cdfc7eSAndroid Build Coastguard Worker /* Close netlink socket */
39*49cdfc7eSAndroid Build Coastguard Worker void tst_netlink_destroy_context(const char *file, const int lineno,
40*49cdfc7eSAndroid Build Coastguard Worker 	struct tst_netlink_context *ctx);
41*49cdfc7eSAndroid Build Coastguard Worker #define NETLINK_DESTROY_CONTEXT(ctx) \
42*49cdfc7eSAndroid Build Coastguard Worker 	tst_netlink_destroy_context(__FILE__, __LINE__, (ctx))
43*49cdfc7eSAndroid Build Coastguard Worker 
44*49cdfc7eSAndroid Build Coastguard Worker /* Send all messages in given buffer */
45*49cdfc7eSAndroid Build Coastguard Worker int tst_netlink_send(const char *file, const int lineno,
46*49cdfc7eSAndroid Build Coastguard Worker 	struct tst_netlink_context *ctx);
47*49cdfc7eSAndroid Build Coastguard Worker #define NETLINK_SEND(ctx) tst_netlink_send(__FILE__, __LINE__, (ctx))
48*49cdfc7eSAndroid Build Coastguard Worker 
49*49cdfc7eSAndroid Build Coastguard Worker /* Send all messages in given buffer and validate kernel response */
50*49cdfc7eSAndroid Build Coastguard Worker int tst_netlink_send_validate(const char *file, const int lineno,
51*49cdfc7eSAndroid Build Coastguard Worker 	struct tst_netlink_context *ctx);
52*49cdfc7eSAndroid Build Coastguard Worker #define NETLINK_SEND_VALIDATE(ctx) \
53*49cdfc7eSAndroid Build Coastguard Worker 	tst_netlink_send_validate(__FILE__, __LINE__, (ctx))
54*49cdfc7eSAndroid Build Coastguard Worker 
55*49cdfc7eSAndroid Build Coastguard Worker /* Wait until data is available for reading from the netlink socket */
56*49cdfc7eSAndroid Build Coastguard Worker int tst_netlink_wait(struct tst_netlink_context *ctx);
57*49cdfc7eSAndroid Build Coastguard Worker #define NETLINK_WAIT tst_netlink_wait
58*49cdfc7eSAndroid Build Coastguard Worker 
59*49cdfc7eSAndroid Build Coastguard Worker /*
60*49cdfc7eSAndroid Build Coastguard Worker  * Read from netlink socket and return an array of partially parsed messages.
61*49cdfc7eSAndroid Build Coastguard Worker  * header == NULL indicates end of array.
62*49cdfc7eSAndroid Build Coastguard Worker  */
63*49cdfc7eSAndroid Build Coastguard Worker struct tst_netlink_message *tst_netlink_recv(const char *file, const int lineno,
64*49cdfc7eSAndroid Build Coastguard Worker 	struct tst_netlink_context *ctx);
65*49cdfc7eSAndroid Build Coastguard Worker #define NETLINK_RECV(ctx) tst_netlink_recv(__FILE__, __LINE__, (ctx))
66*49cdfc7eSAndroid Build Coastguard Worker 
67*49cdfc7eSAndroid Build Coastguard Worker /* Add new message to buffer */
68*49cdfc7eSAndroid Build Coastguard Worker int tst_netlink_add_message(const char *file, const int lineno,
69*49cdfc7eSAndroid Build Coastguard Worker 	struct tst_netlink_context *ctx, const struct nlmsghdr *header,
70*49cdfc7eSAndroid Build Coastguard Worker 	const void *payload, size_t payload_size);
71*49cdfc7eSAndroid Build Coastguard Worker #define NETLINK_ADD_MESSAGE(ctx, header, payload, psize) \
72*49cdfc7eSAndroid Build Coastguard Worker 	tst_netlink_add_message(__FILE__, __LINE__, (ctx), (header), \
73*49cdfc7eSAndroid Build Coastguard Worker 		(payload), (psize))
74*49cdfc7eSAndroid Build Coastguard Worker 
75*49cdfc7eSAndroid Build Coastguard Worker /* Add arbitrary nlattr attribute to last message */
76*49cdfc7eSAndroid Build Coastguard Worker int tst_netlink_add_attr(const char *file, const int lineno,
77*49cdfc7eSAndroid Build Coastguard Worker 	struct tst_netlink_context *ctx, unsigned short type, const void *data,
78*49cdfc7eSAndroid Build Coastguard Worker 	unsigned short len);
79*49cdfc7eSAndroid Build Coastguard Worker #define NETLINK_ADD_ATTR(ctx, type, data, len) \
80*49cdfc7eSAndroid Build Coastguard Worker 	tst_netlink_add_attr(__FILE__, __LINE__, (ctx), (type), (data), (len))
81*49cdfc7eSAndroid Build Coastguard Worker 
82*49cdfc7eSAndroid Build Coastguard Worker /* Add string nlattr attribute to last message */
83*49cdfc7eSAndroid Build Coastguard Worker int tst_netlink_add_attr_string(const char *file, const int lineno,
84*49cdfc7eSAndroid Build Coastguard Worker 	struct tst_netlink_context *ctx, unsigned short type, const char *data);
85*49cdfc7eSAndroid Build Coastguard Worker #define NETLINK_ADD_ATTR_STRING(ctx, type, data) \
86*49cdfc7eSAndroid Build Coastguard Worker 	tst_netlink_add_attr_string(__FILE__, __LINE__, (ctx), (type), (data))
87*49cdfc7eSAndroid Build Coastguard Worker 
88*49cdfc7eSAndroid Build Coastguard Worker /*
89*49cdfc7eSAndroid Build Coastguard Worker  * Add list of arbitrary nlattr attributes to last message. The list is
90*49cdfc7eSAndroid Build Coastguard Worker  * terminated by attribute with negative length. Nested sublists are supported.
91*49cdfc7eSAndroid Build Coastguard Worker  */
92*49cdfc7eSAndroid Build Coastguard Worker int tst_netlink_add_attr_list(const char *file, const int lineno,
93*49cdfc7eSAndroid Build Coastguard Worker 	struct tst_netlink_context *ctx,
94*49cdfc7eSAndroid Build Coastguard Worker 	const struct tst_netlink_attr_list *list);
95*49cdfc7eSAndroid Build Coastguard Worker #define NETLINK_ADD_ATTR_LIST(ctx, list) \
96*49cdfc7eSAndroid Build Coastguard Worker 	tst_netlink_add_attr_list(__FILE__, __LINE__, (ctx), (list))
97*49cdfc7eSAndroid Build Coastguard Worker 
98*49cdfc7eSAndroid Build Coastguard Worker /* Add arbitrary rtattr attribute to last message */
99*49cdfc7eSAndroid Build Coastguard Worker int tst_rtnl_add_attr(const char *file, const int lineno,
100*49cdfc7eSAndroid Build Coastguard Worker 	struct tst_netlink_context *ctx, unsigned short type, const void *data,
101*49cdfc7eSAndroid Build Coastguard Worker 	unsigned short len);
102*49cdfc7eSAndroid Build Coastguard Worker #define RTNL_ADD_ATTR(ctx, type, data, len) \
103*49cdfc7eSAndroid Build Coastguard Worker 	tst_rtnl_add_attr(__FILE__, __LINE__, (ctx), (type), (data), (len))
104*49cdfc7eSAndroid Build Coastguard Worker 
105*49cdfc7eSAndroid Build Coastguard Worker /* Add string rtattr attribute to last message */
106*49cdfc7eSAndroid Build Coastguard Worker int tst_rtnl_add_attr_string(const char *file, const int lineno,
107*49cdfc7eSAndroid Build Coastguard Worker 	struct tst_netlink_context *ctx, unsigned short type, const char *data);
108*49cdfc7eSAndroid Build Coastguard Worker #define RTNL_ADD_ATTR_STRING(ctx, type, data) \
109*49cdfc7eSAndroid Build Coastguard Worker 	tst_rtnl_add_attr_string(__FILE__, __LINE__, (ctx), (type), (data))
110*49cdfc7eSAndroid Build Coastguard Worker 
111*49cdfc7eSAndroid Build Coastguard Worker /*
112*49cdfc7eSAndroid Build Coastguard Worker  * Add list of arbitrary rtattr attributes to last message. The list is
113*49cdfc7eSAndroid Build Coastguard Worker  * terminated by attribute with negative length. Nested sublists are supported.
114*49cdfc7eSAndroid Build Coastguard Worker  */
115*49cdfc7eSAndroid Build Coastguard Worker int tst_rtnl_add_attr_list(const char *file, const int lineno,
116*49cdfc7eSAndroid Build Coastguard Worker 	struct tst_netlink_context *ctx,
117*49cdfc7eSAndroid Build Coastguard Worker 	const struct tst_netlink_attr_list *list);
118*49cdfc7eSAndroid Build Coastguard Worker #define RTNL_ADD_ATTR_LIST(ctx, list) \
119*49cdfc7eSAndroid Build Coastguard Worker 	tst_rtnl_add_attr_list(__FILE__, __LINE__, (ctx), (list))
120*49cdfc7eSAndroid Build Coastguard Worker 
121*49cdfc7eSAndroid Build Coastguard Worker /* Check that all sent messages with NLM_F_ACK flag have been acked without
122*49cdfc7eSAndroid Build Coastguard Worker  * error. Usage:
123*49cdfc7eSAndroid Build Coastguard Worker  *
124*49cdfc7eSAndroid Build Coastguard Worker  * tst_netlink_send(ctx);
125*49cdfc7eSAndroid Build Coastguard Worker  * tst_netlink_wait(ctx);
126*49cdfc7eSAndroid Build Coastguard Worker  * response = tst_netlink_recv(ctx);
127*49cdfc7eSAndroid Build Coastguard Worker  * if (!tst_netlink_check_acks(ctx, response)) { ... }
128*49cdfc7eSAndroid Build Coastguard Worker  * tst_netlink_free_message(response);
129*49cdfc7eSAndroid Build Coastguard Worker  */
130*49cdfc7eSAndroid Build Coastguard Worker int tst_netlink_check_acks(const char *file, const int lineno,
131*49cdfc7eSAndroid Build Coastguard Worker 	struct tst_netlink_context *ctx, struct tst_netlink_message *response);
132*49cdfc7eSAndroid Build Coastguard Worker #define NETLINK_CHECK_ACKS(ctx, response) \
133*49cdfc7eSAndroid Build Coastguard Worker 	tst_netlink_check_acks(__FILE__, __LINE__, (ctx), (response))
134*49cdfc7eSAndroid Build Coastguard Worker 
135*49cdfc7eSAndroid Build Coastguard Worker #endif /* TST_NETLINK_H */
136