[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