From beeaefa353f0434eb23768678866c8f4df0ea922 Mon Sep 17 00:00:00 2001 From: Vincent Bernat Date: Mon, 8 Dec 2008 11:08:09 +0100 Subject: [PATCH] Don't send anything on inactive slaves (this confuses most switches) --- CHANGELOG | 1 + src/features.c | 28 +++++++++++++++++++++++++--- src/lldpd.c | 12 ++++++++++-- src/lldpd.h | 3 ++- 4 files changed, 38 insertions(+), 6 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 411fd44f..cb96a1a1 100644 --- 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 diff --git a/src/features.c b/src/features.c index acc766d8..c3440731 100644 --- a/src/features.c +++ b/src/features.c @@ -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 diff --git a/src/lldpd.c b/src/lldpd.c index d5cf46df..9f6dd1f7 100644 --- a/src/lldpd.c +++ b/src/lldpd.c @@ -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) diff --git a/src/lldpd.h b/src/lldpd.h index 6312c1df..b65b815a 100644 --- a/src/lldpd.h +++ b/src/lldpd.h @@ -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(); -- 2.39.5