summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCordell O'Leary <cordell.oleary@alliedtelesis.co.nz>2024-01-23 11:58:59 +1300
committerThomas Haller <thaller@redhat.com>2024-02-29 21:00:30 +0100
commite21278edd556be41358bc41c9dcca5c534ac2ca3 (patch)
treeae105fe2c6d825cf9de1130f2eaac5274db521b4
parent4f324f7303fddf736f8b71504e48efe6cca72ace (diff)
downloadlibnl-e21278edd556be41358bc41c9dcca5c534ac2ca3.tar.gz
tests: add test for bridge vlan attributes.
-rw-r--r--include/nl-priv-static-route/nl-priv-static-route.h4
-rw-r--r--lib/route/link/bridge.c8
-rw-r--r--tests/check-direct.c127
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 65ff5312..ad9f98f9 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 3d186be1..a9c7eea7 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 db1f48dd..33b7742d 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;
}