• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: LGPL-2.1-only */
2 /*
3  * Copyright (c) 2013 Thomas Graf <tgraf@suug.ch>
4  */
5 
6 #include <linux/netlink.h>
7 #include <linux/if_ether.h>
8 
9 #include "cksuite-all.h"
10 #include "netlink/attr.h"
11 #include "netlink/msg.h"
12 #include "netlink/route/cls/u32.h"
13 #include "netlink-private/route/tc-api.h"
14 #include "netlink-private/nl-auto.h"
15 
START_TEST(attr_size)16 START_TEST(attr_size)
17 {
18 	ck_assert_msg(nla_attr_size(0) == NLA_HDRLEN,
19 		      "Length of empty attribute should match header size");
20 	ck_assert_msg(nla_attr_size(1) == NLA_HDRLEN + 1,
21 		      "Length of 1 bytes payload should be NLA_HDRLEN + 1");
22 	ck_assert_msg(nla_attr_size(2) == NLA_HDRLEN + 2,
23 		      "Length of 2 bytes payload should be NLA_HDRLEN + 2");
24 	ck_assert_msg(nla_attr_size(3) == NLA_HDRLEN + 3,
25 		      "Length of 3 bytes payload should be NLA_HDRLEN + 3");
26 	ck_assert_msg(nla_attr_size(4) == NLA_HDRLEN + 4,
27 		      "Length of 4 bytes payload should be NLA_HDRLEN + 4");
28 
29 	ck_assert_msg(nla_total_size(1) == NLA_HDRLEN + 4,
30 		      "Total size of 1 bytes payload should result in 8 bytes");
31 	ck_assert_msg(nla_total_size(2) == NLA_HDRLEN + 4,
32 		      "Total size of 2 bytes payload should result in 8 bytes");
33 	ck_assert_msg(nla_total_size(3) == NLA_HDRLEN + 4,
34 		      "Total size of 3 bytes payload should result in 8 bytes");
35 	ck_assert_msg(nla_total_size(4) == NLA_HDRLEN + 4,
36 		      "Total size of 4 bytes payload should result in 8 bytes");
37 
38 	ck_assert_msg(nla_padlen(1) == 3,
39 		      "2 bytes of payload should result in 3 padding bytes");
40 	ck_assert_msg(nla_padlen(2) == 2,
41 		      "2 bytes of payload should result in 2 padding bytes");
42 	ck_assert_msg(nla_padlen(3) == 1,
43 		      "3 bytes of payload should result in 1 padding bytes");
44 	ck_assert_msg(nla_padlen(4) == 0,
45 		      "4 bytes of payload should result in 0 padding bytes");
46 	ck_assert_msg(nla_padlen(5) == 3,
47 		      "5 bytes of payload should result in 3 padding bytes");
48 }
49 END_TEST
50 
START_TEST(msg_construct)51 START_TEST(msg_construct)
52 {
53 	struct nl_msg *msg;
54 	struct nlmsghdr *nlh;
55 	struct nlattr *a;
56 	int i, rem;
57 
58 	msg = nlmsg_alloc();
59 	ck_assert_msg(msg, "Unable to allocate netlink message");
60 
61 	for (i = 1; i < 256; i++) {
62 		ck_assert_msg(nla_put_u32(msg, i, i + 1) == 0,
63 			      "Unable to add attribute %d", i);
64 	}
65 
66 	nlh = nlmsg_hdr(msg);
67 	i = 1;
68 	nlmsg_for_each_attr (a, nlh, 0, rem) {
69 		ck_assert_msg(nla_type(a) == i, "Expected attribute %d", i);
70 		i++;
71 		ck_assert_msg(nla_get_u32(a) == i,
72 			      "Expected attribute value %d", i);
73 	}
74 
75 	nlmsg_free(msg);
76 }
77 END_TEST
78 
START_TEST(clone_cls_u32)79 START_TEST(clone_cls_u32)
80 {
81 	_nl_auto_rtnl_link struct rtnl_link *link = NULL;
82 	_nl_auto_rtnl_cls struct rtnl_cls *cls = NULL;
83 	_nl_auto_rtnl_cls struct rtnl_cls *cls2 = NULL;
84 	int r;
85 	const uint32_t direction = 16;
86 
87 	link = rtnl_link_alloc();
88 	ck_assert(link);
89 
90 	rtnl_link_set_ifindex(link, 5);
91 
92 	cls = rtnl_cls_alloc();
93 	ck_assert(cls);
94 
95 	rtnl_tc_set_link(TC_CAST(cls), link);
96 
97 	r = rtnl_tc_set_kind(TC_CAST(cls), "u32");
98 	ck_assert(r == 0);
99 
100 	rtnl_cls_set_prio(cls, 1);
101 	rtnl_cls_set_protocol(cls, ETH_P_IP);
102 
103 	rtnl_tc_set_parent(TC_CAST(cls), TC_HANDLE(1, 0));
104 
105 	rtnl_u32_set_hashtable(cls, 5);
106 
107 	rtnl_u32_add_key_uint32(cls, 0x0a000914, 0xffffffff, direction, 0);
108 
109 	rtnl_u32_set_hashmask(cls, 0xff000000, direction);
110 
111 	rtnl_u32_add_mark(cls, 55, 66);
112 
113 	rtnl_u32_set_link(cls, 44);
114 
115 	cls2 = (struct rtnl_cls *)nl_object_clone((struct nl_object *)cls);
116 	ck_assert(cls2);
117 }
118 END_TEST
119 
120 /*****************************************************************************/
121 
START_TEST(test_nltst_strtok)122 START_TEST(test_nltst_strtok)
123 {
124 #define _assert_strtok(str, ...)                                               \
125 	do {                                                                   \
126 		const char *const _expected[] = { NULL, ##__VA_ARGS__, NULL }; \
127 		_nltst_auto_strfreev char **_tokens = NULL;                    \
128                                                                                \
129 		_tokens = _nltst_strtokv(str);                                 \
130 		_nltst_assert_strv_equal(_tokens, &_expected[1]);              \
131 	} while (0)
132 
133 	_assert_strtok("");
134 	_assert_strtok("    \n");
135 	_assert_strtok("a", "a");
136 	_assert_strtok(" a ", "a");
137 	_assert_strtok(" a\\  b", "a\\ ", "b");
138 	_assert_strtok(" a\\  b   cc\\d", "a\\ ", "b", "cc\\d");
139 	_assert_strtok(" a\\  b\\   cc\\d", "a\\ ", "b\\ ", "cc\\d");
140 }
141 END_TEST
142 
143 /*****************************************************************************/
144 
make_nl_attr_suite(void)145 Suite *make_nl_attr_suite(void)
146 {
147 	Suite *suite = suite_create("Netlink attributes");
148 	TCase *tc = tcase_create("Core");
149 
150 	tcase_add_test(tc, attr_size);
151 	tcase_add_test(tc, msg_construct);
152 	tcase_add_test(tc, clone_cls_u32);
153 	tcase_add_test(tc, test_nltst_strtok);
154 	suite_add_tcase(suite, tc);
155 
156 	return suite;
157 }
158