xref: /aosp_15_r20/external/libnl/tests/nl-test-util.h (revision 4dc78e53d49367fa8e61b07018507c90983a077d)
1*4dc78e53SAndroid Build Coastguard Worker /* SPDX-License-Identifier: LGPL-2.1-only */
2*4dc78e53SAndroid Build Coastguard Worker 
3*4dc78e53SAndroid Build Coastguard Worker #ifndef __NL_TEST_UTIL_H__
4*4dc78e53SAndroid Build Coastguard Worker #define __NL_TEST_UTIL_H__
5*4dc78e53SAndroid Build Coastguard Worker 
6*4dc78e53SAndroid Build Coastguard Worker #include <sys/stat.h>
7*4dc78e53SAndroid Build Coastguard Worker #include <check.h>
8*4dc78e53SAndroid Build Coastguard Worker 
9*4dc78e53SAndroid Build Coastguard Worker #include <netlink/object.h>
10*4dc78e53SAndroid Build Coastguard Worker #include <netlink/cache.h>
11*4dc78e53SAndroid Build Coastguard Worker 
12*4dc78e53SAndroid Build Coastguard Worker #include "base/nl-base-utils.h"
13*4dc78e53SAndroid Build Coastguard Worker #include "nl-aux-core/nl-core.h"
14*4dc78e53SAndroid Build Coastguard Worker #include "nl-aux-route/nl-route.h"
15*4dc78e53SAndroid Build Coastguard Worker 
16*4dc78e53SAndroid Build Coastguard Worker /*****************************************************************************/
17*4dc78e53SAndroid Build Coastguard Worker 
_nltst_strfreev(char ** strv)18*4dc78e53SAndroid Build Coastguard Worker static inline void _nltst_strfreev(char **strv)
19*4dc78e53SAndroid Build Coastguard Worker {
20*4dc78e53SAndroid Build Coastguard Worker 	size_t i;
21*4dc78e53SAndroid Build Coastguard Worker 
22*4dc78e53SAndroid Build Coastguard Worker 	if (strv) {
23*4dc78e53SAndroid Build Coastguard Worker 		for (i = 0; strv[i]; i++)
24*4dc78e53SAndroid Build Coastguard Worker 			free(strv[i]);
25*4dc78e53SAndroid Build Coastguard Worker 		free(strv);
26*4dc78e53SAndroid Build Coastguard Worker 	}
27*4dc78e53SAndroid Build Coastguard Worker }
28*4dc78e53SAndroid Build Coastguard Worker 
29*4dc78e53SAndroid Build Coastguard Worker #define _nltst_auto_strfreev _nl_auto(_nltst_auto_strfreev_fcn)
30*4dc78e53SAndroid Build Coastguard Worker _NL_AUTO_DEFINE_FCN_TYPED0(char **, _nltst_auto_strfreev_fcn, _nltst_strfreev);
31*4dc78e53SAndroid Build Coastguard Worker 
32*4dc78e53SAndroid Build Coastguard Worker /*****************************************************************************/
33*4dc78e53SAndroid Build Coastguard Worker 
34*4dc78e53SAndroid Build Coastguard Worker #ifndef ck_assert_ptr_nonnull
35*4dc78e53SAndroid Build Coastguard Worker #define ck_assert_ptr_nonnull(ptr) ck_assert(ptr)
36*4dc78e53SAndroid Build Coastguard Worker #endif
37*4dc78e53SAndroid Build Coastguard Worker 
38*4dc78e53SAndroid Build Coastguard Worker #ifndef ck_assert_pstr_ne
39*4dc78e53SAndroid Build Coastguard Worker #define ck_assert_pstr_ne(a, b)                                              \
40*4dc78e53SAndroid Build Coastguard Worker 	do {                                                                 \
41*4dc78e53SAndroid Build Coastguard Worker 		const char *_a = (a);                                        \
42*4dc78e53SAndroid Build Coastguard Worker 		const char *_b = (b);                                        \
43*4dc78e53SAndroid Build Coastguard Worker                                                                              \
44*4dc78e53SAndroid Build Coastguard Worker 		ck_assert(!(_a == _b || (_a && _b && strcmp(_a, _b) == 0))); \
45*4dc78e53SAndroid Build Coastguard Worker 	} while (0)
46*4dc78e53SAndroid Build Coastguard Worker #endif
47*4dc78e53SAndroid Build Coastguard Worker 
48*4dc78e53SAndroid Build Coastguard Worker #ifndef ck_assert_ptr_null
49*4dc78e53SAndroid Build Coastguard Worker #define ck_assert_ptr_null(ptr) ck_assert(!(ptr))
50*4dc78e53SAndroid Build Coastguard Worker #endif
51*4dc78e53SAndroid Build Coastguard Worker 
52*4dc78e53SAndroid Build Coastguard Worker /*****************************************************************************/
53*4dc78e53SAndroid Build Coastguard Worker 
54*4dc78e53SAndroid Build Coastguard Worker #define __nltst_assert_nonnull(uniq, x)                      \
55*4dc78e53SAndroid Build Coastguard Worker 	({                                                   \
56*4dc78e53SAndroid Build Coastguard Worker 		typeof(x) _NL_UNIQ_T(_x, uniq) = (x);        \
57*4dc78e53SAndroid Build Coastguard Worker                                                              \
58*4dc78e53SAndroid Build Coastguard Worker 		ck_assert_ptr_nonnull(_NL_UNIQ_T(_x, uniq)); \
59*4dc78e53SAndroid Build Coastguard Worker                                                              \
60*4dc78e53SAndroid Build Coastguard Worker 		_NL_UNIQ_T(_x, uniq);                        \
61*4dc78e53SAndroid Build Coastguard Worker 	})
62*4dc78e53SAndroid Build Coastguard Worker 
63*4dc78e53SAndroid Build Coastguard Worker #define _nltst_assert_nonnull(x) __nltst_assert_nonnull(_NL_UNIQ, x)
64*4dc78e53SAndroid Build Coastguard Worker 
_nltst_strdup(const char * str)65*4dc78e53SAndroid Build Coastguard Worker static inline char *_nltst_strdup(const char *str)
66*4dc78e53SAndroid Build Coastguard Worker {
67*4dc78e53SAndroid Build Coastguard Worker 	return str ? _nltst_assert_nonnull(strdup(str)) : NULL;
68*4dc78e53SAndroid Build Coastguard Worker }
69*4dc78e53SAndroid Build Coastguard Worker 
70*4dc78e53SAndroid Build Coastguard Worker /*****************************************************************************/
71*4dc78e53SAndroid Build Coastguard Worker 
72*4dc78e53SAndroid Build Coastguard Worker #define __nltst_sprintf_arr(uniq, arr, fmt, ...)                      \
73*4dc78e53SAndroid Build Coastguard Worker 	({                                                            \
74*4dc78e53SAndroid Build Coastguard Worker 		char *const _NL_UNIQ_T(arr, uniq) = (arr);            \
75*4dc78e53SAndroid Build Coastguard Worker 		int _NL_UNIQ_T(c, uniq);                              \
76*4dc78e53SAndroid Build Coastguard Worker                                                                       \
77*4dc78e53SAndroid Build Coastguard Worker 		_NL_STATIC_ASSERT(sizeof(arr) >                       \
78*4dc78e53SAndroid Build Coastguard Worker 				  sizeof(_NL_UNIQ_T(arr, uniq)));     \
79*4dc78e53SAndroid Build Coastguard Worker                                                                       \
80*4dc78e53SAndroid Build Coastguard Worker 		_NL_UNIQ_T(c, uniq) = snprintf(_NL_UNIQ_T(arr, uniq), \
81*4dc78e53SAndroid Build Coastguard Worker 					       sizeof(arr), fmt,      \
82*4dc78e53SAndroid Build Coastguard Worker 					       ##__VA_ARGS__);        \
83*4dc78e53SAndroid Build Coastguard Worker                                                                       \
84*4dc78e53SAndroid Build Coastguard Worker 		ck_assert_int_lt(_NL_UNIQ_T(c, uniq), sizeof(arr));   \
85*4dc78e53SAndroid Build Coastguard Worker                                                                       \
86*4dc78e53SAndroid Build Coastguard Worker 		_NL_UNIQ_T(arr, uniq);                                \
87*4dc78e53SAndroid Build Coastguard Worker 	})
88*4dc78e53SAndroid Build Coastguard Worker 
89*4dc78e53SAndroid Build Coastguard Worker #define _nltst_sprintf_arr(arr, fmt, ...) \
90*4dc78e53SAndroid Build Coastguard Worker 	__nltst_sprintf_arr(_NL_UNIQ, arr, fmt, ##__VA_ARGS__)
91*4dc78e53SAndroid Build Coastguard Worker 
92*4dc78e53SAndroid Build Coastguard Worker /*****************************************************************************/
93*4dc78e53SAndroid Build Coastguard Worker 
94*4dc78e53SAndroid Build Coastguard Worker void _nltst_get_urandom(void *ptr, size_t len);
95*4dc78e53SAndroid Build Coastguard Worker 
96*4dc78e53SAndroid Build Coastguard Worker uint32_t _nltst_rand_u32(void);
97*4dc78e53SAndroid Build Coastguard Worker 
_nltst_rand_u32_range(uint32_t n)98*4dc78e53SAndroid Build Coastguard Worker static inline uint32_t _nltst_rand_u32_range(uint32_t n)
99*4dc78e53SAndroid Build Coastguard Worker {
100*4dc78e53SAndroid Build Coastguard Worker 	uint32_t rem;
101*4dc78e53SAndroid Build Coastguard Worker 	uint32_t i;
102*4dc78e53SAndroid Build Coastguard Worker 
103*4dc78e53SAndroid Build Coastguard Worker 	if (n == 0)
104*4dc78e53SAndroid Build Coastguard Worker 		return _nltst_rand_u32();
105*4dc78e53SAndroid Build Coastguard Worker 	if (n == 1)
106*4dc78e53SAndroid Build Coastguard Worker 		return 0;
107*4dc78e53SAndroid Build Coastguard Worker 
108*4dc78e53SAndroid Build Coastguard Worker 	rem = UINT32_MAX % n;
109*4dc78e53SAndroid Build Coastguard Worker 	for (;;) {
110*4dc78e53SAndroid Build Coastguard Worker 		i = _nltst_rand_u32();
111*4dc78e53SAndroid Build Coastguard Worker 		if (i < (UINT32_MAX - rem))
112*4dc78e53SAndroid Build Coastguard Worker 			return i % n;
113*4dc78e53SAndroid Build Coastguard Worker 	}
114*4dc78e53SAndroid Build Coastguard Worker }
115*4dc78e53SAndroid Build Coastguard Worker 
_nltst_rand_bool(void)116*4dc78e53SAndroid Build Coastguard Worker static inline bool _nltst_rand_bool(void)
117*4dc78e53SAndroid Build Coastguard Worker {
118*4dc78e53SAndroid Build Coastguard Worker 	return _nltst_rand_u32() % 2 == 0;
119*4dc78e53SAndroid Build Coastguard Worker }
120*4dc78e53SAndroid Build Coastguard Worker 
121*4dc78e53SAndroid Build Coastguard Worker #define _nltst_rand_select(a, ...)                                 \
122*4dc78e53SAndroid Build Coastguard Worker 	({                                                         \
123*4dc78e53SAndroid Build Coastguard Worker 		const typeof(a) _lst[] = { (a), ##__VA_ARGS__ };   \
124*4dc78e53SAndroid Build Coastguard Worker                                                                    \
125*4dc78e53SAndroid Build Coastguard Worker 		_lst[_nltst_rand_u32_range(_NL_N_ELEMENTS(_lst))]; \
126*4dc78e53SAndroid Build Coastguard Worker 	})
127*4dc78e53SAndroid Build Coastguard Worker 
128*4dc78e53SAndroid Build Coastguard Worker /*****************************************************************************/
129*4dc78e53SAndroid Build Coastguard Worker 
130*4dc78e53SAndroid Build Coastguard Worker #define _nltst_assert(expr)                                           \
131*4dc78e53SAndroid Build Coastguard Worker 	({                                                            \
132*4dc78e53SAndroid Build Coastguard Worker 		typeof(expr) _expr = (expr);                          \
133*4dc78e53SAndroid Build Coastguard Worker                                                                       \
134*4dc78e53SAndroid Build Coastguard Worker 		if (!_expr) {                                         \
135*4dc78e53SAndroid Build Coastguard Worker 			ck_assert_msg(0, "assert(%s) failed", #expr); \
136*4dc78e53SAndroid Build Coastguard Worker 		}                                                     \
137*4dc78e53SAndroid Build Coastguard Worker 		_expr;                                                \
138*4dc78e53SAndroid Build Coastguard Worker 	})
139*4dc78e53SAndroid Build Coastguard Worker 
140*4dc78e53SAndroid Build Coastguard Worker #define _nltst_assert_errno(expr)                                            \
141*4dc78e53SAndroid Build Coastguard Worker 	do {                                                                 \
142*4dc78e53SAndroid Build Coastguard Worker 		if (expr) {                                                  \
143*4dc78e53SAndroid Build Coastguard Worker 		} else {                                                     \
144*4dc78e53SAndroid Build Coastguard Worker 			const int _errno = (errno);                          \
145*4dc78e53SAndroid Build Coastguard Worker                                                                              \
146*4dc78e53SAndroid Build Coastguard Worker 			ck_assert_msg(0, "assert(%s) failed (errno=%d, %s)", \
147*4dc78e53SAndroid Build Coastguard Worker 				      #expr, _errno, strerror(_errno));      \
148*4dc78e53SAndroid Build Coastguard Worker 		}                                                            \
149*4dc78e53SAndroid Build Coastguard Worker 	} while (0)
150*4dc78e53SAndroid Build Coastguard Worker 
151*4dc78e53SAndroid Build Coastguard Worker #define _nltst_assert_retcode(expr)                                                   \
152*4dc78e53SAndroid Build Coastguard Worker 	do {                                                                          \
153*4dc78e53SAndroid Build Coastguard Worker 		const int _r = (expr);                                                \
154*4dc78e53SAndroid Build Coastguard Worker                                                                                       \
155*4dc78e53SAndroid Build Coastguard Worker 		if (_r < 0) {                                                         \
156*4dc78e53SAndroid Build Coastguard Worker 			ck_assert_msg(                                                \
157*4dc78e53SAndroid Build Coastguard Worker 				0, "command(%s) failed with return code %d",          \
158*4dc78e53SAndroid Build Coastguard Worker 				#expr, _r);                                           \
159*4dc78e53SAndroid Build Coastguard Worker 		}                                                                     \
160*4dc78e53SAndroid Build Coastguard Worker 		if (_r > 0) {                                                         \
161*4dc78e53SAndroid Build Coastguard Worker 			ck_assert_msg(                                                \
162*4dc78e53SAndroid Build Coastguard Worker 				0,                                                    \
163*4dc78e53SAndroid Build Coastguard Worker 				"command(%s) has unexpected positive return code %d", \
164*4dc78e53SAndroid Build Coastguard Worker 				#expr, _r);                                           \
165*4dc78e53SAndroid Build Coastguard Worker 		}                                                                     \
166*4dc78e53SAndroid Build Coastguard Worker 	} while (0)
167*4dc78e53SAndroid Build Coastguard Worker 
168*4dc78e53SAndroid Build Coastguard Worker #define _nltst_close(fd)                      \
169*4dc78e53SAndroid Build Coastguard Worker 	do {                                  \
170*4dc78e53SAndroid Build Coastguard Worker 		int _r;                       \
171*4dc78e53SAndroid Build Coastguard Worker                                               \
172*4dc78e53SAndroid Build Coastguard Worker 		_r = _nl_close((fd));         \
173*4dc78e53SAndroid Build Coastguard Worker 		_nltst_assert_errno(_r == 0); \
174*4dc78e53SAndroid Build Coastguard Worker 	} while (0)
175*4dc78e53SAndroid Build Coastguard Worker 
176*4dc78e53SAndroid Build Coastguard Worker #define _nltst_fclose(f)                      \
177*4dc78e53SAndroid Build Coastguard Worker 	do {                                  \
178*4dc78e53SAndroid Build Coastguard Worker 		int _r;                       \
179*4dc78e53SAndroid Build Coastguard Worker                                               \
180*4dc78e53SAndroid Build Coastguard Worker 		_r = fclose((f));             \
181*4dc78e53SAndroid Build Coastguard Worker 		_nltst_assert_errno(_r == 0); \
182*4dc78e53SAndroid Build Coastguard Worker 	} while (0)
183*4dc78e53SAndroid Build Coastguard Worker 
184*4dc78e53SAndroid Build Coastguard Worker void _nltst_assert_link_exists_full(const char *ifname, bool exists);
185*4dc78e53SAndroid Build Coastguard Worker 
186*4dc78e53SAndroid Build Coastguard Worker #define _nltst_assert_link_exists(ifname) \
187*4dc78e53SAndroid Build Coastguard Worker 	_nltst_assert_link_exists_full((ifname), true)
188*4dc78e53SAndroid Build Coastguard Worker 
189*4dc78e53SAndroid Build Coastguard Worker #define _nltst_assert_link_not_exists(ifname) \
190*4dc78e53SAndroid Build Coastguard Worker 	_nltst_assert_link_exists_full((ifname), false)
191*4dc78e53SAndroid Build Coastguard Worker 
192*4dc78e53SAndroid Build Coastguard Worker /*****************************************************************************/
193*4dc78e53SAndroid Build Coastguard Worker 
194*4dc78e53SAndroid Build Coastguard Worker typedef union {
195*4dc78e53SAndroid Build Coastguard Worker 	in_addr_t addr4;
196*4dc78e53SAndroid Build Coastguard Worker 	struct in_addr a4;
197*4dc78e53SAndroid Build Coastguard Worker 	struct in6_addr a6;
198*4dc78e53SAndroid Build Coastguard Worker } NLTstIPAddr;
199*4dc78e53SAndroid Build Coastguard Worker 
_nltst_inet_ntop(int addr_family,const void * addr,char buf[static INET_ADDRSTRLEN])200*4dc78e53SAndroid Build Coastguard Worker static inline char *_nltst_inet_ntop(int addr_family, const void *addr,
201*4dc78e53SAndroid Build Coastguard Worker 				     char buf[static INET_ADDRSTRLEN])
202*4dc78e53SAndroid Build Coastguard Worker {
203*4dc78e53SAndroid Build Coastguard Worker 	char *r;
204*4dc78e53SAndroid Build Coastguard Worker 
205*4dc78e53SAndroid Build Coastguard Worker 	ck_assert(addr_family == AF_INET || addr_family == AF_INET6);
206*4dc78e53SAndroid Build Coastguard Worker 	ck_assert(addr);
207*4dc78e53SAndroid Build Coastguard Worker 
208*4dc78e53SAndroid Build Coastguard Worker 	r = (char *)inet_ntop(addr_family, addr, buf,
209*4dc78e53SAndroid Build Coastguard Worker 			      (addr_family == AF_INET) ? INET_ADDRSTRLEN :
210*4dc78e53SAndroid Build Coastguard Worker 							 INET6_ADDRSTRLEN);
211*4dc78e53SAndroid Build Coastguard Worker 	ck_assert_ptr_eq(r, buf);
212*4dc78e53SAndroid Build Coastguard Worker 	ck_assert_int_lt(strlen(r), (addr_family == AF_INET) ?
213*4dc78e53SAndroid Build Coastguard Worker 					    INET_ADDRSTRLEN :
214*4dc78e53SAndroid Build Coastguard Worker 					    INET6_ADDRSTRLEN);
215*4dc78e53SAndroid Build Coastguard Worker 	return r;
216*4dc78e53SAndroid Build Coastguard Worker }
217*4dc78e53SAndroid Build Coastguard Worker 
_nltst_inet_ntop_dup(int addr_family,const void * addr)218*4dc78e53SAndroid Build Coastguard Worker static inline char *_nltst_inet_ntop_dup(int addr_family, const void *addr)
219*4dc78e53SAndroid Build Coastguard Worker {
220*4dc78e53SAndroid Build Coastguard Worker 	return (char *)_nltst_inet_ntop(addr_family, addr,
221*4dc78e53SAndroid Build Coastguard Worker 					malloc((addr_family == AF_INET) ?
222*4dc78e53SAndroid Build Coastguard Worker 						       INET_ADDRSTRLEN :
223*4dc78e53SAndroid Build Coastguard Worker 						       INET6_ADDRSTRLEN));
224*4dc78e53SAndroid Build Coastguard Worker }
225*4dc78e53SAndroid Build Coastguard Worker 
_nltst_inet_pton(int addr_family,const char * str,int * out_addr_family,void * out_addr)226*4dc78e53SAndroid Build Coastguard Worker static inline bool _nltst_inet_pton(int addr_family, const char *str,
227*4dc78e53SAndroid Build Coastguard Worker 				    int *out_addr_family, void *out_addr)
228*4dc78e53SAndroid Build Coastguard Worker {
229*4dc78e53SAndroid Build Coastguard Worker 	NLTstIPAddr a;
230*4dc78e53SAndroid Build Coastguard Worker 	int r;
231*4dc78e53SAndroid Build Coastguard Worker 
232*4dc78e53SAndroid Build Coastguard Worker 	ck_assert(addr_family == AF_UNSPEC || addr_family == AF_INET ||
233*4dc78e53SAndroid Build Coastguard Worker 		  addr_family == AF_INET6);
234*4dc78e53SAndroid Build Coastguard Worker 
235*4dc78e53SAndroid Build Coastguard Worker 	/* when requesting @out_addr, then the addr-family must either be
236*4dc78e53SAndroid Build Coastguard Worker 	 * pre-determined or requested too. */
237*4dc78e53SAndroid Build Coastguard Worker 	ck_assert(!out_addr || out_addr_family || addr_family != AF_UNSPEC);
238*4dc78e53SAndroid Build Coastguard Worker 
239*4dc78e53SAndroid Build Coastguard Worker 	if (!str)
240*4dc78e53SAndroid Build Coastguard Worker 		return false;
241*4dc78e53SAndroid Build Coastguard Worker 
242*4dc78e53SAndroid Build Coastguard Worker 	if (addr_family == AF_UNSPEC)
243*4dc78e53SAndroid Build Coastguard Worker 		addr_family = strchr(str, ':') ? AF_INET6 : AF_INET;
244*4dc78e53SAndroid Build Coastguard Worker 
245*4dc78e53SAndroid Build Coastguard Worker 	r = inet_pton(addr_family, str, &a);
246*4dc78e53SAndroid Build Coastguard Worker 	if (r != 1)
247*4dc78e53SAndroid Build Coastguard Worker 		return false;
248*4dc78e53SAndroid Build Coastguard Worker 
249*4dc78e53SAndroid Build Coastguard Worker 	if (out_addr) {
250*4dc78e53SAndroid Build Coastguard Worker 		memcpy(out_addr, &a,
251*4dc78e53SAndroid Build Coastguard Worker 		       addr_family == AF_INET ? sizeof(in_addr_t) :
252*4dc78e53SAndroid Build Coastguard Worker 						sizeof(struct in6_addr));
253*4dc78e53SAndroid Build Coastguard Worker 	}
254*4dc78e53SAndroid Build Coastguard Worker 	if (out_addr_family)
255*4dc78e53SAndroid Build Coastguard Worker 		*out_addr_family = addr_family;
256*4dc78e53SAndroid Build Coastguard Worker 
257*4dc78e53SAndroid Build Coastguard Worker 	return true;
258*4dc78e53SAndroid Build Coastguard Worker }
259*4dc78e53SAndroid Build Coastguard Worker 
_nltst_inet_valid(int addr_family,const char * addr)260*4dc78e53SAndroid Build Coastguard Worker static inline bool _nltst_inet_valid(int addr_family, const char *addr)
261*4dc78e53SAndroid Build Coastguard Worker {
262*4dc78e53SAndroid Build Coastguard Worker 	return _nltst_inet_pton(addr_family, addr, NULL, NULL);
263*4dc78e53SAndroid Build Coastguard Worker }
264*4dc78e53SAndroid Build Coastguard Worker 
_nltst_inet4(const char * addr)265*4dc78e53SAndroid Build Coastguard Worker static inline in_addr_t _nltst_inet4(const char *addr)
266*4dc78e53SAndroid Build Coastguard Worker {
267*4dc78e53SAndroid Build Coastguard Worker 	in_addr_t addr_bin = 0;
268*4dc78e53SAndroid Build Coastguard Worker 
269*4dc78e53SAndroid Build Coastguard Worker 	_nltst_assert(_nltst_inet_pton(AF_INET, addr, NULL, &addr_bin));
270*4dc78e53SAndroid Build Coastguard Worker 	return addr_bin;
271*4dc78e53SAndroid Build Coastguard Worker }
272*4dc78e53SAndroid Build Coastguard Worker 
_nltst_inet6p(const char * addr)273*4dc78e53SAndroid Build Coastguard Worker static inline struct in6_addr *_nltst_inet6p(const char *addr)
274*4dc78e53SAndroid Build Coastguard Worker {
275*4dc78e53SAndroid Build Coastguard Worker 	_nl_thread_local static struct in6_addr addr_bin;
276*4dc78e53SAndroid Build Coastguard Worker 
277*4dc78e53SAndroid Build Coastguard Worker 	ck_assert(_nltst_inet_pton(AF_INET6, addr, NULL, &addr_bin));
278*4dc78e53SAndroid Build Coastguard Worker 	return &addr_bin;
279*4dc78e53SAndroid Build Coastguard Worker }
280*4dc78e53SAndroid Build Coastguard Worker 
_nltst_inet6(const char * addr)281*4dc78e53SAndroid Build Coastguard Worker static inline struct in6_addr _nltst_inet6(const char *addr)
282*4dc78e53SAndroid Build Coastguard Worker {
283*4dc78e53SAndroid Build Coastguard Worker 	struct in6_addr addr_bin;
284*4dc78e53SAndroid Build Coastguard Worker 
285*4dc78e53SAndroid Build Coastguard Worker 	ck_assert(_nltst_inet_pton(AF_INET6, addr, NULL, &addr_bin));
286*4dc78e53SAndroid Build Coastguard Worker 	return addr_bin;
287*4dc78e53SAndroid Build Coastguard Worker }
288*4dc78e53SAndroid Build Coastguard Worker 
_nltst_inet_addr_family(int addr_family,const char * addr)289*4dc78e53SAndroid Build Coastguard Worker static inline int _nltst_inet_addr_family(int addr_family, const char *addr)
290*4dc78e53SAndroid Build Coastguard Worker {
291*4dc78e53SAndroid Build Coastguard Worker 	if (!_nltst_inet_pton(addr_family, addr, &addr_family, NULL))
292*4dc78e53SAndroid Build Coastguard Worker 		return AF_UNSPEC;
293*4dc78e53SAndroid Build Coastguard Worker 	return addr_family;
294*4dc78e53SAndroid Build Coastguard Worker }
295*4dc78e53SAndroid Build Coastguard Worker 
_nltst_inet_normalize(int addr_family,const char * addr,char buf[static INET_ADDRSTRLEN])296*4dc78e53SAndroid Build Coastguard Worker static inline char *_nltst_inet_normalize(int addr_family, const char *addr,
297*4dc78e53SAndroid Build Coastguard Worker 					  char buf[static INET_ADDRSTRLEN])
298*4dc78e53SAndroid Build Coastguard Worker {
299*4dc78e53SAndroid Build Coastguard Worker 	NLTstIPAddr a;
300*4dc78e53SAndroid Build Coastguard Worker 
301*4dc78e53SAndroid Build Coastguard Worker 	buf[0] = '\0';
302*4dc78e53SAndroid Build Coastguard Worker 	if (!_nltst_inet_pton(addr_family, addr, &addr_family, &a))
303*4dc78e53SAndroid Build Coastguard Worker 		return NULL;
304*4dc78e53SAndroid Build Coastguard Worker 	return _nltst_inet_ntop(addr_family, &a, buf);
305*4dc78e53SAndroid Build Coastguard Worker }
306*4dc78e53SAndroid Build Coastguard Worker 
307*4dc78e53SAndroid Build Coastguard Worker /*****************************************************************************/
308*4dc78e53SAndroid Build Coastguard Worker 
309*4dc78e53SAndroid Build Coastguard Worker char *_nltst_strtok(const char **p_str);
310*4dc78e53SAndroid Build Coastguard Worker 
311*4dc78e53SAndroid Build Coastguard Worker char **_nltst_strtokv(const char *str);
312*4dc78e53SAndroid Build Coastguard Worker 
313*4dc78e53SAndroid Build Coastguard Worker #define _nltst_assert_strv_equal(strv1, strv2)                            \
314*4dc78e53SAndroid Build Coastguard Worker 	do {                                                              \
315*4dc78e53SAndroid Build Coastguard Worker 		typeof(strv1) _strv1 = (strv1);                           \
316*4dc78e53SAndroid Build Coastguard Worker 		typeof(strv2) _strv2 = (strv2);                           \
317*4dc78e53SAndroid Build Coastguard Worker 		_nl_unused const void *_strv1_typecheck1 = _strv1;        \
318*4dc78e53SAndroid Build Coastguard Worker 		_nl_unused const void *_strv2_typecheck1 = _strv2;        \
319*4dc78e53SAndroid Build Coastguard Worker 		_nl_unused const char *_strv1_typecheck2 =                \
320*4dc78e53SAndroid Build Coastguard Worker 			_strv1 ? _strv1[0] : NULL;                        \
321*4dc78e53SAndroid Build Coastguard Worker 		_nl_unused const char *_strv2_typecheck2 =                \
322*4dc78e53SAndroid Build Coastguard Worker 			_strv2 ? _strv2[0] : NULL;                        \
323*4dc78e53SAndroid Build Coastguard Worker 		size_t _i;                                                \
324*4dc78e53SAndroid Build Coastguard Worker                                                                           \
325*4dc78e53SAndroid Build Coastguard Worker 		ck_assert_int_eq(!!_strv1, !!_strv2);                     \
326*4dc78e53SAndroid Build Coastguard Worker 		if (_strv1) {                                             \
327*4dc78e53SAndroid Build Coastguard Worker 			for (_i = 0; _strv1[_i] || _strv2[_i]; _i++) {    \
328*4dc78e53SAndroid Build Coastguard Worker 				ck_assert_str_eq(_strv1[_i], _strv2[_i]); \
329*4dc78e53SAndroid Build Coastguard Worker 			}                                                 \
330*4dc78e53SAndroid Build Coastguard Worker 		}                                                         \
331*4dc78e53SAndroid Build Coastguard Worker 	} while (0)
332*4dc78e53SAndroid Build Coastguard Worker 
333*4dc78e53SAndroid Build Coastguard Worker #define _NLTST_CHARSET_SPACE " \n\r\t"
334*4dc78e53SAndroid Build Coastguard Worker 
335*4dc78e53SAndroid Build Coastguard Worker #define _nltst_char_is(ch, charset) (!!(strchr("" charset "", (ch))))
336*4dc78e53SAndroid Build Coastguard Worker 
337*4dc78e53SAndroid Build Coastguard Worker #define _nltst_char_is_space(ch) _nltst_char_is(ch, _NLTST_CHARSET_SPACE)
338*4dc78e53SAndroid Build Coastguard Worker 
339*4dc78e53SAndroid Build Coastguard Worker #define _nltst_str_skip_predicate(s, ch, predicate)           \
340*4dc78e53SAndroid Build Coastguard Worker 	({                                                    \
341*4dc78e53SAndroid Build Coastguard Worker 		typeof(s) _s1 = (s);                          \
342*4dc78e53SAndroid Build Coastguard Worker 		_nl_unused const char *_s1_typecheck = (_s1); \
343*4dc78e53SAndroid Build Coastguard Worker                                                               \
344*4dc78e53SAndroid Build Coastguard Worker 		if (_s1) {                                    \
345*4dc78e53SAndroid Build Coastguard Worker 			while (({                             \
346*4dc78e53SAndroid Build Coastguard Worker 				const char ch = _s1[0];       \
347*4dc78e53SAndroid Build Coastguard Worker                                                               \
348*4dc78e53SAndroid Build Coastguard Worker 				(ch != '\0') && (predicate);  \
349*4dc78e53SAndroid Build Coastguard Worker 			}))                                   \
350*4dc78e53SAndroid Build Coastguard Worker 				_s1++;                        \
351*4dc78e53SAndroid Build Coastguard Worker 		}                                             \
352*4dc78e53SAndroid Build Coastguard Worker 		_s1;                                          \
353*4dc78e53SAndroid Build Coastguard Worker 	})
354*4dc78e53SAndroid Build Coastguard Worker 
355*4dc78e53SAndroid Build Coastguard Worker #define _nltst_str_skip_charset(s, charset) \
356*4dc78e53SAndroid Build Coastguard Worker 	_nltst_str_skip_predicate(s, _ch, _nltst_char_is(_ch, "" charset ""))
357*4dc78e53SAndroid Build Coastguard Worker 
358*4dc78e53SAndroid Build Coastguard Worker #define _nltst_str_skip_space(s) \
359*4dc78e53SAndroid Build Coastguard Worker 	_nltst_str_skip_charset(s, _NLTST_CHARSET_SPACE)
360*4dc78e53SAndroid Build Coastguard Worker 
361*4dc78e53SAndroid Build Coastguard Worker #define _nltst_str_has_prefix_and_space(s, prefix)                         \
362*4dc78e53SAndroid Build Coastguard Worker 	({                                                                 \
363*4dc78e53SAndroid Build Coastguard Worker 		typeof(s) _s2 = (s);                                       \
364*4dc78e53SAndroid Build Coastguard Worker 		_nl_unused const char *_s2_typecheck = (_s2);              \
365*4dc78e53SAndroid Build Coastguard Worker 		const size_t _l = strlen("" prefix "");                    \
366*4dc78e53SAndroid Build Coastguard Worker                                                                            \
367*4dc78e53SAndroid Build Coastguard Worker 		if (_s2) {                                                 \
368*4dc78e53SAndroid Build Coastguard Worker 			if ((strncmp(_s2, "" prefix "", _l)) == 0 &&       \
369*4dc78e53SAndroid Build Coastguard Worker 			    _nltst_char_is_space(_s2[_l]))                 \
370*4dc78e53SAndroid Build Coastguard Worker 				_s2 = _nltst_str_skip_space(&_s2[_l + 1]); \
371*4dc78e53SAndroid Build Coastguard Worker 			else                                               \
372*4dc78e53SAndroid Build Coastguard Worker 				_s2 = NULL;                                \
373*4dc78e53SAndroid Build Coastguard Worker 		}                                                          \
374*4dc78e53SAndroid Build Coastguard Worker 		_s2;                                                       \
375*4dc78e53SAndroid Build Coastguard Worker 	})
376*4dc78e53SAndroid Build Coastguard Worker 
377*4dc78e53SAndroid Build Coastguard Worker #define _nltst_str_find_first_not_from_charset(s, charset)    \
378*4dc78e53SAndroid Build Coastguard Worker 	({                                                    \
379*4dc78e53SAndroid Build Coastguard Worker 		typeof(s) _s3 = (s);                          \
380*4dc78e53SAndroid Build Coastguard Worker 		_nl_unused const char *_s3_typecheck = (_s3); \
381*4dc78e53SAndroid Build Coastguard Worker 		size_t _l3;                                   \
382*4dc78e53SAndroid Build Coastguard Worker                                                               \
383*4dc78e53SAndroid Build Coastguard Worker 		_l3 = strspn(_s3, "" charset "");             \
384*4dc78e53SAndroid Build Coastguard Worker                                                               \
385*4dc78e53SAndroid Build Coastguard Worker 		&_s3[_l3];                                    \
386*4dc78e53SAndroid Build Coastguard Worker 	})
387*4dc78e53SAndroid Build Coastguard Worker 
388*4dc78e53SAndroid Build Coastguard Worker #define _nltst_str_find_first_from_charset(s, charset)        \
389*4dc78e53SAndroid Build Coastguard Worker 	({                                                    \
390*4dc78e53SAndroid Build Coastguard Worker 		typeof(s) _s3 = (s);                          \
391*4dc78e53SAndroid Build Coastguard Worker 		_nl_unused const char *_s3_typecheck = (_s3); \
392*4dc78e53SAndroid Build Coastguard Worker 		size_t _l3;                                   \
393*4dc78e53SAndroid Build Coastguard Worker                                                               \
394*4dc78e53SAndroid Build Coastguard Worker 		_l3 = strcspn(_s3, "" charset "");            \
395*4dc78e53SAndroid Build Coastguard Worker                                                               \
396*4dc78e53SAndroid Build Coastguard Worker 		&_s3[_l3];                                    \
397*4dc78e53SAndroid Build Coastguard Worker 	})
398*4dc78e53SAndroid Build Coastguard Worker 
399*4dc78e53SAndroid Build Coastguard Worker /*****************************************************************************/
400*4dc78e53SAndroid Build Coastguard Worker 
401*4dc78e53SAndroid Build Coastguard Worker void nltst_netns_fixture_setup(void);
402*4dc78e53SAndroid Build Coastguard Worker void nltst_netns_fixture_teardown(void);
403*4dc78e53SAndroid Build Coastguard Worker 
404*4dc78e53SAndroid Build Coastguard Worker struct nltst_netns;
405*4dc78e53SAndroid Build Coastguard Worker 
406*4dc78e53SAndroid Build Coastguard Worker struct nltst_netns *nltst_netns_enter(void);
407*4dc78e53SAndroid Build Coastguard Worker void nltst_netns_leave(struct nltst_netns *nsdata);
408*4dc78e53SAndroid Build Coastguard Worker 
409*4dc78e53SAndroid Build Coastguard Worker /*****************************************************************************/
410*4dc78e53SAndroid Build Coastguard Worker 
411*4dc78e53SAndroid Build Coastguard Worker #define _nltst_system(command) _nltst_assert_retcode(system(command))
412*4dc78e53SAndroid Build Coastguard Worker 
413*4dc78e53SAndroid Build Coastguard Worker bool _nltst_in_ci(void);
414*4dc78e53SAndroid Build Coastguard Worker 
415*4dc78e53SAndroid Build Coastguard Worker bool _nltst_has_iproute2(void);
416*4dc78e53SAndroid Build Coastguard Worker bool _nltst_skip_no_iproute2(const char *msg);
417*4dc78e53SAndroid Build Coastguard Worker 
418*4dc78e53SAndroid Build Coastguard Worker /*****************************************************************************/
419*4dc78e53SAndroid Build Coastguard Worker 
420*4dc78e53SAndroid Build Coastguard Worker typedef struct {
421*4dc78e53SAndroid Build Coastguard Worker 	int addr_family;
422*4dc78e53SAndroid Build Coastguard Worker 	int ifindex;
423*4dc78e53SAndroid Build Coastguard Worker 	int plen;
424*4dc78e53SAndroid Build Coastguard Worker 	char *addr;
425*4dc78e53SAndroid Build Coastguard Worker 	char *addr_pattern;
426*4dc78e53SAndroid Build Coastguard Worker } NLTstSelectRoute;
427*4dc78e53SAndroid Build Coastguard Worker 
428*4dc78e53SAndroid Build Coastguard Worker #define _nltst_assert_select_route(select_route)                             \
429*4dc78e53SAndroid Build Coastguard Worker 	do {                                                                 \
430*4dc78e53SAndroid Build Coastguard Worker 		const NLTstSelectRoute *_select_route_5 = (select_route);    \
431*4dc78e53SAndroid Build Coastguard Worker                                                                              \
432*4dc78e53SAndroid Build Coastguard Worker 		ck_assert_ptr_nonnull(_select_route_5);                      \
433*4dc78e53SAndroid Build Coastguard Worker 		_nl_assert_addr_family_or_unspec(                            \
434*4dc78e53SAndroid Build Coastguard Worker 			_select_route_5->addr_family);                       \
435*4dc78e53SAndroid Build Coastguard Worker 		ck_assert_int_ge(_select_route_5->ifindex, 0);               \
436*4dc78e53SAndroid Build Coastguard Worker 		ck_assert_int_ge(_select_route_5->plen, -1);                 \
437*4dc78e53SAndroid Build Coastguard Worker 		ck_assert_int_le(                                            \
438*4dc78e53SAndroid Build Coastguard Worker 			_select_route_5->plen,                               \
439*4dc78e53SAndroid Build Coastguard Worker 			_select_route_5->addr_family == AF_INET ? 32 : 128); \
440*4dc78e53SAndroid Build Coastguard Worker 		ck_assert(!_select_route_5->addr || ({                       \
441*4dc78e53SAndroid Build Coastguard Worker 			char _buf[INET6_ADDRSTRLEN];                         \
442*4dc78e53SAndroid Build Coastguard Worker 			const char *_s2;                                     \
443*4dc78e53SAndroid Build Coastguard Worker                                                                              \
444*4dc78e53SAndroid Build Coastguard Worker 			_s2 = _nltst_inet_normalize(                         \
445*4dc78e53SAndroid Build Coastguard Worker 				_select_route_5->addr_family,                \
446*4dc78e53SAndroid Build Coastguard Worker 				_select_route_5->addr, _buf);                \
447*4dc78e53SAndroid Build Coastguard Worker 			(_select_route_5->addr_family != AF_UNSPEC && _s2 && \
448*4dc78e53SAndroid Build Coastguard Worker 			 _nl_streq(_s2, _select_route_5->addr));             \
449*4dc78e53SAndroid Build Coastguard Worker 		}));                                                         \
450*4dc78e53SAndroid Build Coastguard Worker 		ck_assert(!_select_route_5->addr_pattern ||                  \
451*4dc78e53SAndroid Build Coastguard Worker 			  !_select_route_5->addr);                           \
452*4dc78e53SAndroid Build Coastguard Worker 		ck_assert(!_select_route_5->addr_pattern ||                  \
453*4dc78e53SAndroid Build Coastguard Worker 			  _select_route_5->addr_family != AF_UNSPEC);        \
454*4dc78e53SAndroid Build Coastguard Worker 	} while (0)
455*4dc78e53SAndroid Build Coastguard Worker 
456*4dc78e53SAndroid Build Coastguard Worker void _nltst_select_route_clear(NLTstSelectRoute *select_route);
457*4dc78e53SAndroid Build Coastguard Worker 
458*4dc78e53SAndroid Build Coastguard Worker #define _nltst_auto_clear_select_route \
459*4dc78e53SAndroid Build Coastguard Worker 	_nl_auto(_nltst_auto_clear_select_route_fcn)
460*4dc78e53SAndroid Build Coastguard Worker _NL_AUTO_DEFINE_FCN_STRUCT(NLTstSelectRoute, _nltst_auto_clear_select_route_fcn,
461*4dc78e53SAndroid Build Coastguard Worker 			   _nltst_select_route_clear);
462*4dc78e53SAndroid Build Coastguard Worker 
463*4dc78e53SAndroid Build Coastguard Worker int _nltst_select_route_cmp(const NLTstSelectRoute *select_route1,
464*4dc78e53SAndroid Build Coastguard Worker 			    const NLTstSelectRoute *select_route2);
465*4dc78e53SAndroid Build Coastguard Worker 
466*4dc78e53SAndroid Build Coastguard Worker static inline bool
_nltst_select_route_equal(const NLTstSelectRoute * select_route1,const NLTstSelectRoute * select_route2)467*4dc78e53SAndroid Build Coastguard Worker _nltst_select_route_equal(const NLTstSelectRoute *select_route1,
468*4dc78e53SAndroid Build Coastguard Worker 			  const NLTstSelectRoute *select_route2)
469*4dc78e53SAndroid Build Coastguard Worker {
470*4dc78e53SAndroid Build Coastguard Worker 	return _nltst_select_route_cmp(select_route1, select_route2) == 0;
471*4dc78e53SAndroid Build Coastguard Worker }
472*4dc78e53SAndroid Build Coastguard Worker 
473*4dc78e53SAndroid Build Coastguard Worker char *_nltst_select_route_to_string(const NLTstSelectRoute *select_route);
474*4dc78e53SAndroid Build Coastguard Worker 
475*4dc78e53SAndroid Build Coastguard Worker void _nltst_select_route_parse(const char *str,
476*4dc78e53SAndroid Build Coastguard Worker 			       NLTstSelectRoute *out_select_route);
477*4dc78e53SAndroid Build Coastguard Worker 
478*4dc78e53SAndroid Build Coastguard Worker bool _nltst_select_route_match(struct nl_object *route,
479*4dc78e53SAndroid Build Coastguard Worker 			       const NLTstSelectRoute *select_route,
480*4dc78e53SAndroid Build Coastguard Worker 			       bool do_assert);
481*4dc78e53SAndroid Build Coastguard Worker 
482*4dc78e53SAndroid Build Coastguard Worker /*****************************************************************************/
483*4dc78e53SAndroid Build Coastguard Worker 
484*4dc78e53SAndroid Build Coastguard Worker void _nltst_object_identical(const void *a, const void *b);
485*4dc78e53SAndroid Build Coastguard Worker 
486*4dc78e53SAndroid Build Coastguard Worker char *_nltst_object_to_string(const struct nl_object *obj);
487*4dc78e53SAndroid Build Coastguard Worker 
488*4dc78e53SAndroid Build Coastguard Worker struct nl_object **_nltst_cache_get_all(struct nl_cache *cache,
489*4dc78e53SAndroid Build Coastguard Worker 					size_t *out_len);
490*4dc78e53SAndroid Build Coastguard Worker 
491*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link *_nltst_cache_get_link(struct nl_cache *cache,
492*4dc78e53SAndroid Build Coastguard Worker 					const char *ifname);
493*4dc78e53SAndroid Build Coastguard Worker 
494*4dc78e53SAndroid Build Coastguard Worker struct nl_cache *_nltst_rtnl_link_alloc_cache(struct nl_sock *sk,
495*4dc78e53SAndroid Build Coastguard Worker 					      int addr_family, unsigned flags);
496*4dc78e53SAndroid Build Coastguard Worker 
497*4dc78e53SAndroid Build Coastguard Worker struct nl_cache *_nltst_rtnl_route_alloc_cache(struct nl_sock *sk,
498*4dc78e53SAndroid Build Coastguard Worker 					       int addr_family);
499*4dc78e53SAndroid Build Coastguard Worker 
500*4dc78e53SAndroid Build Coastguard Worker struct nl_sock *_nltst_socket(int protocol);
501*4dc78e53SAndroid Build Coastguard Worker 
502*4dc78e53SAndroid Build Coastguard Worker void _nltst_add_link(struct nl_sock *sk, const char *ifname, const char *kind,
503*4dc78e53SAndroid Build Coastguard Worker 		     int *out_ifindex);
504*4dc78e53SAndroid Build Coastguard Worker 
505*4dc78e53SAndroid Build Coastguard Worker void _nltst_delete_link(struct nl_sock *sk, const char *ifname);
506*4dc78e53SAndroid Build Coastguard Worker 
507*4dc78e53SAndroid Build Coastguard Worker void _nltst_get_link(struct nl_sock *sk, const char *ifname, int *out_ifindex,
508*4dc78e53SAndroid Build Coastguard Worker 		     struct rtnl_link **out_link);
509*4dc78e53SAndroid Build Coastguard Worker 
510*4dc78e53SAndroid Build Coastguard Worker void _nltst_assert_route_list(struct nl_object *const *objs, ssize_t len,
511*4dc78e53SAndroid Build Coastguard Worker 			      const char *const *expected_routes);
512*4dc78e53SAndroid Build Coastguard Worker 
513*4dc78e53SAndroid Build Coastguard Worker void _nltst_assert_route_cache_v(struct nl_cache *cache,
514*4dc78e53SAndroid Build Coastguard Worker 				 const char *const *expected_routes);
515*4dc78e53SAndroid Build Coastguard Worker 
516*4dc78e53SAndroid Build Coastguard Worker #define _nltst_assert_route_cache(cache, ...) \
517*4dc78e53SAndroid Build Coastguard Worker 	_nltst_assert_route_cache_v(cache,    \
518*4dc78e53SAndroid Build Coastguard Worker 				    ((const char *const[200]){ __VA_ARGS__ }))
519*4dc78e53SAndroid Build Coastguard Worker 
520*4dc78e53SAndroid Build Coastguard Worker #endif /* __NL_TEST_UTIL_H__ */
521