Use 0.0.0.0/0 host route as router option

There is a currently a hacky way to get the dhcp-agent to hand out a
gateway route using a host route on the subnet. If you pass a route
that has 0.0.0.0/0 as its destination, dnsmasq will pass it as a static
route. Unfortunately it will also pass the router option if the subnet
has a gateway set. This is inconsistent and precludes users from options
that are available in nova-network like using an external gateway.

This patch fixes things by allowing a 0.0.0.0/0 host route to override
the router setting passed by dnsmasq. This prevents the situation
where dnsmasq hands out two default routes.

Change-Id: Ia70223070bfd437f1c2eb48fde94491d7ee61fcb
This commit is contained in:
Vishvananda Ishaya 2013-06-10 14:37:26 -07:00
parent 090432c130
commit 86088a2241
2 changed files with 49 additions and 5 deletions

View File

@ -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'))

View File

@ -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