[libvirt] [Fwd: [PATCH v9] add 802.1Qbh and 802.1Qbg handling]
Arnd Bergmann
arnd at arndb.de
Thu May 27 11:55:33 UTC 2010
On Thursday 27 May 2010, Stefan Berger wrote:
> +static int
> +getPortProfileStatus(struct nlattr **tb, int32_t vf, uint16_t *status)
> +{
> + int rc = 1;
> + const char *msg = NULL;
> + struct nlattr *tb2[IFLA_VF_PORT_MAX + 1],
> + *tb3[IFLA_PORT_MAX+1];
> +
> + if (vf == PORT_SELF_VF) {
> + if (tb[IFLA_PORT_SELF]) {
> + if (nla_parse_nested(tb3, IFLA_PORT_MAX, tb[IFLA_PORT_SELF],
> + ifla_port_policy)) {
> + msg = _("error parsing nested IFLA_VF_PORT part");
> + goto err_exit;
> + }
> + }
> + } else {
> + if (tb[IFLA_VF_PORTS]) {
> + if (nla_parse_nested(tb2, IFLA_VF_PORT_MAX, tb[IFLA_VF_PORTS],
> + ifla_vf_ports_policy)) {
> + msg = _("error parsing nested IFLA_VF_PORTS part");
> + goto err_exit;
> + }
> + if (tb2[IFLA_VF_PORT]) {
> + if (nla_parse_nested(tb3, IFLA_PORT_MAX, tb2[IFLA_VF_PORT],
> + ifla_port_policy)) {
> + msg = _("error parsing nested IFLA_VF_PORT part");
> + goto err_exit;
> + }
> + }
> + }
> + }
There may be multiple IFLA_VF_PORT attributes in the IFLA_VF_PORTS list,
so you cannot do nla_parse_nested. I think this should be nla_for_each_attr
instead, and compare the uuid to the one you expect.
> + memcpy(ifla_vf_mac.mac, macaddr, 6);
> +
> + rta = rtattrCreate(rtattbuf, sizeof(rtattbuf), IFLA_VFINFO_LIST,
> + NULL, 0);
> + if (!rta ||
> + !(vfinfolist = nlAppend(nlm, sizeof(nlmsgbuf),
> + rtattbuf, rta->rta_len)))
> + goto buffer_too_small;
> +
> + rta = rtattrCreate(rtattbuf, sizeof(rtattbuf), IFLA_VF_INFO,
> + NULL, 0);
> + if (!rta ||
> + !(vfinfo = nlAppend(nlm, sizeof(nlmsgbuf),
> + rtattbuf, rta->rta_len)))
> + goto buffer_too_small;
> +
> + rta = rtattrCreate(rtattbuf, sizeof(rtattbuf), IFLA_VF_MAC,
> + &ifla_vf_mac, sizeof(ifla_vf_mac));
> + if (!rta || !nlAppend(nlm, sizeof(nlmsgbuf), rtattbuf, rta->rta_len))
> + goto buffer_too_small;
> +
> + rta = rtattrCreate(rtattbuf, sizeof(rtattbuf), IFLA_VF_VLAN,
> + &ifla_vf_vlan, sizeof(ifla_vf_vlan));
> +
> + if (!rta || !nlAppend(nlm, sizeof(nlmsgbuf), rtattbuf, rta->rta_len))
> + goto buffer_too_small;
> +
> + vfinfo->rta_len = (char *)nlm + nlm->nlmsg_len - (char *)vfinfo;
> +
> + vfinfolist->rta_len = (char *)nlm + nlm->nlmsg_len -
> + (char *)vfinfolist;
> + }
This part looks good now.
> + if (vf == PORT_SELF_VF) {
> + rta = rtattrCreate(rtattbuf, sizeof(rtattbuf), IFLA_PORT_SELF, NULL, 0);
> + } else {
> + rta = rtattrCreate(rtattbuf, sizeof(rtattbuf), IFLA_VF_PORTS, NULL, 0);
> + if (!rta ||
> + !(vfports = nlAppend(nlm, sizeof(nlmsgbuf),
> + rtattbuf, rta->rta_len)))
> + goto buffer_too_small;
> +
> + /* begin nesting vfports */
> + rta = rtattrCreate(rtattbuf, sizeof(rtattbuf), IFLA_VF_PORT, NULL, 0);
> + }
But this still goes down the IFLA_PORT_SELF route because you pass PORT_SELF_VF
even for nltarget_kernel==false, where it makes no sense.
Maybe make the above
if (vf == PORT_SELF_VF && nltarget_kernel)
> + if (vf != PORT_SELF_VF) {
> + /* end nesting of vfports */
> + vfports->rta_len = (char *)nlm + nlm->nlmsg_len - (char *)vfports;
> + }
Here too.
> + if (nltarget_kernel) {
> + if (nlComm(nlm, &recvbuf, &recvbuflen) < 0)
> + return -1;
> + } else {
> + if (nlCommWaitSuccess(nlm, RTMGRP_LINK, &recvbuf, &recvbuflen,
> + 5 * MICROSEC_PER_SEC) < 0)
> + return -1;
> + }
I don't understand this part yet. Do we need this difference?
> + while (--repeats >= 0) {
> + rc = link_dump(nltarget_kernel, NULL, ifindex, tb, &recvbuf);
> + if (rc)
> + goto err_exit;
> + rc = getPortProfileStatus(tb, vf, &status);
> + if (rc == 0) {
> + if (status == PORT_PROFILE_RESPONSE_SUCCESS ||
> + status == PORT_VDP_RESPONSE_SUCCESS) {
> + break;
> + } else if (status == PORT_PROFILE_RESPONSE_INPROGRESS) {
> + // keep trying...
> + } else {
> + virReportSystemError(EINVAL,
> + _("error %d during port-profile setlink on ifindex %d"),
> + status, ifindex);
> + rc = 1;
> + break;
> + }
Hmm, we seem to be missing an INPROGRESS status for Qbg. Any suggestions
what we should return there? Should we possibly just leave out
IFLA_PORT_RESPONSE in order to signal INPROGRESS, as in not clear yet?
> + rc = doPortProfileOpCommon(nltarget_kernel,
> + physdev_ifname, physdev_ifindex,
> + macaddr,
> + vlanid,
> + NULL,
> + &portVsi,
> + virtPort->u.virtPort8021Qbg.instanceID,
> + NULL,
> + PORT_SELF_VF,
> + op);
This is where we pass PORT_SELF_VF together with nltarget_kernel=false,
as mentioned above.
Arnd
More information about the libvir-list
mailing list