# HG changeset patch # User Tero Marttila # Date 1395170735 -7200 # Node ID de275bf6db7002c665ffe988e7bfb24f7095e0f0 # Parent 8455f42d8926a7fa9c087bad2e0b05f1e7687cbe pvl.hosts-lldp: handle non-lldp-supporting switches, use dot1q per default for (port, vlan) leaf node mappings, with fallback to dot1d diff -r 8455f42d8926 -r de275bf6db70 bin/pvl.hosts-lldp --- a/bin/pvl.hosts-lldp Tue Mar 18 21:24:35 2014 +0200 +++ b/bin/pvl.hosts-lldp Tue Mar 18 21:25:35 2014 +0200 @@ -51,6 +51,10 @@ except snmp.SNMPError as ex : log.warning("%s: %s", host, ex) continue + + if not local : + log.info("%s: no lldp support", host) + continue log.info("%s: %s", host, local) @@ -117,7 +121,13 @@ # second pass to discver links for host, agent in _hosts_lldp : - for port, remote in agent.remotes() : + try : + remotes = list(agent.remotes()) + except snmp.SNMPError as ex : + log.warn("%s: broken lldp remotes: %s", host, ex) + continue + + for port, remote in remotes : port = agent.port(port) remote_chassis = remote['chassis'] @@ -145,7 +155,7 @@ # multiple taggd vlans / port vlan_tagged = collections.defaultdict(set) - for vlan, (tagged, untagged) in agent.vlans() : + for vlan, (tagged, untagged) in agent.vlan_ports() : log.info("%s: %s: %s + %s", host, vlan, tagged, untagged) for port in tagged : @@ -174,10 +184,38 @@ for host, agent in hosts_bridge(options, hosts) : ports = collections.defaultdict(list) - for ether, port in agent.fdb() : - if port : - ports[port].append(ether) - + try : + vlan_fdb_ports = list(agent.vlan_fdb_ports()) + except snmp.SNMPError as ex : + log.warn("%s: broken dot1q fdb: %s", host, ex) + continue + + if vlan_fdb_ports : + log.info("%s: have dot1q ports", host) + + for ether, port, vlan in agent.vlan_fdb_ports() : + if not port : + # XXX: unknown? + continue + + ports[(port, vlan)].append(ether) + else : + try : + fdb_ports = list(agent.fdb_ports()) + except snmp.SNMPError as ex : + log.warn("%s: broken dot1q fdb: %s", host, ex) + continue + + # fallback to dot1d fdb + log.info("%s: fallback to dot1d", host) + + for ether, port in agent.fdb_ports() : + if not port : + # XXX: unknown? + continue + + ports[(port, None)].append(ether) + yield host, ports COLOR_VLANS = { @@ -394,11 +432,23 @@ if remote_host : print "{host:30} {host.location:>30} {local[port]:>25} <-> {remote[port]:<25} {remote_host.location:>30} # {remote[chassis]} ({remote_host})".format(host=host, local=local, remote=remote, remote_host=remote_host) else : - print "{host:30} {host.location:>30} {local[port]:>25} <-- {remote[port]:<25} {empty:30} # {remote[chassis]} ({remote[sys_name]})".format(host=host, local=local, remote=remote, empty='') + print "{host:30} {host.location:>30} {local[port]:>25} --> {remote[port]:<25} {empty:30} # {remote[chassis]} ({remote[sys_name]})".format(host=host, local=local, remote=remote, empty='') + for host, ports in vlans.iteritems() : + for port, (untag, tagged) in ports.iteritems() : + print "{host:30} {host.location:>30} {port:25} {untag}{tagged}".format(host=host, port=port, + untag = '({untag}) '.format(untag=untag) if untag else '', + tagged = ' '.join('<{tag}>'.format(tag=tag) for tag in tagged), + ) + for host, ports in leafs : - for port, ethers in ports.iteritems() : - print "{host:30} {host.location:>30} {port:25} <== # {ethers}".format(host=host, port=port, ethers=' '.join(ethers)) + for (port, vlan), ethers in ports.iteritems() : + print "{host:30} {host.location:>30} {port:25} <-- {vlan} # {ethers}".format( + host = host, + port = port, + vlan = '<{vlan}>'.format(vlan=vlan) if vlan else '', + ethers = ' '.join(ethers), + ) if __name__ == '__main__': pvl.args.main(main)