diff options
author | Cordell O'Leary <cordell.oleary@alliedtelesis.co.nz> | 2024-01-22 22:58:59 (GMT) |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2024-02-29 20:00:30 (GMT) |
commit | e21278edd556be41358bc41c9dcca5c534ac2ca3 (patch) | |
tree | ae105fe2c6d825cf9de1130f2eaac5274db521b4 | |
parent | 4f324f7303fddf736f8b71504e48efe6cca72ace (diff) | |
download | libnl-e21278edd556be41358bc41c9dcca5c534ac2ca3.zip libnl-e21278edd556be41358bc41c9dcca5c534ac2ca3.tar.gz libnl-e21278edd556be41358bc41c9dcca5c534ac2ca3.tar.bz2 |
tests: add test for bridge vlan attributes.
-rw-r--r-- | include/nl-priv-static-route/nl-priv-static-route.h | 4 | ||||
-rw-r--r-- | lib/route/link/bridge.c | 8 | ||||
-rw-r--r-- | tests/check-direct.c | 127 |
3 files changed, 135 insertions, 4 deletions
diff --git a/include/nl-priv-static-route/nl-priv-static-route.h b/include/nl-priv-static-route/nl-priv-static-route.h index 65ff531..ad9f98f 100644 --- a/include/nl-priv-static-route/nl-priv-static-route.h +++ b/include/nl-priv-static-route/nl-priv-static-route.h @@ -3,6 +3,10 @@ #ifndef NETLINK_ROUTE_UTILS_PRIV_H_ #define NETLINK_ROUTE_UTILS_PRIV_H_ +#include <netlink/route/link/bridge.h> + extern const uint8_t *const _nltst_map_stat_id_from_IPSTATS_MIB_v2; +extern int _nl_bridge_fill_vlan_info(struct nl_msg *msg, + struct rtnl_link_bridge_vlan *vlan_info); #endif diff --git a/lib/route/link/bridge.c b/lib/route/link/bridge.c index 3d186be..a9c7eea 100644 --- a/lib/route/link/bridge.c +++ b/lib/route/link/bridge.c @@ -23,6 +23,7 @@ #include "nl-route.h" #include "link-api.h" #include "nl-priv-dynamic-core/nl-core.h" +#include "nl-priv-static-route/nl-priv-static-route.h" #define VLAN_VID_MASK 0x0fff /* VLAN Identifier */ @@ -257,7 +258,7 @@ static int bridge_parse_af_full(struct rtnl_link *link, struct nlattr *attr_full return 0; } -static int bridge_fill_vlan_info(struct nl_msg *msg, struct rtnl_link_bridge_vlan * vlan_info) +int _nl_bridge_fill_vlan_info(struct nl_msg *msg, struct rtnl_link_bridge_vlan * vlan_info) { struct bridge_vlan_info vinfo; int i = -1, j, k; @@ -395,9 +396,8 @@ static int bridge_fill_af(struct rtnl_link *link, struct nl_msg *msg, if (bd->ce_mask & BRIDGE_ATTR_CONFIG_MODE) NLA_PUT_U16(msg, IFLA_BRIDGE_FLAGS, bd->b_config_mode); - if (bd->ce_mask & BRIDGE_ATTR_PORT_VLAN) - { - if(bridge_fill_vlan_info(msg,&bd->vlan_info)){ + if (bd->ce_mask & BRIDGE_ATTR_PORT_VLAN) { + if (_nl_bridge_fill_vlan_info(msg, &bd->vlan_info)) { goto nla_put_failure; } } diff --git a/tests/check-direct.c b/tests/check-direct.c index db1f48d..33b7742 100644 --- a/tests/check-direct.c +++ b/tests/check-direct.c @@ -5,10 +5,16 @@ #include <check.h> #include <linux/snmp.h> +#include <linux/if_bridge.h> #include <netlink/route/link.h> +#include <netlink/route/link/bridge.h> #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) { @@ -53,12 +59,133 @@ START_TEST(static_checks) } 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; } |