Skip to content

Commit 2d05ee3

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "Translate VF network capabilities to port binding" into stable/2023.1
2 parents 3ce1bd5 + 4fcc8c3 commit 2d05ee3

File tree

7 files changed

+47
-3
lines changed

7 files changed

+47
-3
lines changed

nova/network/neutron.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1601,6 +1601,13 @@ def _get_vf_pci_device_profile(self, pci_dev):
16011601
'pf_mac_address': pf_mac,
16021602
'vf_num': vf_num,
16031603
})
1604+
1605+
# Update port binding capabilities using PCI device's network
1606+
# capabilities if they exist.
1607+
pci_net_caps = pci_dev.network_caps
1608+
if pci_net_caps:
1609+
vf_profile.update({'capabilities': pci_net_caps})
1610+
16041611
return vf_profile
16051612

16061613
def _get_pci_device_profile(self, pci_dev):

nova/objects/pci_device.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,13 @@ def mac_address(self):
588588
"""
589589
return self.extra_info.get('mac_address')
590590

591+
@property
592+
def network_caps(self):
593+
"""PCI device network capabilities or empty list if not available"""
594+
caps_json = self.extra_info.get('capabilities', '{}')
595+
caps = jsonutils.loads(caps_json)
596+
return caps.get('network', [])
597+
591598

592599
@base.NovaObjectRegistry.register
593600
class PciDeviceList(base.ObjectListBase, base.NovaObject):

nova/tests/fixtures/libvirt_data.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2182,6 +2182,7 @@ def fake_kvm_guest():
21822182
<feature name='rxvlan'/>
21832183
<feature name='txvlan'/>
21842184
<feature name='rxhash'/>
2185+
<feature name='switchdev'/>
21852186
<capability type='80203'/>
21862187
</capability>
21872188
</device>""", # noqa:E501

nova/tests/unit/network/test_neutron.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8144,17 +8144,20 @@ def test__get_vf_pci_device_profile(self):
81448144
'pf_mac_address': '52:54:00:1e:59:c6',
81458145
'vf_num': 1,
81468146
},
8147+
'network_caps': ['gso', 'sg', 'tso', 'tx'],
81478148
'dev_type': obj_fields.PciDeviceType.SRIOV_VF,
81488149
}
81498150
PciDevice = collections.namedtuple('PciDevice',
81508151
['vendor_id', 'product_id', 'address',
81518152
'card_serial_number', 'sriov_cap',
8152-
'dev_type', 'parent_addr'])
8153+
'dev_type', 'parent_addr',
8154+
'network_caps'])
81538155
mydev = PciDevice(**pci_dev)
81548156
self.assertEqual(self.api._get_vf_pci_device_profile(mydev),
81558157
{'pf_mac_address': '52:54:00:1e:59:c6',
81568158
'vf_num': 1,
8157-
'card_serial_number': 'MT2113X00000'})
8159+
'card_serial_number': 'MT2113X00000',
8160+
'capabilities': ['gso', 'sg', 'tso', 'tx']})
81588161

81598162
@mock.patch.object(
81608163
neutronapi.API, '_get_vf_pci_device_profile',

nova/tests/unit/objects/test_pci_device.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,16 @@ def test_pci_device_extra_info_card_serial_number(self):
171171
self.pci_device = pci_device.PciDevice.create(None, self.dev_dict)
172172
self.assertEqual(self.pci_device.card_serial_number, '42')
173173

174+
def test_pci_device_extra_info_network_capabilities(self):
175+
self.dev_dict = copy.copy(dev_dict)
176+
self.pci_device = pci_device.PciDevice.create(None, self.dev_dict)
177+
self.assertEqual(self.pci_device.network_caps, [])
178+
179+
self.dev_dict = copy.copy(dev_dict)
180+
self.dev_dict['capabilities'] = {'network': ['sg', 'tso', 'tx']}
181+
self.pci_device = pci_device.PciDevice.create(None, self.dev_dict)
182+
self.assertEqual(self.pci_device.network_caps, ['sg', 'tso', 'tx'])
183+
174184
def test_update_device(self):
175185
self.pci_device = pci_device.PciDevice.create(None, dev_dict)
176186
self.pci_device.obj_reset_changes()

nova/tests/unit/virt/libvirt/test_host.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1343,7 +1343,7 @@ def test_get_pcidev_info(self):
13431343
"parent_ifname": "ens1",
13441344
"capabilities": {
13451345
"network": ["rx", "tx", "sg", "tso", "gso", "gro", "rxvlan",
1346-
"txvlan", "rxhash"],
1346+
"txvlan", "rxhash", "switchdev"],
13471347
"sriov": {"pf_mac_address": "52:54:00:1e:59:c6",
13481348
"vf_num": 1},
13491349
# Should be obtained from the parent PF in this case.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
---
2+
fixes:
3+
- |
4+
Previously ``switchdev`` capabilities should be configured manually by a
5+
user with admin privileges using port's binding profile. This blocked
6+
regular users from managing ports with Open vSwitch hardware offloading
7+
as providing write access to a port's binding profile to non-admin users
8+
introduces security risks. For example, a binding profile may contain a
9+
``pci_slot`` definition, which denotes the host PCI address of the
10+
device attached to the VM. A malicious user can use this parameter to
11+
passthrough any host device to a guest, so it is impossible to provide
12+
write access to a binding profile to regular users in many scenarios.
13+
14+
This patch fixes this situation by translating VF capabilities reported
15+
by Libvirt to Neutron port binding profiles. Other VF capabilities are
16+
translated as well for possible future use.

0 commit comments

Comments
 (0)