]> git.ipfire.org Git - thirdparty/lldpd.git/commitdiff
Also check for VLAN on bridges.
authorVincent Bernat <bernat@luffy.cx>
Thu, 14 May 2009 15:56:59 +0000 (17:56 +0200)
committerVincent Bernat <bernat@luffy.cx>
Thu, 14 May 2009 16:00:51 +0000 (18:00 +0200)
src/features.c
src/lldpd.c
src/lldpd.h
src/priv.c

index 74379df97ecf180fcb24f1959064cc3dccc15dc3..fe988b55a784bbc1ead9856e326956e2249978a6 100644 (file)
@@ -80,6 +80,53 @@ iface_is_bridge(struct lldpd *cfg, const char *name)
        return 1;
 }
 
+static int
+old_iface_is_bridged_to(struct lldpd *cfg, const char *slave, const char *master)
+{
+       int j, index = if_nametoindex(slave);
+       int ifptindices[MAX_PORTS];
+       unsigned long args2[4] = { BRCTL_GET_PORT_LIST,
+                                  (unsigned long)ifptindices, MAX_PORTS, 0 };
+       struct ifreq ifr;
+
+       strncpy(ifr.ifr_name, master, IFNAMSIZ);
+       memset(ifptindices, 0, sizeof(ifptindices));
+       ifr.ifr_data = (char *)&args2;
+
+       if (ioctl(cfg->g_sock, SIOCDEVPRIVATE, &ifr) < 0) {
+               LLOG_WARN("unable to get bridge members for %s",
+                   ifr.ifr_name);
+               return 0;
+       }
+
+       for (j = 0; j < MAX_PORTS; j++) {
+               if (ifptindices[j] == index)
+                       return 1;
+       }
+
+       return 0;
+}
+
+int
+iface_is_bridged_to(struct lldpd *cfg, const char *slave, const char *master)
+{
+       char path[SYSFS_PATH_MAX];
+       int f;
+
+       /* Master should be a bridge, first */
+       if (!iface_is_bridge(cfg, master)) return 0;
+
+       if (snprintf(path, SYSFS_PATH_MAX,
+               SYSFS_CLASS_NET "%s/" SYSFS_BRIDGE_PORT_SUBDIR "/%s/port_no",
+               master, slave) >= SYSFS_PATH_MAX)
+               LLOG_WARNX("path truncated");
+       if ((f = priv_open(path)) < 0) {
+               return old_iface_is_bridged_to(cfg, slave, master);
+       }
+       close(f);
+       return 1;
+}
+
 int
 iface_is_vlan(struct lldpd *cfg, const char *name)
 {
index 5d4222ec8156b23d78b4f7a806a28600b6a78cba..2c9e1c534751d7fb466bc5c5011b05c8cb560254 100644 (file)
@@ -597,8 +597,10 @@ lldpd_port_add(struct lldpd *cfg, struct ifaddrs *ifa)
                /* Check if we already have checked this one */
                int skip = 0;
                TAILQ_FOREACH(vlan, &port->p_vlans, v_entries) {
-                       if (strcmp(vlan->v_name, oifa->ifa_name) == 0)
+                       if (strcmp(vlan->v_name, oifa->ifa_name) == 0) {
                                skip = 1;
+                               break;
+                       }
                }
                if (skip) continue;
 #endif
@@ -616,6 +618,7 @@ lldpd_port_add(struct lldpd *cfg, struct ifaddrs *ifa)
                strlcpy(ifv.device1, oifa->ifa_name, sizeof(ifv.device1));
                if ((ioctl(cfg->g_sock, SIOCGIFVLAN, &ifv) >= 0) &&
                    ((iface_is_bond_slave(cfg, hardware->h_ifname, ifv.u.device2, NULL)) ||
+                    (iface_is_bridged_to(cfg, hardware->h_ifname, ifv.u.device2)) ||
                     (strncmp(hardware->h_ifname, ifv.u.device2, sizeof(ifv.u.device2)) == 0))) {
                        if ((vlan = (struct lldpd_vlan *)
                             calloc(1, sizeof(struct lldpd_vlan))) == NULL)
index 302b9273ac4d8fb6b8e0814a16a8bdeed89e6bf8..19683ed5381b248a2cd9faccf01b795e17097dd2 100644 (file)
@@ -382,6 +382,8 @@ int  ctl_msg_unpack_structure(char *, void *, unsigned int, struct hmsg *, void
 
 /* features.c */
 int     iface_is_bridge(struct lldpd *, const char *);
+int     iface_is_bridged_to(struct lldpd *,
+    const char *, const char *);
 int     iface_is_wireless(struct lldpd *, const char *);
 int     iface_is_vlan(struct lldpd *, const char *);
 int     iface_is_bond(struct lldpd *, const char *);
index e087cca456c8a1e6f8cf840a6d112d3454eef6fb..a2ac841d26ac031cfc2af4f545ec59286244a7a2 100644 (file)
@@ -259,6 +259,7 @@ asroot_open()
                "/proc/self/net/bonding/[^.][^/]*",
                SYSFS_CLASS_NET "[^.][^/]*/brforward",
                SYSFS_CLASS_NET "[^.][^/]*/brport",
+               SYSFS_CLASS_NET "[^.][^/]*/brif/[^.][^/]*/port_no",
                SYSFS_CLASS_DMI "product_version",
                SYSFS_CLASS_DMI "product_serial",
                SYSFS_CLASS_DMI "product_name",