[libvirt] [RFC] [PATCH 3/3 v2] vepa+vsi: Some experimental code for 802.1Qbh

Scott Feldman scofeldm at cisco.com
Sat May 22 06:35:37 UTC 2010


On 5/21/10 6:50 AM, "Stefan Berger" <stefanb at linux.vnet.ibm.com> wrote:

> This patch may get 802.1Qbh devices working. I am adding some code to
> poll for the status of an 802.1Qbh device and loop for a while until the
> status indicates success. This part for sure needs more work and
> testing...

I think we can drop this patch 3/3.  For bh, we don't want to poll for
status because it may take awhile before status of other than in-progress is
indicated.  Link UP on the eth is the async notification of status=success.
 
> I am recycling link_dump from a previous patch.
> 
> Changes from V1 to V2:
> - Following tree
> 
> Signed-off-by: Stefan Berger <stefanb at linux.vnet.ibm.com>
> 
> ---
>  src/util/macvtap.c |  116
> +++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 116 insertions(+)
> 
> Index: libvirt-acl/src/util/macvtap.c
> ===================================================================
> --- libvirt-acl.orig/src/util/macvtap.c
> +++ libvirt-acl/src/util/macvtap.c
> @@ -960,6 +960,95 @@ getPortProfileStatus(struct nlmsghdr *nl
>  
>  
>  static int
> +link_dump(int ifindex, const char *ifname, struct nlattr **tb,
> +          char **recvbuf)
> +{
> +    int rc = 0;
> +    char nlmsgbuf[256] = { 0, };
> +    struct nlmsghdr *nlm = (struct nlmsghdr *)nlmsgbuf, *resp;
> +    struct nlmsgerr *err;
> +    char rtattbuf[64];
> +    struct rtattr *rta;
> +    struct ifinfomsg i = {
> +        .ifi_family = AF_UNSPEC,
> +        .ifi_index  = ifindex
> +    };
> +    int recvbuflen;
> +
> +    *recvbuf = NULL;
> +
> +    nlInit(nlm, NLM_F_REQUEST, RTM_GETLINK);
> +
> +    if (!nlAppend(nlm, sizeof(nlmsgbuf), &i, sizeof(i)))
> +        goto buffer_too_small;
> +
> +    if (ifindex < 0 && ifname != NULL) {
> +        rta = rtattrCreate(rtattbuf, sizeof(rtattbuf), IFLA_IFNAME,
> +                           ifname, strlen(ifname) + 1);
> +        if (!rta)
> +            goto buffer_too_small;
> +
> +        if (!nlAppend(nlm, sizeof(nlmsgbuf), rtattbuf, rta->rta_len))
> +            goto buffer_too_small;
> +    }
> +
> +    if (nlComm(nlm, recvbuf, &recvbuflen) < 0)
> +        return -1;
> +
> +    if (recvbuflen < NLMSG_LENGTH(0) || *recvbuf == NULL)
> +        goto malformed_resp;
> +
> +    resp = (struct nlmsghdr *)*recvbuf;
> +
> +    switch (resp->nlmsg_type) {
> +    case NLMSG_ERROR:
> +        err = (struct nlmsgerr *)NLMSG_DATA(resp);
> +        if (resp->nlmsg_len < NLMSG_LENGTH(sizeof(*err)))
> +            goto malformed_resp;
> +
> +        switch (-err->error) {
> +        case 0:
> +        break;
> +
> +        default:
> +            virReportSystemError(-err->error,
> +                                 _("error dumping %d interface"),
> +                                 ifindex);
> +            rc = -1;
> +        }
> +    break;
> +
> +    case GENL_ID_CTRL:
> +    case NLMSG_DONE:
> +        if (nlmsg_parse(resp, sizeof(struct ifinfomsg),
> +                        tb, IFLA_MAX, ifla_policy)) {
> +            goto malformed_resp;
> +        }
> +    break;
> +
> +    default:
> +        goto malformed_resp;
> +    }
> +
> +    if (rc != 0)
> +        VIR_FREE(*recvbuf);
> +
> +    return rc;
> +
> +malformed_resp:
> +    macvtapError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                 _("malformed netlink response message"));
> +    VIR_FREE(*recvbuf);
> +    return -1;
> +
> +buffer_too_small:
> +    macvtapError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                 _("internal buffer is too small"));
> +    return -1;
> +}
> +
> +
> +static int
>  doPortProfileOpSetLink(bool multicast,
>                         const char *ifname, int ifindex,
>                         const char *profileId,
> @@ -1151,6 +1240,10 @@ doPortProfileOpCommon(bool multicast,
>                        uint8_t op)
>  {
>      int rc;
> +    char *recvbuf = NULL;
> +    struct nlattr *tb[IFLA_MAX + 1];
> +    int repeats = 5;
> +    uint16_t status;
>  
>      rc = doPortProfileOpSetLink(multicast,
>                                  ifname, ifindex,
> @@ -1167,6 +1260,30 @@ doPortProfileOpCommon(bool multicast,
>          return rc;
>      }
>  
> +    if (!multicast) {
> +        /* 802.1Qbh -- query for status */
> +        while (--repeats) {
> +            rc = link_dump(ifindex, ifname, tb, &recvbuf);
> +            if (rc)
> +                goto err_exit;
> +            rc = getPortProfileStatus((struct nlmsghdr *)recvbuf,
> &status);
> +            if (rc == 0) {
> +                if (status == 0)
> +                    break;
> +                if (status != 0) {
> +                    fprintf(stderr,"Current status: %d\n", status);
> +                    rc = 1;
> +                }
> +            }
> +            usleep(10000);
> +
> +            VIR_FREE(recvbuf);
> +        }
> +    }
> +
> +err_exit:
> +    VIR_FREE(recvbuf);
> +
>      return rc;
>  }
>  
> 




More information about the libvir-list mailing list