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

Mark Wu wudxw at linux.vnet.ibm.com
Thu Jan 2 09:50:47 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 7b90826..07bf41e 100644
--- a/src/kimchi/API.json
+++ b/src/kimchi/API.json
@@ -56,6 +56,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 a6790b8..b3589e9 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
@@ -65,7 +66,6 @@ from kimchi.distroloader import DistroLoader
 from kimchi.exception import InvalidOperation, InvalidParameter, MissingParameter
 from kimchi.exception import NotFoundError, OperationFailed
 from kimchi.featuretests import FeatureTests
-from kimchi.networkxml import to_network_xml
 from kimchi.objectstore import ObjectStore
 from kimchi.scan import Scanner
 from kimchi.screenshot import VMScreenshot
@@ -806,7 +806,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_vlanned_bridge(str(iface),
+                                                str(params['vlan_id']))
         else:
             raise InvalidParameter("the interface should be bare nic, "
                                    "bonding or bridge device.")
@@ -830,7 +835,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)
@@ -888,8 +893,44 @@ class Model(object):
         if network.isActive():
             raise InvalidOperation(
                 "Unable to delete the active network %s" % name)
+        self._remove_vlanned_bridge(network)
         network.undefine()
 
+    def _get_vlanned_bridge_name(self, interface, vlan_id):
+        return '-'.join(('kimchi', interface, vlan_id))
+
+    def _is_vlanned_bridge(self, bridge):
+        return  bridge.startswith('kimchi-')
+
+    def _create_vlanned_bridge(self, interface, vlan_id):
+        bridge = self._get_vlanned_bridge_name(interface, vlan_id)
+        bridge_xml = networkxml.create_vlanned_bridge_xml(bridge, interface,
+                                                          vlan_id)
+        conn = self.conn.get()
+        conn.changeBegin()
+        try:
+            vlanned_bridge = conn.interfaceDefineXML(bridge_xml)
+            vlanned_bridge.create()
+        except:
+            conn.changeRollback()
+            raise OperationFailed('Failed to create vlanned bridge')
+        else:
+            conn.changeCommit()
+            return bridge
+
+    def _remove_vlanned_bridge(self, network):
+        try:
+            bridge = network.bridgeName()
+        except libvirt.libvirtError:
+            pass
+        else:
+            if self._is_vlanned_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