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); 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 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); 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 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); 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 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); 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 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); 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 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); 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 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); 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 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); 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 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); 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 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); 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 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); 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 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); 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 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 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