[libvirt] 802.1q vlan-tagging support for libvirt

John Levon levon at movementarian.org
Tue Apr 7 21:44:21 UTC 2009


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




More information about the libvir-list mailing list