aboutsummaryrefslogtreecommitdiffstats
path: root/libbridge/libbridge_init.c
diff options
context:
space:
mode:
Diffstat (limited to 'libbridge/libbridge_init.c')
-rw-r--r--libbridge/libbridge_init.c104
1 files changed, 29 insertions, 75 deletions
diff --git a/libbridge/libbridge_init.c b/libbridge/libbridge_init.c
index 4c34b31..e2eab77 100644
--- a/libbridge/libbridge_init.c
+++ b/libbridge/libbridge_init.c
@@ -22,48 +22,35 @@
#include <errno.h>
#include <string.h>
#include <dirent.h>
+#include <sys/types.h>
+#include <sys/stat.h>
#include "libbridge.h"
#include "libbridge_private.h"
int br_socket_fd = -1;
-struct sysfs_class *br_class_net;
int br_init(void)
{
if ((br_socket_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
return errno;
-
- br_class_net = sysfs_open_class("net");
- return 0;
-}
-
-int br_refresh(void)
-{
- if (br_class_net) {
- sysfs_close_class(br_class_net);
- br_class_net = sysfs_open_class("net");
- }
-
return 0;
}
void br_shutdown(void)
{
- sysfs_close_class(br_class_net);
- br_class_net = NULL;
close(br_socket_fd);
br_socket_fd = -1;
}
-#ifdef HAVE_LIBSYSFS
/* If /sys/class/net/XXX/bridge exists then it must be a bridge */
-static int isbridge(const struct sysfs_class_device *dev)
+static int isbridge(const struct dirent *entry)
{
char path[SYSFS_PATH_MAX];
+ struct stat st;
- snprintf(path, sizeof(path), "%s/bridge", dev->path);
- return !sysfs_path_is_dir(path);
+ snprintf(path, SYSFS_PATH_MAX, SYSFS_CLASS_NET "%s/bridge", entry->d_name);
+ return stat(path, &st) == 0 && S_ISDIR(st.st_mode);
}
/*
@@ -72,32 +59,24 @@ static int isbridge(const struct sysfs_class_device *dev)
static int new_foreach_bridge(int (*iterator)(const char *name, void *),
void *arg)
{
- struct sysfs_class_device *dev;
- struct dlist *devlist;
- int count = 0;
+ struct dirent **namelist;
+ int i, count = 0;
- if (!br_class_net) {
- dprintf("no class /sys/class/net\n");
- return -EOPNOTSUPP;
- }
+ count = scandir(SYSFS_CLASS_NET, &namelist, isbridge, alphasort);
+ if (count < 0)
+ return -1;
- devlist = sysfs_get_class_devices(br_class_net);
- if (!devlist) {
- dprintf("Can't read devices from sysfs\n");
- return -errno;
+ for (i = 0; i < count; i++) {
+ if (iterator(namelist[i]->d_name, arg))
+ break;
}
- dlist_for_each_data(devlist, dev, struct sysfs_class_device) {
- if (isbridge(dev)) {
- ++count;
- if (iterator(dev->name, arg))
- break;
- }
- }
+ for (i = 0; i < count; i++)
+ free(namelist[i]);
+ free(namelist);
return count;
}
-#endif
/*
* Old interface uses ioctl
@@ -143,11 +122,9 @@ int br_foreach_bridge(int (*iterator)(const char *, void *),
void *arg)
{
int ret;
-#ifdef HAVE_LIBSYSFS
ret = new_foreach_bridge(iterator, arg);
if (ret <= 0)
-#endif
ret = old_foreach_bridge(iterator, arg);
return ret;
@@ -205,45 +182,22 @@ int br_foreach_port(const char *brname,
int (*iterator)(const char *br, const char *port, void *arg),
void *arg)
{
-#ifdef HAVE_LIBSYSFS
- struct sysfs_class_device *dev;
- DIR *dir;
- struct dirent *dirent;
- int err = 0;
+ int i, count;
+ struct dirent **namelist;
char path[SYSFS_PATH_MAX];
- if (!br_class_net ||
- !(dev = sysfs_get_class_device(br_class_net, (char *) brname)))
- goto old;
-
- snprintf(path, sizeof(path), "%s/%s",
- dev->path, SYSFS_BRIDGE_PORT_SUBDIR);
-
-
- dir = opendir(path);
- if (!dir) {
- /* no /sys/class/net/ethX/brif subdirectory
- * either: old kernel, or not really a bridge
- */
- goto old;
- }
+ snprintf(path, SYSFS_PATH_MAX, SYSFS_CLASS_NET "%s/brport", brname);
+ count = scandir(path, &namelist, 0, alphasort);
+ if (count < 0)
+ return old_foreach_port(brname, iterator, arg);
- err = 0;
- while ((dirent = readdir(dir)) != NULL) {
- if (0 == strcmp(dirent->d_name, "."))
- continue;
- if (0 == strcmp(dirent->d_name, ".."))
- continue;
- ++err;
- if (iterator(brname, dirent->d_name, arg))
+ for (i = 0; i < count; i++) {
+ if (iterator(brname, namelist[i]->d_name, arg))
break;
}
- closedir(dir);
-
- return err;
+ for (i = 0; i < count; i++)
+ free(namelist[i]);
+ free(namelist);
- old:
-#endif
- return old_foreach_port(brname, iterator, arg);
-
+ return count;
}