diff --git a/doc/source/admin/config-qos.rst b/doc/source/admin/config-qos.rst index 4f1dc09a951..e08b8ce4147 100644 --- a/doc/source/admin/config-qos.rst +++ b/doc/source/admin/config-qos.rst @@ -84,12 +84,20 @@ traffic directions (from the VM point of view). .. table:: **Neutron backends, supported directions and enforcement types for Minimum Packet Rate rule** - ============================ ==================== ==================== ============== ===== - Enforcement type \ Backend Open vSwitch SR-IOV Linux Bridge OVN - ============================ ==================== ==================== ============== ===== - Dataplane - - - - - Placement - - - - - ============================ ==================== ==================== ============== ===== + ============================ ========================== ==================== ============== ===== + Enforcement type \ Backend Open vSwitch SR-IOV Linux Bridge OVN + ============================ ========================== ==================== ============== ===== + Dataplane - - - - + Placement Any(1)/Egress/Ingress (2) - - - + ============================ ========================== ==================== ============== ===== + +.. note:: + + (1) Minimum packet rate rule supports ``any`` direction that can be used + with non-hardware-offloaded OVS deployments, where packets processed + from both ingress and egress directions are handled by the same set of + CPU cores. + (2) Since Yoga. For an ml2 plug-in, the list of supported QoS rule types and parameters is defined as a common subset of rules supported by all active mechanism drivers. diff --git a/neutron/plugins/ml2/drivers/openvswitch/agent/extension_drivers/qos_driver.py b/neutron/plugins/ml2/drivers/openvswitch/agent/extension_drivers/qos_driver.py index bda3b29f4dd..b173400b2f8 100644 --- a/neutron/plugins/ml2/drivers/openvswitch/agent/extension_drivers/qos_driver.py +++ b/neutron/plugins/ml2/drivers/openvswitch/agent/extension_drivers/qos_driver.py @@ -214,3 +214,22 @@ class QosOVSAgentDriver(qos.QosLinuxAgentDriver): return LOG.debug("Minimum bandwidth rule for ingress direction was deleted " "for port %s", port['port_id']) + + # NOTE(przszc): Even though dataplane enforcement is not yet implemented + # for minimum packet rate rule, we need dummy methods to support placement + # enforcement. + def create_minimum_packet_rate(self, port, rule): + LOG.debug("Minimum packet rate rule was created for port %s and " + "rule %s.", port['port_id'], rule.id) + + def update_minimum_packet_rate(self, port, rule): + LOG.debug("Minimum packet rate rule was updated for port %s and " + "rule %s.", port['port_id'], rule.id) + + def delete_minimum_packet_rate(self, port): + LOG.debug("Minimum packet rate rule was deleted for port %s", + port['port_id']) + + def delete_minimum_packet_rate_ingress(self, port): + LOG.debug("Minimum packet rate rule for ingress direction was deleted " + "for port %s", port['port_id']) diff --git a/neutron/services/qos/drivers/openvswitch/driver.py b/neutron/services/qos/drivers/openvswitch/driver.py index b12a0d75ed7..5ec3ff69abd 100644 --- a/neutron/services/qos/drivers/openvswitch/driver.py +++ b/neutron/services/qos/drivers/openvswitch/driver.py @@ -21,6 +21,7 @@ from neutron_lib.services.qos import constants as qos_consts from oslo_log import log as logging from neutron.objects import network as network_object +from neutron.services.qos import constants as neutron_qos_consts LOG = logging.getLogger(__name__) @@ -43,7 +44,13 @@ SUPPORTED_RULES = { qos_consts.MIN_KBPS: { 'type:range': [0, db_consts.DB_INTEGER_MAX_VALUE]}, qos_consts.DIRECTION: {'type:values': constants.VALID_DIRECTIONS} - } + }, + neutron_qos_consts.RULE_TYPE_MINIMUM_PACKET_RATE: { + qos_consts.MIN_KPPS: { + 'type:range': [0, db_consts.DB_INTEGER_MAX_VALUE]}, + qos_consts.DIRECTION: { + 'type:values': constants.VALID_DIRECTIONS_AND_ANY}, + }, } diff --git a/neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/extension_drivers/test_qos_driver.py b/neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/extension_drivers/test_qos_driver.py index 714330863ad..a8f6d1697be 100644 --- a/neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/extension_drivers/test_qos_driver.py +++ b/neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/extension_drivers/test_qos_driver.py @@ -260,3 +260,35 @@ class QosOVSAgentDriverTestCase(ovs_test_base.OVSAgentConfigTestBase): self.qos_driver.update_minimum_bandwidth(port, rule) mock_delete_minimum_bandwidth_queue.assert_called_once_with( 'port_id', ['port1', 'port2'], 'ofport', 1500) + + # TODO(przszc): Update tests when dataplane enforcement is implemented for + # minimum packet rate rule + def test_create_minimum_packet_rate(self): + try: + port = {'port_id': 'p_id'} + rule = mock.MagicMock(id='rule_id') + self.qos_driver.create_minimum_packet_rate(port, rule) + except Exception: + self.fail('create_minimum_packet_rate failed') + + def test_update_minimum_packet_rate(self): + try: + port = {'port_id': 'p_id'} + rule = mock.MagicMock(id='rule_id') + self.qos_driver.update_minimum_packet_rate(port, rule) + except Exception: + self.fail('update_minimum_packet_rate failed') + + def test_delete_minimum_packet_rate(self): + try: + port = {'port_id': 'p_id'} + self.qos_driver.delete_minimum_packet_rate(port) + except Exception: + self.fail('delete_minimum_packet_rate failed') + + def test_delete_minimum_packet_rate_ingress(self): + try: + port = {'port_id': 'p_id'} + self.qos_driver.delete_minimum_packet_rate_ingress(port) + except Exception: + self.fail('delete_minimum_packet_rate_ingress failed') diff --git a/releasenotes/notes/qos_min_pps_rule_ovs-3fe3d73227980c53.yaml b/releasenotes/notes/qos_min_pps_rule_ovs-3fe3d73227980c53.yaml new file mode 100644 index 00000000000..17f8b4239bf --- /dev/null +++ b/releasenotes/notes/qos_min_pps_rule_ovs-3fe3d73227980c53.yaml @@ -0,0 +1,5 @@ +--- +features: + - | + Enabled placement enforcement for QoS minimum packet rate rule in OVS + backend.