Correct fix for IPv6 auto address interfaces

This is a partial revert of d1fb423830.
That patch attempted to allow the DHCP agent to manage IPv6 interfaces
to avoid a KeyError in the subnet_interface_map. However, this led
to races with router advertisements and static configuration
(see bug 1627902).

The correct fix was actually a very simple conditional that was broken
because this map shouldn't have been referenced for IPv6 subnets in
the first place. The force metadata option was shortcutting the whole
evaluation so the agent was trying to add a metadata route to a v6
subnet.

This patch undoes the v6 changes from
d1fb423830, corrects the conditional,
and adds a simple unit test that ensures the branch doesn't throw
and error.

Closes-Bug: #1624079
Change-Id: Ide494b6333a4f1e279ab58aa27c0aa719e79545d
(cherry picked from commit c0d0986e8b)
This commit is contained in:
Kevin Benton 2016-09-25 15:49:19 -07:00 committed by Ihar Hrachyshka
parent 20bb7be828
commit 98c4c0876d
3 changed files with 14 additions and 11 deletions

View File

@ -894,10 +894,10 @@ class Dnsmasq(DhcpLocalProcess):
# Add host routes for isolated network segments
if (self.conf.force_metadata or
(isolated_subnets[subnet.id] and
self.conf.enable_isolated_metadata and
subnet.ip_version == 4)):
if ((self.conf.force_metadata or
(isolated_subnets[subnet.id] and
self.conf.enable_isolated_metadata)) and
subnet.ip_version == 4):
subnet_dhcp_ip = subnet_to_interface_ip[subnet.id]
host_routes.append(
'%s/32,%s' % (METADATA_DEFAULT_IP, subnet_dhcp_ip)
@ -1373,7 +1373,7 @@ class DeviceManager(object):
ip_cidrs = []
for fixed_ip in port.fixed_ips:
subnet = fixed_ip.subnet
if not ipv6_utils.is_slaac_subnet(subnet):
if not ipv6_utils.is_auto_address_subnet(subnet):
net = netaddr.IPNetwork(subnet.cidr)
ip_cidr = '%s/%s' % (fixed_ip.ip_address, net.prefixlen)
ip_cidrs.append(ip_cidr)

View File

@ -76,12 +76,6 @@ def is_auto_address_subnet(subnet):
or subnet['ipv6_ra_mode'] in modes)
def is_slaac_subnet(subnet):
"""Check if subnet is a slaac subnet."""
return (subnet['ipv6_address_mode'] == const.IPV6_SLAAC
or subnet['ipv6_ra_mode'] == const.IPV6_SLAAC)
def is_eui64_address(ip_address):
"""Check if ip address is EUI64."""
ip = netaddr.IPAddress(ip_address)

View File

@ -1572,6 +1572,15 @@ class TestDnsmasq(TestBase):
self._test_output_opts_file(expected, FakeV6Network())
def test_output_opts_file_ipv6_address_force_metadata(self):
fake_v6 = '2001:0200:feed:7ac0::1'
expected = (
'tag:tag0,option6:dns-server,%s\n'
'tag:tag0,option6:domain-search,openstacklocal').lstrip() % (
'[' + fake_v6 + ']')
self.conf.force_metadata = True
self._test_output_opts_file(expected, FakeV6Network())
@property
def _test_no_dhcp_domain_alloc_data(self):
exp_host_name = '/dhcp/cccccccc-cccc-cccc-cccc-cccccccccccc/host'