[LTP] [PATCH v2 22/31] testcases: sysfs: Add sys_net03
Cyril Hrubis <[email protected]>
| Newsgroups | it.linux.lists.ltp |
|---|---|
| Message-ID | <[email protected]> |
A test for /sys/class/net/*/* files. Similar to sys_net02 but checks bridge related files after briding a virtual ethernet interface. Signed-off-by: Cyril Hrubis <[email protected]> --- runtest/sysfs | 1 + testcases/kernel/sysfs/class/net/.gitignore | 1 + testcases/kernel/sysfs/class/net/sys_net03.c | 144 +++++++++++++++++++ 3 files changed, 146 insertions(+) create mode 100644 testcases/kernel/sysfs/class/net/sys_net03.c diff --git a/runtest/sysfs b/runtest/sysfs index fee8a0b2b..b2cc0005c 100644 --- a/runtest/sysfs +++ b/runtest/sysfs @@ -17,3 +17,4 @@ sys_rtc01 sys_rtc01 sys_thermal01 sys_thermal01 sys_net01 sys_net01 sys_net02 sys_net02 +sys_net03 sys_net03 diff --git a/testcases/kernel/sysfs/class/net/.gitignore b/testcases/kernel/sysfs/class/net/.gitignore index b70d02158..8c3782a3b 100644 --- a/testcases/kernel/sysfs/class/net/.gitignore +++ b/testcases/kernel/sysfs/class/net/.gitignore @@ -1,2 +1,3 @@ /sys_net01 /sys_net02 +/sys_net03 diff --git a/testcases/kernel/sysfs/class/net/sys_net03.c b/testcases/kernel/sysfs/class/net/sys_net03.c new file mode 100644 index 000000000..fcc5c5451 --- /dev/null +++ b/testcases/kernel/sysfs/class/net/sys_net03.c @@ -0,0 +1,144 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2026 Cyril Hrubis <[email protected]> + */ + +/*\ + * Verifies that bridge port sysfs attributes correctly appear, hold sane + * values, and disappear again as a network device is enslaved to and + * released from a bridge. + * + * The test creates a bridge and a veth pair, then: + * + * - verifies /sys/class/net/<bridge>/brif/ is empty and + * /sys/class/net/<port>/brport does not exist before enslaving + * - enslaves one end of the veth pair to the bridge + * - verifies /sys/class/net/<bridge>/brif/<port> appears and + * /sys/class/net/<port>/brport/{state,priority,path_cost} hold sane values + * - verifies /sys/class/net/<bridge>/bridge/{stp_state,forward_delay} hold + * sane values + * - releases the port from the bridge + * - verifies /sys/class/net/<bridge>/brif/ is empty and + * /sys/class/net/<port>/brport does not exist again + * + * This needs root to create the bridge and veth devices. + */ + +#include <limits.h> +#include <string.h> +#include <dirent.h> +#include <unistd.h> + +#include "tst_test.h" +#include "tst_netdevice.h" +#include "tst_sysfs_assert.h" + +#define BRNAME "ltp_br0" +#define IFNAME1 "ltp_vethb1" +#define IFNAME2 "ltp_vethb2" + +#define BR_PATH "/sys/class/net/" BRNAME +#define PORT_PATH "/sys/class/net/" IFNAME1 + +static int bridge_created; +static int veth_created; + +static int count_dir_entries(const char *path) +{ + DIR *d; + struct dirent *ent; + int count = 0; + + d = SAFE_OPENDIR(path); + + while ((ent = SAFE_READDIR(d))) { + if (ent->d_name[0] == '.') + continue; + + count++; + } + + SAFE_CLOSEDIR(d); + + return count; +} + +static void setup(void) +{ + NETDEV_ADD_DEVICE(BRNAME, "bridge"); + bridge_created = 1; + + CREATE_VETH_PAIR(IFNAME1, IFNAME2); + veth_created = 1; + + NETDEV_SET_STATE(BRNAME, 1); + NETDEV_SET_STATE(IFNAME1, 1); + NETDEV_SET_STATE(IFNAME2, 1); +} + +static void check_not_enslaved(const char *desc) +{ + int nports = count_dir_entries(BR_PATH "/brif"); + + tst_res(TINFO, "%s", desc); + + TST_EXP_EQ_LI(nports, 0); + + if (access(PORT_PATH "/brport", F_OK)) + tst_res(TPASS, PORT_PATH "/brport does not exist"); + else + tst_res(TFAIL, PORT_PATH "/brport unexpectedly exists"); +} + +static void check_enslaved(void) +{ + int nports = count_dir_entries(BR_PATH "/brif"); + + tst_res(TINFO, "port enslaved to bridge"); + + TST_EXP_EQ_LI(nports, 1); + + if (!access(BR_PATH "/brif/" IFNAME1, F_OK)) + tst_res(TPASS, BR_PATH "/brif/" IFNAME1 " exists"); + else + tst_res(TFAIL, BR_PATH "/brif/" IFNAME1 " does not exist"); + + TST_SYSFS_ASSERT_RANGELL(0, 4, PORT_PATH "/brport/state"); + TST_SYSFS_ASSERT_RANGELL(0, 255, PORT_PATH "/brport/priority"); + TST_SYSFS_ASSERT_RANGELL(1, LONG_MAX, PORT_PATH "/brport/path_cost"); + + TST_SYSFS_ASSERT_RANGELL(0, 2, BR_PATH "/bridge/stp_state"); + TST_SYSFS_ASSERT_RANGELL(1, LONG_MAX, BR_PATH "/bridge/forward_delay"); +} + +static void run(void) +{ + check_not_enslaved("before enslaving"); + + NETDEV_SET_MASTER(IFNAME1, BRNAME); + check_enslaved(); + + NETDEV_SET_MASTER(IFNAME1, NULL); + check_not_enslaved("after releasing"); +} + +static void cleanup(void) +{ + if (veth_created) + NETDEV_REMOVE_DEVICE(IFNAME1); + + if (bridge_created) + NETDEV_REMOVE_DEVICE(BRNAME); +} + +static struct tst_test test = { + .test_all = run, + .setup = setup, + .cleanup = cleanup, + .needs_root = 1, + .needs_kconfigs = (const char *const[]){ + "CONFIG_VETH", + "CONFIG_BRIDGE", + NULL + }, +}; -- 2.54.0 -- Mailing list info: https://lists.linux.it/listinfo/ltp