On Tue, Apr 07, 2009 at 06:39:17PM -0300, Klaus Heinrich Kiwi wrote: > I was thinking about the semantics I described above. It ultimately I just caught this discussion. We have implemented basic vlan support (for xend, bridged only). Is there an existing patch from you guys for the user interface? Below is our current libvirt patch regards john Support setting of vlan ID for network interfaces Signed-off-by: John Levon <john.levon@xxxxxxx> Signed-off-by: Max Zhen <max.zhen@xxxxxxx> diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng --- a/docs/schemas/domain.rng +++ b/docs/schemas/domain.rng @@ -692,6 +692,13 @@ </optional> </element> </optional> + <optional> + <element name='vlan'> + <attribute name='id'> + <ref name='unsignedInt'/> + </attribute> + </element> + </optional> </interleave> </define> diff --git a/src/domain_conf.c b/src/domain_conf.c --- a/src/domain_conf.c +++ b/src/domain_conf.c @@ -918,6 +918,7 @@ virDomainNetDefParseXML(virConnectPtr co char *address = NULL; char *port = NULL; char *model = NULL; + char *vlanid = NULL; if (VIR_ALLOC(def) < 0) { virReportOOMError(conn); @@ -983,6 +984,8 @@ virDomainNetDefParseXML(virConnectPtr co model = virXMLPropString(cur, "type"); } else if (xmlStrEqual (cur->name, BAD_CAST "networkresource")) { virDomainNetDefParseXMLRate(def, cur); + } else if (xmlStrEqual (cur->name, BAD_CAST "vlan")) { + vlanid = virXMLPropString(cur, "id"); } } cur = cur->next; @@ -1093,6 +1096,16 @@ virDomainNetDefParseXML(virConnectPtr co model = NULL; } + def->vlanid = 0; + + if (vlanid != NULL) { + if (virStrToLong_i(vlanid, NULL, 10, &def->vlanid) < 0) { + virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", + _("Cannot parse vlan ID")); + goto error; + } + } + cleanup: VIR_FREE(macaddr); VIR_FREE(network); @@ -1104,6 +1117,7 @@ cleanup: VIR_FREE(bridge); VIR_FREE(model); VIR_FREE(type); + VIR_FREE(vlanid); return def; @@ -3035,6 +3049,9 @@ virDomainNetDefFormat(virConnectPtr conn unit, period, def->rate.value); } + if (def->vlanid) + virBufferVSprintf(buf, " <vlan id='%d' />\n", def->vlanid); + virBufferAddLit(buf, " </interface>\n"); return 0; diff --git a/src/domain_conf.h b/src/domain_conf.h --- a/src/domain_conf.h +++ b/src/domain_conf.h @@ -186,6 +186,7 @@ struct _virDomainNetDef { int period; long value; } rate; + int vlanid; }; enum virDomainChrSrcType { diff --git a/src/virsh.c b/src/virsh.c --- a/src/virsh.c +++ b/src/virsh.c @@ -4762,6 +4762,7 @@ static const vshCmdOptDef opts_attach_in {"mac", VSH_OT_DATA, 0, gettext_noop("MAC address")}, {"script", VSH_OT_DATA, 0, gettext_noop("script used to bridge network interface")}, {"capped-bandwidth", VSH_OT_STRING, 0, gettext_noop("bandwidth limit for this interface")}, + {"vlanid", VSH_OT_INT, 0, gettext_noop("VLAN ID attached to this interface")}, {NULL, 0, 0, NULL} }; @@ -4769,7 +4770,7 @@ cmdAttachInterface(vshControl *ctl, cons cmdAttachInterface(vshControl *ctl, const vshCmd *cmd) { virDomainPtr dom = NULL; - char *mac, *target, *script, *type, *source, *bw; + char *mac, *target, *script, *type, *source, *bw, *vlanid; int typ, ret = FALSE; char *buf = NULL, *tmp = NULL; @@ -4787,6 +4788,7 @@ cmdAttachInterface(vshControl *ctl, cons mac = vshCommandOptString(cmd, "mac", NULL); script = vshCommandOptString(cmd, "script", NULL); bw = vshCommandOptString(cmd, "capped-bandwidth", NULL); + vlanid = vshCommandOptString(cmd, "vlanid", NULL); /* check interface type */ if (STREQ(type, "network")) { @@ -4866,6 +4868,21 @@ cmdAttachInterface(vshControl *ctl, cons tmp = vshRealloc(ctl, tmp, strlen(unit) + strlen(bw) + strlen(format)); if (!tmp) goto cleanup; sprintf(tmp, format, unit, r); + buf = vshRealloc(ctl, buf, strlen(buf) + strlen(tmp) + 1); + if (!buf) goto cleanup; + strcat(buf, tmp); + } + + if (vlanid != NULL) { + char *left; + long r = strtol(vlanid, &left, 10); + if ((r <= 0) || (r >= 4095) || (*left != '\0')) { + vshError(ctl, FALSE, _("Bad VLAN ID: %s in command 'attach-interface'"), vlanid); + goto cleanup; + } + tmp = vshRealloc(ctl, tmp, strlen(vlanid) + 20); + if (!tmp) goto cleanup; + sprintf(tmp, " <vlan id='%s'/>\n", vlanid); buf = vshRealloc(ctl, buf, strlen(buf) + strlen(tmp) + 1); if (!buf) goto cleanup; strcat(buf, tmp); diff --git a/src/xend_internal.c b/src/xend_internal.c --- a/src/xend_internal.c +++ b/src/xend_internal.c @@ -1896,7 +1896,10 @@ xend_parse_rate(const char *ratestr, int if (sscanf(ratestr, "%lu,%lu", &amount, &interval) == 2) { *unit = VIR_DOMAIN_NET_RATE_KB; *period = VIR_DOMAIN_NET_PERIOD_S; - *val = (amount * 8) / (interval / 1000000); + /* bytes to kilobits */ + *val = (amount / 125); + /* factor in period interval */ + *val /= (interval / 1000000); return 0; } @@ -2046,6 +2049,15 @@ xenDaemonParseSxprNets(virConnectPtr con _("ignoring malformed rate limit '%s'"), tmp); } else { net->rate.enabled = 1; + } + } + + tmp = sexpr_node(node, "device/vif/vlanid"); + if (tmp) { + if (virStrToLong_i(tmp, NULL, 0, &net->vlanid) != 0) { + virXendError(conn, VIR_ERR_INTERNAL_ERROR, + _("malformed vlanid '%s'"), tmp); + goto cleanup; } } @@ -5553,6 +5565,9 @@ xenDaemonFormatSxprNet(virConnectPtr con unit, period); } + if (def->vlanid) + virBufferVSprintf(buf, "(vlanid '%d')", def->vlanid); + /* * apparently (type ioemu) breaks paravirt drivers on HVM so skip this * from Xen 3.1.0 -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list