It takes longer to explain this than to fix it...
In the past we weren't able to save the VF's own MAC address *at all*
when using it for hostdev assignment, because we had already unbound
the VF from the host net driver prior to saving its config. With the
previous patch, that problem has been solved, so we now have the VF's
MAC address saved and can move on to the *next* problem, which is twofold:
1) during teardown we restore the config before we've re-bound, so the
VF doesn't have a net driver, and thus we can't set its MAC address
directly.
2) even if we delay restoring the config until the VF is bound to a
net driver, the request to set its MAC address would fail, since
(during device setup) we had set the "admin MAC" for the VF via an
RTM_SETLINK to the PF - once you've set the admin MAC for a VF, the
VF driver (either on host or on guest) is not allowed to change the
VF's MAC address "forever" (well, until you reload the PF driver,
but that requires destroying and recreating every single VF, which
isn't something you can require).
The solution is to keep the restoration of config at the same place,
but to set the *admin MAC* to the address you want the VF to have -
when the VF net driver is later initialized (as a part of re-binding
to the VF net driver) its MAC will be initialized to the current value
of the admin MAC.
---
src/util/virhostdev.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c
index ad9ba65..cf57354 100644
--- a/src/util/virhostdev.c
+++ b/src/util/virhostdev.c
@@ -562,6 +562,30 @@ virHostdevNetConfigRestore(virDomainHostdevDefPtr hostdev,
&adminMAC, &vlan, &MAC);
if (ret == 0) {
+ /* if a MAC was stored for the VF, we should now restore
+ * that as the adminMAC. We have to do it this way because
+ * the VF is still not bound to the host's net driver, so
+ * we can't directly set its MAC (and even after it is
+ * re-bound to the host net driver, it will still have its
+ * "administratively set" flag on, and that prohibits the
+ * VF's net driver from directly setting the MAC
+ * anyway). But it we set the desired VF MAC as the "admin
+ * MAC" *now*, then when the VF is re-bound to the host
+ * net driver (which will happen soon after returning from
+ * this function), that adminMAC will be set (by the PF)
+ * as the VF's new initial MAC.
+ *
+ * If no MAC was stored for the VF, that means it wasn't
+ * bound to a net driver before we used it anyway, so the
+ * adminMAC is all we have, and we can just restore it
+ * directly.
+ */
+ if (MAC) {
+ VIR_FREE(adminMAC);
+ adminMAC = MAC;
+ MAC = NULL;
+ }
+
ignore_value(virNetDevSetNetConfig(linkdev, vf,
adminMAC, vlan, MAC, true));
}
--
2.9.3