From 0852c5da007016987afe5a452f44d800b306d742 Mon Sep 17 00:00:00 2001 From: Dag Wieers Date: Wed, 20 Mar 2013 17:35:37 +0100 Subject: [PATCH] Improve Linux network facts incl. bridges, ppp, wwan devices This patch adds all interfaces (even inactive ones) to setup output. --- setup | 101 ++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 56 insertions(+), 45 deletions(-) diff --git a/setup b/setup index 74799ebca91..1849bb90c37 100644 --- a/setup +++ b/setup @@ -982,21 +982,53 @@ class LinuxNetwork(Network): all_ipv4_addresses = [], all_ipv6_addresses = [], ) - rc, out, err = module.run_command([ip_path, 'addr', 'show']) - for line in out.split('\n'): - if line: + + for path in glob.glob('/sys/class/net/*'): + if not os.path.isdir(path): continue + device = os.path.basename(path) + interfaces[device] = { 'device': device } + if os.path.exists(os.path.join(path, 'address')): + macaddress = open(os.path.join(path, 'address')).read().strip() + if macaddress and macaddress != '00:00:00:00:00:00': + interfaces[device]['macaddress'] = macaddress + if os.path.exists(os.path.join(path, 'mtu')): + interfaces[device]['mtu'] = int(open(os.path.join(path, 'mtu')).read().strip()) + if os.path.exists(os.path.join(path, 'operstate')): + interfaces[device]['active'] = open(os.path.join(path, 'operstate')).read().strip() != 'down' +# if os.path.exists(os.path.join(path, 'carrier')): +# interfaces[device]['link'] = open(os.path.join(path, 'carrier')).read().strip() == '1' + if os.path.exists(os.path.join(path, 'device','driver', 'module')): + interfaces[device]['module'] = os.path.basename(os.path.realpath(os.path.join(path, 'device', 'driver', 'module'))) + if os.path.exists(os.path.join(path, 'type')): + type = open(os.path.join(path, 'type')).read().strip() + if type == '1': + interfaces[device]['type'] = 'ether' + elif type == '512': + interfaces[device]['type'] = 'ppp' + elif type == '772': + interfaces[device]['type'] = 'loopback' + if os.path.exists(os.path.join(path, 'bridge')): + interfaces[device]['type'] = 'bridge' + interfaces[device]['interfaces'] = [ os.path.basename(b) for b in glob.glob(os.path.join(path, 'brif', '*')) ] + if os.path.exists(os.path.join(path, 'bridge', 'bridge_id')): + interfaces[device]['id'] = open(os.path.join(path, 'bridge', 'bridge_id')).read().strip() + if os.path.exists(os.path.join(path, 'bridge', 'stp_state')): + interfaces[device]['stp'] = open(os.path.join(path, 'bridge', 'stp_state')).read().strip() == '1' + if os.path.exists(os.path.join(path, 'bonding')): + interfaces[device]['type'] = 'bonding' + interfaces[device]['slaves'] = open(os.path.join(path, 'bonding', 'slaves')).read().split() + interfaces[device]['mode'] = open(os.path.join(path, 'bonding', 'mode')).read().split()[0] + interfaces[device]['miimon'] = open(os.path.join(path, 'bonding', 'miimon')).read().split()[0] + interfaces[device]['lacp_rate'] = open(os.path.join(path, 'bonding', 'lacp_rate')).read().split()[0] + primary = open(os.path.join(path, 'bonding', 'primary')).read() + if primary: + interfaces[device]['primary'] = primary + interfaces[device]['all_slaves_active'] = open(os.path.join(path, 'bonding', 'all_slaves_active')).read() == '1' + output = subprocess.Popen(['/sbin/ip', 'addr', 'show', device], stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()[0] + for line in output.split('\n'): + if not line: continue words = line.split() - if not line.startswith(' '): - device = words[1][0:-1] - mtu = words[4] - elif words[0].startswith('link/'): - iface_type = words[0].split('/')[1] - # tun interfaces can have any interface type, but won't have an address - if iface_type in ('void', 'none') or len(words) == 1: - macaddress = 'unknown' - else: - macaddress = words[1] - elif words[0] == 'inet': + if words[0] == 'inet': if '/' in words[1]: address, netmask_length = words[1].split('/') else: @@ -1004,26 +1036,13 @@ class LinuxNetwork(Network): address = words[1] netmask_length = "32" address_bin = struct.unpack('!L', socket.inet_aton(address))[0] - netmask_bin = (1<<32) - (1<<32>>int(netmask_length)) netmask = socket.inet_ntoa(struct.pack('!L', netmask_bin)) - network = socket.inet_ntoa(struct.pack('!L', address_bin & netmask_bin)) - iface = words[-1] - # If an interface has multiple IPv4 addresses, make up an - # interface name for each address - if iface in interfaces: - i = 0 - while str(iface) + "_" + str(i) in interfaces: - i += 1 - iface = str(iface) + "_" + str(i) - - interfaces[iface] = {} - interfaces[iface]['macaddress'] = macaddress - interfaces[iface]['mtu'] = mtu - interfaces[iface]['type'] = iface_type - interfaces[iface]['device'] = device + if iface != device: + interfaces[iface] = {} + interfaces[iface].update(facts[device]) interfaces[iface]['ipv4'] = {'address': address, 'netmask': netmask, 'network': network} @@ -1033,26 +1052,18 @@ class LinuxNetwork(Network): default_ipv4['netmask'] = netmask default_ipv4['network'] = network default_ipv4['macaddress'] = macaddress - default_ipv4['mtu'] = mtu - default_ipv4['type'] = iface_type + default_ipv4['mtu'] = interfaces[device]['mtu'] + default_ipv4['type'] = interfaces[device]['type'] default_ipv4['alias'] = words[-1] if not address.startswith('127.'): ips['all_ipv4_addresses'].append(address) - elif words[0] == 'inet6': address, prefix = words[1].split('/') scope = words[3] - - iface = device - if iface not in interfaces: - interfaces[iface] = {} - interfaces[iface]['macaddress'] = macaddress - interfaces[iface]['mtu'] = mtu - interfaces[iface]['device'] = device - if 'ipv6' not in interfaces[iface]: - interfaces[iface]['ipv6'] = [] - interfaces[iface]['ipv6'].append( { + if 'ipv6' not in interfaces[device]: + interfaces[device]['ipv6'] = [] + interfaces[device]['ipv6'].append( { 'address': address, 'prefix': prefix, 'scope': scope} ) @@ -1062,8 +1073,8 @@ class LinuxNetwork(Network): default_ipv6['prefix'] = prefix default_ipv6['scope'] = scope default_ipv6['macaddress'] = macaddress - default_ipv6['mtu'] = mtu - default_ipv6['type'] = iface_type + default_ipv6['mtu'] = interfaces[device]['mtu'] + default_ipv6['type'] = interfaces[device]['type'] if not address == '::1': ips['all_ipv6_addresses'].append(address)