[libvirt] [PATCH v5 2/2] Add de-association handling to macvlan code

D. Herrendoerfer d.herrendoerfer at herrendoerfer.name
Fri Feb 24 14:38:25 UTC 2012


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 at 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 at 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 at redhat.com
>> https://www.redhat.com/mailman/listinfo/libvir-list
>
> --
> libvir-list mailing list
> libvir-list at redhat.com
> https://www.redhat.com/mailman/listinfo/libvir-list




More information about the libvir-list mailing list