You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ed...@apache.org on 2012/08/10 21:06:46 UTC

git commit: Summary: Introduce Vif Driver in KVM Add BridgeVifDriver and move current vif implementation to it.

Updated Branches:
  refs/heads/master 9be74d1d1 -> bc12fd233


    Summary: Introduce Vif Driver in KVM
    Add BridgeVifDriver and move current vif implementation to it.

    - remove dependency on VirtualRoutingResource.
    - factor out some of the networking code in LibvirtComputingResource
      to BridgeVifDriver.

    Add base class for KVM VifDriver.

    Add VifDriver Interface for KVM.

    RB: https://reviews.apache.org/r/6285
    Send-by: Tomoe Sugihara <to...@midokura.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/commit/bc12fd23
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/bc12fd23
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/bc12fd23

Branch: refs/heads/master
Commit: bc12fd2337459813289d2ee384bd96e76cfa4430
Parents: 9be74d1
Author: Edison Su <di...@gmail.com>
Authored: Fri Aug 10 12:05:24 2012 -0700
Committer: Edison Su <di...@gmail.com>
Committed: Fri Aug 10 12:05:24 2012 -0700

----------------------------------------------------------------------
 .../virtualnetwork/VirtualRoutingResource.java     |   49 ----
 .../hypervisor/kvm/resource/BridgeVifDriver.java   |  197 +++++++++++++++
 .../kvm/resource/LibvirtComputingResource.java     |  173 +++++---------
 .../cloud/hypervisor/kvm/resource/VifDriver.java   |   39 +++
 .../hypervisor/kvm/resource/VifDriverBase.java     |   55 ++++
 5 files changed, 350 insertions(+), 163 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/bc12fd23/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
index 33e2971..3f4679d 100755
--- a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
+++ b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
@@ -639,49 +639,6 @@ public class VirtualRoutingResource implements Manager {
 
         return command.execute();
     }
