Skip larger than /64 subnets in DHCP agent

Dnsmasq can't handle these in IPv6 so we need to skip them to avoid
a whole bunch of log noise caused by continual retrying of issues.

Closes-Bug: #1645616
Change-Id: I36d167506cc45731e3f500a0c59b70b1bc27590f
(cherry picked from commit 028a349bc5)
This commit is contained in:
Kevin Benton 2016-11-15 17:34:16 -08:00
parent 2580bcb5bc
commit 5413853b85
3 changed files with 57 additions and 6 deletions

View File

@ -369,6 +369,11 @@ class Dnsmasq(DhcpLocalProcess):
('set:', self._TAG_PREFIX % i,
cidr.network, mode, lease))
else:
if cidr.prefixlen < 64:
LOG.debug('Ignoring subnet %(subnet)s, CIDR has '
'prefix length < 64: %(cidr)s',
{'subnet': subnet.id, 'cidr': cidr})
continue
cmd.append('--dhcp-range=%s%s,%s,%s,%d,%s' %
('set:', self._TAG_PREFIX % i,
cidr.network, mode,

View File

@ -84,10 +84,11 @@ class DHCPAgentOVSTestFramework(base.BaseSudoTestCase):
self.conf.set_override('check_child_processes_interval', 1, 'AGENT')
def network_dict_for_dhcp(self, dhcp_enabled=True, ip_version=4):
def network_dict_for_dhcp(self, dhcp_enabled=True, ip_version=4,
prefix_override=None):
net_id = uuidutils.generate_uuid()
subnet_dict = self.create_subnet_dict(
net_id, dhcp_enabled, ip_version)
net_id, dhcp_enabled, ip_version, prefix_override)
port_dict = self.create_port_dict(
net_id, subnet_dict.id,
mac_address=str(self._DHCP_PORT_MAC_ADDRESS),
@ -98,12 +99,16 @@ class DHCPAgentOVSTestFramework(base.BaseSudoTestCase):
net_id, [subnet_dict], [port_dict])
return net_dict
def create_subnet_dict(self, net_id, dhcp_enabled=True, ip_version=4):
def create_subnet_dict(self, net_id, dhcp_enabled=True, ip_version=4,
prefix_override=None):
cidr = self._IP_ADDRS[ip_version]['cidr']
if prefix_override is not None:
cidr = '/'.join((cidr.split('/')[0], str(prefix_override)))
sn_dict = dhcp.DictModel({
"id": uuidutils.generate_uuid(),
"network_id": net_id,
"ip_version": ip_version,
"cidr": self._IP_ADDRS[ip_version]['cidr'],
"cidr": cidr,
"gateway_ip": (self.
_IP_ADDRS[ip_version]['gateway']),
"enable_dhcp": dhcp_enabled,
@ -254,6 +259,18 @@ class DHCPAgentOVSTestCase(DHCPAgentOVSTestFramework):
dhcp_enabled=dhcp_enabled)
self.assert_dhcp_resources(network, dhcp_enabled)
def test_create_subnet_with_non64_ipv6_cidrs(self):
# the agent should not throw exceptions on weird prefixes
dhcp_enabled = True
version = 6
for i in (0, 1, 41, 81, 121, 127, 128):
network = self.network_dict_for_dhcp(
dhcp_enabled, ip_version=version, prefix_override=i)
self.configure_dhcp_for_network(network=network,
dhcp_enabled=dhcp_enabled)
self.assertFalse(self.agent.needs_resync_reasons[network.id],
msg="prefix size of %s triggered resync" % i)
def test_agent_mtu_set_on_interface_driver(self):
network = self.network_dict_for_dhcp()
network["mtu"] = 789

View File

@ -492,6 +492,19 @@ class FakeV6SubnetStateless(object):
self.ipv6_ra_mode = None
class FakeV6SubnetStatelessBadPrefixLength(object):
def __init__(self):
self.id = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee'
self.ip_version = 6
self.cidr = 'ffeb:3ba5:a17a:4ba3::/56'
self.gateway_ip = 'ffeb:3ba5:a17a:4ba3::1'
self.enable_dhcp = True
self.dns_nameservers = []
self.host_routes = []
self.ipv6_address_mode = constants.DHCPV6_STATELESS
self.ipv6_ra_mode = None
class FakeV4SubnetNoGateway(FakeV4Subnet):
def __init__(self):
super(FakeV4SubnetNoGateway, self).__init__()
@ -795,6 +808,14 @@ class FakeV6NetworkStatelessDHCP(object):
self.namespace = 'qdhcp-ns'
class FakeV6NetworkStatelessDHCPBadPrefixLength(object):
def __init__(self):
self.id = 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb'
self.subnets = [FakeV6SubnetStatelessBadPrefixLength()]
self.ports = [FakeV6PortExtraOpt()]
self.namespace = 'qdhcp-ns'
class FakeNetworkWithV6SatelessAndV4DHCPSubnets(object):
def __init__(self):
self.id = 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb'
@ -1024,7 +1045,8 @@ class TestDnsmasq(TestBase):
def _test_spawn(self, extra_options, network=FakeDualNetwork(),
max_leases=16777216, lease_duration=86400,
has_static=True, no_resolv='--no-resolv'):
has_static=True, no_resolv='--no-resolv',
has_stateless=True):
def mock_get_conf_file_name(kind):
return '/dhcp/%s/%s' % (network.id, kind)
@ -1057,7 +1079,7 @@ class TestDnsmasq(TestBase):
if has_static:
prefix = '--dhcp-range=set:tag%d,%s,static,%s%s'
prefix6 = '--dhcp-range=set:tag%d,%s,static,%s,%s%s'
else:
elif has_stateless:
prefix = '--dhcp-range=set:tag%d,%s,%s%s'
prefix6 = '--dhcp-range=set:tag%d,%s,%s,%s%s'
possible_leases = 0
@ -1140,6 +1162,13 @@ class TestDnsmasq(TestBase):
self._test_spawn(['--conf-file=', '--domain=openstacklocal'],
network, has_static=False)
def test_spawn_no_dhcp_range_bad_prefix_length(self):
network = FakeV6NetworkStatelessDHCPBadPrefixLength()
subnet = FakeV6SubnetStatelessBadPrefixLength()
network.subnets = [subnet]
self._test_spawn(['--conf-file=', '--domain=openstacklocal'],
network, has_static=False, has_stateless=False)
def test_spawn_cfg_dns_server(self):
self.conf.set_override('dnsmasq_dns_servers', ['8.8.8.8'])
self._test_spawn(['--conf-file=',