From: Vincent Bernat Date: Thu, 27 Nov 2008 19:02:05 +0000 (+0100) Subject: Handle bridge in a different way using BRCTL_GET_BRIDGES instead of X-Git-Tag: 0.3~33 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c6df6eb9e06044bbcd3cfaa61d7267466cfafa8e;p=thirdparty%2Flldpd.git Handle bridge in a different way using BRCTL_GET_BRIDGES instead of trying to ioctl all devices --- diff --git a/src/features.c b/src/features.c index bdcaa58b..bc269bbe 100644 --- a/src/features.c +++ b/src/features.c @@ -20,12 +20,12 @@ #include #include #include -#include #include #include #include #include #include +#include #include #include #include @@ -35,23 +35,32 @@ #define SYSFS_PATH_MAX 256 #define MAX_PORTS 1024 +#define MAX_BRIDGES 1024 /* net/if.h */ extern unsigned int if_nametoindex (__const char *__ifname) __THROW; +extern char *if_indextoname (unsigned int __ifindex, char *__ifname) __THROW; int old_iface_is_bridge(struct lldpd *cfg, const char *name) { - struct ifreq ifr; - struct __bridge_info i; - unsigned long args[4] = { BRCTL_GET_BRIDGE_INFO, - (unsigned long) &i, 0, 0 }; - strlcpy(ifr.ifr_name, name, IFNAMSIZ); - ifr.ifr_data = (char *) &args; - - if (ioctl(cfg->g_sock, SIOCDEVPRIVATE, &ifr) < 0) + int ifindices[MAX_BRIDGES]; + char ifname[IFNAMSIZ]; + int num, i; + unsigned long args[3] = { BRCTL_GET_BRIDGES, + (unsigned long)ifindices, MAX_BRIDGES }; + if ((num = ioctl(cfg->g_sock, SIOCGIFBR, args)) < 0) { + LLOG_WARN("unable to get available bridges"); return 0; - return 1; + } + for (i = 0; i < num; i++) { + if (if_indextoname(ifindices[i], ifname) == NULL) + LLOG_WARN("unable to get name of interface %d", + ifindices[i]); + else if (strncmp(name, ifname, IFNAMSIZ) == 0) + return 1; + } + return 0; } int @@ -73,33 +82,37 @@ iface_is_bridge(struct lldpd *cfg, const char *name) int old_iface_is_bridged(struct lldpd *cfg, const char *name) { - int i; + int i, j, num; int ifindex = if_nametoindex(name); - int ifindices[MAX_PORTS]; - unsigned long args[4] = { BRCTL_GET_PORT_LIST, - (unsigned long)ifindices, MAX_PORTS, 0 }; + int ifptindices[MAX_PORTS], ifbrindices[MAX_BRIDGES]; + unsigned long args1[3] = { BRCTL_GET_BRIDGES, + (unsigned long)ifbrindices, MAX_BRIDGES }; + unsigned long args2[4] = { BRCTL_GET_PORT_LIST, + (unsigned long)ifptindices, MAX_PORTS, 0 }; struct ifreq ifr; - struct ifaddrs *ifap, *ifa; - if (getifaddrs(&ifap) != 0) { - LLOG_WARN("unable to get interface list"); + if ((num = ioctl(cfg->g_sock, SIOCGIFBR, args1)) < 0) { + LLOG_WARN("unable to get available bridges"); return 0; } + for (i = 0; i < num; i++) { + if (if_indextoname(ifbrindices[i], ifr.ifr_name) == NULL) { + LLOG_WARN("unable to get name of interface %d", + ifbrindices[i]); + continue; + } + memset(ifptindices, 0, sizeof(ifptindices)); + ifr.ifr_data = (char *)&args2; - for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { - memset(ifindices, 0, sizeof(ifindices)); - strncpy(ifr.ifr_name, ifa->ifa_name, IFNAMSIZ); - ifr.ifr_data = (char *)&args; - - if (ioctl(cfg->g_sock, SIOCDEVPRIVATE, &ifr) < 0) - /* Not a bridge */ + if (ioctl(cfg->g_sock, SIOCDEVPRIVATE, &ifr) < 0) { + LLOG_WARN("unable to get bridge members for %s", + ifr.ifr_name); continue; + } - for (i = 0; i < MAX_PORTS; i++) { - if (ifindices[i] == ifindex) { - freeifaddrs(ifap); + for (j = 0; j < MAX_PORTS; i++) { + if (ifptindices[i] == ifindex) return 1; - } } }