1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4
5 #include <sys/param.h>
6 #include <sys/module.h>
7
8 #include <net/ethernet.h>
9
10 #include <netlink/netlink.h>
11 #include <netlink/netlink_route.h>
12 #include "netlink/netlink_snl.h"
13 #include "netlink/netlink_snl_route.h"
14 #include "netlink/netlink_snl_route_parsers.h"
15
16 #include <atf-c.h>
17
18 static const struct snl_hdr_parser *snl_all_core_parsers[] = {
19 &snl_errmsg_parser, &snl_donemsg_parser,
20 &_nla_bit_parser, &_nla_bitset_parser,
21 };
22
23 static const struct snl_hdr_parser *snl_all_route_parsers[] = {
24 &_metrics_mp_nh_parser, &_mpath_nh_parser, &_metrics_parser, &snl_rtm_route_parser,
25 &_vf_driver_field_parser, &_vf_driver_parser, &_vf_parser,
26 &_vf_status_parser,
27 &_link_fbsd_parser, &snl_rtm_link_parser, &snl_rtm_link_parser_simple,
28 &_neigh_fbsd_parser, &snl_rtm_neigh_parser,
29 &_addr_fbsd_parser, &snl_rtm_addr_parser, &_nh_fbsd_parser, &snl_nhmsg_parser,
30 };
31
32 ATF_TC(snl_verify_core_parsers);
ATF_TC_HEAD(snl_verify_core_parsers,tc)33 ATF_TC_HEAD(snl_verify_core_parsers, tc)
34 {
35 atf_tc_set_md_var(tc, "descr", "Tests snl(3) core nlmsg parsers are correct");
36 }
37
ATF_TC_BODY(snl_verify_core_parsers,tc)38 ATF_TC_BODY(snl_verify_core_parsers, tc)
39 {
40 SNL_VERIFY_PARSERS(snl_all_core_parsers);
41
42 }
43
44 ATF_TC(snl_parse_bitset_array);
ATF_TC_HEAD(snl_parse_bitset_array,tc)45 ATF_TC_HEAD(snl_parse_bitset_array, tc)
46 {
47 atf_tc_set_md_var(tc, "descr",
48 "Tests snl(3) parsing a growing nested bit array");
49 atf_tc_set_md_var(tc, "require.kmods", "netlink");
50 }
51
ATF_TC_BODY(snl_parse_bitset_array,tc)52 ATF_TC_BODY(snl_parse_bitset_array, tc)
53 {
54 struct snl_attr_bit *bit;
55 struct snl_parsed_link link = {};
56 struct snl_state ss;
57 struct snl_writer nw;
58 struct nlmsghdr *hdr;
59 uint32_t mask, value;
60 char name[16];
61 int bits_off, entry_off, fbsd_off, caps_off;
62
63 ATF_REQUIRE(snl_init(&ss, NETLINK_ROUTE));
64 snl_init_writer(&ss, &nw);
65 hdr = snl_create_msg_request(&nw, RTM_NEWLINK);
66 ATF_REQUIRE(hdr != NULL);
67 ATF_REQUIRE(snl_reserve_msg_object(&nw, struct ifinfomsg) != NULL);
68
69 fbsd_off = snl_add_msg_attr_nested(&nw, IFLA_FREEBSD);
70 ATF_REQUIRE(fbsd_off != 0);
71 caps_off = snl_add_msg_attr_nested(&nw, IFLAF_CAPS);
72 ATF_REQUIRE(caps_off != 0);
73 ATF_REQUIRE(snl_add_msg_attr_u32(&nw, NLA_BITSET_SIZE, 32));
74 mask = 0x1ff;
75 value = 0x155;
76 ATF_REQUIRE(snl_add_msg_attr(&nw, NLA_BITSET_MASK, sizeof(mask),
77 &mask));
78 ATF_REQUIRE(snl_add_msg_attr(&nw, NLA_BITSET_VALUE, sizeof(value),
79 &value));
80 bits_off = snl_add_msg_attr_nested(&nw, NLA_BITSET_BITS);
81 ATF_REQUIRE(bits_off != 0);
82 for (uint32_t i = 0; i < 9; i++) {
83 entry_off = snl_add_msg_attr_nested(&nw, i + 1);
84 ATF_REQUIRE(entry_off != 0);
85 ATF_REQUIRE(snl_add_msg_attr_u32(&nw,
86 NLA_BITSET_BIT_INDEX, i));
87 snprintf(name, sizeof(name), "bit-%u", i);
88 ATF_REQUIRE(snl_add_msg_attr_string(&nw,
89 NLA_BITSET_BIT_NAME, name));
90 if ((i & 1) == 0)
91 ATF_REQUIRE(snl_add_msg_attr_flag(&nw,
92 NLA_BITSET_BIT_VALUE));
93 snl_end_attr_nested(&nw, entry_off);
94 }
95 snl_end_attr_nested(&nw, bits_off);
96 snl_end_attr_nested(&nw, caps_off);
97 snl_end_attr_nested(&nw, fbsd_off);
98 hdr = snl_finalize_msg(&nw);
99 ATF_REQUIRE(hdr != NULL);
100
101 ATF_REQUIRE(snl_parse_nlmsg(&ss, hdr, &snl_rtm_link_parser, &link));
102 ATF_REQUIRE_EQ(link.iflaf_caps.bits.count, 9);
103 bit = link.iflaf_caps.bits.items[8];
104 ATF_CHECK_EQ(bit->bit_index, 8);
105 ATF_CHECK_STREQ(bit->bit_name, "bit-8");
106 ATF_CHECK_EQ(bit->bit_value, 1);
107 }
108
109 ATF_TC(snl_parse_vf_status);
ATF_TC_HEAD(snl_parse_vf_status,tc)110 ATF_TC_HEAD(snl_parse_vf_status, tc)
111 {
112 atf_tc_set_md_var(tc, "descr",
113 "Tests snl(3) parsing nested VF status");
114 atf_tc_set_md_var(tc, "require.kmods", "netlink");
115 }
116
ATF_TC_BODY(snl_parse_vf_status,tc)117 ATF_TC_BODY(snl_parse_vf_status, tc)
118 {
119 static const uint8_t mac[] = { 0x02, 0, 0, 0, 0, 1 };
120 static const uint8_t extension_data[] = { 1, 2, 3, 4 };
121 struct snl_parsed_vf_driver_field *field;
122 struct snl_parsed_vf_driver *driver;
123 struct snl_parsed_vf_status *status;
124 struct snl_parsed_link link = {};
125 struct snl_parsed_vf *vf;
126 struct snl_state ss;
127 struct snl_writer nw;
128 struct nlmsghdr *hdr;
129 uint32_t i;
130 int driver_off, entry_off, fbsd_off, field_off, status_off;
131
132 ATF_REQUIRE(snl_init(&ss, NETLINK_ROUTE));
133 snl_init_writer(&ss, &nw);
134 hdr = snl_create_msg_request(&nw, RTM_NEWLINK);
135 ATF_REQUIRE(hdr != NULL);
136 ATF_REQUIRE(snl_reserve_msg_object(&nw, struct ifinfomsg) != NULL);
137 ATF_REQUIRE(snl_add_msg_attr_u32(&nw, IFLA_NUM_VF, 9));
138
139 fbsd_off = snl_add_msg_attr_nested(&nw, IFLA_FREEBSD);
140 ATF_REQUIRE(fbsd_off != 0);
141 status_off = snl_add_msg_attr_nested(&nw, IFLAF_VF_STATUS);
142 ATF_REQUIRE(status_off != 0);
143 ATF_REQUIRE(snl_add_msg_attr_u8(&nw, IFLAF_VFS_PF_LINK_STATE,
144 IFLAF_VF_LINK_UP));
145 ATF_REQUIRE(snl_add_msg_attr_u64(&nw, IFLAF_VFS_PF_LINK_SPEED,
146 10000000000ULL));
147 snl_end_attr_nested(&nw, status_off);
148 snl_end_attr_nested(&nw, fbsd_off);
149
150 entry_off = snl_add_msg_attr_nested(&nw, IFLA_FREEBSD_VF);
151 ATF_REQUIRE(entry_off != 0);
152 ATF_REQUIRE(snl_add_msg_attr_u32(&nw, IFLAF_VF_INDEX, 7));
153 ATF_REQUIRE(snl_add_msg_attr_bool(&nw, IFLAF_VF_CONFIGURED, true));
154 ATF_REQUIRE(snl_add_msg_attr_bool(&nw, IFLAF_VF_TRAFFIC_ALLOWED,
155 true));
156 ATF_REQUIRE(snl_add_msg_attr_bool(&nw, IFLAF_VF_FAULT_BLOCKED,
157 false));
158 ATF_REQUIRE(snl_add_msg_attr_u16(&nw, IFLAF_VF_NUM_TX_QUEUES, 4));
159 ATF_REQUIRE(snl_add_msg_attr_u16(&nw, IFLAF_VF_NUM_RX_QUEUES, 8));
160 ATF_REQUIRE(snl_add_msg_attr_u64(&nw, IFLAF_VF_MIN_TX_RATE,
161 25000000000ULL));
162 ATF_REQUIRE(snl_add_msg_attr_u64(&nw, IFLAF_VF_MAX_TX_RATE,
163 100000000000ULL));
164 ATF_REQUIRE(snl_add_msg_attr_u8(&nw, IFLAF_VF_VLAN_MODE,
165 IFLAF_VF_VLAN_ACCESS));
166 ATF_REQUIRE(snl_add_msg_attr_u16(&nw, IFLAF_VF_VLAN, 0));
167 ATF_REQUIRE(snl_add_msg_attr_u8(&nw, IFLAF_VF_VLAN_PCP, 5));
168 ATF_REQUIRE(snl_add_msg_attr_u16(&nw, IFLAF_VF_VLAN_PROTO,
169 ETHERTYPE_VLAN));
170 ATF_REQUIRE(snl_add_msg_attr(&nw, IFLAF_VF_MAC, sizeof(mac), mac));
171
172 driver_off = snl_add_msg_attr_nested(&nw, IFLAF_VF_DRIVER);
173 ATF_REQUIRE(driver_off != 0);
174 ATF_REQUIRE(snl_add_msg_attr_string(&nw, IFLAF_VFD_NAME,
175 "driver.test"));
176 ATF_REQUIRE(snl_add_msg_attr_u32(&nw, IFLAF_VFD_VERSION, 3));
177 field_off = snl_add_msg_attr_nested(&nw, IFLAF_VFD_FIELD);
178 ATF_REQUIRE(field_off != 0);
179 ATF_REQUIRE(snl_add_msg_attr_string(&nw, IFLAF_VFDF_NAME,
180 "ready"));
181 ATF_REQUIRE(snl_add_msg_attr_bool(&nw, IFLAF_VFDF_BOOL, false));
182 snl_end_attr_nested(&nw, field_off);
183 field_off = snl_add_msg_attr_nested(&nw, IFLAF_VFD_FIELD);
184 ATF_REQUIRE(field_off != 0);
185 ATF_REQUIRE(snl_add_msg_attr_string(&nw, IFLAF_VFDF_NAME,
186 "opaque"));
187 ATF_REQUIRE(snl_add_msg_attr(&nw, IFLAF_VFDF_BINARY,
188 sizeof(extension_data), extension_data));
189 snl_end_attr_nested(&nw, field_off);
190 field_off = snl_add_msg_attr_nested(&nw, IFLAF_VFD_FIELD);
191 ATF_REQUIRE(field_off != 0);
192 ATF_REQUIRE(snl_add_msg_attr_string(&nw, IFLAF_VFDF_NAME,
193 "sequence"));
194 ATF_REQUIRE(snl_add_msg_attr_u64(&nw, IFLAF_VFDF_NUMBER,
195 0x100000002ULL));
196 snl_end_attr_nested(&nw, field_off);
197 field_off = snl_add_msg_attr_nested(&nw, IFLAF_VFD_FIELD);
198 ATF_REQUIRE(field_off != 0);
199 ATF_REQUIRE(snl_add_msg_attr_string(&nw, IFLAF_VFDF_NAME,
200 "mode"));
201 ATF_REQUIRE(snl_add_msg_attr_string(&nw, IFLAF_VFDF_STRING,
202 "diagnostic"));
203 snl_end_attr_nested(&nw, field_off);
204 /* A newer field value type must not hide fields known to this parser. */
205 field_off = snl_add_msg_attr_nested(&nw, IFLAF_VFD_FIELD);
206 ATF_REQUIRE(field_off != 0);
207 ATF_REQUIRE(snl_add_msg_attr_string(&nw, IFLAF_VFDF_NAME,
208 "future-value"));
209 ATF_REQUIRE(snl_add_msg_attr_u32(&nw, IFLAF_VFDF_MAX + 1, 1));
210 snl_end_attr_nested(&nw, field_off);
211 snl_end_attr_nested(&nw, driver_off);
212 snl_end_attr_nested(&nw, entry_off);
213
214 /* A second attribute of the same type is the second array member. */
215 entry_off = snl_add_msg_attr_nested(&nw, IFLA_FREEBSD_VF);
216 ATF_REQUIRE(entry_off != 0);
217 ATF_REQUIRE(snl_add_msg_attr_u32(&nw, IFLAF_VF_INDEX, 8));
218 ATF_REQUIRE(snl_add_msg_attr_bool(&nw, IFLAF_VF_CONFIGURED, false));
219 ATF_REQUIRE(snl_add_msg_attr_u64(&nw, IFLAF_VF_MIN_TX_RATE, 0));
220 ATF_REQUIRE(snl_add_msg_attr_u64(&nw, IFLAF_VF_MAX_TX_RATE, 0));
221 snl_end_attr_nested(&nw, entry_off);
222 /* Cross the parser array's initial capacity to exercise growth. */
223 for (i = 9; i <= 15; i++) {
224 entry_off = snl_add_msg_attr_nested(&nw, IFLA_FREEBSD_VF);
225 ATF_REQUIRE(entry_off != 0);
226 ATF_REQUIRE(snl_add_msg_attr_u32(&nw, IFLAF_VF_INDEX, i));
227 snl_end_attr_nested(&nw, entry_off);
228 }
229 hdr = snl_finalize_msg(&nw);
230 ATF_REQUIRE(hdr != NULL);
231
232 ATF_REQUIRE(snl_parse_nlmsg(&ss, hdr, &snl_rtm_link_parser, &link));
233 ATF_CHECK_EQ(link.ifla_num_vf, 9);
234 status = &link.iflaf_vf_status;
235 ATF_CHECK(status->present);
236 ATF_CHECK_EQ(status->pf_link_state, IFLAF_VF_LINK_UP);
237 ATF_CHECK_EQ(status->pf_link_speed, 10000000000ULL);
238 ATF_REQUIRE_EQ(status->vfs.count, 9);
239 vf = status->vfs.items[0];
240 ATF_CHECK_EQ(vf->index, 7);
241 ATF_CHECK_EQ(vf->configured, 1);
242 ATF_CHECK((vf->attrs & (1ULL << IFLAF_VF_TRAFFIC_ALLOWED)) != 0);
243 ATF_CHECK_EQ(vf->traffic_allowed, true);
244 ATF_CHECK((vf->attrs & (1ULL << IFLAF_VF_FAULT_BLOCKED)) != 0);
245 ATF_CHECK_EQ(vf->fault_blocked, false);
246 ATF_CHECK((vf->attrs & (1ULL << IFLAF_VF_NUM_TX_QUEUES)) != 0);
247 ATF_CHECK_EQ(vf->tx_queue_count, 4);
248 ATF_CHECK((vf->attrs & (1ULL << IFLAF_VF_NUM_RX_QUEUES)) != 0);
249 ATF_CHECK_EQ(vf->rx_queue_count, 8);
250 ATF_CHECK((vf->attrs & (1ULL << IFLAF_VF_MIN_TX_RATE)) != 0);
251 ATF_CHECK_EQ(vf->min_tx_rate_bps, 25000000000ULL);
252 ATF_CHECK((vf->attrs & (1ULL << IFLAF_VF_MAX_TX_RATE)) != 0);
253 ATF_CHECK_EQ(vf->max_tx_rate_bps, 100000000000ULL);
254 ATF_CHECK((vf->attrs & (1ULL << IFLAF_VF_VLAN_MODE)) != 0);
255 ATF_CHECK_EQ(vf->vlan_mode, IFLAF_VF_VLAN_ACCESS);
256 ATF_CHECK((vf->attrs & (1ULL << IFLAF_VF_VLAN)) != 0);
257 ATF_CHECK_EQ(vf->vlan, 0);
258 ATF_CHECK((vf->attrs & (1ULL << IFLAF_VF_VLAN_PCP)) != 0);
259 ATF_CHECK_EQ(vf->vlan_pcp, 5);
260 ATF_CHECK((vf->attrs & (1ULL << IFLAF_VF_VLAN_PROTO)) != 0);
261 ATF_CHECK_EQ(vf->vlan_proto, ETHERTYPE_VLAN);
262 ATF_REQUIRE(vf->mac != NULL);
263 ATF_CHECK_EQ(NLA_DATA_LEN(vf->mac), sizeof(mac));
264 ATF_CHECK(memcmp(NLA_DATA(vf->mac), mac, sizeof(mac)) == 0);
265 ATF_REQUIRE_EQ(vf->drivers.count, 1);
266 driver = vf->drivers.items[0];
267 ATF_CHECK_STREQ(driver->name, "driver.test");
268 ATF_CHECK_EQ(driver->version, 3);
269 ATF_REQUIRE_EQ(driver->fields.count, 4);
270 field = driver->fields.items[0];
271 ATF_CHECK_STREQ(field->name, "ready");
272 ATF_CHECK_EQ(field->type, SNL_VFDF_BOOL);
273 ATF_CHECK_EQ(field->boolean, false);
274 field = driver->fields.items[1];
275 ATF_CHECK_STREQ(field->name, "opaque");
276 ATF_CHECK_EQ(field->type, SNL_VFDF_BINARY);
277 ATF_REQUIRE(field->binary != NULL);
278 ATF_CHECK_EQ(NLA_DATA_LEN(field->binary), sizeof(extension_data));
279 ATF_CHECK(memcmp(NLA_DATA(field->binary), extension_data,
280 sizeof(extension_data)) == 0);
281 field = driver->fields.items[2];
282 ATF_CHECK_STREQ(field->name, "sequence");
283 ATF_CHECK_EQ(field->type, SNL_VFDF_NUMBER);
284 ATF_CHECK_EQ(field->number, 0x100000002ULL);
285 field = driver->fields.items[3];
286 ATF_CHECK_STREQ(field->name, "mode");
287 ATF_CHECK_EQ(field->type, SNL_VFDF_STRING);
288 ATF_CHECK_STREQ(field->string, "diagnostic");
289 vf = status->vfs.items[1];
290 ATF_CHECK_EQ(vf->index, 8);
291 ATF_CHECK_EQ(vf->configured, false);
292 ATF_CHECK((vf->attrs & (1ULL << IFLAF_VF_MIN_TX_RATE)) != 0);
293 ATF_CHECK_EQ(vf->min_tx_rate_bps, 0);
294 ATF_CHECK((vf->attrs & (1ULL << IFLAF_VF_MAX_TX_RATE)) != 0);
295 ATF_CHECK_EQ(vf->max_tx_rate_bps, 0);
296 vf = status->vfs.items[8];
297 ATF_CHECK_EQ(vf->index, 15);
298 }
299
300 ATF_TC(snl_parse_vf_trunk_pcp);
ATF_TC_HEAD(snl_parse_vf_trunk_pcp,tc)301 ATF_TC_HEAD(snl_parse_vf_trunk_pcp, tc)
302 {
303 atf_tc_set_md_var(tc, "descr",
304 "Tests snl(3) parsing trunk PCP values and omitted priority");
305 atf_tc_set_md_var(tc, "require.kmods", "netlink");
306 }
307
ATF_TC_BODY(snl_parse_vf_trunk_pcp,tc)308 ATF_TC_BODY(snl_parse_vf_trunk_pcp, tc)
309 {
310 struct snl_parsed_link link = {};
311 struct snl_parsed_vf *vf;
312 struct snl_state ss;
313 struct snl_writer nw;
314 struct nlmsghdr *hdr;
315 uint32_t i;
316 int entry_off;
317
318 ATF_REQUIRE(snl_init(&ss, NETLINK_ROUTE));
319 snl_init_writer(&ss, &nw);
320 hdr = snl_create_msg_request(&nw, RTM_NEWLINK);
321 ATF_REQUIRE(hdr != NULL);
322 ATF_REQUIRE(snl_reserve_msg_object(&nw, struct ifinfomsg) != NULL);
323 ATF_REQUIRE(snl_add_msg_attr_u32(&nw, IFLA_NUM_VF, 9));
324 for (i = 0; i < 9; i++) {
325 entry_off = snl_add_msg_attr_nested(&nw, IFLA_FREEBSD_VF);
326 ATF_REQUIRE(entry_off != 0);
327 ATF_REQUIRE(snl_add_msg_attr_u32(&nw, IFLAF_VF_INDEX, i));
328 ATF_REQUIRE(snl_add_msg_attr_u8(&nw, IFLAF_VF_VLAN_MODE,
329 IFLAF_VF_VLAN_TRUNK));
330 /* Cover PCP 0..7 and absence, without an imposed VLAN. */
331 if (i < 8)
332 ATF_REQUIRE(snl_add_msg_attr_u8(&nw, IFLAF_VF_VLAN_PCP,
333 i));
334 snl_end_attr_nested(&nw, entry_off);
335 }
336 hdr = snl_finalize_msg(&nw);
337 ATF_REQUIRE(hdr != NULL);
338 ATF_REQUIRE(snl_parse_nlmsg(&ss, hdr, &snl_rtm_link_parser, &link));
339 ATF_CHECK_EQ(link.ifla_num_vf, 9);
340 ATF_REQUIRE_EQ(link.iflaf_vf_status.vfs.count, 9);
341 for (i = 0; i < 9; i++) {
342 vf = link.iflaf_vf_status.vfs.items[i];
343 ATF_CHECK_EQ(vf->index, i);
344 ATF_CHECK((vf->attrs & (1ULL << IFLAF_VF_VLAN_MODE)) != 0);
345 ATF_CHECK_EQ(vf->vlan_mode, IFLAF_VF_VLAN_TRUNK);
346 ATF_CHECK((vf->attrs & ((1ULL << IFLAF_VF_VLAN) |
347 (1ULL << IFLAF_VF_VLAN_PROTO))) == 0);
348 ATF_CHECK_EQ((vf->attrs & (1ULL << IFLAF_VF_VLAN_PCP)) != 0,
349 i < 8);
350 if (i < 8)
351 ATF_CHECK_EQ(vf->vlan_pcp, i);
352 }
353 snl_free(&ss);
354 }
355
356 ATF_TC(snl_parse_large_vf_status);
ATF_TC_HEAD(snl_parse_large_vf_status,tc)357 ATF_TC_HEAD(snl_parse_large_vf_status, tc)
358 {
359 atf_tc_set_md_var(tc, "descr",
360 "Tests snl(3) parsing more than 256 full VF records");
361 atf_tc_set_md_var(tc, "require.kmods", "netlink");
362 }
363
ATF_TC_BODY(snl_parse_large_vf_status,tc)364 ATF_TC_BODY(snl_parse_large_vf_status, tc)
365 {
366 static const char *field_names[] = {
367 "mirror-configured",
368 "mirror-ingress-active",
369 "mirror-egress-active",
370 };
371 static const uint32_t vf_count = 512;
372 struct snl_parsed_vf_driver *driver;
373 struct snl_parsed_vf_status *status;
374 struct snl_parsed_link link = {};
375 struct snl_parsed_vf *vf;
376 struct snl_state ss;
377 struct snl_writer nw;
378 struct nlmsghdr *hdr;
379 uint8_t mac[ETHER_ADDR_LEN] = { 0x02, 0, 0, 0, 0, 0 };
380 uint32_t i, j;
381 int driver_off, entry_off, fbsd_off, field_off, status_off;
382
383 ATF_REQUIRE(snl_init(&ss, NETLINK_ROUTE));
384 snl_init_writer(&ss, &nw);
385 hdr = snl_create_msg_request(&nw, RTM_NEWLINK);
386 ATF_REQUIRE(hdr != NULL);
387 ATF_REQUIRE(snl_reserve_msg_object(&nw, struct ifinfomsg) != NULL);
388 ATF_REQUIRE(snl_add_msg_attr_u32(&nw, IFLA_NUM_VF, vf_count));
389 fbsd_off = snl_add_msg_attr_nested(&nw, IFLA_FREEBSD);
390 ATF_REQUIRE(fbsd_off != 0);
391 status_off = snl_add_msg_attr_nested(&nw, IFLAF_VF_STATUS);
392 ATF_REQUIRE(status_off != 0);
393 ATF_REQUIRE(snl_add_msg_attr_u8(&nw, IFLAF_VFS_PF_LINK_STATE,
394 IFLAF_VF_LINK_UP));
395 ATF_REQUIRE(snl_add_msg_attr_u64(&nw, IFLAF_VFS_PF_LINK_SPEED,
396 100000000000ULL));
397 snl_end_attr_nested(&nw, status_off);
398 snl_end_attr_nested(&nw, fbsd_off);
399
400 for (i = 0; i < vf_count; i++) {
401 mac[4] = i >> 8;
402 mac[5] = i;
403 entry_off = snl_add_msg_attr_nested(&nw, IFLA_FREEBSD_VF);
404 ATF_REQUIRE(entry_off != 0);
405 ATF_REQUIRE(snl_add_msg_attr_u32(&nw, IFLAF_VF_INDEX, i));
406 ATF_REQUIRE(snl_add_msg_attr_bool(&nw, IFLAF_VF_CONFIGURED,
407 true));
408 ATF_REQUIRE(snl_add_msg_attr_bool(&nw, IFLAF_VF_INITIALIZED,
409 true));
410 ATF_REQUIRE(snl_add_msg_attr(&nw, IFLAF_VF_MAC, sizeof(mac),
411 mac));
412 ATF_REQUIRE(snl_add_msg_attr_u8(&nw, IFLAF_VF_VLAN_MODE,
413 IFLAF_VF_VLAN_ACCESS));
414 ATF_REQUIRE(snl_add_msg_attr_u16(&nw, IFLAF_VF_VLAN,
415 i & EVL_VLID_MASK));
416 ATF_REQUIRE(snl_add_msg_attr_u8(&nw, IFLAF_VF_VLAN_PCP,
417 i & 7));
418 ATF_REQUIRE(snl_add_msg_attr_u16(&nw, IFLAF_VF_VLAN_PROTO,
419 ETHERTYPE_VLAN));
420 ATF_REQUIRE(snl_add_msg_attr_u32(&nw, IFLAF_VF_VLAN_COUNT,
421 1));
422 ATF_REQUIRE(snl_add_msg_attr_u32(&nw, IFLAF_VF_VLAN_LIMIT,
423 16));
424 ATF_REQUIRE(snl_add_msg_attr_u16(&nw,
425 IFLAF_VF_NUM_TX_QUEUES, 4));
426 ATF_REQUIRE(snl_add_msg_attr_u16(&nw,
427 IFLAF_VF_NUM_RX_QUEUES, 4));
428 ATF_REQUIRE(snl_add_msg_attr_u64(&nw, IFLAF_VF_MIN_TX_RATE,
429 1000000000ULL));
430 ATF_REQUIRE(snl_add_msg_attr_u64(&nw, IFLAF_VF_MAX_TX_RATE,
431 10000000000ULL));
432 ATF_REQUIRE(snl_add_msg_attr_bool(&nw, IFLAF_VF_ALLOW_SET_MAC,
433 true));
434 ATF_REQUIRE(snl_add_msg_attr_bool(&nw,
435 IFLAF_VF_ALLOW_SET_VLAN, true));
436 ATF_REQUIRE(snl_add_msg_attr_bool(&nw,
437 IFLAF_VF_MAC_ANTI_SPOOF, true));
438 ATF_REQUIRE(snl_add_msg_attr_bool(&nw, IFLAF_VF_ALLOW_PROMISC,
439 false));
440 ATF_REQUIRE(snl_add_msg_attr_bool(&nw,
441 IFLAF_VF_TRAFFIC_ALLOWED, true));
442 ATF_REQUIRE(snl_add_msg_attr_bool(&nw,
443 IFLAF_VF_FAULT_BLOCKED, false));
444 ATF_REQUIRE(snl_add_msg_attr_bool(&nw, IFLAF_VF_QUARANTINED,
445 false));
446 ATF_REQUIRE(snl_add_msg_attr_string(&nw,
447 IFLAF_VF_API_VERSION, "1.1"));
448 ATF_REQUIRE(snl_add_msg_attr_u8(&nw,
449 IFLAF_VF_LINK_STATE_POLICY, IFLAF_VF_LINK_AUTO));
450
451 driver_off = snl_add_msg_attr_nested(&nw, IFLAF_VF_DRIVER);
452 ATF_REQUIRE(driver_off != 0);
453 ATF_REQUIRE(snl_add_msg_attr_string(&nw, IFLAF_VFD_NAME,
454 "driver.ice"));
455 ATF_REQUIRE(snl_add_msg_attr_u32(&nw, IFLAF_VFD_VERSION, 1));
456 for (j = 0; j < nitems(field_names); j++) {
457 field_off = snl_add_msg_attr_nested(&nw,
458 IFLAF_VFD_FIELD);
459 ATF_REQUIRE(field_off != 0);
460 ATF_REQUIRE(snl_add_msg_attr_string(&nw,
461 IFLAF_VFDF_NAME, field_names[j]));
462 ATF_REQUIRE(snl_add_msg_attr_bool(&nw,
463 IFLAF_VFDF_BOOL, false));
464 snl_end_attr_nested(&nw, field_off);
465 }
466 snl_end_attr_nested(&nw, driver_off);
467 snl_end_attr_nested(&nw, entry_off);
468 }
469 hdr = snl_finalize_msg(&nw);
470 ATF_REQUIRE(hdr != NULL);
471 ATF_REQUIRE_MSG(hdr->nlmsg_len > UINT16_MAX,
472 "test message is only %u bytes", hdr->nlmsg_len);
473
474 ATF_REQUIRE(snl_parse_nlmsg(&ss, hdr, &snl_rtm_link_parser, &link));
475 ATF_CHECK_EQ(link.ifla_num_vf, vf_count);
476 status = &link.iflaf_vf_status;
477 ATF_CHECK(status->present);
478 ATF_REQUIRE_EQ(status->vfs.count, vf_count);
479 vf = status->vfs.items[0];
480 ATF_CHECK_EQ(vf->index, 0);
481 vf = status->vfs.items[vf_count - 1];
482 ATF_CHECK_EQ(vf->index, vf_count - 1);
483 ATF_CHECK_EQ(vf->tx_queue_count, 4);
484 ATF_CHECK_EQ(vf->rx_queue_count, 4);
485 ATF_REQUIRE_EQ(vf->drivers.count, 1);
486 driver = vf->drivers.items[0];
487 ATF_CHECK_STREQ(driver->name, "driver.ice");
488 ATF_CHECK_EQ(driver->fields.count, nitems(field_names));
489 }
490
491 ATF_TC(snl_parse_empty_vf_status);
ATF_TC_HEAD(snl_parse_empty_vf_status,tc)492 ATF_TC_HEAD(snl_parse_empty_vf_status, tc)
493 {
494 atf_tc_set_md_var(tc, "descr",
495 "Tests snl(3) parsing an empty VF status snapshot");
496 atf_tc_set_md_var(tc, "require.kmods", "netlink");
497 }
498
ATF_TC_BODY(snl_parse_empty_vf_status,tc)499 ATF_TC_BODY(snl_parse_empty_vf_status, tc)
500 {
501 struct snl_parsed_link link = {};
502 struct snl_state ss;
503 struct snl_writer nw;
504 struct nlmsghdr *hdr;
505 int fbsd_off, status_off;
506
507 ATF_REQUIRE(snl_init(&ss, NETLINK_ROUTE));
508 snl_init_writer(&ss, &nw);
509 hdr = snl_create_msg_request(&nw, RTM_NEWLINK);
510 ATF_REQUIRE(hdr != NULL);
511 ATF_REQUIRE(snl_reserve_msg_object(&nw, struct ifinfomsg) != NULL);
512 ATF_REQUIRE(snl_add_msg_attr_u32(&nw, IFLA_NUM_VF, 0));
513 fbsd_off = snl_add_msg_attr_nested(&nw, IFLA_FREEBSD);
514 ATF_REQUIRE(fbsd_off != 0);
515 status_off = snl_add_msg_attr_nested(&nw, IFLAF_VF_STATUS);
516 ATF_REQUIRE(status_off != 0);
517 ATF_REQUIRE(snl_add_msg_attr_u8(&nw, IFLAF_VFS_PF_LINK_STATE,
518 IFLAF_VF_LINK_DOWN));
519 snl_end_attr_nested(&nw, status_off);
520 snl_end_attr_nested(&nw, fbsd_off);
521 hdr = snl_finalize_msg(&nw);
522 ATF_REQUIRE(hdr != NULL);
523
524 ATF_REQUIRE(snl_parse_nlmsg(&ss, hdr, &snl_rtm_link_parser, &link));
525 ATF_CHECK_EQ(link.ifla_num_vf, 0);
526 ATF_CHECK(link.iflaf_vf_status.present);
527 ATF_CHECK_EQ(link.iflaf_vf_status.pf_link_state,
528 IFLAF_VF_LINK_DOWN);
529 ATF_CHECK_EQ(link.iflaf_vf_status.vfs.count, 0);
530 }
531
532 ATF_TC(snl_parse_vf_status_error);
ATF_TC_HEAD(snl_parse_vf_status_error,tc)533 ATF_TC_HEAD(snl_parse_vf_status_error, tc)
534 {
535 atf_tc_set_md_var(tc, "descr",
536 "Tests snl(3) parsing a VF status provider error");
537 atf_tc_set_md_var(tc, "require.kmods", "netlink");
538 }
539
ATF_TC_BODY(snl_parse_vf_status_error,tc)540 ATF_TC_BODY(snl_parse_vf_status_error, tc)
541 {
542 struct snl_parsed_link link = {};
543 struct snl_state ss;
544 struct snl_writer nw;
545 struct nlmsghdr *hdr;
546 int fbsd_off, status_off;
547
548 ATF_REQUIRE(snl_init(&ss, NETLINK_ROUTE));
549 snl_init_writer(&ss, &nw);
550 hdr = snl_create_msg_request(&nw, RTM_NEWLINK);
551 ATF_REQUIRE(hdr != NULL);
552 ATF_REQUIRE(snl_reserve_msg_object(&nw, struct ifinfomsg) != NULL);
553 fbsd_off = snl_add_msg_attr_nested(&nw, IFLA_FREEBSD);
554 ATF_REQUIRE(fbsd_off != 0);
555 status_off = snl_add_msg_attr_nested(&nw, IFLAF_VF_STATUS);
556 ATF_REQUIRE(status_off != 0);
557 ATF_REQUIRE(snl_add_msg_attr_u32(&nw, IFLAF_VFS_ERROR, EMSGSIZE));
558 snl_end_attr_nested(&nw, status_off);
559 snl_end_attr_nested(&nw, fbsd_off);
560 hdr = snl_finalize_msg(&nw);
561 ATF_REQUIRE(hdr != NULL);
562
563 ATF_REQUIRE(snl_parse_nlmsg(&ss, hdr, &snl_rtm_link_parser, &link));
564 ATF_CHECK(link.iflaf_vf_status.present);
565 ATF_CHECK_EQ(link.iflaf_vf_status.error, EMSGSIZE);
566 ATF_CHECK_EQ(link.iflaf_vf_status.vfs.count, 0);
567 }
568
569 ATF_TC(snl_verify_route_parsers);
ATF_TC_HEAD(snl_verify_route_parsers,tc)570 ATF_TC_HEAD(snl_verify_route_parsers, tc)
571 {
572 atf_tc_set_md_var(tc, "descr", "Tests snl(3) route parsers are correct");
573 }
574
ATF_TC_BODY(snl_verify_route_parsers,tc)575 ATF_TC_BODY(snl_verify_route_parsers, tc)
576 {
577 SNL_VERIFY_PARSERS(snl_all_route_parsers);
578
579 }
580
581 ATF_TC(snl_parse_errmsg_capped);
ATF_TC_HEAD(snl_parse_errmsg_capped,tc)582 ATF_TC_HEAD(snl_parse_errmsg_capped, tc)
583 {
584 atf_tc_set_md_var(tc, "descr", "Tests snl(3) correctly parsing capped errors");
585 atf_tc_set_md_var(tc, "require.kmods", "netlink");
586 }
587
ATF_TC_BODY(snl_parse_errmsg_capped,tc)588 ATF_TC_BODY(snl_parse_errmsg_capped, tc)
589 {
590 struct snl_state ss;
591 struct snl_writer nw;
592
593 if (!snl_init(&ss, NETLINK_ROUTE))
594 atf_tc_fail("snl_init() failed");
595
596 int optval = 1;
597 ATF_CHECK(setsockopt(ss.fd, SOL_NETLINK, NETLINK_CAP_ACK, &optval, sizeof(optval)) == 0);
598
599 optval = 0;
600 ATF_CHECK(setsockopt(ss.fd, SOL_NETLINK, NETLINK_EXT_ACK, &optval, sizeof(optval)) == 0);
601 snl_init_writer(&ss, &nw);
602
603 struct nlmsghdr *hdr = snl_create_msg_request(&nw, 255);
604 ATF_CHECK(hdr != NULL);
605 ATF_CHECK(snl_reserve_msg_object(&nw, struct ifinfomsg) != NULL);
606 snl_add_msg_attr_string(&nw, 143, "some random string");
607 ATF_CHECK(snl_finalize_msg(&nw) != NULL);
608
609 ATF_CHECK(snl_send_message(&ss, hdr));
610
611 struct nlmsghdr *rx_hdr = snl_read_reply(&ss, hdr->nlmsg_seq);
612 ATF_CHECK(rx_hdr != NULL);
613 ATF_CHECK(rx_hdr->nlmsg_type == NLMSG_ERROR);
614
615 struct snl_errmsg_data e = {};
616 ATF_CHECK(rx_hdr->nlmsg_len == sizeof(struct nlmsghdr) + sizeof(struct nlmsgerr));
617 ATF_CHECK(snl_parse_errmsg(&ss, rx_hdr, &e));
618 ATF_CHECK(e.error != 0);
619 ATF_CHECK(!memcmp(hdr, e.orig_hdr, sizeof(struct nlmsghdr)));
620 }
621
622 ATF_TC(snl_parse_errmsg_capped_extack);
ATF_TC_HEAD(snl_parse_errmsg_capped_extack,tc)623 ATF_TC_HEAD(snl_parse_errmsg_capped_extack, tc)
624 {
625 atf_tc_set_md_var(tc, "descr", "Tests snl(3) correctly parsing capped errors with extack");
626 atf_tc_set_md_var(tc, "require.kmods", "netlink");
627 }
628
ATF_TC_BODY(snl_parse_errmsg_capped_extack,tc)629 ATF_TC_BODY(snl_parse_errmsg_capped_extack, tc)
630 {
631 struct snl_state ss;
632 struct snl_writer nw;
633
634 if (!snl_init(&ss, NETLINK_ROUTE))
635 atf_tc_fail("snl_init() failed");
636
637 int optval = 1;
638 ATF_CHECK(setsockopt(ss.fd, SOL_NETLINK, NETLINK_CAP_ACK, &optval, sizeof(optval)) == 0);
639 optval = 1;
640 ATF_CHECK(setsockopt(ss.fd, SOL_NETLINK, NETLINK_EXT_ACK, &optval, sizeof(optval)) == 0);
641
642 snl_init_writer(&ss, &nw);
643
644 struct nlmsghdr *hdr = snl_create_msg_request(&nw, 255);
645 ATF_CHECK(hdr != NULL);
646 ATF_CHECK(snl_reserve_msg_object(&nw, struct ifinfomsg) != NULL);
647 snl_add_msg_attr_string(&nw, 143, "some random string");
648 ATF_CHECK(snl_finalize_msg(&nw) != NULL);
649
650 ATF_CHECK(snl_send_message(&ss, hdr));
651
652 struct nlmsghdr *rx_hdr = snl_read_reply(&ss, hdr->nlmsg_seq);
653 ATF_CHECK(rx_hdr != NULL);
654 ATF_CHECK(rx_hdr->nlmsg_type == NLMSG_ERROR);
655
656 struct snl_errmsg_data e = {};
657 ATF_CHECK(snl_parse_errmsg(&ss, rx_hdr, &e));
658 ATF_CHECK(e.error != 0);
659 ATF_CHECK(!memcmp(hdr, e.orig_hdr, sizeof(struct nlmsghdr)));
660
661 ATF_CHECK(e.error_str != NULL);
662 }
663
664 ATF_TC(snl_parse_errmsg_uncapped_extack);
ATF_TC_HEAD(snl_parse_errmsg_uncapped_extack,tc)665 ATF_TC_HEAD(snl_parse_errmsg_uncapped_extack, tc)
666 {
667 atf_tc_set_md_var(tc, "descr", "Tests snl(3) correctly parsing errors with extack");
668 atf_tc_set_md_var(tc, "require.kmods", "netlink");
669 }
670
ATF_TC_BODY(snl_parse_errmsg_uncapped_extack,tc)671 ATF_TC_BODY(snl_parse_errmsg_uncapped_extack, tc)
672 {
673 struct snl_state ss;
674 struct snl_writer nw;
675
676 ATF_CHECK(snl_init(&ss, NETLINK_ROUTE));
677
678 int optval = 1;
679 ATF_CHECK(setsockopt(ss.fd, SOL_NETLINK, NETLINK_EXT_ACK, &optval, sizeof(optval)) == 0);
680
681 snl_init_writer(&ss, &nw);
682
683 struct nlmsghdr *hdr = snl_create_msg_request(&nw, 255);
684 ATF_CHECK(hdr != NULL);
685 ATF_CHECK(snl_reserve_msg_object(&nw, struct ifinfomsg) != NULL);
686 snl_add_msg_attr_string(&nw, 143, "some random string");
687 ATF_CHECK(snl_finalize_msg(&nw) != NULL);
688
689 ATF_CHECK(snl_send_message(&ss, hdr));
690
691 struct nlmsghdr *rx_hdr = snl_read_reply(&ss, hdr->nlmsg_seq);
692 ATF_CHECK(rx_hdr != NULL);
693 ATF_CHECK(rx_hdr->nlmsg_type == NLMSG_ERROR);
694
695 struct snl_errmsg_data e = {};
696 ATF_CHECK(snl_parse_errmsg(&ss, rx_hdr, &e));
697 ATF_CHECK(e.error != 0);
698 ATF_CHECK(!memcmp(hdr, e.orig_hdr, hdr->nlmsg_len));
699
700 ATF_CHECK(e.error_str != NULL);
701 }
702
703 ATF_TC(snl_list_ifaces);
ATF_TC_HEAD(snl_list_ifaces,tc)704 ATF_TC_HEAD(snl_list_ifaces, tc)
705 {
706 atf_tc_set_md_var(tc, "descr", "Tests snl(3) listing interfaces");
707 atf_tc_set_md_var(tc, "require.kmods", "netlink");
708 }
709
710 struct nl_parsed_link {
711 uint32_t ifi_index;
712 uint32_t ifla_mtu;
713 char *ifla_ifname;
714 };
715
716 #define _IN(_field) offsetof(struct ifinfomsg, _field)
717 #define _OUT(_field) offsetof(struct nl_parsed_link, _field)
718 static struct snl_attr_parser ap_link[] = {
719 { .type = IFLA_IFNAME, .off = _OUT(ifla_ifname), .cb = snl_attr_get_string },
720 { .type = IFLA_MTU, .off = _OUT(ifla_mtu), .cb = snl_attr_get_uint32 },
721 };
722 static struct snl_field_parser fp_link[] = {
723 {.off_in = _IN(ifi_index), .off_out = _OUT(ifi_index), .cb = snl_field_get_uint32 },
724 };
725 #undef _IN
726 #undef _OUT
727 SNL_DECLARE_PARSER(link_parser, struct ifinfomsg, fp_link, ap_link);
728
729
ATF_TC_BODY(snl_list_ifaces,tc)730 ATF_TC_BODY(snl_list_ifaces, tc)
731 {
732 struct snl_state ss;
733 struct snl_writer nw;
734
735 if (!snl_init(&ss, NETLINK_ROUTE))
736 atf_tc_fail("snl_init() failed");
737
738 snl_init_writer(&ss, &nw);
739
740 struct nlmsghdr *hdr = snl_create_msg_request(&nw, RTM_GETLINK);
741 ATF_CHECK(hdr != NULL);
742 ATF_CHECK(snl_reserve_msg_object(&nw, struct ifinfomsg) != NULL);
743 ATF_CHECK(snl_finalize_msg(&nw) != NULL);
744 uint32_t seq_id = hdr->nlmsg_seq;
745
746 ATF_CHECK(snl_send_message(&ss, hdr));
747
748 struct snl_errmsg_data e = {};
749 int count = 0;
750
751 while ((hdr = snl_read_reply_multi(&ss, seq_id, &e)) != NULL) {
752 count++;
753 }
754 ATF_REQUIRE(e.error == 0);
755
756 ATF_REQUIRE_MSG(count > 0, "Empty interface list");
757 }
758
ATF_TP_ADD_TCS(tp)759 ATF_TP_ADD_TCS(tp)
760 {
761 ATF_TP_ADD_TC(tp, snl_verify_core_parsers);
762 ATF_TP_ADD_TC(tp, snl_parse_bitset_array);
763 ATF_TP_ADD_TC(tp, snl_verify_route_parsers);
764 ATF_TP_ADD_TC(tp, snl_parse_vf_status);
765 ATF_TP_ADD_TC(tp, snl_parse_vf_trunk_pcp);
766 ATF_TP_ADD_TC(tp, snl_parse_large_vf_status);
767 ATF_TP_ADD_TC(tp, snl_parse_empty_vf_status);
768 ATF_TP_ADD_TC(tp, snl_parse_vf_status_error);
769 ATF_TP_ADD_TC(tp, snl_parse_errmsg_capped);
770 ATF_TP_ADD_TC(tp, snl_parse_errmsg_capped_extack);
771 ATF_TP_ADD_TC(tp, snl_parse_errmsg_uncapped_extack);
772 ATF_TP_ADD_TC(tp, snl_list_ifaces);
773
774 return (atf_no_error());
775 }
776