1 /* SPDX-License-Identifier: LGPL-2.1-only */
2
3 #include "nl-default.h"
4
5 #include <check.h>
6
7 #include <linux/snmp.h>
8 #include <linux/if_bridge.h>
9
10 #include <netlink/route/link.h>
11 #include <netlink/route/link/bridge.h>
12
13 #include "nl-priv-static-route/nl-priv-static-route.h"
14 #include "nl-aux-core/nl-core.h"
15
16 #define CASES 5
17 #define MAX_ATTR 7
18
START_TEST(static_checks)19 START_TEST(static_checks)
20 {
21 int i, j;
22 char strbuf[100];
23
24 _NL_STATIC_ASSERT(RTNL_LINK_RX_PACKETS == 0);
25 assert(_nltst_map_stat_id_from_IPSTATS_MIB_v2[0] ==
26 RTNL_LINK_RX_PACKETS);
27 for (i = 1; i < __IPSTATS_MIB_MAX; i++) {
28 assert(_nltst_map_stat_id_from_IPSTATS_MIB_v2[i] > 0);
29 assert(_nltst_map_stat_id_from_IPSTATS_MIB_v2[i] <
30 __RTNL_LINK_STATS_MAX);
31 for (j = 1; j < i; j++)
32 assert(_nltst_map_stat_id_from_IPSTATS_MIB_v2[i] !=
33 _nltst_map_stat_id_from_IPSTATS_MIB_v2[j]);
34 }
35
36 for (i = 0; i <= RTNL_LINK_STATS_MAX + 1; i++) {
37 const char *s;
38
39 s = rtnl_link_stat2str(i, strbuf, sizeof(strbuf));
40 assert(s);
41 assert(s == strbuf);
42 assert(strlen(s) < sizeof(strbuf));
43 if (strncmp(s, "0x", 2) == 0) {
44 assert(i == RTNL_LINK_STATS_MAX + 1);
45 ck_assert_int_eq(strtoll(&s[2], NULL, 16), i);
46 } else
47 ck_assert_int_le(i, RTNL_LINK_STATS_MAX);
48 ck_assert_int_eq(i, rtnl_link_str2stat(s));
49 }
50
51 ck_assert_int_eq(nl_str2ip_proto(""), -NLE_OBJ_NOTFOUND);
52 ck_assert_int_eq(nl_str2ip_proto("5"), 5);
53 ck_assert_int_eq(nl_str2ip_proto(" 13 "), -NLE_OBJ_NOTFOUND);
54 ck_assert_int_eq(nl_str2ip_proto("13"), 13);
55 ck_assert_int_eq(nl_str2ip_proto("0x13"), 0x13);
56 ck_assert_int_eq(nl_str2ip_proto("0342"), 0342);
57 ck_assert_int_eq(nl_str2ip_proto("2147483647"), 2147483647);
58 ck_assert_int_eq(nl_str2ip_proto("2147483648"), -NLE_OBJ_NOTFOUND);
59 }
60 END_TEST
61
set_bitmap_range(u_int32_t start,u_int32_t end,struct rtnl_link_bridge_vlan * vlan_info,int untagged)62 static void set_bitmap_range(u_int32_t start, u_int32_t end,
63 struct rtnl_link_bridge_vlan *vlan_info,
64 int untagged)
65 {
66 for (u_int32_t i = start; i <= end; i++) {
67 vlan_info->vlan_bitmap[i / 32] |= (((uint32_t)1) << (i % 32));
68 if (untagged) {
69 vlan_info->untagged_bitmap[i / 32] |=
70 (((uint32_t)1) << (i % 32));
71 }
72 }
73 }
74
START_TEST(vlan_attribute_check)75 START_TEST(vlan_attribute_check)
76 {
77 struct nlmsghdr *nlh;
78 struct nlattr *a;
79 int attr_count, rem;
80 struct bridge_vlan_info *vlan_attr;
81 struct rtnl_link_bridge_vlan vlan_info[CASES];
82 struct bridge_vlan_info expected_attr[CASES][MAX_ATTR];
83
84 for (int i = 0; i < CASES; i++) {
85 memset(&vlan_info[i], 0, sizeof(struct rtnl_link_bridge_vlan));
86 memset(&expected_attr[i], 0,
87 sizeof(struct bridge_vlan_info) * MAX_ATTR);
88 }
89
90 // Case 1 setting pvid untagged.
91 vlan_info[0].pvid = 1;
92 set_bitmap_range(1, 1, &vlan_info[0], 1);
93 expected_attr[0][0].vid = 1;
94 expected_attr[0][0].flags = BRIDGE_VLAN_INFO_PVID |
95 BRIDGE_VLAN_INFO_UNTAGGED;
96
97 // Case 2 setting vid range.
98 vlan_info[1].pvid = 0;
99 set_bitmap_range(1, 4094, &vlan_info[1], 0);
100 expected_attr[1][0].vid = 1;
101 expected_attr[1][0].flags = BRIDGE_VLAN_INFO_RANGE_BEGIN;
102 expected_attr[1][1].vid = 4094;
103 expected_attr[1][1].flags = BRIDGE_VLAN_INFO_RANGE_END;
104
105 // Case 3 interweaving pvid with vid range.
106 vlan_info[2].pvid = 7;
107 set_bitmap_range(1, 27, &vlan_info[2], 0);
108 set_bitmap_range(7, 7, &vlan_info[2], 1);
109 expected_attr[2][0].vid = 1;
110 expected_attr[2][0].flags = BRIDGE_VLAN_INFO_RANGE_BEGIN;
111 expected_attr[2][1].vid = 6;
112 expected_attr[2][1].flags = BRIDGE_VLAN_INFO_RANGE_END;
113 expected_attr[2][2].vid = 8;
114 expected_attr[2][2].flags = BRIDGE_VLAN_INFO_RANGE_BEGIN;
115 expected_attr[2][3].vid = 27;
116 expected_attr[2][3].flags = BRIDGE_VLAN_INFO_RANGE_END;
117 expected_attr[2][4].vid = 7;
118 expected_attr[2][4].flags = BRIDGE_VLAN_INFO_PVID |
119 BRIDGE_VLAN_INFO_UNTAGGED;
120
121 // Case 4 interweaving untagged and tagged vid ranges.
122 vlan_info[3].pvid = 1;
123 set_bitmap_range(1, 1, &vlan_info[3], 1);
124 set_bitmap_range(1, 25, &vlan_info[3], 0);
125 set_bitmap_range(26, 50, &vlan_info[3], 1);
126 set_bitmap_range(51, 75, &vlan_info[3], 0);
127 expected_attr[3][0].vid = 2;
128 expected_attr[3][0].flags = BRIDGE_VLAN_INFO_RANGE_BEGIN;
129 expected_attr[3][1].vid = 25;
130 expected_attr[3][1].flags = BRIDGE_VLAN_INFO_RANGE_END;
131 expected_attr[3][2].vid = 26;
132 expected_attr[3][2].flags = BRIDGE_VLAN_INFO_RANGE_BEGIN |
133 BRIDGE_VLAN_INFO_UNTAGGED;
134 expected_attr[3][3].vid = 50;
135 expected_attr[3][3].flags = BRIDGE_VLAN_INFO_RANGE_END |
136 BRIDGE_VLAN_INFO_UNTAGGED;
137 expected_attr[3][4].vid = 51;
138 expected_attr[3][4].flags = BRIDGE_VLAN_INFO_RANGE_BEGIN;
139 expected_attr[3][5].vid = 75;
140 expected_attr[3][5].flags = BRIDGE_VLAN_INFO_RANGE_END;
141 expected_attr[3][6].vid = 1;
142 expected_attr[3][6].flags = BRIDGE_VLAN_INFO_PVID |
143 BRIDGE_VLAN_INFO_UNTAGGED;
144
145 // Case 5 individual vid.
146 vlan_info[4].pvid = 0;
147 set_bitmap_range(5, 5, &vlan_info[4], 0);
148 set_bitmap_range(3067, 3067, &vlan_info[4], 1);
149 expected_attr[4][0].vid = 5;
150 expected_attr[4][0].flags = 0;
151 expected_attr[4][1].vid = 3067;
152 expected_attr[4][1].flags = BRIDGE_VLAN_INFO_UNTAGGED;
153
154 for (int i = 0; i < CASES; i++) {
155 _nl_auto_nl_msg struct nl_msg *msg = nlmsg_alloc();
156 attr_count = 0;
157 ck_assert_msg(msg, "Unable to allocate netlink message");
158 ck_assert_int_eq(0,
159 _nl_bridge_fill_vlan_info(msg, &vlan_info[i]));
160
161 nlh = nlmsg_hdr(msg);
162
163 nlmsg_for_each_attr(a, nlh, 0, rem) {
164 ck_assert_msg(expected_attr[i][attr_count].vid != 0,
165 "Attribute number %d unexpected",
166 attr_count);
167 ck_assert_msg(
168 nla_type(a) == IFLA_BRIDGE_VLAN_INFO,
169 "Expected attribute IFLA_BRIDGE_VLAN_INFO %d",
170 IFLA_BRIDGE_VLAN_INFO);
171 vlan_attr = (struct bridge_vlan_info *)nla_data(a);
172 ck_assert_int_eq(vlan_attr->vid,
173 expected_attr[i][attr_count].vid);
174 ck_assert_int_eq(vlan_attr->flags,
175 expected_attr[i][attr_count].flags);
176 attr_count++;
177 }
178 }
179 }
180 END_TEST
181
make_suite(void)182 static Suite *make_suite(void)
183 {
184 Suite *suite = suite_create("Direct");
185 TCase *tc = tcase_create("Core");
186
187 tcase_add_test(tc, static_checks);
188 tcase_add_test(tc, vlan_attribute_check);
189 suite_add_tcase(suite, tc);
190 return suite;
191 }
192
main(int argc,char * argv[])193 int main(int argc, char *argv[])
194 {
195 SRunner *runner;
196 int nfailed;
197
198 runner = srunner_create(suite_create("main"));
199
200 srunner_add_suite(runner, make_suite());
201
202 srunner_run_all(runner, CK_ENV);
203
204 nfailed = srunner_ntests_failed(runner);
205 srunner_free(runner);
206 return nfailed != 0;
207 }
208