-    
-    private void deletExitingLinkLocalRoutTable(String linkLocalBr) {
-        Script command = new Script("/bin/bash", _timeout);
-        command.add("-c");
-        command.add("ip route | grep " + NetUtils.getLinkLocalCIDR());
-        OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
-        String result = command.execute(parser);
-        boolean foundLinkLocalBr = false;
-        if (result == null && parser.getLines() != null) {
-            String[] lines = parser.getLines().split("\\n");
-            for (String line : lines) {
-                String[] tokens = line.split(" ");
-                if (!tokens[2].equalsIgnoreCase(linkLocalBr)) {
-                    Script.runSimpleBashScript("ip route del " + NetUtils.getLinkLocalCIDR());
-                } else {
-                    foundLinkLocalBr = true;
-                }
-            }
-        }
-        if (!foundLinkLocalBr) {
-            Script.runSimpleBashScript("ifconfig " + linkLocalBr + " 169.254.0.1;" + "ip route add " + NetUtils.getLinkLocalCIDR() + " dev " + linkLocalBr + " src " + NetUtils.getLinkLocalGateway());
-        }
-    }
-
-    public void createControlNetwork(String privBrName) {
-        deletExitingLinkLocalRoutTable(privBrName);
-        if (!isBridgeExists(privBrName)) {
-            Script.runSimpleBashScript("brctl addbr " + privBrName + "; ifconfig " + privBrName + " up; ifconfig " + privBrName + " 169.254.0.1", _timeout);
-        }
-    }
-
-    private boolean isBridgeExists(String bridgeName) {
-        Script command = new Script("/bin/sh", _timeout);
-        command.add("-c");
-        command.add("brctl show|grep " + bridgeName);
-        final OutputInterpreter.OneLineParser parser = new OutputInterpreter.OneLineParser();
-        String result = command.execute(parser);
-        if (result != null || parser.getLine() == null) {
-            return false;
-        } else {
-            return true;
-        }
-    }
 
     private void deleteBridge(String brName) {
         Script cmd = new Script("/bin/sh", _timeout);
@@ -709,12 +666,6 @@ public class VirtualRoutingResource implements Manager {
         cmd.execute();
     }
 
-    public void cleanupPrivateNetwork(String privNwName, String privBrName){
-        if (isBridgeExists(privBrName)) {
-            deleteBridge(privBrName);
-        }
-    }
-
     //    protected Answer execute(final SetFirewallRuleCommand cmd) {
     //    	String args;
     //    	if(cmd.getProtocol().toLowerCase().equals(NetUtils.NAT_PROTO)){

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/bc12fd23/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java
new file mode 100644
index 0000000..cf4de09
--- /dev/null
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java
@@ -0,0 +1,197 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.cloud.hypervisor.kvm.resource;
+
+import com.cloud.agent.api.to.NicTO;
+import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource;
+import com.cloud.exception.InternalErrorException;
+import com.cloud.network.Networks;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.utils.script.OutputInterpreter;
+import com.cloud.utils.script.Script;
+import org.apache.log4j.Logger;
+import org.libvirt.LibvirtException;
+
+import javax.naming.ConfigurationException;
+import java.net.URI;
+import java.util.Map;
+
+public class BridgeVifDriver extends VifDriverBase {
+
+    private static final Logger s_logger = Logger
+            .getLogger(BridgeVifDriver.class);
+    private int _timeout;
+    private String _modifyVlanPath;
+
+    @Override
+    public void configure(Map<String, Object> params) throws ConfigurationException {
+
+        super.configure(params);
+
+        // Set the domr scripts directory
+        params.put("domr.scripts.dir", "scripts/network/domr/kvm");
+
+
+        String networkScriptsDir = (String) params.get("network.scripts.dir");
+        if (networkScriptsDir == null) {
+            networkScriptsDir = "scripts/vm/network/vnet";
+        }
+
+        String value = (String) params.get("scripts.timeout");
+        _timeout = NumbersUtil.parseInt(value, 30 * 60) * 1000;
+
+        _modifyVlanPath = Script.findScript(networkScriptsDir, "modifyvlan.sh");
+        if (_modifyVlanPath == null) {
+            throw new ConfigurationException("Unable to find modifyvlan.sh");
+        }
+
+        try {
+            createControlNetwork();
+        } catch (LibvirtException e) {
+            throw new ConfigurationException(e.getMessage());
+        }
+    }
+
+    @Override
+    public LibvirtVMDef.InterfaceDef plug(NicTO nic, String guestOsType)
+            throws InternalErrorException, LibvirtException {
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("nic=" + nic);
+        }
+
+        LibvirtVMDef.InterfaceDef intf = new LibvirtVMDef.InterfaceDef();
+
+        String vlanId = null;
+        if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan) {
+            URI broadcastUri = nic.getBroadcastUri();
+            vlanId = broadcastUri.getHost();
+        }
+        if (nic.getType() == Networks.TrafficType.Guest) {
+            if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan
+                    && !vlanId.equalsIgnoreCase("untagged")) {
+                String brName = createVlanBr(vlanId, _pifs.get("private"));
+                intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType));
+            } else {
+                intf.defBridgeNet(_bridges.get("guest"), null, nic.getMac(), getGuestNicModel(guestOsType));
+            }
+        } else if (nic.getType() == Networks.TrafficType.Control) {
+            /* Make sure the network is still there */
+            createControlNetwork();
+            intf.defBridgeNet(_bridges.get("linklocal"), null, nic.getMac(), getGuestNicModel(guestOsType));
+        } else if (nic.getType() == Networks.TrafficType.Public) {
+            if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan
+                    && !vlanId.equalsIgnoreCase("untagged")) {
+                String brName = createVlanBr(vlanId, _pifs.get("public"));
+                intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType));
+            } else {
+                intf.defBridgeNet(_bridges.get("public"), null, nic.getMac(), getGuestNicModel(guestOsType));
+            }
+        } else if (nic.getType() == Networks.TrafficType.Management) {
+            intf.defBridgeNet(_bridges.get("private"), null, nic.getMac(), getGuestNicModel(guestOsType));
+        } else if (nic.getType() == Networks.TrafficType.Storage) {
+            String storageBrName = nic.getName() == null ? _bridges.get("private")
+                    : nic.getName();
+            intf.defBridgeNet(storageBrName, null, nic.getMac(), getGuestNicModel(guestOsType));
+        }
+        return intf;
+    }
+
+    @Override
+    public void unplug(LibvirtVMDef.InterfaceDef iface) {
+        // Nothing needed as libvirt cleans up tap interface from bridge.
+    }
+
+    private String setVnetBrName(String vnetId) {
+        return "cloudVirBr" + vnetId;
+    }
+
+    private String createVlanBr(String vlanId, String nic)
+            throws InternalErrorException {
+        String brName = setVnetBrName(vlanId);
+        createVnet(vlanId, nic);
+        return brName;
+    }
+
+    private void createVnet(String vnetId, String pif)
+            throws InternalErrorException {
+        final Script command = new Script(_modifyVlanPath, _timeout, s_logger);
+        command.add("-v", vnetId);
+        command.add("-p", pif);
+        command.add("-o", "add");
+
+        final String result = command.execute();
+        if (result != null) {
+            throw new InternalErrorException("Failed to create vnet " + vnetId
+                    + ": " + result);
+        }
+    }
+
+    private void createControlNetwork() throws LibvirtException {
+        createControlNetwork(_bridges.get("linklocal"));
+    }
+
+    private void deletExitingLinkLocalRoutTable(String linkLocalBr) {
+        Script command = new Script("/bin/bash", _timeout);
+        command.add("-c");
+        command.add("ip route | grep " + NetUtils.getLinkLocalCIDR());
+        OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
+        String result = command.execute(parser);
+        boolean foundLinkLocalBr = false;
+        if (result == null && parser.getLines() != null) {
+            String[] lines = parser.getLines().split("\\n");
+            for (String line : lines) {
+                String[] tokens = line.split(" ");
+                if (!tokens[2].equalsIgnoreCase(linkLocalBr)) {
+                    Script.runSimpleBashScript("ip route del " + NetUtils.getLinkLocalCIDR());
+                } else {
+                    foundLinkLocalBr = true;
+                }
+            }
+        }
+        if (!foundLinkLocalBr) {
+            Script.runSimpleBashScript("ifconfig " + linkLocalBr + " 169.254.0.1;" + "ip route add " +
+                    NetUtils.getLinkLocalCIDR() + " dev " + linkLocalBr + " src " + NetUtils.getLinkLocalGateway());
+        }
+    }
+
+    private void createControlNetwork(String privBrName) {
+        deletExitingLinkLocalRoutTable(privBrName);
+        if (!isBridgeExists(privBrName)) {
+            Script.runSimpleBashScript("brctl addbr " + privBrName + "; ifconfig " + privBrName + " up; ifconfig " +
+                    privBrName + " 169.254.0.1", _timeout);
+        }
+
+    }
+
+    private boolean isBridgeExists(String bridgeName) {
+        Script command = new Script("/bin/sh", _timeout);
+        command.add("-c");
+        command.add("brctl show|grep " + bridgeName);
+        final OutputInterpreter.OneLineParser parser = new OutputInterpreter.OneLineParser();
+        String result = command.execute(parser);
+        if (result != null || parser.getLine() == null) {
+            return false;
+        } else {
+            return true;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/bc12fd23/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
index 64bd928..4a22e73 100755
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
@@ -25,6 +25,7 @@ import java.io.FileReader;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.lang.reflect.InvocationTargetException;
 import java.net.InetAddress;
 import java.net.URI;
 import java.net.URISyntaxException;
@@ -211,7 +212,7 @@ import com.cloud.vm.VirtualMachineName;
 /**
  * LibvirtComputingResource execute requests on the computing/routing host using
  * the libvirt API
- * 
+ *
  * @config {@table || Param Name | Description | Values | Default || ||
  *         hypervisor.type | type of local hypervisor | string | kvm || ||
  *         hypervisor.uri | local hypervisor to connect to | URI |
@@ -261,6 +262,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements
     private String _mountPoint = "/mnt";
     StorageLayer _storage;
     private KVMStoragePoolManager _storagePoolMgr;
+    private VifDriver _vifDriver;
 
     private static final class KeyValueInterpreter extends OutputInterpreter {
         private final Map<String, String> map = new HashMap<String, String>();
@@ -314,7 +316,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements
     private boolean _can_bridge_firewall;
     protected String _localStoragePath;
     protected String _localStorageUUID;
-    private Pair<String, String> _pifs;
+    private Map <String, String> _pifs = new HashMap<String, String>();
+    private Map<String, Map<String, String>> hostNetInfo = new HashMap<String, Map<String, String>>();
     private final Map<String, vmStats> _vmStats = new ConcurrentHashMap<String, vmStats>();
 
     protected boolean _disconnected = true;
@@ -679,26 +682,21 @@ public class LibvirtComputingResource extends ServerResourceBase implements
             }
         }
 
-        try {
-            createControlNetwork();
-        } catch (LibvirtException e) {
-            throw new ConfigurationException(e.getMessage());
-        }
-
-        _pifs = getPifs();
-        if (_pifs.first() == null) {
+        getPifs();
+        if (_pifs.get("private") == null) {
             s_logger.debug("Failed to get private nic name");
             throw new ConfigurationException("Failed to get private nic name");
         }
 
-        if (_pifs.second() == null) {
+        if (_pifs.get("public") == null) {
             s_logger.debug("Failed to get public nic name");
             throw new ConfigurationException("Failed to get public nic name");
         }
-        s_logger.debug("Found pif: " + _pifs.first() + " on " + _privBridgeName
-                + ", pif: " + _pifs.second() + " on " + _publicBridgeName);
+        s_logger.debug("Found pif: " + _pifs.get("private") + " on " + _privBridgeName
+                + ", pif: " + _pifs.get("public") + " on " + _publicBridgeName);
+
 
-        _can_bridge_firewall = can_bridge_firewall(_pifs.second());
+        _can_bridge_firewall = can_bridge_firewall(_pifs.get("public"));
 
         _localGateway = Script
                 .runSimpleBashScript("ip route |grep default|awk '{print $3}'");
@@ -716,7 +714,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements
         if (_migrateSpeed == -1) {
             //get guest network device speed
             _migrateSpeed = 0;
-            String speed = Script.runSimpleBashScript("ethtool " + _pifs.second() + " |grep Speed | cut -d \\  -f 2");
+            String speed = Script.runSimpleBashScript("ethtool " + _pifs.get("public") + " |grep Speed | cut -d \\  -f 2");
             if (speed != null) {
                 String[] tokens = speed.split("M");
                 if (tokens.length == 2) {
@@ -725,16 +723,47 @@ public class LibvirtComputingResource extends ServerResourceBase implements
                     } catch (Exception e) {
                         
                     }
-                    s_logger.debug("device " + _pifs.second() + " has speed: " + String.valueOf(_migrateSpeed));
+                    s_logger.debug("device " + _pifs.get("public") + " has speed: " + String.valueOf(_migrateSpeed));
                 }
             }
             params.put("vm.migrate.speed", String.valueOf(_migrateSpeed));
         }
+        
+        Map<String, String> bridges = new HashMap<String, String>();
+        bridges.put("linklocal", _linkLocalBridgeName);
+        bridges.put("public", _publicBridgeName);
+        bridges.put("private", _privBridgeName);
+        bridges.put("guest", _guestBridgeName);
+
+        params.put("libvirt.host.bridges", (Object) bridges);
+        params.put("libvirt.host.pifs", (Object) _pifs);
+
+        // Load the vif driver
+        String vifDriverName = (String) params.get("libvirt.vif.driver");
+        if (vifDriverName == null) {
+        	s_logger.info("No libvirt.vif.driver specififed. Defaults to BridgeVifDriver.");
+        	vifDriverName = "com.cloud.hypervisor.kvm.resource.BridgeVifDriver";
+        }
+
+        params.put("libvirt.computing.resource", (Object) this);
+
+        try {
+        	Class<?> clazz = Class.forName(vifDriverName);
+        	_vifDriver = (VifDriver) clazz.newInstance();
+        	_vifDriver.configure(params);
+        } catch (ClassNotFoundException e) {
+        	throw new ConfigurationException("Unable to find class for libvirt.vif.driver " + e);
+        } catch (InstantiationException e) {
+        	throw new ConfigurationException("Unable to instantiate class for libvirt.vif.driver " + e);
+        } catch (Exception e) {
+        	throw new ConfigurationException("Failed to initialize libvirt.vif.driver " + e);
+        }
+
 
         return true;
     }
 
-    private Pair<String, String> getPifs() {
+    private void getPifs() {
         /* get pifs from bridge */
         String pubPif = null;
         String privPif = null;
@@ -759,7 +788,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements
                                 + privPif + " | awk {'print $2'}");
             }
         }
