File libvirt-util-don-t-use-netlink-to-save-set-mac-for-macvtap-passthrough-802.1Qbh.patch of Package libvirt
From 6e8777aab9c3d86c5981edda9a57e6a5fe50bd91 Mon Sep 17 00:00:00 2001
Message-Id: <6e8777aab9c3d86c5981edda9a57e6a5fe50bd91@dist-git>
From: Laine Stump <laine@laine.org>
Date: Tue, 29 Sep 2015 14:26:21 -0400
Subject: [PATCH] util: don't use netlink to save/set mac for
macvtap+passthrough+802.1Qbh
Before libvirt sets the MAC address of the physdev (the physical
ethernet device) linked to a macvtap passthrough device, it always
saves the previous MAC address to restore when the guest is finished
(following a "leave nothing behind" policy). For a long time it
accomplished the save/restore with a combination of
ioctl(SIOCGIFHWADDR) and ioctl(SIOCSIFHWADDR), but in commit cbfe38c
(first in libvirt 1.2.15) this was changed to use netlink RTM_GETLINK
and RTM_SETLINK commands sent to the Physical Function (PF) of any
device that was detected to be a Virtual Function (VF).
We later found out that this caused problems with any devices using
the Cisco enic driver (e.g. vmfex cards) because the enic driver
hasn't implemented the function that is called to gather the
information in the IFLA_VFINFO_LIST attribute of RTM_GETLINK
(ndo_get_vf_config() for those keeping score), so we would never get
back a useful response.
In an ideal world, all drivers would implement all functions, but it
turns out that in this case we can work around this omission without
any bad side effects - since all macvtap passthrough <interface>
definitions pointing to a physdev that uses the enic driver *must*
have a <virtualport type='802.1Qbh'>, and since no other type of
ethernet devices use 802.1Qbh, libvirt can change its behavior in this
case to use the old-style. ioctl(SIOC[GS]IFHWADDR). That's what this
patch does.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1251532
(Relevant RHEL7: https://bugzilla.redhat.com/show_bug.cgi?id=1257004)
(cherry-picked from commit 46cf0cefa0168a0d929ca87010f59e1cba6c689b)
Conflicts:
virnetdevmacvlan.c - account for a downstream-only patch to set the
physdev of a macvtap-passthrough interfaces online when it is created
(Bug 1113474).
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/util/virnetdevmacvlan.c | 28 +++++++++++++++++++++-------
1 file changed, 21 insertions(+), 7 deletions(-)
diff --git a/src/util/virnetdevmacvlan.c b/src/util/virnetdevmacvlan.c
index 4a66b43..5f11cac 100644
--- a/src/util/virnetdevmacvlan.c
+++ b/src/util/virnetdevmacvlan.c
@@ -848,18 +848,28 @@ int virNetDevMacVLanCreateWithVPortProfile(const char *tgifname,
* This is especially important when using SRIOV capable cards that
* emulate their switch in firmware.
*/
- if (mode == VIR_NETDEV_MACVLAN_MODE_PASSTHRU) {
- bool isOnline;
- if (virNetDevReplaceNetConfig(linkdev, -1, macaddress, -1, stateDir) < 0)
- return -1;
- if (!virtPortProfile ||
- virtPortProfile->virtPortType != VIR_NETDEV_VPORT_PROFILE_8021QBH) {
+ if (mode == VIR_NETDEV_MACVLAN_MODE_PASSTHRU) {
+ if (virtPortProfile &&
+ virtPortProfile->virtPortType == VIR_NETDEV_VPORT_PROFILE_8021QBH) {
/* we don't set the physdev onlin for 802.1Qbh, because
* that code already does it itself (in
* virNetDevVPortProfileAssociate()), and we don't want to
* change their behavior in any way.
*/
+ /* The Cisco enic driver (the only card that uses
+ * 802.1Qbh) doesn't support IFLA_VFINFO_LIST, which is
+ * required for virNetDevReplaceNetConfig(), so we must
+ * use virNetDevReplaceMacAddress() (which uses
+ * ioctl(SIOCGIFHWADDR) instead.
+ */
+ if (virNetDevReplaceMacAddress(linkdev, macaddress, stateDir) < 0)
+ return -1;
+ } else {
+ bool isOnline;
+
+ if (virNetDevReplaceNetConfig(linkdev, -1, macaddress, -1, stateDir) < 0)
+ return -1;
if (virNetDevIsOnline(linkdev, &isOnline) < 0)
return -1;
if (!isOnline && virNetDevSetOnline(linkdev, true) < 0)
@@ -1003,7 +1013,11 @@ int virNetDevMacVLanDeleteWithVPortProfile(const char *ifname,
int vf = -1;
if (mode == VIR_NETDEV_MACVLAN_MODE_PASSTHRU) {
- ignore_value(virNetDevRestoreNetConfig(linkdev, vf, stateDir));
+ if (virtPortProfile &&
+ virtPortProfile->virtPortType == VIR_NETDEV_VPORT_PROFILE_8021QBH)
+ ignore_value(virNetDevRestoreMacAddress(linkdev, stateDir));
+ else
+ ignore_value(virNetDevRestoreNetConfig(linkdev, vf, stateDir));
/* NB: we can set the linkdev offline even for 802.1Qbh here
* because that is the first thing that will happen for that
--
2.6.2