[Kimchi-devel] [PATCH v3 2/3] Support creating vlan tagged virtual network

Mark Wu wudxw at linux.vnet.ibm.com
Tue Jan 7 03:51:04 UTC 2014


It creates a vlan interface on top of the given nic or bond interface,
and bridge the vlan interface to a new created bridge, which is used to
forward VM's traffic. So all packets transmitted from VM will be tagged
before it departs from the physical network interface.

Signed-off-by: Mark Wu <wudxw at linux.vnet.ibm.com>
---
 src/kimchi/API.json |  6 ++++++
 src/kimchi/model.py | 47 ++++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 50 insertions(+), 3 deletions(-)

diff --git a/src/kimchi/API.json b/src/kimchi/API.json
index 3a3c48f..19b1c51 100644
--- a/src/kimchi/API.json
+++ b/src/kimchi/API.json
@@ -125,6 +125,12 @@
                 "interface": {
                     "description": "The name of a network interface on the host",
                     "type": "string"
+                },
+                "vlan_id": {
+                    "description": "Network's VLAN ID",
+                    "type": "integer",
+                    "maximum": 4094,
+                    "minimum": 1
                 }
             }
         },
diff --git a/src/kimchi/model.py b/src/kimchi/model.py
index a21fcf7..1332b07 100644
--- a/src/kimchi/model.py
+++ b/src/kimchi/model.py
@@ -58,6 +58,7 @@ from kimchi import config
 from kimchi import isoinfo
 from kimchi import netinfo
 from kimchi import network as knetwork
+from kimchi import networkxml
 from kimchi import vnc
 from kimchi import xmlutils
 from kimchi.asynctask import AsyncTask
@@ -66,7 +67,6 @@ from kimchi.exception import InvalidOperation, InvalidParameter, MissingParamete
 from kimchi.exception import NotFoundError, OperationFailed
 from kimchi.featuretests import FeatureTests
 from kimchi.iscsi import TargetClient
-from kimchi.networkxml import to_network_xml
 from kimchi.objectstore import ObjectStore
 from kimchi.scan import Scanner
 from kimchi.screenshot import VMScreenshot
@@ -821,7 +821,12 @@ class Model(object):
         if netinfo.is_bridge(iface):
             params['bridge'] = iface
         elif netinfo.is_bare_nic(iface) or netinfo.is_bonding(iface):
-            params['forward']['dev'] = iface
+            if params.get('vlan_id') is None:
+                params['forward']['dev'] = iface
+            else:
+                params['bridge'] = \
+                    self._create_vlan_tagged_bridge(str(iface),
+                                                    str(params['vlan_id']))
         else:
             raise InvalidParameter("the interface should be bare nic, "
                                    "bonding or bridge device.")
@@ -845,7 +850,7 @@ class Model(object):
         if connection == 'bridge':
             self._set_network_bridge(params)
 
-        xml = to_network_xml(**params)
+        xml = networkxml.to_network_xml(**params)
 
         try:
             network = conn.networkDefineXML(xml)
@@ -903,8 +908,44 @@ class Model(object):
         if network.isActive():
             raise InvalidOperation(
                 "Unable to delete the active network %s" % name)
+        self._remove_vlan_tagged_bridge(network)
         network.undefine()
 
+    def _get_vlan_tagged_bridge_name(self, interface, vlan_id):
+        return '-'.join(('kimchi', interface, vlan_id))
+
+    def _is_vlan_tagged_bridge(self, bridge):
+        return  bridge.startswith('kimchi-')
+
+    def _create_vlan_tagged_bridge(self, interface, vlan_id):
+        br_name = self._get_vlan_tagged_bridge_name(interface, vlan_id)
+        br_xml = networkxml.create_vlan_tagged_bridge_xml(br_name, interface,
+                                                          vlan_id)
+        conn = self.conn.get()
+        conn.changeBegin()
+        try:
+            vlan_tagged_br = conn.interfaceDefineXML(br_xml)
+            vlan_tagged_br.create()
+        except libvirt.libvirtError as e:
+            conn.changeRollback()
+            raise OperationFailed(e.message)
+        else:
+            conn.changeCommit()
+            return br_name
+
+    def _remove_vlan_tagged_bridge(self, network):
+        try:
+            bridge = network.bridgeName()
+        except libvirt.libvirtError:
+            pass
+        else:
+            if self._is_vlan_tagged_bridge(bridge):
+                conn = self.conn.get()
+                iface = conn.interfaceLookupByName(bridge)
+                if iface.isActive():
+                    iface.destroy()
+                iface.undefine()
+
     def add_task(self, target_uri, fn, opaque=None):
         id = self.next_taskid
         self.next_taskid = self.next_taskid + 1
-- 
1.8.4.2




More information about the Kimchi-devel mailing list