-        return new Pair<String, String>(privPif, pubPif);
+        _pifs.put("private", privPif);
+        _pifs.put("public", pubPif);
     }
 
     private boolean checkNetwork(String networkName) {
@@ -1201,9 +1231,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements
             nicTO.setBroadcastUri(BroadcastDomainType.Vlan.toUri(vlanId));
         }
 
-        InterfaceDef nic = createVif(nicTO, InterfaceDef.nicModel.VIRTIO);
         Domain vm = getDomain(conn, vmName);
-        vm.attachDevice(nic.toString());
+        vm.attachDevice(_vifDriver.plug(nicTO, "Other PV").toString());
     }
 
     public Answer execute(IpAssocCommand cmd) {
@@ -2091,25 +2120,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements
         try {
             Connect conn = LibvirtConnection.getConnection();
             for (NicTO nic : nics) {
-                String vlanId = null;
-                if (nic.getBroadcastType() == BroadcastDomainType.Vlan) {
-                    URI broadcastUri = nic.getBroadcastUri();
-                    vlanId = broadcastUri.getHost();
-                }
-                if (nic.getType() == TrafficType.Guest) {
-                    if (nic.getBroadcastType() == BroadcastDomainType.Vlan
-                            && !vlanId.equalsIgnoreCase("untagged")) {
-                        createVlanBr(vlanId, _pifs.first());
-                    }
-                } else if (nic.getType() == TrafficType.Control) {
-                    /* Make sure the network is still there */
-                    createControlNetwork();
-                } else if (nic.getType() == TrafficType.Public) {
-                    if (nic.getBroadcastType() == BroadcastDomainType.Vlan
-                            && !vlanId.equalsIgnoreCase("untagged")) {
-                        createVlanBr(vlanId, _pifs.second());
-                    }
-                }
+                _vifDriver.plug(nic, null);
             }
 
             /* setup disks, e.g for iso */
@@ -2134,20 +2145,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements
         }
     }
 
