6d3351
From e8dcdd23e5f77d0207203da165d6ba0c561a51e2 Mon Sep 17 00:00:00 2001
6d3351
Message-Id: <e8dcdd23e5f77d0207203da165d6ba0c561a51e2@dist-git>
6d3351
From: Laine Stump <laine@redhat.com>
6d3351
Date: Sun, 23 Apr 2017 21:32:05 -0400
6d3351
Subject: [PATCH] util: allow ignoring SIOCSIFHWADDR when errno is EPERM
6d3351
6d3351
Commit f4ef3a71 made a variation of virNetDevSetMAC that would return
6d3351
without logging an error message if errno was set to
6d3351
EADDRNOTAVAIL. This errno is set by some SRIOV VF drivers (in
6d3351
particular igbvf) when they fail to set the device's MAC address due
6d3351
to the PF driver refusing the request. This is useful if we want to
6d3351
try a different method of setting the VF MAC address before giving up
6d3351
(Commit 86556e16 actually does this, setting the desired MAC address
6d3351
to the "admin MAC in the PF, then detaching and reattaching the VF
6d3351
netdev driver to force a reinit of the MAC address).
6d3351
6d3351
During testing of Bug 1442040 it was discovered that the ixgbe driver
6d3351
returns EPERM in this situation, so this patch changes the exception
6d3351
case for silent+non-terminal failure to account for this difference.
6d3351
6d3351
Completes resolution to: https://bugzilla.redhat.com/1415609 (RHEL 7.4)
6d3351
                         https://bugzilla.redhat.com/1442040 (RHEL 7.3.z)
6d3351
6d3351
(cherry picked from commit 997134fb8b17eef6eba439303b382b239996208b)
6d3351
---
6d3351
 src/util/virnetdev.c | 14 +++++++++-----
6d3351
 1 file changed, 9 insertions(+), 5 deletions(-)
6d3351
6d3351
diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c
6d3351
index 170e34827..9aa9c9f88 100644
6d3351
--- a/src/util/virnetdev.c
6d3351
+++ b/src/util/virnetdev.c
6d3351
@@ -226,7 +226,8 @@ int virNetDevExists(const char *ifname)
6d3351
  * virNetDevSetMACInternal:
6d3351
  * @ifname: interface name to set MTU for
6d3351
  * @macaddr: MAC address
6d3351
- * @quiet: true if a failure to set MAC address with errno == EADDRNOTAVAIL
6d3351
+ * @quiet: true if a failure to set MAC address with
6d3351
+ *         errno == EADDRNOTAVAIL || errno == EPERM
6d3351
  *         should be silent (still returns error, but without log)
6d3351
  *
6d3351
  * This function sets the @macaddr for a given interface @ifname.
6d3351
@@ -258,7 +259,8 @@ virNetDevSetMACInternal(const char *ifname,
6d3351
 
6d3351
     if (ioctl(fd, SIOCSIFHWADDR, &ifr) < 0) {
6d3351
 
6d3351
-        if (quiet && errno == EADDRNOTAVAIL)
6d3351
+        if (quiet &&
6d3351
+            (errno == EADDRNOTAVAIL || errno == EPERM))
6d3351
             goto cleanup;
6d3351
 
6d3351
         virReportSystemError(errno,
6d3351
@@ -305,7 +307,8 @@ virNetDevSetMACInternal(const char *ifname,
6d3351
         ifr.ifr_addr.sa_len = VIR_MAC_BUFLEN;
6d3351
 
6d3351
         if (ioctl(s, SIOCSIFLLADDR, &ifr) < 0) {
6d3351
-            if (quiet && errno == EADDRNOTAVAIL)
6d3351
+            if (quiet &&
6d3351
+                (errno == EADDRNOTAVAIL || errno == EPERM))
6d3351
                 goto cleanup;
6d3351
 
6d3351
             virReportSystemError(errno,
6d3351
@@ -2229,11 +2232,12 @@ virNetDevSetNetConfig(const char *linkdev, int vf,
6d3351
             int retries = 100;
6d3351
 
6d3351
             /* if pfDevOrig == NULL, this isn't a VF, so we've failed */
6d3351
-            if (!pfDevOrig || errno != EADDRNOTAVAIL)
6d3351
+            if (!pfDevOrig ||
6d3351
+                (errno != EADDRNOTAVAIL && errno != EPERM))
6d3351
                 goto cleanup;
6d3351
 
6d3351
             /* Otherwise this is a VF, and virNetDevSetMAC failed with
6d3351
-             * EADDRNOTAVAIL, which could be due to the
6d3351
+             * EADDRNOTAVAIL/EPERM, which could be due to the
6d3351
              * "administratively set" flag being set in the PF for
6d3351
              * this VF.  When this happens, we can attempt to use an
6d3351
              * alternate method to set the VF MAC: first set it into
6d3351
-- 
6d3351
2.12.2
6d3351