/* SPDX-License-Identifier: LGPL-2.1-only */ #include "nl-default.h" #include #include #include #include #include #include "nl-priv-static-route/nl-priv-static-route.h" #include "nl-aux-core/nl-core.h" #define CASES 5 #define MAX_ATTR 7 START_TEST(static_checks) { int i, j; char strbuf[100]; _NL_STATIC_ASSERT(RTNL_LINK_RX_PACKETS == 0); assert(_nltst_map_stat_id_from_IPSTATS_MIB_v2[0] == RTNL_LINK_RX_PACKETS); for (i = 1; i < __IPSTATS_MIB_MAX; i++) { assert(_nltst_map_stat_id_from_IPSTATS_MIB_v2[i] > 0); assert(_nltst_map_stat_id_from_IPSTATS_MIB_v2[i] < __RTNL_LINK_STATS_MAX); for (j = 1; j < i; j++) assert(_nltst_map_stat_id_from_IPSTATS_MIB_v2[i] != _nltst_map_stat_id_from_IPSTATS_MIB_v2[j]); } for (i = 0; i <= RTNL_LINK_STATS_MAX + 1; i++) { const char *s; s = rtnl_link_stat2str(i, strbuf, sizeof(strbuf)); assert(s); assert(s == strbuf); assert(strlen(s) < sizeof(strbuf)); if (strncmp(s, "0x", 2) == 0) { assert(i == RTNL_LINK_STATS_MAX + 1); ck_assert_int_eq(strtoll(&s[2], NULL, 16), i); } else ck_assert_int_le(i, RTNL_LINK_STATS_MAX); ck_assert_int_eq(i, rtnl_link_str2stat(s)); } ck_assert_int_eq(nl_str2ip_proto(""), -NLE_OBJ_NOTFOUND); ck_assert_int_eq(nl_str2ip_proto("5"), 5); ck_assert_int_eq(nl_str2ip_proto(" 13 "), -NLE_OBJ_NOTFOUND); ck_assert_int_eq(nl_str2ip_proto("13"), 13); ck_assert_int_eq(nl_str2ip_proto("0x13"), 0x13); ck_assert_int_eq(nl_str2ip_proto("0342"), 0342); ck_assert_int_eq(nl_str2ip_proto("2147483647"), 2147483647); ck_assert_int_eq(nl_str2ip_proto("2147483648"), -NLE_OBJ_NOTFOUND); } END_TEST static void set_bitmap_range(u_int32_t start, u_int32_t end, struct rtnl_link_bridge_vlan *vlan_info, int untagged) { for (u_int32_t i = start; i <= end; i++) { vlan_info->vlan_bitmap[i / 32] |= (((uint32_t)1) << (i % 32)); if (untagged) { vlan_info->untagged_bitmap[i / 32] |= (((uint32_t)1) << (i % 32)); } } } START_TEST(vlan_attribute_check) { struct nlmsghdr *nlh; struct nlattr *a; int attr_count, rem; struct bridge_vlan_info *vlan_attr; struct rtnl_link_bridge_vlan vlan_info[CASES]; struct bridge_vlan_info expected_attr[CASES][MAX_ATTR]; for (int i = 0; i < CASES; i++) { memset(&vlan_info[i], 0, sizeof(struct rtnl_link_bridge_vlan)); memset(&expected_attr[i], 0, sizeof(struct bridge_vlan_info) * MAX_ATTR); } // Case 1 setting pvid untagged. vlan_info[0].pvid = 1; set_bitmap_range(1, 1, &vlan_info[0], 1); expected_attr[0][0].vid = 1; expected_attr[0][0].flags = BRIDGE_VLAN_INFO_PVID | BRIDGE_VLAN_INFO_UNTAGGED; // Case 2 setting vid range. vlan_info[1].pvid = 0; set_bitmap_range(1, 4094, &vlan_info[1], 0); expected_attr[1][0].vid = 1; expected_attr[1][0].flags = BRIDGE_VLAN_INFO_RANGE_BEGIN; expected_attr[1][1].vid = 4094; expected_attr[1][1].flags = BRIDGE_VLAN_INFO_RANGE_END; // Case 3 interweaving pvid with vid range. vlan_info[2].pvid = 7; set_bitmap_range(1, 27, &vlan_info[2], 0); set_bitmap_range(7, 7, &vlan_info[2], 1); expected_attr[2][0].vid = 1; expected_attr[2][0].flags = BRIDGE_VLAN_INFO_RANGE_BEGIN; expected_attr[2][1].vid = 6; expected_attr[2][1].flags = BRIDGE_VLAN_INFO_RANGE_END; expected_attr[2][2].vid = 8; expected_attr[2][2].flags = BRIDGE_VLAN_INFO_RANGE_BEGIN; expected_attr[2][3].vid = 27; expected_attr[2][3].flags = BRIDGE_VLAN_INFO_RANGE_END; expected_attr[2][4].vid = 7; expected_attr[2][4].flags = BRIDGE_VLAN_INFO_PVID | BRIDGE_VLAN_INFO_UNTAGGED; // Case 4 interweaving untagged and tagged vid ranges. vlan_info[3].pvid = 1; set_bitmap_range(1, 1, &vlan_info[3], 1); set_bitmap_range(1, 25, &vlan_info[3], 0); set_bitmap_range(26, 50, &vlan_info[3], 1); set_bitmap_range(51, 75, &vlan_info[3], 0); expected_attr[3][0].vid = 2; expected_attr[3][0].flags = BRIDGE_VLAN_INFO_RANGE_BEGIN; expected_attr[3][1].vid = 25; expected_attr[3][1].flags = BRIDGE_VLAN_INFO_RANGE_END; expected_attr[3][2].vid = 26; expected_attr[3][2].flags = BRIDGE_VLAN_INFO_RANGE_BEGIN | BRIDGE_VLAN_INFO_UNTAGGED; expected_attr[3][3].vid = 50; expected_attr[3][3].flags = BRIDGE_VLAN_INFO_RANGE_END | BRIDGE_VLAN_INFO_UNTAGGED; expected_attr[3][4].vid = 51; expected_attr[3][4].flags = BRIDGE_VLAN_INFO_RANGE_BEGIN; expected_attr[3][5].vid = 75; expected_attr[3][5].flags = BRIDGE_VLAN_INFO_RANGE_END; expected_attr[3][6].vid = 1; expected_attr[3][6].flags = BRIDGE_VLAN_INFO_PVID | BRIDGE_VLAN_INFO_UNTAGGED; // Case 5 individual vid. vlan_info[4].pvid = 0; set_bitmap_range(5, 5, &vlan_info[4], 0); set_bitmap_range(3067, 3067, &vlan_info[4], 1); expected_attr[4][0].vid = 5; expected_attr[4][0].flags = 0; expected_attr[4][1].vid = 3067; expected_attr[4][1].flags = BRIDGE_VLAN_INFO_UNTAGGED; for (int i = 0; i < CASES; i++) { _nl_auto_nl_msg struct nl_msg *msg = nlmsg_alloc(); attr_count = 0; ck_assert_msg(msg, "Unable to allocate netlink message"); ck_assert_int_eq(0, _nl_bridge_fill_vlan_info(msg, &vlan_info[i])); nlh = nlmsg_hdr(msg); nlmsg_for_each_attr(a, nlh, 0, rem) { ck_assert_msg(expected_attr[i][attr_count].vid != 0, "Attribute number %d unexpected", attr_count); ck_assert_msg( nla_type(a) == IFLA_BRIDGE_VLAN_INFO, "Expected attribute IFLA_BRIDGE_VLAN_INFO %d", IFLA_BRIDGE_VLAN_INFO); vlan_attr = (struct bridge_vlan_info *)nla_data(a); ck_assert_int_eq(vlan_attr->vid, expected_attr[i][attr_count].vid); ck_assert_int_eq(vlan_attr->flags, expected_attr[i][attr_count].flags); attr_count++; } } } END_TEST static Suite *make_suite(void) { Suite *suite = suite_create("Direct"); TCase *tc = tcase_create("Core"); tcase_add_test(tc, static_checks); tcase_add_test(tc, vlan_attribute_check); suite_add_tcase(suite, tc); return suite; } int main(int argc, char *argv[]) { SRunner *runner; int nfailed; runner = srunner_create(suite_create("main")); srunner_add_suite(runner, make_suite()); srunner_run_all(runner, CK_ENV); nfailed = srunner_ntests_failed(runner); srunner_free(runner); return nfailed != 0; }