Blob Blame History Raw
From f97142c91f965c0087fcf99122bcd7c0777ef287 Mon Sep 17 00:00:00 2001
Message-Id: <f97142c91f965c0087fcf99122bcd7c0777ef287@dist-git>
From: Laine Stump <laine@laine.org>
Date: Thu, 13 Apr 2017 14:29:34 -0400
Subject: [PATCH] util: after hostdev assignment, restore VF MAC address via
 setting admin MAC

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.

Resolves: https://bugzilla.redhat.com/1442040 (RHEL 7.3.z)
Resolves: https://bugzilla.redhat.com/1415609 (RHEL 7.4)

(cherry picked from commit d6ef331f112ab51af7d14c59cd0b460c2e9609a8)
---
 src/util/virhostdev.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c
index f07e50d2c..fe87fa7d7 100644
--- a/src/util/virhostdev.c
+++ b/src/util/virhostdev.c
@@ -544,6 +544,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.12.2