Remove quadratic netifaces.interfaces() call
[invirt/packages/invirt-dhcp.git] / invirt-dhcpserver
index 5c96f13..6ffcbda 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/python
+import os.path
 import sys
 import pydhcplib
 import pydhcplib.dhcp_network
@@ -24,11 +25,32 @@ from invirt.config import structs as config
 dhcp_options = {'domain_name_server': ','.join(config.dhcp.dns),
                 'ip_address_lease_time': config.dhcp.get('leasetime', 60*60*24)}
 
+class Interfaces(object):
+    @staticmethod
+    def primary_ip(name):
+        """primary_ip returns an interface's primary IP address.
+
+        This is the first IPv4 address returned by "ip addr show $name"
+        """
+        # TODO(quentin): The netifaces module is a pile of crappy C.
+        # Figure out a way to do this in native Python.
+        return ni.ifaddresses(name)[ni.AF_INET][0]['addr']
+
+    @staticmethod
+    def exists(name):
+        """exists checks if an interface exists.
+
+        Args:
+        name: Interface name
+        """
+        return os.path.exists("/sys/class/net/"+name)
+
+
 class DhcpBackend:
     def __init__(self, queue):
         database.connect()
         self.queue = queue
-        self.main_ip = ni.ifaddresses(config.xen.iface)[ni.AF_INET][0]['addr']
+        self.main_ip = Interfaces.primary_ip(config.xen.iface)
     def add_route_and_arp(self, ip, intf, gateway):
         try:
             p = Popen(['ip', 'route', 'add', ip, 'dev', intf, 'src', self.main_ip, 'metric', '2' if intf.startswith('vif') else '1'], stdout=PIPE, stderr=PIPE)
@@ -77,7 +99,7 @@ class DhcpBackend:
                     # in use.
                     for viftype in ('tap', 'vif'):
                         vif = '%s%s.%s' % (viftype, domid, vifnum)
-                        if vif in ni.interfaces():
+                        if Interface.exists(vif):
                             self.add_route_and_arp(nic.ip, vif, nic.gateway)
                             xsc.close()
                             return vif