From 80f547ad1d1e95a05570d9a7db2dac7cad7ff33a Mon Sep 17 00:00:00 2001 From: Rodolfo Alonso Hernandez Date: Wed, 10 May 2023 02:32:46 +0200 Subject: [PATCH] Add a "port" child table "porthardwareoffloadtype" This table has a 1:1 relationship with the "port" table, providing the "hardware_offload_type" field (string). The "neutron-lib" library minimum version is 3.8.0, that contains [1]. NOTE: once the OSC patch is merged [2], the documentation will be updated to reflect how to create a hardware offloaded port without manually defining the port binding profile, [1]https://review.opendev.org/c/openstack/neutron-lib/+/882726 [2]https://review.opendev.org/c/openstack/python-openstackclient/+/892792 Partial-Bug: #2013228 Change-Id: I04f232d6c43e39f254c4559caf041dcf05acec21 --- neutron/common/ovn/extensions.py | 2 + ...dd_port_hardware_offload_extension_type.py | 44 +++++++++++ .../alembic_migrations/versions/EXPAND_HEAD | 2 +- .../db/models/port_hardware_offload_type.py | 38 ++++++++++ neutron/db/port_hardware_offload_type_db.py | 52 +++++++++++++ .../extensions/port_hardware_offload_type.py | 20 +++++ .../extensions/port_hardware_offload_type.py | 44 +++++++++++ neutron/objects/ports.py | 12 ++- .../extensions/port_hardware_offload_type.py | 47 ++++++++++++ neutron/plugins/ml2/plugin.py | 2 + .../tests/contrib/hooks/api_all_extensions | 1 + neutron/tests/tools.py | 4 + .../tests/unit/db/test_db_base_plugin_v2.py | 3 +- .../test_port_hardware_offload_type.py | 73 +++++++++++++++++++ .../test_port_hardware_offload_type.py | 38 ++++++++++ neutron/tests/unit/objects/test_base.py | 5 +- neutron/tests/unit/objects/test_objects.py | 3 +- ...fload-type-extension-acd266f95c1d7d29.yaml | 11 +++ setup.cfg | 1 + 19 files changed, 397 insertions(+), 5 deletions(-) create mode 100644 neutron/db/migration/alembic_migrations/versions/2024.1/expand/0e6eff810791_add_port_hardware_offload_extension_type.py create mode 100644 neutron/db/models/port_hardware_offload_type.py create mode 100644 neutron/db/port_hardware_offload_type_db.py create mode 100644 neutron/extensions/port_hardware_offload_type.py create mode 100644 neutron/objects/port/extensions/port_hardware_offload_type.py create mode 100644 neutron/plugins/ml2/extensions/port_hardware_offload_type.py create mode 100644 neutron/tests/unit/extensions/test_port_hardware_offload_type.py create mode 100644 neutron/tests/unit/objects/port/extensions/test_port_hardware_offload_type.py create mode 100644 releasenotes/notes/port-hardware-offload-type-extension-acd266f95c1d7d29.yaml diff --git a/neutron/common/ovn/extensions.py b/neutron/common/ovn/extensions.py index 440f5e597b2..e898f5dbd7c 100644 --- a/neutron/common/ovn/extensions.py +++ b/neutron/common/ovn/extensions.py @@ -47,6 +47,7 @@ from neutron_lib.api.definitions import network_mtu from neutron_lib.api.definitions import network_mtu_writable from neutron_lib.api.definitions import pagination from neutron_lib.api.definitions import port_device_profile +from neutron_lib.api.definitions import port_hardware_offload_type from neutron_lib.api.definitions import port_mac_address_regenerate from neutron_lib.api.definitions import port_numa_affinity_policy from neutron_lib.api.definitions import port_resource_request @@ -134,6 +135,7 @@ ML2_SUPPORTED_API_EXTENSIONS = [ network_availability_zone.ALIAS, network_ip_availability.ALIAS, port_device_profile.ALIAS, + port_hardware_offload_type.ALIAS, port_mac_address_regenerate.ALIAS, port_numa_affinity_policy.ALIAS, port_security.ALIAS, diff --git a/neutron/db/migration/alembic_migrations/versions/2024.1/expand/0e6eff810791_add_port_hardware_offload_extension_type.py b/neutron/db/migration/alembic_migrations/versions/2024.1/expand/0e6eff810791_add_port_hardware_offload_extension_type.py new file mode 100644 index 00000000000..9df9ea11c7f --- /dev/null +++ b/neutron/db/migration/alembic_migrations/versions/2024.1/expand/0e6eff810791_add_port_hardware_offload_extension_type.py @@ -0,0 +1,44 @@ +# Copyright 2023 OpenStack Foundation +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +from alembic import op +import sqlalchemy as sa + + +"""Add port hardware offload extension type + +Revision ID: 0e6eff810791 +Revises: 054e34dbe6b4 +Create Date: 2023-05-09 23:52:40.677006 + +""" + +# revision identifiers, used by Alembic. +revision = '0e6eff810791' +down_revision = '054e34dbe6b4' + + +def upgrade(): + op.create_table('porthardwareoffloadtype', + sa.Column('port_id', + sa.String(36), + sa.ForeignKey('ports.id', + ondelete="CASCADE"), + primary_key=True, + index=True), + sa.Column('hardware_offload_type', + sa.String(255), + nullable=True) + ) diff --git a/neutron/db/migration/alembic_migrations/versions/EXPAND_HEAD b/neutron/db/migration/alembic_migrations/versions/EXPAND_HEAD index e37dce105e0..866b0a90a0c 100644 --- a/neutron/db/migration/alembic_migrations/versions/EXPAND_HEAD +++ b/neutron/db/migration/alembic_migrations/versions/EXPAND_HEAD @@ -1 +1 @@ -054e34dbe6b4 +0e6eff810791 diff --git a/neutron/db/models/port_hardware_offload_type.py b/neutron/db/models/port_hardware_offload_type.py new file mode 100644 index 00000000000..10486783f54 --- /dev/null +++ b/neutron/db/models/port_hardware_offload_type.py @@ -0,0 +1,38 @@ +# Copyright 2023 Red Hat, Inc. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from neutron_lib.db import model_base +import sqlalchemy as sa +from sqlalchemy import orm + +from neutron.db import models_v2 + + +class PortHardwareOffloadType(model_base.BASEV2): + __tablename__ = 'porthardwareoffloadtype' + + port_id = sa.Column(sa.String(36), + sa.ForeignKey('ports.id', ondelete='CASCADE'), + primary_key=True, + index=True) + hardware_offload_type = sa.Column(sa.String(255)) + port = orm.relationship( + models_v2.Port, + load_on_pending=True, + backref=orm.backref('hardware_offload_type', + lazy='subquery', + uselist=False, + cascade='delete')) + revises_on_change = ('port', ) diff --git a/neutron/db/port_hardware_offload_type_db.py b/neutron/db/port_hardware_offload_type_db.py new file mode 100644 index 00000000000..0776db5bf8f --- /dev/null +++ b/neutron/db/port_hardware_offload_type_db.py @@ -0,0 +1,52 @@ +# Copyright (c) 2023 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from neutron_lib.api.definitions import port_hardware_offload_type as phot +from neutron_lib.api.definitions import portbindings +from neutron_lib import constants as n_const + +from neutron.objects.port.extensions import port_hardware_offload_type as \ + phot_obj + + +class PortHardwareOffloadTypeDbMixin(object): + """Mixin class to add hardware offload type extension to a port""" + + def _process_create_port(self, context, data, result): + hw_type = data.get(phot.HARDWARE_OFFLOAD_TYPE) + if hw_type not in n_const.VALID_HWOL_TYPES: + result[phot.HARDWARE_OFFLOAD_TYPE] = None + return + + obj = phot_obj.PortHardwareOffloadType( + context, port_id=result['id'], hardware_offload_type=hw_type) + obj.create() + result[phot.HARDWARE_OFFLOAD_TYPE] = hw_type + # NOTE(ralonsoh): this is updating not the "result" dictionary but + # the "data" dictionary that are the API input parameters. + try: + pb_profile = data[portbindings.PROFILE] + capabilities = pb_profile.get('capabilities', []) + if hw_type not in capabilities: + capabilities.append(hw_type) + data[portbindings.PROFILE]['capabilities'] = capabilities + except (KeyError, AttributeError): + data[portbindings.PROFILE] = {'capabilities': [hw_type]} + + def _extend_port_dict(self, port_db, result): + if port_db.hardware_offload_type: + result[phot.HARDWARE_OFFLOAD_TYPE] = ( + port_db.hardware_offload_type.hardware_offload_type) + else: + result[phot.HARDWARE_OFFLOAD_TYPE] = None diff --git a/neutron/extensions/port_hardware_offload_type.py b/neutron/extensions/port_hardware_offload_type.py new file mode 100644 index 00000000000..7e5cccce04a --- /dev/null +++ b/neutron/extensions/port_hardware_offload_type.py @@ -0,0 +1,20 @@ +# Copyright (c) 2023 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from neutron_lib.api.definitions import port_hardware_offload_type +from neutron_lib.api import extensions as api_extensions + + +class Port_hardware_offload_type(api_extensions.APIExtensionDescriptor): + api_definition = port_hardware_offload_type diff --git a/neutron/objects/port/extensions/port_hardware_offload_type.py b/neutron/objects/port/extensions/port_hardware_offload_type.py new file mode 100644 index 00000000000..3c8268808f8 --- /dev/null +++ b/neutron/objects/port/extensions/port_hardware_offload_type.py @@ -0,0 +1,44 @@ +# Copyright (c) 2023 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from neutron_lib import constants as lib_constants +from neutron_lib.objects import common_types +from oslo_versionedobjects import fields as obj_fields + +from neutron.db.models import port_hardware_offload_type +from neutron.objects import base + + +# TODO(ralonsoh): move to neutron_lib.objects.common_types +class PortHardwareOffloadTypeEnumField(obj_fields.AutoTypedField): + AUTO_TYPE = obj_fields.Enum(valid_values=lib_constants.VALID_HWOL_TYPES) + + +@base.NeutronObjectRegistry.register +class PortHardwareOffloadType(base.NeutronDbObject): + # Version 1.0: Initial version + VERSION = '1.0' + + db_model = port_hardware_offload_type.PortHardwareOffloadType + + primary_keys = ['port_id'] + + new_facade = True + + fields = { + 'port_id': common_types.UUIDField(), + 'hardware_offload_type': PortHardwareOffloadTypeEnumField(), + } + + foreign_keys = {'Port': {'port_id': 'id'}} diff --git a/neutron/objects/ports.py b/neutron/objects/ports.py index e9fd61b38e3..fab2a69c251 100644 --- a/neutron/objects/ports.py +++ b/neutron/objects/ports.py @@ -337,7 +337,8 @@ class Port(base.NeutronDbObject): # Version 1.6: Added numa_affinity_policy field # Version 1.7: Added port_device field # Version 1.8: Added hints field - VERSION = '1.8' + # Version 1.9: Added hardware_offload_type field + VERSION = '1.9' db_model = models_v2.Port @@ -392,6 +393,7 @@ class Port(base.NeutronDbObject): ), 'numa_affinity_policy': obj_fields.StringField(nullable=True), 'device_profile': obj_fields.StringField(nullable=True), + 'hardware_offload_type': obj_fields.StringField(nullable=True), # TODO(ihrachys): consider adding a 'dns_assignment' fully synthetic # field in later object iterations @@ -411,6 +413,7 @@ class Port(base.NeutronDbObject): 'distributed_bindings', 'dns', 'fixed_ips', + 'hardware_offload_type', 'hints', 'numa_affinity_policy', 'qos_policy_id', @@ -583,6 +586,11 @@ class Port(base.NeutronDbObject): self.device_profile = db_obj.device_profile.device_profile fields_to_change.append('device_profile') + if db_obj.get('hardware_offload_type'): + self.hardware_offload_type = ( + db_obj.hardware_offload_type.hardware_offload_type) + fields_to_change.append('hardware_offload_type') + self.obj_reset_changes(fields_to_change) def obj_make_compatible(self, primitive, target_version): @@ -617,6 +625,8 @@ class Port(base.NeutronDbObject): primitive.pop('device_profile', None) if _target_version < (1, 8): primitive.pop('hints', None) + if _target_version < (1, 9): + primitive.pop('hardware_offload_type', None) @classmethod @db_api.CONTEXT_READER diff --git a/neutron/plugins/ml2/extensions/port_hardware_offload_type.py b/neutron/plugins/ml2/extensions/port_hardware_offload_type.py new file mode 100644 index 00000000000..e7a9e1930ae --- /dev/null +++ b/neutron/plugins/ml2/extensions/port_hardware_offload_type.py @@ -0,0 +1,47 @@ +# Copyright 2023 Red Hat, Inc. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from neutron_lib.api.definitions import port_hardware_offload_type as phot +from neutron_lib.plugins.ml2 import api +from oslo_log import log as logging + +from neutron.db import port_hardware_offload_type_db + + +LOG = logging.getLogger(__name__) + + +class PortHardwareOffloadTypeExtensionDriver( + api.ExtensionDriver, + port_hardware_offload_type_db.PortHardwareOffloadTypeDbMixin): + + _supported_extension_alias = phot.ALIAS + + def initialize(self): + LOG.info('PortHardwareOffloadTypeExtensionDriver initialization ' + 'complete') + + # NOTE(ralonsoh): this extension does not allow to update the port HW type. + # Once created with/without the flag, it cannot be changed. + + @property + def extension_alias(self): + return self._supported_extension_alias + + def process_create_port(self, context, data, result): + self._process_create_port(context, data, result) + + def extend_port_dict(self, session, port_db, result): + self._extend_port_dict(port_db, result) diff --git a/neutron/plugins/ml2/plugin.py b/neutron/plugins/ml2/plugin.py index 02b214ddf1a..f29d741e4d4 100644 --- a/neutron/plugins/ml2/plugin.py +++ b/neutron/plugins/ml2/plugin.py @@ -43,6 +43,7 @@ from neutron_lib.api.definitions import network_mtu as mtu_apidef from neutron_lib.api.definitions import network_mtu_writable as mtuw_apidef from neutron_lib.api.definitions import port as port_def from neutron_lib.api.definitions import port_device_profile as pdp_def +from neutron_lib.api.definitions import port_hardware_offload_type as phot_def from neutron_lib.api.definitions import port_mac_address_override from neutron_lib.api.definitions import port_mac_address_regenerate from neutron_lib.api.definitions import port_numa_affinity_policy as pnap_def @@ -245,6 +246,7 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2, port_mac_address_override.ALIAS, sg_default_rules_ext.ALIAS, sg_rules_default_sg.ALIAS, + phot_def.ALIAS, ] # List of agent types for which all binding_failed ports should try to be diff --git a/neutron/tests/contrib/hooks/api_all_extensions b/neutron/tests/contrib/hooks/api_all_extensions index 900dd7b1bea..ce58876ec86 100644 --- a/neutron/tests/contrib/hooks/api_all_extensions +++ b/neutron/tests/contrib/hooks/api_all_extensions @@ -60,6 +60,7 @@ NETWORK_API_EXTENSIONS+=",security-groups-remote-address-group" NETWORK_API_EXTENSIONS+=",security-groups-rules-belongs-to-default-sg" NETWORK_API_EXTENSIONS+=",security-groups-shared-filtering" NETWORK_API_EXTENSIONS+=",port-device-profile" +NETWORK_API_EXTENSIONS+=",port-hardware-offload-type" NETWORK_API_EXTENSIONS+=",port-mac-address-regenerate" NETWORK_API_EXTENSIONS+=",port-numa-affinity-policy" NETWORK_API_EXTENSIONS+=",port-security-groups-filtering" diff --git a/neutron/tests/tools.py b/neutron/tests/tools.py index d419ebe8f5a..303379efbd7 100644 --- a/neutron/tests/tools.py +++ b/neutron/tests/tools.py @@ -282,3 +282,7 @@ def get_random_security_event(): def get_random_port_numa_affinity_policy(): return random.choice(constants.PORT_NUMA_POLICIES) + + +def get_random_port_hardware_offload_type(): + return random.choice(constants.VALID_HWOL_TYPES) 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 bb301b9263a..1efca99ef4b 100644 --- a/neutron/tests/unit/db/test_db_base_plugin_v2.py +++ b/neutron/tests/unit/db/test_db_base_plugin_v2.py @@ -527,7 +527,8 @@ class NeutronDbPluginV2TestCase(testlib_api.WebTestCase): 'mac_address', 'name', 'fixed_ips', 'tenant_id', 'device_owner', 'security_groups', 'propagate_uplink_status', 'numa_affinity_policy', - 'device_profile', 'hints') + (arg_list or ())): + 'device_profile', 'hints', 'hardware_offload_type') + + (arg_list or ())): # Arg must be present if arg in kwargs: data['port'][arg] = kwargs[arg] diff --git a/neutron/tests/unit/extensions/test_port_hardware_offload_type.py b/neutron/tests/unit/extensions/test_port_hardware_offload_type.py new file mode 100644 index 00000000000..bc9e5f66194 --- /dev/null +++ b/neutron/tests/unit/extensions/test_port_hardware_offload_type.py @@ -0,0 +1,73 @@ +# Copyright (c) 2023 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import ddt +from neutron_lib.api.definitions import port_hardware_offload_type as apidef +from neutron_lib import constants +from neutron_lib import context +from oslo_config import cfg + +from neutron.db import port_hardware_offload_type_db as phot_db +from neutron.objects import ports as ports_obj +from neutron.plugins.ml2 import plugin +from neutron.tests.unit.db import test_db_base_plugin_v2 + + +class PortHardwareOffloadTypeExtensionTestPlugin( + plugin.Ml2Plugin, + phot_db.PortHardwareOffloadTypeDbMixin): + """Test plugin to mixin the port hardware offload type extension.""" + + supported_extension_aliases = [apidef.ALIAS] + + +@ddt.ddt +class PortHardwareOffloadTypeExtensionTestCase( + test_db_base_plugin_v2.NeutronDbPluginV2TestCase): + """Test API extension port-hardware-offload-type attributes.""" + + def setUp(self, *args): + plugin = ('neutron.tests.unit.extensions.test_port_hardware_offload_' + 'type.PortHardwareOffloadTypeExtensionTestPlugin') + extension_drivers = ['port_hardware_offload_type'] + cfg.CONF.set_override('extension_drivers', extension_drivers, 'ml2') + super().setUp(plugin=plugin) + self.ctx = context.get_admin_context() + + def _create_and_check_port_hw_offload_type(self, hardware_offload_type): + name = 'hw_offload_type' + keys = [('name', name), + ('admin_state_up', True), + ('hardware_offload_type', hardware_offload_type)] + port_args = {'name': name} + if hardware_offload_type in constants.VALID_HWOL_TYPES: + port_args['hardware_offload_type'] = hardware_offload_type + with self.port(**port_args) as port: + for k, v in keys: + self.assertEqual(v, port['port'][k]) + + port_ovo = ports_obj.Port.get_object(self.ctx, + id=port['port']['id']) + self.assertEqual(1, len(port_ovo.bindings)) + # NOTE: if the HW type flag is enabled, the port binding profile + # is set correspondingly. + if hardware_offload_type in constants.VALID_HWOL_TYPES: + self.assertEqual({'capabilities': [hardware_offload_type]}, + port_ovo.bindings[0].profile) + else: + self.assertEqual({}, port_ovo.bindings[0].profile) + + @ddt.data(*constants.VALID_HWOL_TYPES, None) + def test_create_port_hardware_offload_type(self, hw_offload_type): + self._create_and_check_port_hw_offload_type(hw_offload_type) diff --git a/neutron/tests/unit/objects/port/extensions/test_port_hardware_offload_type.py b/neutron/tests/unit/objects/port/extensions/test_port_hardware_offload_type.py new file mode 100644 index 00000000000..c501d469e2d --- /dev/null +++ b/neutron/tests/unit/objects/port/extensions/test_port_hardware_offload_type.py @@ -0,0 +1,38 @@ +# Copyright (c) 2023 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from neutron_lib import constants + +from neutron.objects.port.extensions import port_hardware_offload_type +from neutron.tests.unit.objects import test_base as obj_test_base +from neutron.tests.unit import testlib_api + + +class PortHardwareOffloadTypeIfaceObjectTestCase( + obj_test_base.BaseObjectIfaceTestCase): + + _test_class = port_hardware_offload_type.PortHardwareOffloadType + + +class PortHardwareOffloadTypeDbObjectTestCase( + obj_test_base.BaseDbObjectTestCase, + testlib_api.SqlTestCase): + + _test_class = port_hardware_offload_type.PortHardwareOffloadType + + def setUp(self): + super().setUp() + self.update_obj_fields( + {'port_id': lambda: self._create_test_port_id(), + 'hardware_offload_type': constants.HWOL_TYPE_SWITCHDEV}) diff --git a/neutron/tests/unit/objects/test_base.py b/neutron/tests/unit/objects/test_base.py index 6a14951ec3e..5d7dbb2a3d1 100644 --- a/neutron/tests/unit/objects/test_base.py +++ b/neutron/tests/unit/objects/test_base.py @@ -47,6 +47,7 @@ from neutron.objects import flavor from neutron.objects import local_ip from neutron.objects import network as net_obj from neutron.objects.port.extensions import port_device_profile +from neutron.objects.port.extensions import port_hardware_offload_type from neutron.objects.port.extensions import port_numa_affinity_policy from neutron.objects import ports from neutron.objects.qos import policy as qos_policy @@ -559,7 +560,9 @@ FIELD_TYPE_VALUE_GENERATOR_MAP = { tools.get_random_port_numa_affinity_policy, port_device_profile.PortDeviceProfile: lambda: helpers.get_random_string(255), - common_types.PortRangesField: get_random_port_ranges + common_types.PortRangesField: get_random_port_ranges, + port_hardware_offload_type.PortHardwareOffloadTypeEnumField: + tools.get_random_port_hardware_offload_type, } diff --git a/neutron/tests/unit/objects/test_objects.py b/neutron/tests/unit/objects/test_objects.py index 34e21087497..128ac397e0d 100644 --- a/neutron/tests/unit/objects/test_objects.py +++ b/neutron/tests/unit/objects/test_objects.py @@ -73,7 +73,8 @@ object_data = { 'NetworkSegment': '1.0-57b7f2960971e3b95ded20cbc59244a8', 'NetworkSegmentRange': '1.0-bdec1fffc9058ea676089b1f2f2b3cf3', 'NetworkSubnetLock': '1.0-140de39d4b86ae346dc3d70b885bea53', - 'Port': '1.8-1aa850ab5529128de07e82c6fb75fcb5', + 'Port': '1.9-25f8da7ed95f1538f9e08657b0b450c1', + 'PortHardwareOffloadType': '1.0-5f424d02b144fd1832ac3e6b03662674', 'PortDeviceProfile': '1.0-b98c7083cc3e93d176fd7a91ae13af32', 'PortHints': '1.0-9ebf6e12fa427809476a92c7432352b8', 'PortNumaAffinityPolicy': '1.0-38fcea43e7bfb2536461f3d053c43aa3', diff --git a/releasenotes/notes/port-hardware-offload-type-extension-acd266f95c1d7d29.yaml b/releasenotes/notes/port-hardware-offload-type-extension-acd266f95c1d7d29.yaml new file mode 100644 index 00000000000..57ef2376dc1 --- /dev/null +++ b/releasenotes/notes/port-hardware-offload-type-extension-acd266f95c1d7d29.yaml @@ -0,0 +1,11 @@ +--- +features: + - | + Introduce the attribute ``hardware_offload_type`` to ports, that specifies + the hardware offload type this port will request when attached to the + network backend. + + Operators can turn on this feature via the configuration option:: + + [ml2] + extension_drivers = port_hardware_offload_type diff --git a/setup.cfg b/setup.cfg index b833c2ab181..f86eb8b3a0f 100644 --- a/setup.cfg +++ b/setup.cfg @@ -120,6 +120,7 @@ neutron.ml2.extension_drivers = data_plane_status = neutron.plugins.ml2.extensions.data_plane_status:DataPlaneStatusExtensionDriver dns_domain_ports = neutron.plugins.ml2.extensions.dns_integration:DNSDomainPortsExtensionDriver port_device_profile = neutron.plugins.ml2.extensions.port_device_profile:PortDeviceProfileExtensionDriver + port_hardware_offload_type = neutron.plugins.ml2.extensions.port_hardware_offload_type:PortHardwareOffloadTypeExtensionDriver port_numa_affinity_policy = neutron.plugins.ml2.extensions.port_numa_affinity_policy:PortNumaAffinityPolicyExtensionDriver uplink_status_propagation = neutron.plugins.ml2.extensions.uplink_status_propagation:UplinkStatusPropagationExtensionDriver tag_ports_during_bulk_creation = neutron.plugins.ml2.extensions.tag_ports_during_bulk_creation:TagPortsDuringBulkCreationExtensionDriver