-    public void createVnet(String vnetId, String pif)
-            throws InternalErrorException {
-        final Script command = new Script(_modifyVlanPath, _timeout, s_logger);
-        command.add("-v", vnetId);
-        command.add("-p", pif);
-        command.add("-o", "add");
-
-        final String result = command.execute();
-        if (result != null) {
-            throw new InternalErrorException("Failed to create vnet " + vnetId
-                    + ": " + result);
-        }
-    }
-
     private Answer execute(CheckHealthCommand cmd) {
         return new CheckHealthAnswer(cmd, true);
     }
@@ -2333,6 +2330,11 @@ public class LibvirtComputingResource extends ServerResourceBase implements
                 }
             }
 
+            List<InterfaceDef> ifaces = getInterfaces(conn, vmName);
+            for(InterfaceDef iface: ifaces){
+                _vifDriver.unplug(iface);
+            }
+
             final String result2 = cleanupVnet(conn, cmd.getVnet());
 
             if (result != null && result2 != null) {
@@ -2595,7 +2597,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements
                 return arg0.getDeviceId() > arg1.getDeviceId() ? 1 : -1;
             }
         });
-        
+
         for (VolumeTO volume : disks) {
             KVMPhysicalDisk physicalDisk = null;
             KVMStoragePool pool = null;
@@ -2701,7 +2703,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements
 
         patchDisk.defFileBasedDisk(datadiskPath, 1, rootDisk.getBusType(),
                 DiskDef.diskFmtType.RAW);
-        
+
         disks.add(patchDisk);
 
         String bootArgs = vmSpec.getBootArgs();
@@ -2709,59 +2711,10 @@ public class LibvirtComputingResource extends ServerResourceBase implements
         patchSystemVm(bootArgs, datadiskPath, vmName);
     }
 
