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