diff --git a/neutron/plugins/ml2/drivers/mech_sriov/agent/pci_lib.py b/neutron/plugins/ml2/drivers/mech_sriov/agent/pci_lib.py index 32931841c12..55a43bcf9dc 100644 --- a/neutron/plugins/ml2/drivers/mech_sriov/agent/pci_lib.py +++ b/neutron/plugins/ml2/drivers/mech_sriov/agent/pci_lib.py @@ -73,10 +73,14 @@ class PciDeviceIPWrapper(ip_lib.IPWrapper): @param auto: set link_state to auto (0) """ ip = self.device(self.dev_name) - if auto: + # NOTE(ralonsoh): the state=False --> "disable" (2) has precedence over + # "auto" (0) and "enable" (1). + if state is False: + link_state = 2 + elif auto: link_state = 0 else: - link_state = 1 if state else 2 + link_state = 1 vf_config = {'vf': vf_index, 'link_state': link_state} ip.link.set_vf_feature(vf_config) diff --git a/neutron/tests/unit/plugins/ml2/drivers/mech_sriov/agent/test_pci_lib.py b/neutron/tests/unit/plugins/ml2/drivers/mech_sriov/agent/test_pci_lib.py index 8276e189a4f..962c0772ee3 100644 --- a/neutron/tests/unit/plugins/ml2/drivers/mech_sriov/agent/test_pci_lib.py +++ b/neutron/tests/unit/plugins/ml2/drivers/mech_sriov/agent/test_pci_lib.py @@ -67,18 +67,27 @@ class TestPciLib(base.BaseTestCase): self.assertEqual(pci_lib.LinkState.disable.name, result) def test_set_vf_state(self): + # state=True, auto=False --> link_state=enable self.pci_wrapper.set_vf_state(self.VF_INDEX, True) vf = {'vf': self.VF_INDEX, 'link_state': 1} self.mock_ip_device.link.set_vf_feature.assert_called_once_with(vf) + # state=False, auto=False --> link_state=disable self.mock_ip_device.link.set_vf_feature.reset_mock() self.pci_wrapper.set_vf_state(self.VF_INDEX, False) vf = {'vf': self.VF_INDEX, 'link_state': 2} self.mock_ip_device.link.set_vf_feature.assert_called_once_with(vf) + # state=True, auto=True --> link_state=auto + self.mock_ip_device.link.set_vf_feature.reset_mock() + self.pci_wrapper.set_vf_state(self.VF_INDEX, True, auto=True) + vf = {'vf': self.VF_INDEX, 'link_state': 0} + self.mock_ip_device.link.set_vf_feature.assert_called_once_with(vf) + + # state=False, auto=True --> link_state=disable self.mock_ip_device.link.set_vf_feature.reset_mock() self.pci_wrapper.set_vf_state(self.VF_INDEX, False, auto=True) - vf = {'vf': self.VF_INDEX, 'link_state': 0} + vf = {'vf': self.VF_INDEX, 'link_state': 2} self.mock_ip_device.link.set_vf_feature.assert_called_once_with(vf) def test_set_vf_spoofcheck(self): diff --git a/releasenotes/notes/sriov-vf-state-disable-has-precedence-2adecdf959dc0f9e.yaml b/releasenotes/notes/sriov-vf-state-disable-has-precedence-2adecdf959dc0f9e.yaml new file mode 100644 index 00000000000..6ab968a767e --- /dev/null +++ b/releasenotes/notes/sriov-vf-state-disable-has-precedence-2adecdf959dc0f9e.yaml @@ -0,0 +1,7 @@ +--- +security: + - | + A ML2/SR-IOV port with status=DOWN will always set the VF link state to + "disable", regardless of the ``propagate_uplink_status`` port field value. + The port disabling, to stop any transmission, has precedence over the + link state "auto" value.