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:
parent
090432c130
commit
86088a2241
|
@ -367,8 +367,13 @@ class Dnsmasq(DhcpLocalProcess):
|
||||||
self._format_option(i, 'dns-server',
|
self._format_option(i, 'dns-server',
|
||||||
','.join(subnet.dns_nameservers)))
|
','.join(subnet.dns_nameservers)))
|
||||||
|
|
||||||
host_routes = ["%s,%s" % (hr.destination, hr.nexthop)
|
gateway = subnet.gateway_ip
|
||||||
for hr in subnet.host_routes]
|
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
|
# Add host routes for isolated network segments
|
||||||
enable_metadata = (
|
enable_metadata = (
|
||||||
|
@ -388,9 +393,8 @@ class Dnsmasq(DhcpLocalProcess):
|
||||||
','.join(host_routes)))
|
','.join(host_routes)))
|
||||||
|
|
||||||
if subnet.ip_version == 4:
|
if subnet.ip_version == 4:
|
||||||
if subnet.gateway_ip:
|
if gateway:
|
||||||
options.append(self._format_option(i, 'router',
|
options.append(self._format_option(i, 'router', gateway))
|
||||||
subnet.gateway_ip))
|
|
||||||
else:
|
else:
|
||||||
options.append(self._format_option(i, 'router'))
|
options.append(self._format_option(i, 'router'))
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,11 @@ class FakeV4HostRoute:
|
||||||
nexthop = '20.0.0.1'
|
nexthop = '20.0.0.1'
|
||||||
|
|
||||||
|
|
||||||
|
class FakeV4HostRouteGateway:
|
||||||
|
destination = '0.0.0.0/0'
|
||||||
|
nexthop = '10.0.0.1'
|
||||||
|
|
||||||
|
|
||||||
class FakeV6HostRoute:
|
class FakeV6HostRoute:
|
||||||
destination = 'gdca:3ba5:a17a:4ba3::/64'
|
destination = 'gdca:3ba5:a17a:4ba3::/64'
|
||||||
nexthop = 'gdca:3ba5:a17a:4ba3::1'
|
nexthop = 'gdca:3ba5:a17a:4ba3::1'
|
||||||
|
@ -75,6 +80,16 @@ class FakeV4Subnet:
|
||||||
dns_nameservers = ['8.8.8.8']
|
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:
|
class FakeV6Subnet:
|
||||||
id = 'ffffffff-ffff-ffff-ffff-ffffffffffff'
|
id = 'ffffffff-ffff-ffff-ffff-ffffffffffff'
|
||||||
ip_version = 6
|
ip_version = 6
|
||||||
|
@ -123,6 +138,12 @@ class FakeDualNetwork:
|
||||||
ports = [FakePort1(), FakePort2(), FakePort3()]
|
ports = [FakePort1(), FakePort2(), FakePort3()]
|
||||||
|
|
||||||
|
|
||||||
|
class FakeDualNetworkGatewayRoute:
|
||||||
|
id = 'cccccccc-cccc-cccc-cccc-cccccccccccc'
|
||||||
|
subnets = [FakeV4SubnetGatewayRoute(), FakeV6Subnet()]
|
||||||
|
ports = [FakePort1(), FakePort2(), FakePort3()]
|
||||||
|
|
||||||
|
|
||||||
class FakeDualNetworkSingleDHCP:
|
class FakeDualNetworkSingleDHCP:
|
||||||
id = 'cccccccc-cccc-cccc-cccc-cccccccccccc'
|
id = 'cccccccc-cccc-cccc-cccc-cccccccccccc'
|
||||||
subnets = [FakeV4Subnet(), FakeV4SubnetNoDHCP()]
|
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)
|
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):
|
def test_output_opts_file_single_dhcp(self):
|
||||||
expected = """
|
expected = """
|
||||||
tag:tag0,option:dns-server,8.8.8.8
|
tag:tag0,option:dns-server,8.8.8.8
|
||||||
|
|
Loading…
Reference in New Issue