diff --git a/etc/dhcp_agent.ini b/etc/dhcp_agent.ini index e9c458c30e..377c83b649 100644 --- a/etc/dhcp_agent.ini +++ b/etc/dhcp_agent.ini @@ -22,6 +22,10 @@ interface_driver = quantum.agent.linux.interface.OVSInterfaceDriver # no additional setup of the DHCP server. dhcp_driver = quantum.agent.linux.dhcp.Dnsmasq +# Allow overlapping IP (Must have kernel build with CONFIG_NET_NS=y and +# iproute2 package that supports namespaces). +use_namespaces = True + # # Temporary F2 variables until the Agent <> Quantum Server is reworked in F3 # diff --git a/quantum/agent/dhcp_agent.py b/quantum/agent/dhcp_agent.py index 9e3e48d1c3..0643acbf57 100644 --- a/quantum/agent/dhcp_agent.py +++ b/quantum/agent/dhcp_agent.py @@ -53,7 +53,9 @@ class DhcpAgent(object): help="The time in seconds between state poll requests."), cfg.IntOpt('reconnect_interval', default=5, - help="The time in seconds between db reconnect attempts.") + help="The time in seconds between db reconnect attempts."), + cfg.BoolOpt('use_namespaces', default=True, + help="Allow overlapping IP.") ] def __init__(self, conf): @@ -211,7 +213,6 @@ class DeviceManager(object): def __init__(self, conf, db): self.conf = conf self.db = db - if not conf.interface_driver: LOG.error(_('You must specify an interface driver')) self.driver = importutils.import_object(conf.interface_driver, conf) @@ -232,9 +233,14 @@ class DeviceManager(object): port = self._get_or_create_port(network) interface_name = self.get_interface_name(network, port) - if ip_lib.device_exists(interface_name, - self.conf.root_helper, - network.id): + if self.conf.use_namespaces: + namespace = network.id + else: + namespace = None + + if ip_lib.device_exists(interface_name, + self.conf.root_helper, + namespace): if not reuse_existing: raise exceptions.PreexistingDeviceFailure( dev_name=interface_name) @@ -245,7 +251,7 @@ class DeviceManager(object): port.id, interface_name, port.mac_address, - namespace=network.id) + namespace=namespace) ip_cidrs = [] for fixed_ip in port.fixed_ips: subnet = fixed_ip.subnet @@ -254,7 +260,7 @@ class DeviceManager(object): ip_cidrs.append(ip_cidr) self.driver.init_l3(interface_name, ip_cidrs, - namespace=network.id) + namespace=namespace) def destroy(self, network): self.driver.unplug(self.get_interface_name(network)) diff --git a/quantum/agent/linux/dhcp.py b/quantum/agent/linux/dhcp.py index 5792f9a71f..270a2c4ffe 100644 --- a/quantum/agent/linux/dhcp.py +++ b/quantum/agent/linux/dhcp.py @@ -112,9 +112,12 @@ class DhcpLocalProcess(DhcpBase): if self.active: cmd = ['kill', '-9', pid] - ip_wrapper = ip_lib.IPWrapper(self.root_helper, - namespace=self.network.id) - ip_wrapper.netns.execute(cmd) + if self.conf.use_namespaces: + ip_wrapper = ip_lib.IPWrapper(self.root_helper, + namespace=self.network.id) + ip_wrapper.netns.execute(cmd) + else: + utils.execute(cmd, self.root_helper) self.device_delegate.destroy(self.network) elif pid: LOG.debug(_('DHCP for %s pid %d is stale, ignoring command') % @@ -222,9 +225,12 @@ class Dnsmasq(DhcpLocalProcess): if self.conf.dnsmasq_dns_server: cmd.append('--server=%s' % self.conf.dnsmasq_dns_server) - ip_wrapper = ip_lib.IPWrapper(self.root_helper, - namespace=self.network.id) - ip_wrapper.netns.execute(cmd) + if self.conf.use_namespaces: + ip_wrapper = ip_lib.IPWrapper(self.root_helper, + namespace=self.network.id) + ip_wrapper.netns.execute(cmd) + else: + utils.execute(cmd, self.root_helper) def reload_allocations(self): """If all subnets turn off dhcp, kill the process.""" @@ -238,9 +244,13 @@ class Dnsmasq(DhcpLocalProcess): self._output_hosts_file() self._output_opts_file() cmd = ['kill', '-HUP', self.pid] - ip_wrapper = ip_lib.IPWrapper(self.root_helper, - namespace=self.network.id) - ip_wrapper.netns.execute(cmd) + + if self.conf.use_namespaces: + ip_wrapper = ip_lib.IPWrapper(self.root_helper, + namespace=self.network.id) + ip_wrapper.netns.execute(cmd) + else: + utils.execute(cmd, self.root_helper) LOG.debug(_('Reloading allocations for network: %s') % self.network.id) def _output_hosts_file(self): diff --git a/quantum/tests/unit/test_dhcp_agent.py b/quantum/tests/unit/test_dhcp_agent.py index b1c822f800..d42b937303 100644 --- a/quantum/tests/unit/test_dhcp_agent.py +++ b/quantum/tests/unit/test_dhcp_agent.py @@ -378,6 +378,7 @@ class TestDeviceManager(unittest.TestCase): self.conf.set_override('interface_driver', 'quantum.agent.linux.interface.NullDriver') self.conf.root_helper = 'sudo' + self.conf.use_namespaces = True self.client_cls_p = mock.patch('quantumclient.v2_0.client.Client') client_cls = self.client_cls_p.start() diff --git a/quantum/tests/unit/test_linux_dhcp.py b/quantum/tests/unit/test_linux_dhcp.py index 2686253812..effdfe8df6 100644 --- a/quantum/tests/unit/test_linux_dhcp.py +++ b/quantum/tests/unit/test_linux_dhcp.py @@ -168,6 +168,7 @@ class TestBase(unittest.TestCase): self.conf.register_opts(dhcp.OPTS) self.conf(args=args) self.conf.set_override('state_path', '') + self.conf.use_namespaces = True self.replace_p = mock.patch('quantum.agent.linux.dhcp.replace_file') self.execute_p = mock.patch('quantum.agent.linux.utils.execute')