Skip to content

Commit 493bfd0

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "Check the device ID and host ID during virtual port binding" into stable/2023.1
2 parents 96267a2 + 4adbc85 commit 493bfd0

File tree

4 files changed

+14
-9
lines changed

4 files changed

+14
-9
lines changed

neutron/common/ovn/utils.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -979,10 +979,13 @@ def determine_bind_host(sb_idl, port, port_context=None):
979979

980980

981981
def validate_port_binding_and_virtual_port(
982-
port_context, nb_idl, sb_idl, ml2_plugin, port):
982+
port_context, nb_idl, ml2_plugin, port, original_port):
983983
"""If the port is type=virtual and it is bound, raise BadRequest"""
984-
if not determine_bind_host(sb_idl, port, port_context=port_context):
985-
# The port is not bound, exit.
984+
# If the port receives an update of the device ID and the binding profile
985+
# host ID fields, at the same time, this is because Nova is trying to bind
986+
# the port to a VM (device ID) in a host (host ID).
987+
if not (port['device_id'] != original_port['device_id'] and
988+
port[portbindings.HOST_ID] != original_port[portbindings.HOST_ID]):
986989
return
987990

988991
fixed_ips = port.get('fixed_ips', [])

neutron/plugins/ml2/drivers/ovn/mech_driver/mech_driver.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -819,7 +819,7 @@ def update_port_precommit(self, context):
819819
ovn_utils.validate_and_get_data_from_binding_profile(port)
820820
self._validate_port_extra_dhcp_opts(port)
821821
ovn_utils.validate_port_binding_and_virtual_port(
822-
context, self.nb_ovn, self.sb_ovn, self._plugin, port)
822+
context, self.nb_ovn, self._plugin, port, original_port)
823823
if self._is_port_provisioning_required(port, context.host,
824824
context.original_host):
825825
self._insert_port_provisioning_block(context.plugin_context,

neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/test_mech_driver.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4420,20 +4420,21 @@ def test_update_port_bound(self):
44204420
with self.port(subnet=self.subnet, is_admin=True) as port:
44214421
port = port['port']
44224422
updated_port = copy.deepcopy(port)
4423-
updated_port[portbindings.HOST_ID] = 'host1'
4424-
context = mock.Mock(current=updated_port, original=port)
4423+
updated_port['device_id'] = 'device_id_new'
4424+
updated_port[portbindings.HOST_ID] = 'host_id_new'
4425+
_context = mock.Mock(current=updated_port, original=port)
44254426
with mock.patch.object(self.mech_driver._plugin, 'get_subnets') \
44264427
as mock_get_subnets:
44274428
mock_get_subnets.return_value = [self.subnet['subnet']]
44284429
# 1) The port is not virtual, it has no parents.
44294430
self.mock_vp_parents.return_value = ''
4430-
self.mech_driver.update_port_precommit(context)
4431+
self.mech_driver.update_port_precommit(_context)
44314432
# 2) The port (LSP) has parents, that means it is a virtual
44324433
# port.
44334434
self.mock_vp_parents.return_value = ['parent-0', 'parent-1']
44344435
self.assertRaises(n_exc.BadRequest,
44354436
self.mech_driver.update_port_precommit,
4436-
context)
4437+
_context)
44374438

44384439

44394440
class TestOVNAvailabilityZone(OVNMechanismDriverTestCase):

releasenotes/notes/ovn-virtual-port-prevent-binding-50efba5521e8a28e.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ other:
66
first one is considered a virtual port. If the second port (non-virtual)
77
is bound to ML2/OVN, the virtual port cannot be bound to a virtual
88
machine; a virtual port is created only to reserve a set of IP addresses
9-
to be used by other ports.
9+
to be used by other ports. The OVN mechanism driver prevents that a virtual
10+
port has a device ID; a device ID is provided when the port is being bound.

0 commit comments

Comments
 (0)