diff --git a/quantum/agent/linux/dhcp.py b/quantum/agent/linux/dhcp.py index 54f620d783..fb1a68705f 100644 --- a/quantum/agent/linux/dhcp.py +++ b/quantum/agent/linux/dhcp.py @@ -367,8 +367,13 @@ class Dnsmasq(DhcpLocalProcess): self._format_option(i, 'dns-server', ','.join(subnet.dns_nameservers))) - host_routes = ["%s,%s" % (hr.destination, hr.nexthop) - for hr in subnet.host_routes] + gateway = subnet.gateway_ip + host_routes = [] + for hr in subnet.host_routes: + if hr.destination == "0.0.0.0/0": + gateway = hr.nexthop + else: + host_routes.append("%s,%s" % (hr.destination, hr.nexthop)) # Add host routes for isolated network segments enable_metadata = ( @@ -388,9 +393,8 @@ class Dnsmasq(DhcpLocalProcess): ','.join(host_routes))) if subnet.ip_version == 4: - if subnet.gateway_ip: - options.append(self._format_option(i, 'router', - subnet.gateway_ip)) + if gateway: + options.append(self._format_option(i, 'router', gateway)) else: options.append(self._format_option(i, 'router')) diff --git a/quantum/tests/unit/test_linux_dhcp.py b/quantum/tests/unit/test_linux_dhcp.py index 0590922805..ed2f89f4e5 100644 --- a/quantum/tests/unit/test_linux_dhcp.py +++ b/quantum/tests/unit/test_linux_dhcp.py @@ -60,6 +60,11 @@ class FakeV4HostRoute: nexthop = '20.0.0.1' +class FakeV4HostRouteGateway: + destination = '0.0.0.0/0' + nexthop = '10.0.0.1' + + class FakeV6HostRoute: destination = 'gdca:3ba5:a17a:4ba3::/64' nexthop = 'gdca:3ba5:a17a:4ba3::1' @@ -75,6 +80,16 @@ class FakeV4Subnet: dns_nameservers = ['8.8.8.8'] +class FakeV4SubnetGatewayRoute: + id = 'dddddddd-dddd-dddd-dddd-dddddddddddd' + ip_version = 4 + cidr = '192.168.0.0/24' + gateway_ip = '192.168.0.1' + enable_dhcp = True + host_routes = [FakeV4HostRouteGateway] + dns_nameservers = ['8.8.8.8'] + + class FakeV6Subnet: id = 'ffffffff-ffff-ffff-ffff-ffffffffffff' ip_version = 6 @@ -123,6 +138,12 @@ class FakeDualNetwork: ports = [FakePort1(), FakePort2(), FakePort3()] +class FakeDualNetworkGatewayRoute: + id = 'cccccccc-cccc-cccc-cccc-cccccccccccc' + subnets = [FakeV4SubnetGatewayRoute(), FakeV6Subnet()] + ports = [FakePort1(), FakePort2(), FakePort3()] + + class FakeDualNetworkSingleDHCP: id = 'cccccccc-cccc-cccc-cccc-cccccccccccc' subnets = [FakeV4Subnet(), FakeV4SubnetNoDHCP()] @@ -495,6 +516,25 @@ tag:tag1,option:classless-static-route,%s,%s""".lstrip() % (fake_v6, self.safe.assert_called_once_with('/foo/opts', expected) + def test_output_opts_file_gateway_route(self): + fake_v6 = 'gdca:3ba5:a17a:4ba3::1' + fake_v6_cidr = 'gdca:3ba5:a17a:4ba3::/64' + expected = """ +tag:tag0,option:dns-server,8.8.8.8 +tag:tag0,option:router,10.0.0.1 +tag:tag1,option:dns-server,%s +tag:tag1,option:classless-static-route,%s,%s""".lstrip() % (fake_v6, + fake_v6_cidr, + fake_v6) + + with mock.patch.object(dhcp.Dnsmasq, 'get_conf_file_name') as conf_fn: + conf_fn.return_value = '/foo/opts' + dm = dhcp.Dnsmasq(self.conf, FakeDualNetworkGatewayRoute(), + version=float(2.59)) + dm._output_opts_file() + + self.safe.assert_called_once_with('/foo/opts', expected) + def test_output_opts_file_single_dhcp(self): expected = """ tag:tag0,option:dns-server,8.8.8.8