From 059b472059add9c1cfd4031a57143e92473976c1 Mon Sep 17 00:00:00 2001 Message-Id: <059b472059add9c1cfd4031a57143e92473976c1@dist-git> From: Laine Stump Date: Thu, 13 Apr 2017 14:29:30 -0400 Subject: [PATCH] util: use new virNetDev*NetConfig() functions for macvtap setup/teardown This patch modifies the macvtap passthrough setup to use virNetDevSaveNetConfig()+virNetDevSetConfig() instead of virNetDevReplaceNetConfig() or virNetDevReplaceMacAddress(), and the teardown to use virNetDevReadNetConfig()+virNetDevSetConfig() instead of virNetDevRestoreNetConfig() or virNetDevRestoreMacAddress(). Since the older functions only saved/restored the admin MAC and vlan tag (which is incorrect) and the new functions save/restore the VF's own MAC address and vlan tag (correct), this actually fixes a bug (which was introduced by commit cb3fe38c7, which was itself supposed to be a fix for https://bugzilla.redhat.com/1113474 ). The downside to this patch is that it causes an *apparent* regression in that bug (because there will once again be an error reported if the interface had previously been used for VFIO device assignment), but in reality, the code hasn't been working for *any* case before this current patch (at least not with any recent kernel). Anyway, that "regression" will be fixed with an upcoming patch that fixes it the *right* way. Resolves: https://bugzilla.redhat.com/1442040 (RHEL 7.3.z) Resolves: https://bugzilla.redhat.com/1415609 (RHEL 7.4) (cherry picked from commit b91a33638476cf57d910b6056a8fc11921edd029) --- src/util/virnetdevmacvlan.c | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/src/util/virnetdevmacvlan.c b/src/util/virnetdevmacvlan.c index 61da55415..40d64675e 100644 --- a/src/util/virnetdevmacvlan.c +++ b/src/util/virnetdevmacvlan.c @@ -1011,20 +1011,22 @@ virNetDevMacVLanCreateWithVPortProfile(const char *ifnameRequested, */ if (mode == VIR_NETDEV_MACVLAN_MODE_PASSTHRU) { + bool setVlan = true; + if (virtPortProfile && virtPortProfile->virtPortType == VIR_NETDEV_VPORT_PROFILE_8021QBH) { - /* 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 this function (which uses ioctl(SIOCGIFHWADDR) - * instead or virNetDevReplaceNetConfig() + /* The Cisco enic driver (the only SRIOV-capable card that + * uses 802.1Qbh) doesn't support IFLA_VFINFO_LIST, which + * is required to get/set the vlan tag of a VF. */ - if (virNetDevReplaceMacAddress(linkdev, macaddress, stateDir) < 0) - return -1; - } else { - if (virNetDevReplaceNetConfig(linkdev, -1, macaddress, vlan, stateDir) < 0) - return -1; + setVlan = false; } + + if (virNetDevSaveNetConfig(linkdev, -1, stateDir, setVlan) < 0) + return -1; + + if (virNetDevSetNetConfig(linkdev, -1, NULL, vlan, macaddress, setVlan) < 0) + return -1; } if (ifnameRequested) { @@ -1205,11 +1207,19 @@ int virNetDevMacVLanDeleteWithVPortProfile(const char *ifname, } if (mode == VIR_NETDEV_MACVLAN_MODE_PASSTHRU) { - if (virtPortProfile && - virtPortProfile->virtPortType == VIR_NETDEV_VPORT_PROFILE_8021QBH) - ignore_value(virNetDevRestoreMacAddress(linkdev, stateDir)); - else - ignore_value(virNetDevRestoreNetConfig(linkdev, -1, stateDir)); + virMacAddrPtr MAC = NULL; + virMacAddrPtr adminMAC = NULL; + virNetDevVlanPtr vlan = NULL; + + if (virNetDevReadNetConfig(linkdev, -1, stateDir, + &adminMAC, &vlan, &MAC) == 0) { + + ignore_value(virNetDevSetNetConfig(linkdev, -1, + adminMAC, vlan, MAC, !!vlan)); + VIR_FREE(MAC); + VIR_FREE(adminMAC); + virNetDevVlanFree(vlan); + } } virNetlinkEventRemoveClient(0, macaddr, NETLINK_ROUTE); -- 2.12.2