@@ -105,3 +105,106 @@ class HugePageConfig(object):
return
utils.system("echo 0 > %s" % self.kernel_hp_file)
logging.debug("Hugepage memory successfuly dealocated")
+
+
+class PrivateBridgeError(Exception):
+ def __init__(self, brname):
+ self.brname = brname
+
+ def __str__(self):
+ return "Bridge %s not available after setup" % self.brname
+
+
+class PrivateBridgeConfig(object):
+ __shared_state = {}
+ def __init__(self, params=None):
+ self.__dict__ = self.__shared_state
+ if params is not None:
+ self.brname = params.get("priv_brname", 'atbr0')
+ self.subnet = params.get("priv_subnet", '192.168.58')
+ self.ip_version = params.get("bridge_ip_version", "ipv4")
+ self.dhcp_server_pid = None
+
+
+ def _add_bridge(self):
+ utils.system("brctl addbr %s" % self.brname)
+ ip_fwd_path = "/proc/sys/net/%s/ip_forward" % self.ip_version
+ ip_fwd = open(ip_fwd_path, "w")
+ ip_fwd.write("1\n")
+ utils.system("brctl stp %s on" % self.brname)
+ utils.system("brctl setfd %s 0" % self.brname)
+
+
+ def _bring_bridge_up(self):
+ utils.system("ifconfig %s %s.1 up" % (self.brname, self.subnet))
+
+
+ def _enable_nat(self):
+ utils.system("iptables -t nat -A POSTROUTING -s %s.254/24 ! "
+ "-d %s.254/24 -j MASQUERADE" % (self.subnet, self.subnet))
+
+
+ def _start_dhcp_server(self):
+ utils.system("service dnsmasq stop")
+ utils.system("dnsmasq --strict-order --bind-interfaces "
+ "--listen-address %s.1 --dhcp-range %s.1,%s.254 "
+ "--pid-file=/tmp/dnsmasq.pid "
+ "--log-facility=/tmp/dnsmasq.log" %
+ (self.subnet, self.subnet, self.subnet))
+ try:
+ self.dhcp_server_pid = int(open('/tmp/dnsmasq.pid', 'r').read())
+ except ValueError:
+ raise PrivateBridgeError(self.brname)
+ logging.debug("Started internal DHCP server with PID %s",
+ self.dhcp_server_pid)
+
+
+ def _verify_bridge(self):
+ brctl_output = utils.system_output("brctl show")
+ if self.brname not in brctl_output:
+ raise PrivateBridgeError(self.brname)
+
+
+ def setup(self):
+ brctl_output = utils.system_output("brctl show")
+ if self.brname not in brctl_output:
+ logging.info("Configuring KVM test private bridge %s", self.brname)
+ self._add_bridge()
+ self._bring_bridge_up()
+ self._enable_nat()
+ self._start_dhcp_server()
+ self._verify_bridge()
+
+
+ def _stop_dhcp_server(self):
+ os.kill(self.dhcp_server_pid, 15)
+
+
+ def _bring_bridge_down(self):
+ utils.system("ifconfig %s down" % self.brname)
+
+
+ def _disable_nat(self):
+ utils.system("iptables -t nat -D POSTROUTING -s %s.254/24 !"
+ " -d %s.254/24 -j MASQUERADE" % (self.subnet, self.subnet))
+
+
+ def _remove_bridge(self):
+ utils.system("brctl delbr %s" % self.brname)
+
+
+ def cleanup(self):
+ brctl_output = utils.system_output("brctl show")
+ cleanup = False
+ for line in brctl_output:
+ if line.startswith(self.brname):
+ # len == 4 means there is a TAP using the bridge
+ # so don't try to clean up
+ if len(line.split()) < 4:
+ cleanup = True
+ if cleanup:
+ logging.debug("Cleaning up KVM test private bridge %s", self.brname)
+ self._stop_dhcp_server()
+ self._bring_bridge_down()
+ self._disable_nat()
+ self._remove_bridge()