-    private String createVlanBr(String vlanId, String nic)
-            throws InternalErrorException {
-        String brName = setVnetBrName(vlanId);
-        createVnet(vlanId, nic);
-        return brName;
-    }
-
-    private InterfaceDef createVif(NicTO nic,
-                                   InterfaceDef.nicModel model) throws InternalErrorException,
-            LibvirtException {
-        InterfaceDef intf = new InterfaceDef();
-
-        String vlanId = null;
-        if (nic.getBroadcastType() == BroadcastDomainType.Vlan) {
-            URI broadcastUri = nic.getBroadcastUri();
-            vlanId = broadcastUri.getHost();
-        }
-
-        if (nic.getType() == TrafficType.Guest) {
-            if (nic.getBroadcastType() == BroadcastDomainType.Vlan
-                    && !vlanId.equalsIgnoreCase("untagged")) {
-                String brName = createVlanBr(vlanId, _pifs.first());
-                intf.defBridgeNet(brName, null, nic.getMac(), model);
-            } else {
-                intf.defBridgeNet(_guestBridgeName, null, nic.getMac(), model);
-            }
-        } else if (nic.getType() == TrafficType.Control) {
-            /* Make sure the network is still there */
-            createControlNetwork();
-            intf.defBridgeNet(_linkLocalBridgeName, null, nic.getMac(), model);
-        } else if (nic.getType() == TrafficType.Public) {
-            if (nic.getBroadcastType() == BroadcastDomainType.Vlan
-                    && !vlanId.equalsIgnoreCase("untagged")) {
-                String brName = createVlanBr(vlanId, _pifs.second());
-                intf.defBridgeNet(brName, null, nic.getMac(), model);
-            } else {
-                intf.defBridgeNet(_publicBridgeName, null, nic.getMac(), model);
-            }
-        } else if (nic.getType() == TrafficType.Management) {
-            intf.defBridgeNet(_privBridgeName, null, nic.getMac(), model);
-        } else if (nic.getType() == TrafficType.Storage) {
-            String storageBrName = nic.getName() == null ? _privBridgeName
-                    : nic.getName();
-            intf.defBridgeNet(storageBrName, null, nic.getMac(), model);
-        }
-
-        return intf;
-    }
-
     private void createVif(LibvirtVMDef vm, NicTO nic)
             throws InternalErrorException, LibvirtException {
         vm.getDevices().addDevice(
-                createVif(nic, getGuestNicModel(vm.getGuestOSType())));
+                _vifDriver.plug(nic, vm.getGuestOSType()).toString());
     }
 
     protected CheckSshAnswer execute(CheckSshCommand cmd) {
@@ -3610,7 +3563,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements
         }
     }
 
