]> git.ipfire.org Git - thirdparty/lldpd.git/commitdiff
Don't send anything on inactive slaves (this confuses most switches)
authorVincent Bernat <vbernat@wanadooportails.com>
Mon, 8 Dec 2008 10:08:09 +0000 (11:08 +0100)
committerVincent Bernat <vbernat@wanadooportails.com>
Mon, 8 Dec 2008 10:08:09 +0000 (11:08 +0100)
CHANGELOG
src/features.c
src/lldpd.c
src/lldpd.h

index 411fd44fa1d939223cede93821e566ec67cbc493..cb96a1a1fc991cb246887a8c50d89799a0256828 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,6 +2,7 @@ lldpd (0.3)
 
   * Initial support of LLDP-MED (inventory part)
   * Fix for bridge detection (don't send bridge ioctl on random interfaces)
+  * Don't send anything on inactive slaves (this confuses most switches)
 
  -- Vincent Bernat <bernat@luffy.cx>
 
index acc766d8a563014605e03d8b52b418ec132404f5..c3440731d8992c913ca4cbe1366819a76d95dbf6 100644 (file)
@@ -118,7 +118,8 @@ iface_is_bond(struct lldpd *cfg, const char *name)
 }
 
 int
-iface_is_bond_slave(struct lldpd *cfg, const char *slave, const char *master)
+iface_is_bond_slave(struct lldpd *cfg, const char *slave, const char *master,
+    int *active)
 {
        struct ifreq ifr;
        struct ifbond ifb;
@@ -135,8 +136,11 @@ iface_is_bond_slave(struct lldpd *cfg, const char *slave, const char *master)
                        ifr.ifr_data = &ifs;
                        ifs.slave_id = ifb.num_slaves;
                        if ((ioctl(cfg->g_sock, SIOCBONDSLAVEINFOQUERY, &ifr) >= 0) &&
-                           (strncmp(ifs.slave_name, slave, sizeof(ifs.slave_name)) == 0))
+                           (strncmp(ifs.slave_name, slave, sizeof(ifs.slave_name)) == 0)) {
+                               if (active)
+                                       *active = ifs.state;
                                return 1;
+                       }
                }
        }
        return 0;
@@ -153,7 +157,7 @@ iface_is_enslaved(struct lldpd *cfg, const char *name)
                return -1;
        }
        for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
-               if (iface_is_bond_slave(cfg, name, ifa->ifa_name)) {
+               if (iface_is_bond_slave(cfg, name, ifa->ifa_name, NULL)) {
                        master = if_nametoindex(ifa->ifa_name);
                        freeifaddrs(ifap);
                        return master;
@@ -163,6 +167,24 @@ iface_is_enslaved(struct lldpd *cfg, const char *name)
        return -1;
 }
 
+int
+iface_is_slave_active(struct lldpd *cfg, int master, const char *slave)
+{
+       char mastername[IFNAMSIZ];
+       int active;
+       if (if_indextoname(master, mastername) == NULL) {
+               LLOG_WARNX("unable to get master name for %s",
+                   slave);
+               return 0;       /* Safest choice */
+       }
+       if (!iface_is_bond_slave(cfg, slave, mastername, &active)) {
+               LLOG_WARNX("unable to get slave status for %s",
+                   slave);
+               return 0;               /* Safest choice */
+       }
+       return (active == BOND_STATE_ACTIVE);
+}
+
 #ifdef ENABLE_LLDPMED
        /* Fill in inventory stuff:
            - hardware version: /sys/class/dmi/id/product_version
index d5cf46df005f9203567570ba5ad3ea9f1b5a49ad..9f6dd1f7a97b0260363abd92976c8f901f85832d 100644 (file)
@@ -581,7 +581,7 @@ lldpd_port_add(struct lldpd *cfg, struct ifaddrs *ifa)
 
                /* Aggregation check */
 #ifdef ENABLE_DOT3
-               if (iface_is_bond_slave(cfg, hardware->h_ifname, oifa->ifa_name))
+               if (iface_is_bond_slave(cfg, hardware->h_ifname, oifa->ifa_name, NULL))
                        port->p_aggregid = if_nametoindex(oifa->ifa_name);
 #endif
 
@@ -591,7 +591,7 @@ lldpd_port_add(struct lldpd *cfg, struct ifaddrs *ifa)
                ifv.cmd = GET_VLAN_REALDEV_NAME_CMD;
                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)) ||
+                   ((iface_is_bond_slave(cfg, hardware->h_ifname, ifv.u.device2, NULL)) ||
                     (strncmp(hardware->h_ifname, ifv.u.device2, sizeof(ifv.u.device2)) == 0))) {
                        if ((vlan = (struct lldpd_vlan *)
                             calloc(1, sizeof(struct lldpd_vlan))) == NULL)
@@ -1181,6 +1181,14 @@ lldpd_send_all(struct lldpd *cfg)
                /* Ignore if interface is down */
                if ((hardware->h_flags & IFF_UP) == 0)
                        continue;
+               /* Don't send on inactive slaves */
+               if ((hardware->h_raw_real > 0) &&
+                   (!iface_is_slave_active(cfg, hardware->h_master,
+                       hardware->h_ifname))) {
+                       LLOG_DEBUG("%s is inactive, don't send anything",
+                               hardware->h_ifname);
+                       continue;
+               }
 
                for (i=0; cfg->g_protocols[i].mode != 0; i++) {
                        if (!cfg->g_protocols[i].enabled)
index 6312c1dfb3101bbdb235e207a0615f7149857460..b65b815ae288e9d5500d1aecaf918a77fbd6f386 100644 (file)
@@ -334,8 +334,9 @@ int  iface_is_wireless(struct lldpd *, const char *);
 int     iface_is_vlan(struct lldpd *, const char *);
 int     iface_is_bond(struct lldpd *, const char *);
 int     iface_is_bond_slave(struct lldpd *,
-           const char *, const char *);
+    const char *, const char *, int *);
 int     iface_is_enslaved(struct lldpd *, const char *);
+int     iface_is_slave_active(struct lldpd *, int, const char *);
 #ifdef ENABLE_LLDPMED
 char   *dmi_hw();
 char   *dmi_fw();