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(a)sun.com>
Signed-off-by: Max Zhen <max.zhen(a)sun.com>
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