
24 Feb
2012
24 Feb
'12
9:38 a.m.
On Feb 24, 2012, at 3:29 PM, D. Herrendoerfer wrote: > > On Feb 23, 2012, at 11:16 PM, Laine Stump wrote: > >> On 02/22/2012 08:17 AM, D. Herrendoerfer wrote: >>> From: "D. Herrendoerfer" <d.herrendoerfer@herrendoerfer.name> >>> >>> Add de-association handling for 802.1qbg (vepa) via lldpad >>> netlink messages. Also adds the possibility to perform an >>> association request without waiting for a confirmation. >> >> The main issue I see with this patch is with whitespace, but that can >> easily be fixed prior to pushing it, so ACK. Is the message format >> used >> by this patch, the absolute final version? (i.e. can we safely push >> it >> an know that it will be correct?) > > The patch to libvirt was picked this week. So yes, we can assume > that the > message will not be changed. But as always : Never say never ! The patch to lldpad (Doh!) was picked ... > The callback mechanism is not re-armed when libvirt is restarted now. > The reason is: lldpad remembers who sent the associate by pid - since > in theory there could be multiple agents performing associations. > So if the libvirt pid changes, there is little we can do now. > > And thanks ! > > Dirk H > >> >>> >>> Signed-off-by: D. Herrendoerfer <d.herrendoerfer@herrendoerfer.name> >>> --- >>> src/qemu/qemu_migration.c | 2 +- >>> src/util/virnetdevmacvlan.c | 315 +++++++++++++++++++++++++++ >>> ++++++++++- >>> src/util/virnetdevvportprofile.c | 33 +++-- >>> src/util/virnetdevvportprofile.h | 3 +- >>> 4 files changed, 339 insertions(+), 14 deletions(-) >>> >>> diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c >>> index 12cfbde..31428f8 100644 >>> --- a/src/qemu/qemu_migration.c >>> +++ b/src/qemu/qemu_migration.c >>> @@ -2567,7 +2567,7 @@ >>> qemuMigrationVPAssociatePortProfiles(virDomainDefPtr def) { >>> net->mac, >>> >>> virDomainNetGetActualDirectDev(net), >>> def->uuid, >>> - >>> VIR_NETDEV_VPORT_PROFILE_OP_MIGRATE_IN_FINISH) < 0) >>> + >>> VIR_NETDEV_VPORT_PROFILE_OP_MIGRATE_IN_FINISH, false) < 0) >>> goto err_exit; >>> } >>> last_good_net = i; >>> diff --git a/src/util/virnetdevmacvlan.c b/src/util/ >>> virnetdevmacvlan.c >>> index 25d0846..b3e3325 100644 >>> --- a/src/util/virnetdevmacvlan.c >>> +++ b/src/util/virnetdevmacvlan.c >>> @@ -46,7 +46,6 @@ VIR_ENUM_IMPL(virNetDevMacVLanMode, >>> VIR_NETDEV_MACVLAN_MODE_LAST, >>> "passthrough") >>> >>> #if WITH_MACVTAP >>> - >> >> spurious whitespace change. >> >>> # include <stdint.h> >>> # include <stdio.h> >>> # include <errno.h> >>> @@ -57,6 +56,8 @@ VIR_ENUM_IMPL(virNetDevMacVLanMode, >>> VIR_NETDEV_MACVLAN_MODE_LAST, >>> # include <linux/if.h> >>> # include <linux/if_tun.h> >>> >>> +# include <c-ctype.h> >>> + >>> /* Older kernels lacked this enum value. */ >>> # if !HAVE_DECL_MACVLAN_MODE_PASSTHRU >>> # define MACVLAN_MODE_PASSTHRU 8 >>> @@ -68,6 +69,8 @@ VIR_ENUM_IMPL(virNetDevMacVLanMode, >>> VIR_NETDEV_MACVLAN_MODE_LAST, >>> # include "virfile.h" >>> # include "virnetlink.h" >>> # include "virnetdev.h" >>> +# include "virpidfile.h" >>> + >>> >>> # define MACVTAP_NAME_PREFIX "macvtap" >>> # define MACVTAP_NAME_PATTERN "macvtap%d" >>> @@ -75,6 +78,7 @@ VIR_ENUM_IMPL(virNetDevMacVLanMode, >>> VIR_NETDEV_MACVLAN_MODE_LAST, >>> # define MACVLAN_NAME_PREFIX "macvlan" >>> # define MACVLAN_NAME_PATTERN "macvlan%d" >>> >>> + >> >> Another spurious whitespace change. >> >>> /** >>> * virNetDevMacVLanCreate: >>> * >>> @@ -445,6 +449,293 @@ static const uint32_t >>> modeMap[VIR_NETDEV_MACVLAN_MODE_LAST] = { >>> [VIR_NETDEV_MACVLAN_MODE_PASSTHRU] = MACVLAN_MODE_PASSTHRU, >>> }; >>> >>> +/* Struct to hold the state and configuration of a 802.1qbg port */ >>> +struct virNetlinkCallbackData { >>> + char cr_ifname[64]; >>> + virNetDevVPortProfilePtr virtPortProfile; >>> + const unsigned char *macaddress; >>> + const char *linkdev; >>> + const unsigned char *vmuuid; >>> + enum virNetDevVPortProfileOp vmOp; >>> + unsigned int linkState; >>> +}; >>> + >>> +typedef struct virNetlinkCallbackData *virNetlinkCallbackDataPtr; >>> + >>> +#define INSTANCE_STRLEN 36 >>> + >>> +static int instance2str(const unsigned char *p, char *dst, size_t >>> size) >>> +{ >>> + if (dst && size > INSTANCE_STRLEN) { >>> + snprintf(dst, size, "%02x%02x%02x%02x-%02x%02x-%02x%02x-" >>> + "%02x%02x-%02x%02x%02x%02x%02x%02x", >>> + p[0], p[1], p[2], p[3], >>> + p[4], p[5], p[6], p[7], >>> + p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]); >>> + return 0; >>> + } >>> + return -1; >>> +} >>> + >>> +# define LLDPAD_PID_FILE "/var/run/lldpad.pid" >>> +# define VIRIP_PID_FILE "/var/run/virip.pid" >>> + >>> +/** >>> + * virNetDevMacVLanVPortProfileCallback: >>> + * >>> + * @msg: The buffer containing the received netlink message >>> + * @length: The length of the received netlink message. >>> + * @peer: The netling sockaddr containing the peer information >>> + * @handeled: Contains information if the message has been >>> replied to yet >>> + * @opaque: Contains vital information regarding the associated >>> vm an interface >>> + * >>> + * This function is called when a netlink message is received. >>> The function >>> + * reads the message and responds if it is pertinent to the >>> running VMs >>> + * network interface. >>> + */ >>> + >>> +static void >>> +virNetDevMacVLanVPortProfileCallback( unsigned char *msg, >>> + int length, >>> + struct sockaddr_nl *peer, >>> + bool *handled, >>> + void *opaque) >>> +{ >>> + struct nla_policy ifla_vf_policy[IFLA_VF_MAX + 1] = { >>> + [IFLA_VF_MAC] = {.minlen = sizeof(struct ifla_vf_mac), >>> + .maxlen = sizeof(struct ifla_vf_mac)}, >>> + [IFLA_VF_VLAN] = {.minlen = sizeof(struct ifla_vf_vlan), >>> + .maxlen = sizeof(struct ifla_vf_vlan)}, >> >> The indentation looks off here. Don't know if it's the actual patch >> or >> my mail client... >> >>> + }; >>> + >>> + struct nla_policy ifla_port_policy[IFLA_PORT_MAX + 1] = { >>> + [IFLA_PORT_RESPONSE] = {.type = NLA_U16}, >>> + }; >>> + >>> + struct nlattr *tb[IFLA_MAX + 1], >>> + *tb3[IFLA_PORT_MAX + 1], >>> + *tb_vfinfo[IFLA_VF_MAX + 1], *tb_vfinfo_list; >>> + >>> + struct ifinfomsg ifinfo; >>> + struct nlmsghdr *hdr; >>> + void *data; >>> + int rem; >>> + char *ifname; >>> + bool indicate = false; >> >> The previous 4 lines all have tab characters instead of spaces. >> libvirt >> likes spaces only. >> >>> + virNetlinkCallbackDataPtr calld = opaque; >>> + pid_t lldpad_pid = 0; >>> + pid_t virip_pid = 0; >>> + >>> + hdr = (struct nlmsghdr *) msg; >> >> Another tab. I'll stop pointing these out, and just mention that >> "make >> syntax-check" will show these to you - you should try to run make >> syntax >> check before sending patches. >> >>> + data = nlmsg_data(hdr); >>> + >>> + /* Quickly decide if we want this or not */ >>> + >>> + if (virPidFileReadPath(LLDPAD_PID_FILE, &lldpad_pid) < 0) >>> + return; >>> + >>> + ignore_value(virPidFileReadPath(VIRIP_PID_FILE, &virip_pid)); >>> + >>> + if (hdr->nlmsg_pid != lldpad_pid && hdr->nlmsg_pid != >>> virip_pid) >>> + return; // we only care for lldpad and virip messages >>> + if (hdr->nlmsg_type != RTM_SETLINK) >>> + return; // we only care for RTM_SETLINK >>> + if (*handled) >>> + return; // if it has been handeled - dont handle again >> >> misspelled "handled" (Could this if be further up in the function?) >> >>> + >>> + /* DEBUG start */ >>> + VIR_INFO("netlink message nl_sockaddr: %p len: %d", peer, >>> length); >>> + VIR_DEBUG("nlmsg_type = 0x%02x",hdr->nlmsg_type); >>> + VIR_DEBUG("nlmsg_len = 0x%04x",hdr->nlmsg_len ); >>> + VIR_DEBUG("nlmsg_pid = %d",hdr->nlmsg_pid ); >>> + VIR_DEBUG("nlmsg_seq = 0x%08x",hdr->nlmsg_seq ); >>> + VIR_DEBUG("nlmsg_flags = 0x%04x",hdr->nlmsg_flags ); >>> + >>> + VIR_DEBUG("lldpad pid = %d",lldpad_pid); >>> + >>> + switch (hdr->nlmsg_type) { >>> + case RTM_NEWLINK: >>> + case RTM_DELLINK: >>> + case RTM_SETLINK: >>> + case RTM_GETLINK: >>> + VIR_DEBUG(" IFINFOMSG\n"); >>> + VIR_DEBUG(" ifi_family = 0x%02x\n", >>> + ((struct ifinfomsg *)data)->ifi_family); >>> + VIR_DEBUG(" ifi_type = 0x%x\n", >>> + ((struct ifinfomsg *)data)->ifi_type); >>> + VIR_DEBUG(" ifi_index = %i\n", >>> + ((struct ifinfomsg *)data)->ifi_index); >>> + VIR_DEBUG(" ifi_flags = 0x%04x\n", >>> + ((struct ifinfomsg *)data)->ifi_flags); >>> + VIR_DEBUG(" ifi_change = 0x%04x\n", >>> + ((struct ifinfomsg *)data)->ifi_change); >>> + } >>> + /* DEBUG end */ >>> + >>> + /* Parse netlink message assume a setlink with vfports */ >>> + memcpy(&ifinfo, NLMSG_DATA(hdr), sizeof ifinfo); >>> + VIR_DEBUG("family:%#x type:%#x index:%d flags:%#x change:%#x", >>> + ifinfo.ifi_family, ifinfo.ifi_type, ifinfo.ifi_index, >>> + ifinfo.ifi_flags, ifinfo.ifi_change); >>> + if (nlmsg_parse(hdr, sizeof ifinfo, >>> + (struct nlattr **)&tb, IFLA_MAX, NULL)) { >>> + VIR_DEBUG("error parsing request..."); >>> + return; >>> + } >>> + >>> + if (tb[IFLA_VFINFO_LIST]) { >>> + VIR_DEBUG("FOUND IFLA_VFINFO_LIST!"); >>> + >>> + nla_for_each_nested(tb_vfinfo_list, tb[IFLA_VFINFO_LIST], >>> rem) { >>> + if (nla_type(tb_vfinfo_list) != IFLA_VF_INFO) { >>> + VIR_DEBUG("nested parsing of" >>> + "IFLA_VFINFO_LIST failed."); >>> + return; >>> + } >>> + if (nla_parse_nested(tb_vfinfo, IFLA_VF_MAX, >>> + tb_vfinfo_list, ifla_vf_policy)) { >>> + VIR_DEBUG("nested parsing of " >>> + "IFLA_VF_INFO failed."); >>> + return; >>> + } >>> + } >>> + >>> + if (tb_vfinfo[IFLA_VF_MAC]) { >>> + struct ifla_vf_mac *mac = >>> + RTA_DATA(tb_vfinfo[IFLA_VF_MAC]); >>> + unsigned char *m = mac->mac; >>> + >>> + VIR_DEBUG("IFLA_VF_MAC=%2x:%2x:%2x:%2x:%2x:%2x", >>> + m[0], m[1], m[2], m[3], m[4], m[5]); >>> + >>> + if (memcmp(calld->macaddress, m, VIR_MAC_BUFLEN)) >>> + { >>> + /* Repeat the same check for a broadcast mac */ >>> + unsigned char broadcastmac[VIR_MAC_BUFLEN]; >>> + int i; >>> + >>> + for (i=0;i<VIR_MAC_BUFLEN;i++) >>> + broadcastmac[i]=0xFF; >>> + >>> + if (memcmp(calld->macaddress, broadcastmac, >>> VIR_MAC_BUFLEN)) { >>> + VIR_DEBUG("MAC address match failed."); >>> + return; >> >> >> Why not just compare calld->macaddress[i] to 0xFF in the for loop, >> returning immediately when a non-FF byte is found? >> >> >>> + } >>> + } >>> + } >>> + >>> + if (tb_vfinfo[IFLA_VF_VLAN]) { >>> + struct ifla_vf_vlan *vlan = >>> + RTA_DATA(tb_vfinfo[IFLA_VF_VLAN]); >>> + >>> + VIR_DEBUG("IFLA_VF_VLAN=%d", vlan->vlan); >>> + } >>> + } >>> + >>> + if (tb[IFLA_IFNAME]) { >>> + ifname = (char *)RTA_DATA(tb[IFLA_IFNAME]); >>> + VIR_DEBUG("IFLA_IFNAME=%s\n", ifname); >>> + } >>> + >>> + if (tb[IFLA_OPERSTATE]) { >>> + rem = *(unsigned short *)RTA_DATA(tb[IFLA_OPERSTATE]); >>> + VIR_DEBUG("IFLA_OPERSTATE=%d\n", rem); >>> + } >>> + >>> + if (tb[IFLA_VF_PORTS]) { >>> + struct nlattr *tb_vf_ports; >>> + >>> + VIR_DEBUG("found IFLA_VF_PORTS\n"); >>> + nla_for_each_nested(tb_vf_ports, tb[IFLA_VF_PORTS], rem) { >>> + >>> + VIR_DEBUG("iterating\n"); >>> + if (nla_type(tb_vf_ports) != IFLA_VF_PORT) { >>> + VIR_DEBUG("not a IFLA_VF_PORT. skipping\n"); >>> + continue; >>> + } >>> + if (nla_parse_nested(tb3, IFLA_PORT_MAX, tb_vf_ports, >>> + ifla_port_policy)) { >>> + VIR_DEBUG("nested parsing on level 2" >>> + " failed."); >>> + } >>> + if (tb3[IFLA_PORT_VF]) { >>> + VIR_DEBUG("IFLA_PORT_VF=%d", >>> + *(uint32_t >>> + *) (RTA_DATA(tb3[IFLA_PORT_VF]))); >>> + } >>> + if (tb3[IFLA_PORT_PROFILE]) { >>> + VIR_DEBUG("IFLA_PORT_PROFILE=%s", (char *) >>> + RTA_DATA(tb3[IFLA_PORT_PROFILE])); >>> + } >>> + >>> + if (tb3[IFLA_PORT_VSI_TYPE]) { >>> + struct ifla_port_vsi *pvsi; >>> + int tid = 0; >>> + >>> + pvsi = (struct ifla_port_vsi *) >>> + RTA_DATA(tb3[IFLA_PORT_VSI_TYPE]); >>> + tid = pvsi->vsi_type_id[2] << 16 | >>> + pvsi->vsi_type_id[1] << 8 | >>> + pvsi->vsi_type_id[0]; >>> + >>> + VIR_DEBUG("mgr_id: %d", pvsi->vsi_mgr_id); >>> + VIR_DEBUG("type_id: %d", tid); >>> + VIR_DEBUG("type_version: %d", >>> + pvsi->vsi_type_version); >>> + } >>> + >>> + if (tb3[IFLA_PORT_INSTANCE_UUID]) { >>> + char instance[INSTANCE_STRLEN + 2]; >>> + unsigned char *uuid; >>> + >>> + uuid = (unsigned char *) >>> + RTA_DATA(tb3[IFLA_PORT_INSTANCE_UUID]); >>> + instance2str(uuid, instance, sizeof(instance)); >>> + VIR_DEBUG("IFLA_PORT_INSTANCE_UUID=%s\n", >>> + instance); >>> + } >>> + >>> + if (tb3[IFLA_PORT_REQUEST]) { >>> + uint8_t req = *(uint8_t *) >>> RTA_DATA(tb3[IFLA_PORT_REQUEST]); >>> + VIR_DEBUG("IFLA_PORT_REQUEST=%d", req); >>> + >>> + if ( req == PORT_REQUEST_DISASSOCIATE ) { >>> + VIR_DEBUG("Set dissaccociated."); >>> + indicate=true; >>> + } >>> + } >>> + >>> + if (tb3[IFLA_PORT_RESPONSE]) { >>> + VIR_DEBUG("IFLA_PORT_RESPONSE=%d\n", *(uint16_t *) >>> + RTA_DATA(tb3[IFLA_PORT_RESPONSE])); >>> + } >>> + } >>> + } >>> + >>> + if (!indicate) { >>> + return; >>> + } >>> + >>> + VIR_INFO("Re-send 802.1qbg associate request:"); >>> + VIR_INFO(" if: %s",calld->cr_ifname ); >>> + VIR_INFO(" lf: %s",calld->linkdev ); >>> + VIR_INFO(" mac: %02x:%02x:%02x:%02x:%02x:%02x",calld- >>> >macaddress[0], >>> + calld- >>> >macaddress[1], >>> + calld- >>> >macaddress[2], >>> + calld- >>> >macaddress[3], >>> + calld- >>> >macaddress[4], >>> + calld- >>> >macaddress[5] ); >> >> Bad indentation. >> >>> + >>> + ignore_value(virNetDevVPortProfileAssociate(calld->cr_ifname, >>> + calld->virtPortProfile, >>> + calld->macaddress, >>> + calld->linkdev, >>> + calld->vmuuid, calld- >>> >vmOp, true)); >>> + >>> + *handled = true; >>> + return; >>> +} >>> + >>> /** >>> * virNetDevMacVLanCreateWithVPortProfile: >>> * Create an instance of a macvtap device and open its tap character >>> @@ -547,7 +838,7 @@ create_name: >>> virtPortProfile, >>> macaddress, >>> linkdev, >>> - vmuuid, vmOp) < 0) { >>> + vmuuid, vmOp, false) < 0) { >>> rc = -1; >>> goto link_del_exit; >>> } >>> @@ -589,6 +880,23 @@ create_name: >>> goto disassociate_exit; >>> } >>> >>> + if (virNetlinkEventServiceIsRunning()) { >>> + virNetlinkCallbackDataPtr calld; >>> + >>> + if (VIR_ALLOC(calld) < 0) { >>> + virReportOOMError(); >>> + goto disassociate_exit; >>> + } >>> + >>> + strncpy(calld->cr_ifname,cr_ifname,64); >>> + calld->virtPortProfile=virtPortProfile; >>> + calld->macaddress=macaddress; >>> + calld->linkdev=linkdev; >>> + calld->vmuuid=vmuuid; >>> + calld->vmOp=vmOp; >> >> Put spaces around "=" signs. >> >>> + >>> + >>> virNetlinkEventAddClient(virNetDevMacVLanVPortProfileCallback, >>> calld, macaddress); >> >> Maybe we should check for a return value here. >> >> >>> + } >>> >>> return rc; >>> >>> @@ -638,6 +946,9 @@ int >>> virNetDevMacVLanDeleteWithVPortProfile(const char *ifname, >>> if (virNetDevMacVLanDelete(ifname) < 0) >>> ret = -1; >>> } >>> + >>> + virNetlinkEventRemoveClient(0,macaddr); >>> + >>> return ret; >>> } >>> >>> diff --git a/src/util/virnetdevvportprofile.c b/src/util/ >>> virnetdevvportprofile.c >>> index faadc3a..554f128 100644 >>> --- a/src/util/virnetdevvportprofile.c >>> +++ b/src/util/virnetdevvportprofile.c >>> @@ -650,7 +650,8 @@ virNetDevVPortProfileOpCommon(const char >>> *ifname, int ifindex, >>> const unsigned char *instanceId, >>> const unsigned char *hostUUID, >>> int32_t vf, >>> - uint8_t op) >>> + uint8_t op, >>> + bool setlink_only) >>> { >>> int rc; >>> unsigned char *recvbuf = NULL; >>> @@ -675,6 +676,9 @@ virNetDevVPortProfileOpCommon(const char >>> *ifname, int ifindex, >>> return rc; >>> } >>> >>> + if (setlink_only) /*for re-associations on existing links*/ >>> + return 0; >>> + >>> while (--repeats >= 0) { >>> rc = virNetDevVPortProfileLinkDump(NULL, ifindex, >>> nltarget_kernel, tb, >>> &recvbuf, >>> virNetDevVPortProfileGetLldpadPid); >>> @@ -751,7 +755,8 @@ static int >>> virNetDevVPortProfileOp8021Qbg(const char *ifname, >>> const unsigned char *macaddr, >>> const virNetDevVPortProfilePtr >>> virtPort, >>> - enum virNetDevVPortProfileLinkOp >>> virtPortOp) >>> + enum virNetDevVPortProfileLinkOp >>> virtPortOp, >>> + bool setlink_only) >>> { >>> int rc = 0; >>> int op = PORT_REQUEST_ASSOCIATE; >>> @@ -804,7 +809,8 @@ virNetDevVPortProfileOp8021Qbg(const char >>> *ifname, >>> virtPort- >>> >u.virtPort8021Qbg.instanceID, >>> NULL, >>> vf, >>> - op); >>> + op, >>> + setlink_only); >>> >>> err_exit: >>> >>> @@ -892,7 +898,8 @@ virNetDevVPortProfileOp8021Qbh(const char >>> *ifname, >>> (virtPortOp == >>> >>> VIR_NETDEV_VPORT_PROFILE_LINK_OP_PREASSOCIATE_RR) ? >>> >>> PORT_REQUEST_PREASSOCIATE_RR >>> - : >>> PORT_REQUEST_ASSOCIATE); >>> + : >>> PORT_REQUEST_ASSOCIATE, >>> + false); >>> if (rc == -2) >>> /* Association timed out, disassociate */ >>> virNetDevVPortProfileOpCommon(NULL, ifindex, >>> @@ -904,7 +911,8 @@ virNetDevVPortProfileOp8021Qbh(const char >>> *ifname, >>> NULL, >>> NULL, >>> vf, >>> - >>> PORT_REQUEST_DISASSOCIATE); >>> + >>> PORT_REQUEST_DISASSOCIATE, >>> + false); >>> break; >>> >>> case VIR_NETDEV_VPORT_PROFILE_LINK_OP_DISASSOCIATE: >>> @@ -917,7 +925,8 @@ virNetDevVPortProfileOp8021Qbh(const char >>> *ifname, >>> NULL, >>> NULL, >>> vf, >>> - >>> PORT_REQUEST_DISASSOCIATE); >>> + >>> PORT_REQUEST_DISASSOCIATE, >>> + false); >>> break; >>> >>> default: >>> @@ -938,6 +947,7 @@ err_exit: >>> * @virtPort: pointer to the object holding port profile parameters >>> * @vmuuid : the UUID of the virtual machine >>> * @vmOp : The VM operation (i.e., create, no-op) >>> + * @setlink_only : Only set the link - dont wait for the link to >>> come up >>> * >>> * Associate a port on a swtich with a profile. This function >>> * may notify a kernel driver or an external daemon to run >>> @@ -954,7 +964,8 @@ virNetDevVPortProfileAssociate(const char >>> *macvtap_ifname, >>> const unsigned char *macvtap_macaddr, >>> const char *linkdev, >>> const unsigned char *vmuuid, >>> - enum virNetDevVPortProfileOp vmOp) >>> + enum virNetDevVPortProfileOp vmOp, >>> + bool setlink_only) >>> { >>> int rc = 0; >>> >>> @@ -976,7 +987,8 @@ virNetDevVPortProfileAssociate(const char >>> *macvtap_ifname, >>> virtPort, >>> (vmOp == >>> VIR_NETDEV_VPORT_PROFILE_OP_MIGRATE_IN_START) >>> ? >>> VIR_NETDEV_VPORT_PROFILE_LINK_OP_PREASSOCIATE >>> - : >>> VIR_NETDEV_VPORT_PROFILE_LINK_OP_ASSOCIATE); >>> + : >>> VIR_NETDEV_VPORT_PROFILE_LINK_OP_ASSOCIATE, >>> + setlink_only); >>> break; >>> >>> case VIR_NETDEV_VPORT_PROFILE_8021QBH: >>> @@ -1033,7 +1045,7 @@ virNetDevVPortProfileDisassociate(const char >>> *macvtap_ifname, >>> case VIR_NETDEV_VPORT_PROFILE_8021QBG: >>> rc = virNetDevVPortProfileOp8021Qbg(macvtap_ifname, >>> macvtap_macaddr, >>> virtPort, >>> - >>> VIR_NETDEV_VPORT_PROFILE_LINK_OP_DISASSOCIATE); >>> + >>> VIR_NETDEV_VPORT_PROFILE_LINK_OP_DISASSOCIATE, false); >>> break; >>> >>> case VIR_NETDEV_VPORT_PROFILE_8021QBH: >>> @@ -1056,7 +1068,8 @@ int virNetDevVPortProfileAssociate(const >>> char *macvtap_ifname ATTRIBUTE_UNUSED, >>> const unsigned char *macvtap_macaddr >>> ATTRIBUTE_UNUSED, >>> const char *linkdev ATTRIBUTE_UNUSED, >>> const unsigned char *vmuuid >>> ATTRIBUTE_UNUSED, >>> - enum virNetDevVPortProfileOp vmOp >>> ATTRIBUTE_UNUSED) >>> + enum virNetDevVPortProfileOp vmOp >>> ATTRIBUTE_UNUSED, >>> + bool setlink_only) >>> { >>> virReportSystemError(ENOSYS, "%s", >>> _("Virtual port profile association not >>> supported on this platform")); >>> diff --git a/src/util/virnetdevvportprofile.h b/src/util/ >>> virnetdevvportprofile.h >>> index 7a8d81f..fe80086 100644 >>> --- a/src/util/virnetdevvportprofile.h >>> +++ b/src/util/virnetdevvportprofile.h >>> @@ -81,7 +81,8 @@ int virNetDevVPortProfileAssociate(const char >>> *ifname, >>> const unsigned char *macaddr, >>> const char *linkdev, >>> const unsigned char *vmuuid, >>> - enum virNetDevVPortProfileOp >>> vmOp) >>> + enum virNetDevVPortProfileOp >>> vmOp, >>> + bool setlink_only) >>> ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4) >>> ATTRIBUTE_NONNULL(5) ATTRIBUTE_RETURN_CHECK; >>> >> >> -- >> libvir-list mailing list >> libvir-list@redhat.com >> https://www.redhat.com/mailman/listinfo/libvir-list > > -- > libvir-list mailing list > libvir-list@redhat.com > https://www.redhat.com/mailman/listinfo/libvir-list