@%@UCRWARNING=# @%@ auto lo iface lo inet loopback @!@ import collections import ipaddr import re try: from univention.ipv4 import networkNumber except ImportError: def splitDotted(ip): quad = map(int, ip.split('.'))[:4] while len(quad) < 4: quad.append(0) return quad def joinDotted(ip): return '%d.%d.%d.%d' % tuple(ip[0:4]) def networkNumber(dottedIp, dottedNetmask): ip = splitDotted(dottedIp) netmask = splitDotted(dottedNetmask) network = map(lambda (i, n): i & n, zip(ip, netmask)) return joinDotted(network) RE_IFACE = re.compile('^interfaces/([^/]+)/((?:ipv6/([^/]+)/)?.*)$') interfaces = {} ipv6_interfaces = {} for key, value in configRegistry.items(): m = RE_IFACE.match(key) if not m: continue iface, subkey, ipv6_name = m.groups() interfaces.setdefault(iface, {})[subkey] = value if ipv6_name: ipv6_interfaces.setdefault(iface, set()).add(ipv6_name) def check_gateway(ip, netmask, gateway): """ Check if the 'ip' is in the same network as the 'gatewy'. >>> check_gateway('1.2.3.4', '255.255.255.0', '1.2.3.1') True """ if not gateway: return False return networkNumber(ip, netmask) == networkNumber(gateway, netmask) def auto(interface, start): """Print 'auto iface' statements only once.""" print if not start: return if interface not in auto.printed_interfaces: print 'auto %s' % interface auto.printed_interfaces.add(interface) auto.printed_interfaces = set() gateway_found = False ifhandler = configRegistry.get('interfaces/handler', 'ifplugd') gateway = configRegistry.get('gateway') primary = configRegistry.get('interface/primary', 'eth0') for interface, settings in sorted(interfaces.items(), key=lambda (interface, settings): settings.get('order', interface)): iface = interface.replace("_", ":") address = settings.get('address') start = configRegistry.is_true('interfaces/%s/start' % interface, True) if settings.get('type') == 'dhcp': if ifhandler == 'ifplugd' and configRegistry.is_true('interfaces/%s/ifplugd' % interface, True): auto(iface, start) print 'iface %s inet dhcp' % iface elif ifhandler == 'networkmanager' and configRegistry.is_false('interfaces/%s/networkmanager' % interface, True): auto(iface, start) print 'iface %s inet dhcp' % iface else: continue if settings.get('type') == 'manual': auto(iface, start) print 'iface %s inet manual' % iface elif address: auto(iface, start) print 'iface %s inet static' % iface print '\taddress %s' % address network = settings.get('network') if network: print '\tnetwork %s' % network netmask = settings.get('netmask') if netmask: print '\tnetmask %s' % netmask broadcast = settings.get('broadcast') if broadcast: print '\tbroadcast %s' % broadcast if address and netmask and gateway and not gateway_found: if check_gateway(address, netmask, gateway): print '\tgateway %s' % gateway gateway_found = True else: continue for key, value in settings.items(): if key.startswith('route/'): if value.startswith('host ') or value.startswith('net '): print '\tup ip route add -%s dev %s' % (value, interface) for key, value in sorted(settings.items()): if key.startswith('options/'): print '\t%s' % (value,) if interface == primary: if settings.get('netmask', "") == "255.255.255.255" and gateway: print "\tup ip route add %s/32 dev %s" % (gateway, primary) print "\tup ip route add default via %s" % (gateway,) gateway_found = False gateway = configRegistry.get('ipv6/gateway') parsedGateway = None try: if gateway: parsedGateway = ipaddr.IPv6Address(gateway) except ValueError: print '# WARNING: %r is not a valid IPv6 address! (from UCRV ipv6/gateway)' % (gateway, ) # UCRV format: interfaces/$DEVICE/ipv6/$NAME/{address,prefix} # 0 1 2 3 4 # $NAME "default" is _the_ v6 address for the interface def sortDefaultFirst(x, y): if x == y: return 0 elif x == 'default': return -1 elif y == 'default': return 1 elif x < y: return -1 elif x > y: return 1 for interface, names in ipv6_interfaces.items(): interface_addresses = [] used_interface_addresses = set() settings = interfaces[interface] start = configRegistry.is_true('interfaces/%s/start' % interface, True) for name in sorted(names, sortDefaultFirst): address = settings.get('ipv6/%s/address' % (name, )) prefix = settings.get('ipv6/%s/prefix' % (name, )) parsedAddress = None parsedPrefix = None try: if address: parsedAddress = ipaddr.IPv6Address(address) except ValueError: print '# WARNING: %r is not a valid IPv6 address! (from UCRV interfaces/%s/ipv6/%s/address)' % (address, interface, name, ) try: if parsedAddress and prefix: parsedPrefix = ipaddr.IPv6Network(address + '/' + prefix) except ValueError: print '# WARNING: %r is not a valid IPv6 prefix (should be integer 0-128)! (from UCRV interfaces/%s/ipv6/%s/prefix)' % (prefix, interface, name, ) if parsedAddress is not None and parsedPrefix is not None: if parsedAddress in used_interface_addresses: print '# WARNING: duplicate address %s for interface (from UCRV interfaces/%s/ipv6/%s/{address,prefix})' % (parsedAddress, interface, name, ) continue interface_addresses.append((name, address, prefix, parsedPrefix, )) used_interface_addresses.add(parsedAddress) if interface_addresses: auto(interface, start) print 'iface %s inet6 static' % (interface, ) # check if gateway is local on this interface if not gateway_found and parsedGateway: if [True for (n, a, nm, parsedPrefix, ) in interface_addresses if parsedPrefix and parsedGateway in parsedPrefix]: print '\tgateway %s' % gateway gateway_found = True ((name, address, prefix, parsedPrefix, ), interface_addresses, ) = (interface_addresses[0], interface_addresses[1:], ) # first address is a special case print '# %s' % (name, ) print '\taddress %s' % address print '\tnetmask %s' % prefix # rest via up/down commands for (name, address, prefix, parsedPrefix, ) in interface_addresses: print '# %s' % (name, ) print '\tup ip addr add %s/%s dev %s' % (address, prefix, interface, ) print '\tdown ip addr del %s/%s dev %s' % (address, prefix, interface, ) @!@