Libvirt: do not set MAC when unplugging macvtap VF
- This change updates unplug_hw_veb to reset the VF MAC when unplugging macvtap SR-IOV vifs. Doing this will prevent a network partition to be formed as the VM's MAC is no longer retained on the VF after the vif has been unplugged, allowing traffic with the VFs former MAC to be transmitted on the PF in case it is reused in another host. - This change corrects an outdated comment to reflect that network drivers allow setting a VF's MAC to zero via ip tool. It should be noted that setting the VF's netdev MAC to zero is not allowed and thus ip tool return code in this scenario is ignored in linux_utils.set_vf_interface_vlan(). We also leave a TODO to futher clean up this code later in Stein. Change-Id: I4f78f3cc412d7ec59456aea915a1ebfc8b27681f Closes-Bug: #1808252
This commit is contained in:
parent
ee57c92e8b
commit
9e77c3d3bb
|
@ -975,6 +975,8 @@ class LibvirtVifTestCase(test.NoDBTestCase):
|
|||
mock_get_ifname.side_effect = ['eth1', 'eth13']
|
||||
exit_code = [0, 2, 254]
|
||||
port_state = 'up' if vlan > 0 else 'down'
|
||||
mac = ('00:00:00:00:00:00' if op.__name__ == 'unplug'
|
||||
else self.vif_hw_veb_macvtap['address'])
|
||||
calls = {
|
||||
'get_ifname':
|
||||
[mock.call(self.vif_hw_veb_macvtap['profile']['pci_slot'],
|
||||
|
@ -982,15 +984,10 @@ class LibvirtVifTestCase(test.NoDBTestCase):
|
|||
mock.call(self.vif_hw_veb_macvtap['profile']['pci_slot'])],
|
||||
'get_vf_num':
|
||||
[mock.call(self.vif_hw_veb_macvtap['profile']['pci_slot'])],
|
||||
'execute': [mock.call('ip', 'link', 'set', 'eth1',
|
||||
'vf', 1, 'mac',
|
||||
self.vif_hw_veb_macvtap['address'],
|
||||
'vlan', vlan,
|
||||
run_as_root=True,
|
||||
'execute': [mock.call('ip', 'link', 'set', 'eth1', 'vf', 1,
|
||||
'mac', mac, 'vlan', vlan, run_as_root=True,
|
||||
check_exit_code=exit_code)],
|
||||
'set_macaddr': [mock.call('eth13',
|
||||
self.vif_hw_veb_macvtap['address'],
|
||||
port_state=port_state)]
|
||||
'set_macaddr': [mock.call('eth13', mac, port_state=port_state)]
|
||||
}
|
||||
op(self.instance, self.vif_hw_veb_macvtap)
|
||||
mock_get_ifname.assert_has_calls(calls['get_ifname'])
|
||||
|
|
|
@ -765,14 +765,19 @@ class LibvirtGenericVIFDriver(object):
|
|||
pass
|
||||
|
||||
def unplug_hw_veb(self, instance, vif):
|
||||
# TODO(vladikr): This code can be removed once the minimum version of
|
||||
# Libvirt is incleased above 1.3.5, as vlan will be set by libvirt
|
||||
# TODO(sean-k-mooney): remove in Train after backporting 0 mac
|
||||
# change as this should no longer be needed with libvirt >= 3.2.0.
|
||||
if vif['vnic_type'] == network_model.VNIC_TYPE_MACVTAP:
|
||||
# The ip utility doesn't accept the MAC 00:00:00:00:00:00.
|
||||
# Therefore, keep the MAC unchanged. Later operations on
|
||||
# the same VF will not be affected by the existing MAC.
|
||||
# NOTE(sean-k-mooney): Retaining the vm mac on the vf
|
||||
# after unplugging the vif prevents the PF from transmitting
|
||||
# a packet with that destination address. This would create a
|
||||
# a network partition in the event a vm is migrated or the neuton
|
||||
# port is reused for another vm before the VF is reused.
|
||||
# The ip utility accepts the MAC 00:00:00:00:00:00 which can
|
||||
# be used to reset the VF mac when no longer in use by a vm.
|
||||
# As such we hardcode the 00:00:00:00:00:00 mac.
|
||||
linux_net_utils.set_vf_interface_vlan(vif['profile']['pci_slot'],
|
||||
mac_addr=vif['address'])
|
||||
mac_addr='00:00:00:00:00:00')
|
||||
elif vif['vnic_type'] == network_model.VNIC_TYPE_DIRECT:
|
||||
if "trusted" in vif['profile']:
|
||||
linux_net.set_vf_trusted(vif['profile']['pci_slot'], False)
|
||||
|
|
Loading…
Reference in New Issue