-    private boolean isGuestPVEnabled(String guestOS) {
+    boolean isGuestPVEnabled(String guestOS) {
         if (guestOS == null) {
             return false;
         }
@@ -3662,10 +3615,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements
         }
     }
 
-    private String setVnetBrName(String vnetId) {
-        return "cloudVirBr" + vnetId;
-    }
-
     private String getVnetIdFromBrName(String vnetBrName) {
         return vnetBrName.replaceAll("cloudVirBr", "");
     }
@@ -4070,10 +4019,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements
         return new Pair<Double, Double>(rx, tx);
     }
 
-    private void createControlNetwork() throws LibvirtException {
-        _virtRouterResource.createControlNetwork(_linkLocalBridgeName);
-    }
-
     private Answer execute(NetworkRulesSystemVmCommand cmd) {
         boolean success = false;
         Connect conn;

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/bc12fd23/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/VifDriver.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/VifDriver.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/VifDriver.java
new file mode 100644
index 0000000..c3083b2
--- /dev/null
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/VifDriver.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.cloud.hypervisor.kvm.resource;
+
+import com.cloud.agent.api.to.NicTO;
+import com.cloud.exception.InternalErrorException;
+import org.libvirt.LibvirtException;
+
+import javax.naming.ConfigurationException;
+import java.util.Map;
+
+public interface VifDriver {
+
+    public void configure(Map<String, Object> params)
+            throws ConfigurationException;
+
+    public LibvirtVMDef.InterfaceDef plug(NicTO nic, String guestOsType)
+            throws InternalErrorException, LibvirtException;
+
+    public void unplug(LibvirtVMDef.InterfaceDef iface);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/bc12fd23/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/VifDriverBase.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/VifDriverBase.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/VifDriverBase.java
new file mode 100644
index 0000000..0694e62
--- /dev/null
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/VifDriverBase.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.cloud.hypervisor.kvm.resource;
+
+import com.cloud.agent.api.to.NicTO;
+import com.cloud.exception.InternalErrorException;
+import org.libvirt.LibvirtException;
+
+import javax.naming.ConfigurationException;
+import java.util.Map;
+
+public abstract class VifDriverBase implements VifDriver {
+
+    protected LibvirtComputingResource _libvirtComputingResource;
+    protected Map<String, String> _pifs;
+    protected Map<String, String> _bridges;
+
+    @Override
+    public void configure(Map<String, Object> params)
+            throws ConfigurationException {
+        _libvirtComputingResource = (LibvirtComputingResource) params.get("libvirt.computing.resource");
+        _bridges = (Map<String, String>) params.get("libvirt.host.bridges");
+        _pifs = (Map<String, String>) params.get("libvirt.host.pifs");
+    }
+
+    public abstract LibvirtVMDef.InterfaceDef plug(NicTO nic, String guestOsType) throws InternalErrorException,
+                                                                                         LibvirtException;
+
+    public abstract void unplug(LibvirtVMDef.InterfaceDef iface);
+
+    protected LibvirtVMDef.InterfaceDef.nicModel getGuestNicModel(String guestOSType) {
+        if (_libvirtComputingResource.isGuestPVEnabled(guestOSType)) {
+            return LibvirtVMDef.InterfaceDef.nicModel.VIRTIO;
+        } else {
+            return LibvirtVMDef.InterfaceDef.nicModel.E1000;
+        }
+    }
+}