xref: /aosp_15_r20/external/libnl/tests/cksuite-all-attr.c (revision 4dc78e53d49367fa8e61b07018507c90983a077d)
1 /* SPDX-License-Identifier: LGPL-2.1-only */
2 /*
3  * Copyright (c) 2013 Thomas Graf <[email protected]>
4  */
5 
6 #include "nl-default.h"
7 
8 #include <linux/netlink.h>
9 #include <linux/if_ether.h>
10 
11 #include <netlink/attr.h>
12 #include <netlink/msg.h>
13 #include <netlink/route/cls/u32.h>
14 
15 #include "cksuite-all.h"
16 #include "nl-aux-route/nl-route.h"
17 
START_TEST(attr_size)18 START_TEST(attr_size)
19 {
20 	ck_assert_msg(nla_attr_size(0) == NLA_HDRLEN,
21 		      "Length of empty attribute should match header size");
22 	ck_assert_msg(nla_attr_size(1) == NLA_HDRLEN + 1,
23 		      "Length of 1 bytes payload should be NLA_HDRLEN + 1");
24 	ck_assert_msg(nla_attr_size(2) == NLA_HDRLEN + 2,
25 		      "Length of 2 bytes payload should be NLA_HDRLEN + 2");
26 	ck_assert_msg(nla_attr_size(3) == NLA_HDRLEN + 3,
27 		      "Length of 3 bytes payload should be NLA_HDRLEN + 3");
28 	ck_assert_msg(nla_attr_size(4) == NLA_HDRLEN + 4,
29 		      "Length of 4 bytes payload should be NLA_HDRLEN + 4");
30 
31 	ck_assert_msg(nla_total_size(1) == NLA_HDRLEN + 4,
32 		      "Total size of 1 bytes payload should result in 8 bytes");
33 	ck_assert_msg(nla_total_size(2) == NLA_HDRLEN + 4,
34 		      "Total size of 2 bytes payload should result in 8 bytes");
35 	ck_assert_msg(nla_total_size(3) == NLA_HDRLEN + 4,
36 		      "Total size of 3 bytes payload should result in 8 bytes");
37 	ck_assert_msg(nla_total_size(4) == NLA_HDRLEN + 4,
38 		      "Total size of 4 bytes payload should result in 8 bytes");
39 
40 	ck_assert_msg(nla_padlen(1) == 3,
41 		      "2 bytes of payload should result in 3 padding bytes");
42 	ck_assert_msg(nla_padlen(2) == 2,
43 		      "2 bytes of payload should result in 2 padding bytes");
44 	ck_assert_msg(nla_padlen(3) == 1,
45 		      "3 bytes of payload should result in 1 padding bytes");
46 	ck_assert_msg(nla_padlen(4) == 0,
47 		      "4 bytes of payload should result in 0 padding bytes");
48 	ck_assert_msg(nla_padlen(5) == 3,
49 		      "5 bytes of payload should result in 3 padding bytes");
50 }
51 END_TEST
52 
START_TEST(msg_construct)53 START_TEST(msg_construct)
54 {
55 	struct nl_msg *msg;
56 	struct nlmsghdr *nlh;
57 	struct nlattr *a;
58 	int i, rem;
59 
60 	msg = nlmsg_alloc();
61 	ck_assert_msg(msg, "Unable to allocate netlink message");
62 
63 	for (i = 1; i < 256; i++) {
64 		ck_assert_msg(nla_put_u32(msg, i, i + 1) == 0,
65 			      "Unable to add attribute %d", i);
66 	}
67 
68 	nlh = nlmsg_hdr(msg);
69 	i = 1;
70 	nlmsg_for_each_attr(a, nlh, 0, rem) {
71 		ck_assert_msg(nla_type(a) == i, "Expected attribute %d", i);
72 		i++;
73 		ck_assert_msg(nla_get_u32(a) == (unsigned)i,
74 			      "Expected attribute value %d", i);
75 	}
76 
77 	nlmsg_free(msg);
78 }
79 END_TEST
80 
START_TEST(clone_cls_u32)81 START_TEST(clone_cls_u32)
82 {
83 	_nl_auto_rtnl_link struct rtnl_link *link = NULL;
84 	_nl_auto_rtnl_cls struct rtnl_cls *cls = NULL;
85 	_nl_auto_rtnl_cls struct rtnl_cls *cls2 = NULL;
86 	int r;
87 	const uint32_t direction = 16;
88 
89 	link = rtnl_link_alloc();
90 	ck_assert(link);
91 
92 	rtnl_link_set_ifindex(link, 5);
93 
94 	cls = rtnl_cls_alloc();
95 	ck_assert(cls);
96 
97 	rtnl_tc_set_link(TC_CAST(cls), link);
98 
99 	r = rtnl_tc_set_kind(TC_CAST(cls), "u32");
100 	ck_assert(r == 0);
101 
102 	rtnl_cls_set_prio(cls, 1);
103 	rtnl_cls_set_protocol(cls, ETH_P_IP);
104 
105 	rtnl_tc_set_parent(TC_CAST(cls), TC_HANDLE(1, 0));
106 
107 	rtnl_u32_set_hashtable(cls, 5);
108 
109 	rtnl_u32_add_key_uint32(cls, 0x0a000914, 0xffffffff, direction, 0);
110 
111 	rtnl_u32_set_hashmask(cls, 0xff000000, direction);
112 
113 	rtnl_u32_add_mark(cls, 55, 66);
114 
115 	rtnl_u32_set_link(cls, 44);
116 
117 	cls2 = (struct rtnl_cls *)nl_object_clone((struct nl_object *)cls);
118 	ck_assert(cls2);
119 }
120 END_TEST
121 
122 /*****************************************************************************/
123 
START_TEST(test_nltst_strtok)124 START_TEST(test_nltst_strtok)
125 {
126 #define _assert_strtok(str, ...)                                               \
127 	do {                                                                   \
128 		const char *const _expected[] = { NULL, ##__VA_ARGS__, NULL }; \
129 		_nltst_auto_strfreev char **_tokens = NULL;                    \
130                                                                                \
131 		_tokens = _nltst_strtokv(str);                                 \
132 		_nltst_assert_strv_equal(_tokens, &_expected[1]);              \
133 	} while (0)
134 
135 	_assert_strtok("");
136 	_assert_strtok("    \n");
137 	_assert_strtok("a", "a");
138 	_assert_strtok(" a ", "a");
139 	_assert_strtok(" a\\  b", "a\\ ", "b");
140 	_assert_strtok(" a\\  b   cc\\d", "a\\ ", "b", "cc\\d");
141 	_assert_strtok(" a\\  b\\   cc\\d", "a\\ ", "b\\ ", "cc\\d");
142 }
143 END_TEST
144 
145 /*****************************************************************************/
146 
START_TEST(test_nltst_select_route)147 START_TEST(test_nltst_select_route)
148 {
149 	/* This is a unit test for testing the unit-test helper function
150 	 * _nltst_select_route_parse(). */
151 
152 #define _check(str, exp_addr_family, exp_addr_pattern, exp_plen)               \
153 	do {                                                                   \
154 		const char *_str = (str);                                      \
155 		const int _exp_addr_family = (exp_addr_family);                \
156 		const char *const _exp_addr_pattern = (exp_addr_pattern);      \
157 		const int _exp_plen = (exp_plen);                              \
158 		_nltst_auto_clear_select_route NLTstSelectRoute                \
159 			_select_route = { 0 };                                 \
160 		_nltst_auto_clear_select_route NLTstSelectRoute                \
161 			_select_route2 = { 0 };                                \
162 		_nl_auto_free char *_str2 = NULL;                              \
163                                                                                \
164 		_nltst_select_route_parse(_str, &_select_route);               \
165 		ck_assert_int_eq(_exp_addr_family, _select_route.addr_family); \
166 		if (_nltst_inet_valid(AF_UNSPEC, _exp_addr_pattern)) {         \
167 			ck_assert_str_eq(_exp_addr_pattern,                    \
168 					 _select_route.addr);                  \
169 			ck_assert_ptr_null(_select_route.addr_pattern);        \
170 		} else {                                                       \
171 			ck_assert_str_eq(_exp_addr_pattern,                    \
172 					 _select_route.addr_pattern);          \
173 			ck_assert_ptr_null(_select_route.addr);                \
174 		}                                                              \
175 		ck_assert_int_eq(_exp_plen, _select_route.plen);               \
176                                                                                \
177 		_nltst_assert_select_route(&_select_route);                    \
178                                                                                \
179 		_str2 = _nltst_select_route_to_string(&_select_route);         \
180 		ck_assert_ptr_nonnull(_str2);                                  \
181                                                                                \
182 		_nltst_select_route_parse(_str2, &_select_route2);             \
183                                                                                \
184 		ck_assert(_nltst_select_route_equal(&_select_route,            \
185 						    &_select_route2));         \
186 	} while (0)
187 
188 	_check("0.0.0.0", AF_INET, "0.0.0.0", -1);
189 	_check("4 0.0.0.0/0", AF_INET, "0.0.0.0", 0);
190 	_check(" 6\n 0:0::/0", AF_INET6, "::", 0);
191 	_check(" \n 0:0::/100", AF_INET6, "::", 100);
192 	_check("6 0:0::*/0   ", AF_INET6, "0:0::*", 0);
193 	_check("6 0:0::*/128   ", AF_INET6, "0:0::*", 128);
194 	_check("6 0:0::*   ", AF_INET6, "0:0::*", -1);
195 
196 #undef _check
197 }
198 
199 /*****************************************************************************/
200 
make_nl_attr_suite(void)201 Suite *make_nl_attr_suite(void)
202 {
203 	Suite *suite = suite_create("Netlink attributes");
204 	TCase *tc = tcase_create("Core");
205 
206 	tcase_add_test(tc, attr_size);
207 	tcase_add_test(tc, msg_construct);
208 	tcase_add_test(tc, clone_cls_u32);
209 	tcase_add_test(tc, test_nltst_strtok);
210 	tcase_add_test(tc, test_nltst_select_route);
211 	suite_add_tcase(suite, tc);
212 
213 	return suite;
214 }
215