* 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>
}
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;
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;
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;
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
/* 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
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)
/* 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)
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();