diff options
author | Brian Haley <haleyb.dev@gmail.com> | 2023-03-01 00:52:38 -0500 |
---|---|---|
committer | Brian Haley <haleyb.dev@gmail.com> | 2023-04-26 12:22:30 -0400 |
commit | 88ce859b568248a0ee2f47a5d91c1708b774d20e (patch) | |
tree | 1b8117a50dfb6a4369de8c4c3b3b4f3a611c364a /neutron/tests | |
parent | 5cd0388eb7cac84fc1aaa425184bf4af67ed0608 (diff) | |
download | neutron-88ce859b568248a0ee2f47a5d91c1708b774d20e.tar.gz |
Change API to validate network MTU minimums
A network's MTU is now only valid if it is the minimum value
allowed based on the IP version of the associated subnets,
68 for IPv4 and 1280 for IPv6.
This minimum is now enforced in the following ways:
1) When a subnet is associated with a network, validate
the MTU is large enough for the IP version. Not only
would the subnet be unusable if it was allowed, but the
Linux kernel can fail adding addresses and configuring
network settings like the MTU.
2) When a network MTU is changed, validate the MTU is large
enough for any currently associated subnets. Allowing a
smaller MTU would render any existing subnets unusable.
Closes-bug: #1988069
Change-Id: Ia4017a8737f9a7c63945df546c8a7243b2673ceb
Diffstat (limited to 'neutron/tests')
-rw-r--r-- | neutron/tests/unit/db/test_db_base_plugin_v2.py | 84 | ||||
-rw-r--r-- | neutron/tests/unit/fake_resources.py | 1 |
2 files changed, 82 insertions, 3 deletions
diff --git a/neutron/tests/unit/db/test_db_base_plugin_v2.py b/neutron/tests/unit/db/test_db_base_plugin_v2.py index a25ccc4f0d..5dd9bbd905 100644 --- a/neutron/tests/unit/db/test_db_base_plugin_v2.py +++ b/neutron/tests/unit/db/test_db_base_plugin_v2.py @@ -49,6 +49,7 @@ import neutron from neutron.api import api_common from neutron.api import extensions from neutron.api.v2 import router +from neutron.common import _constants as common_constants from neutron.common import ipv6_utils from neutron.common.ovn import utils as ovn_utils from neutron.common import test_lib @@ -60,6 +61,7 @@ from neutron.db import ipam_backend_mixin from neutron.db.models import l3 as l3_models from neutron.db.models import securitygroup as sg_models from neutron.db import models_v2 +from neutron.exceptions import mtu as mtu_exc from neutron.ipam.drivers.neutrondb_ipam import driver as ipam_driver from neutron.ipam import exceptions as ipam_exc from neutron.objects import network as network_obj @@ -373,7 +375,7 @@ class NeutronDbPluginV2TestCase(testlib_api.WebTestCase): 'admin_state_up': admin_state_up, 'tenant_id': tenant_id}} for arg in (('admin_state_up', 'tenant_id', 'shared', - 'vlan_transparent', + 'vlan_transparent', 'mtu', 'availability_zone_hints') + (arg_list or ())): # Arg must be present if arg in kwargs: @@ -7066,7 +7068,8 @@ class NeutronDbPluginV2AsMixinTestCase(NeutronDbPluginV2TestCase, super(NeutronDbPluginV2AsMixinTestCase, self).setUp() self.plugin = importutils.import_object(DB_PLUGIN_KLASS) self.context = context.get_admin_context() - self.net_data = {'network': {'id': 'fake-id', + self.net_id = uuidutils.generate_uuid() + self.net_data = {'network': {'id': self.net_id, 'name': 'net1', 'admin_state_up': True, 'tenant_id': TEST_TENANT_ID, @@ -7075,7 +7078,7 @@ class NeutronDbPluginV2AsMixinTestCase(NeutronDbPluginV2TestCase, def test_create_network_with_default_status(self): net = self.plugin.create_network(self.context, self.net_data) default_net_create_status = 'ACTIVE' - expected = [('id', 'fake-id'), ('name', 'net1'), + expected = [('id', self.net_id), ('name', 'net1'), ('admin_state_up', True), ('tenant_id', TEST_TENANT_ID), ('shared', False), ('status', default_net_create_status)] for k, v in expected: @@ -7113,6 +7116,81 @@ class NeutronDbPluginV2AsMixinTestCase(NeutronDbPluginV2TestCase, new_subnetpool_id, None) + def test_create_subnet_invalid_network_mtu_ipv4_returns_409(self): + self.net_data['network']['mtu'] = common_constants.IPV4_MIN_MTU - 1 + net = self.plugin.create_network(self.context, self.net_data) + self._create_subnet(self.fmt, + net['id'], + '10.0.0.0/24', + webob.exc.HTTPConflict.code) + + def test_create_subnet_invalid_network_mtu_ipv6_returns_409(self): + self.net_data['network']['mtu'] = constants.IPV6_MIN_MTU - 1 + net = self.plugin.create_network(self.context, self.net_data) + self._create_subnet(self.fmt, + net['id'], + '2001:db8:0:1::/64', + webob.exc.HTTPConflict.code, + ip_version=constants.IP_VERSION_6) + + def test_update_network_invalid_mtu(self): + self.net_data['network']['mtu'] = 1500 + net = self.plugin.create_network(self.context, self.net_data) + + # This should succeed with no subnets + self.net_data['network']['mtu'] = common_constants.IPV4_MIN_MTU - 1 + self.plugin.update_network(self.context, net['id'], self.net_data) + + # reset mtu + self.net_data['network']['mtu'] = 1500 + self.plugin.update_network(self.context, net['id'], self.net_data) + + self._create_subnet(self.fmt, + net['id'], + '10.0.0.0/24', + ip_version=constants.IP_VERSION_4) + + # These should succeed with just an IPv4 subnet present + self.net_data['network']['mtu'] = constants.IPV6_MIN_MTU + self.plugin.update_network(self.context, net['id'], self.net_data) + self.net_data['network']['mtu'] = constants.IPV6_MIN_MTU - 1 + self.plugin.update_network(self.context, net['id'], self.net_data) + self.net_data['network']['mtu'] = common_constants.IPV4_MIN_MTU + self.plugin.update_network(self.context, net['id'], self.net_data) + + # This should fail with any subnets present + self.net_data['network']['mtu'] = common_constants.IPV4_MIN_MTU - 1 + with testlib_api.ExpectedException(mtu_exc.NetworkMTUSubnetConflict): + self.plugin.update_network(self.context, net['id'], self.net_data) + + def test_update_network_invalid_mtu_ipv4_ipv6(self): + self.net_data['network']['mtu'] = 1500 + net = self.plugin.create_network(self.context, self.net_data) + + self._create_subnet(self.fmt, + net['id'], + '10.0.0.0/24', + ip_version=constants.IP_VERSION_4) + self._create_subnet(self.fmt, + net['id'], + '2001:db8:0:1::/64', + ip_version=constants.IP_VERSION_6) + + # This should succeed with both subnets present + self.net_data['network']['mtu'] = constants.IPV6_MIN_MTU + self.plugin.update_network(self.context, net['id'], self.net_data) + + # These should all fail with both subnets present + with testlib_api.ExpectedException(mtu_exc.NetworkMTUSubnetConflict): + self.net_data['network']['mtu'] = constants.IPV6_MIN_MTU - 1 + self.plugin.update_network(self.context, net['id'], self.net_data) + with testlib_api.ExpectedException(mtu_exc.NetworkMTUSubnetConflict): + self.net_data['network']['mtu'] = common_constants.IPV4_MIN_MTU + self.plugin.update_network(self.context, net['id'], self.net_data) + with testlib_api.ExpectedException(mtu_exc.NetworkMTUSubnetConflict): + self.net_data['network']['mtu'] = common_constants.IPV4_MIN_MTU - 1 + self.plugin.update_network(self.context, net['id'], self.net_data) + class TestNetworks(testlib_api.SqlTestCase): def setUp(self): diff --git a/neutron/tests/unit/fake_resources.py b/neutron/tests/unit/fake_resources.py index ff2e0c5401..ca745f6b64 100644 --- a/neutron/tests/unit/fake_resources.py +++ b/neutron/tests/unit/fake_resources.py @@ -322,6 +322,7 @@ class FakeNetwork(object): 'availability_zone_hints': [], 'is_default': False, 'standard_attr_id': 1, + 'mtu': 1500, } # Overwrite default attributes. |