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
This commit is contained in:
Kevin Benton 2016-09-25 15:49:19 -07:00
parent 2dacb8db7a
commit c0d0986e8b
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'