[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