From: Jenkins Date: Thu, 3 Sep 2015 04:05:07 +0000 (+0000) Subject: Merge "DHCP agent: allow using gateway IPs instead of uniquely allocated" X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=b6d780a83cd9a811e8a91db77eb24bb65fa0b075;p=openstack-build%2Fneutron-build.git Merge "DHCP agent: allow using gateway IPs instead of uniquely allocated" --- b6d780a83cd9a811e8a91db77eb24bb65fa0b075 diff --cc neutron/agent/linux/interface.py index cf37fcfc9,5ac117e67..090b62def --- a/neutron/agent/linux/interface.py +++ b/neutron/agent/linux/interface.py @@@ -52,18 -51,47 +52,58 @@@ class LinuxInterfaceDriver(object) def __init__(self, conf): self.conf = conf + if self.conf.network_device_mtu: + self._validate_network_device_mtu() + + def _validate_network_device_mtu(self): + if (ipv6_utils.is_enabled() and + self.conf.network_device_mtu < n_const.IPV6_MIN_MTU): + LOG.error(_LE("IPv6 protocol requires a minimum MTU of " + "%(min_mtu)s, while the configured value is " + "%(current_mtu)s"), {'min_mtu': n_const.IPV6_MIN_MTU, + 'current_mtu': self.conf.network_device_mtu}) + raise SystemExit(1) + @property + def use_gateway_ips(self): + """Whether to use gateway IPs instead of unique IP allocations. + + In each place where the DHCP agent runs, and for each subnet for + which DHCP is handling out IP addresses, the DHCP port needs - + at the Linux level - to have an IP address within that subnet. + Generally this needs to be a unique Neutron-allocated IP + address, because the subnet's underlying L2 domain is bridged + across multiple compute hosts and network nodes, and for HA + there may be multiple DHCP agents running on that same bridged + L2 domain. + + However, if the DHCP ports - on multiple compute/network nodes + but for the same network - are _not_ bridged to each other, + they do not need each to have a unique IP address. Instead + they can all share the same address from the relevant subnet. + This works, without creating any ambiguity, because those + ports are not all present on the same L2 domain, and because + no data within the network is ever sent to that address. + (DHCP requests are broadcast, and it is the network's job to + ensure that such a broadcast will reach at least one of the + available DHCP servers. DHCP responses will be sent _from_ + the DHCP port address.) + + Specifically, for networking backends where it makes sense, + the DHCP agent allows all DHCP ports to use the subnet's + gateway IP address, and thereby to completely avoid any unique + IP address allocation. This behaviour is selected by running + the DHCP agent with a configured interface driver whose + 'use_gateway_ips' property is True. + + When an operator deploys Neutron with an interface driver that + makes use_gateway_ips True, they should also ensure that a + gateway IP address is defined for each DHCP-enabled subnet, + and that the gateway IP address doesn't change during the + subnet's lifetime. + """ + return False + def init_l3(self, device_name, ip_cidrs, namespace=None, preserve_ips=[], gateway_ips=None, clean_connections=False): diff --cc neutron/tests/unit/agent/linux/test_dhcp.py index d4d8e86e8,5508b01d2..d82c02f12 --- a/neutron/tests/unit/agent/linux/test_dhcp.py +++ b/neutron/tests/unit/agent/linux/test_dhcp.py @@@ -500,20 -499,22 +500,27 @@@ class FakeV6Network(object) class FakeDualNetwork(object): id = 'cccccccc-cccc-cccc-cccc-cccccccccccc' subnets = [FakeV4Subnet(), FakeV6SubnetDHCPStateful()] - ports = [FakePort1(), FakeV6Port(), FakeDualPort(), FakeRouterPort()] + # ports = [FakePort1(), FakeV6Port(), FakeDualPort(), FakeRouterPort()] namespace = 'qdhcp-ns' + def __init__(self, domain='openstacklocal'): + self.ports = [FakePort1(domain=domain), FakeV6Port(domain=domain), + FakeDualPort(domain=domain), + FakeRouterPort(domain=domain)] + class FakeDeviceManagerNetwork(object): - id = 'cccccccc-cccc-cccc-cccc-cccccccccccc' - subnets = [FakeV4Subnet(), FakeV6SubnetDHCPStateful()] - ports = [FakePort1(), FakeV6Port(), FakeDualPort(), FakeRouterPort()] - namespace = 'qdhcp-ns' + # Use instance rather than class attributes here, so that we get + # an independent set of ports each time FakeDeviceManagerNetwork() + # is used. + def __init__(self): + self.id = 'cccccccc-cccc-cccc-cccc-cccccccccccc' + self.subnets = [FakeV4Subnet(), FakeV6SubnetDHCPStateful()] + self.ports = [FakePort1(), + FakeV6Port(), + FakeDualPort(), + FakeRouterPort()] + self.namespace = 'qdhcp-ns' class FakeDualNetworkReserved(object):