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):
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):