diff --git a/gbpservice/neutron/extensions/patch.py b/gbpservice/neutron/extensions/patch.py index 78ac0fce7..e5d792a0b 100644 --- a/gbpservice/neutron/extensions/patch.py +++ b/gbpservice/neutron/extensions/patch.py @@ -260,8 +260,6 @@ try: # method when using L7 parameters. # - key: L7Parameter(key, val) # + key: L7Parameter(keyword=key, value=val) - # Also, make sure classifiers with different l7 params are not considered - # conflicting def create_flow_classifier(self, context, flow_classifier): fc = flow_classifier['flow_classifier'] @@ -299,15 +297,8 @@ try: fc, flow_classifier_db ): - # REVISIT(ivar): Conflict considers l7_parameters - if (validators.is_attr_set(fc['l7_parameters']) and - validators.is_attr_set( - flow_classifier_db['l7_parameters'])): - if (fc['l7_parameters'] == - flow_classifier_db['l7_parameters']): - raise fc_ext.FlowClassifierInConflict( - id=flow_classifier_db['id'] - ) + raise fc_ext.FlowClassifierInConflict( + id=flow_classifier_db['id']) flow_classifier_db = flowclassifier_db.FlowClassifier( id=uuidutils.generate_uuid(), tenant_id=tenant_id, @@ -330,6 +321,32 @@ try: flowclassifier_db.FlowClassifierDbPlugin.create_flow_classifier = ( create_flow_classifier) + # Flowclassifier validation should also take into account l7_parameters. + + old_validation = ( + flowclassifier_db.FlowClassifierDbPlugin.flowclassifier_basic_conflict) + + def flowclassifier_basic_conflict(cls, first_flowclassifier, + second_flowclassifier): + def _l7_params_conflict(fc1, fc2): + if (validators.is_attr_set(fc1['l7_parameters']) and + validators.is_attr_set(fc2['l7_parameters'])): + if fc1['l7_parameters'] == fc2['l7_parameters']: + return True + return all(not validators.is_attr_set(fc['l7_parameters']) + for fc in [fc1, fc2]) + return cls._old_flowclassifier_basic_conflict( + first_flowclassifier, second_flowclassifier) and ( + _l7_params_conflict(first_flowclassifier, second_flowclassifier)) + + if getattr(flowclassifier_db.FlowClassifierDbPlugin, + '_old_flowclassifier_basic_conflict', None) is None: + flowclassifier_db.FlowClassifierDbPlugin.\ + _old_flowclassifier_basic_conflict = old_validation + flowclassifier_db.FlowClassifierDbPlugin.\ + flowclassifier_basic_conflict = classmethod( + flowclassifier_basic_conflict) + # NOTE(ivar): Trunk subports don't have a device ID, we need this # validation to pass # NOTE(ivar): It would be ideal to re-use the original function and call diff --git a/gbpservice/neutron/tests/unit/services/sfc/test_aim_sfc_driver.py b/gbpservice/neutron/tests/unit/services/sfc/test_aim_sfc_driver.py index 879e45aaf..caf0b8ab8 100644 --- a/gbpservice/neutron/tests/unit/services/sfc/test_aim_sfc_driver.py +++ b/gbpservice/neutron/tests/unit/services/sfc/test_aim_sfc_driver.py @@ -838,6 +838,20 @@ class TestFlowClassifier(TestAIMServiceFunctionChainingBase): source_ip_prefix='192.168.0.0/24', destination_ip_prefix='192.168.1.0/24', expected_res_status=201)['flow_classifier'] + + # Same subnets, different networks. + net3 = self._make_network(self.fmt, 'net3', True) + self._make_subnet(self.fmt, net1, '192.168.2.1', '192.168.2.0/24') + net4 = self._make_network(self.fmt, 'net4', True) + self._make_subnet(self.fmt, net1, '192.168.3.1', '192.168.3.0/24') + self.create_flow_classifier( + l7_parameters={ + 'logical_source_network': net3['network']['id'], + 'logical_destination_network': net4['network']['id']}, + source_ip_prefix='192.168.0.0/24', + destination_ip_prefix='192.168.1.0/24', + expected_res_status=201) + self.delete_flow_classifier(fc['id'], expected_res_status=204)