You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by mu...@apache.org on 2014/03/14 12:27:06 UTC

[07/14] git commit: updated refs/heads/master to 7d20b08

some bug fixes


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

Branch: refs/heads/master
Commit: 2c7786992f1900daca1ef8c093ceca6e7b735050
Parents: e045883
Author: Murali Reddy <mu...@gmail.com>
Authored: Mon Mar 10 22:16:46 2014 +0530
Committer: Murali Reddy <mu...@gmail.com>
Committed: Fri Mar 14 16:56:37 2014 +0530

----------------------------------------------------------------------
 .../xen/resource/CitrixResourceBase.java        |  14 ++-
 .../api/OvsVpcLogicalTopologyConfigCommand.java |  33 +++++
 .../OvsVpcPhysicalTopologyConfigCommand.java    |   7 +-
 .../com/cloud/network/element/OvsElement.java   |  18 ---
 .../cloud/network/guru/OvsGuestNetworkGuru.java |   2 +-
 .../network/ovs/OvsNetworkTopologyGuru.java     |  10 ++
 .../network/ovs/OvsNetworkTopologyGuruImpl.java | 126 ++++++++++++++++++-
 .../cloud/network/ovs/OvsTunnelManagerImpl.java | 125 ++++++++++++------
 .../xenserver/cloudstack_pluginlib.py           |   4 +-
 scripts/vm/hypervisor/xenserver/ovstunnel       |  14 +--
 .../network/guru/ExternalGuestNetworkGuru.java  |   4 +
 11 files changed, 279 insertions(+), 78 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2c778699/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
index 3e7dfaf..8752921 100644
--- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
+++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
@@ -999,7 +999,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
     /**
      * This method creates a XenServer network and configures it for being used as a L2-in-L3 tunneled network
      */
-    private synchronized Network configureTunnelNetwork(Connection conn, long networkId, long hostId, String bridgeName) {
+    private synchronized Network configureTunnelNetwork(Connection conn, Long networkId, long hostId, String bridgeName) {
         try {
             Network nw = findOrCreateTunnelNetwork(conn, bridgeName);
             String nwName = bridgeName;
@@ -1038,7 +1038,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
                 String[] res = result.split(":");
                 if (res.length != 2 || !res[0].equalsIgnoreCase("SUCCESS")) {
                     //TODO: Should make this error not fatal?
-                    throw new CloudRuntimeException("Unable to pre-configure OVS bridge " + bridge + " for network ID:" + networkId + " - " + res);
+                    throw new CloudRuntimeException("Unable to pre-configure OVS bridge " + bridge );
                 }
             }
             return nw;
@@ -1090,7 +1090,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
                 _isOvs = true;
                 return setupvSwitchNetwork(conn);
             } else {
-                return findOrCreateTunnelNetwork(conn, getOvsTunnelNetworkName(BroadcastDomainType.getValue(uri)));
+                return findOrCreateTunnelNetwork(conn, getOvsTunnelNetworkName(uri.getAuthority()));
             }
         } else if (type == BroadcastDomainType.Storage) {
             if (uri == null) {
@@ -1114,7 +1114,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
 
     private String getOvsTunnelNetworkName(String broadcastUri) {
         if (broadcastUri.contains(".")) {
-            String[] parts = broadcastUri.split(".");
+            String[] parts = broadcastUri.split("\\.");
             return "OVS-DR-VPC-Bridge"+parts[0];
          } else {
             try {
@@ -5266,7 +5266,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
             }
 
             String bridge = nw.getBridge(conn);
-            String result = callHostPlugin(conn, "ovstunnel", "configure_ovs_bridge_for_network_topology", "bridge", bridge, "in_port", cmd.getInPortName());
+            String result = callHostPlugin(conn, "ovstunnel", "destroy_tunnel", "bridge", bridge, "in_port", cmd.getInPortName());
+
             if (result.equalsIgnoreCase("SUCCESS")) {
                 return new Answer(cmd, true, result);
             } else {
@@ -5282,7 +5283,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
         Connection conn = getConnection();
         try {
             String result = callHostPlugin(conn, "ovstunnel", "configure_ovs_bridge_for_network_topology", "bridge",
-                    cmd.getBridgeName(), "host-id", ((Long)cmd.getHostId()).toString());
+                    cmd.getBridgeName(), "host-id", ((Long)cmd.getHostId()).toString(), "config",
+                    cmd.getjsonVpcConfig());
             if (result.equalsIgnoreCase("SUCCESS")) {
                 return new Answer(cmd, true, result);
             } else {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2c778699/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcLogicalTopologyConfigCommand.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcLogicalTopologyConfigCommand.java b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcLogicalTopologyConfigCommand.java
new file mode 100644
index 0000000..2fafb6e
--- /dev/null
+++ b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcLogicalTopologyConfigCommand.java
@@ -0,0 +1,33 @@
+// 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.agent.api;
+
+/**
+ * This command represents view of how a VPC is laid out (on which hosts, which VM is on which host etc)
+ * on the physical infrastructure.
+ */
+public class OvsVpcLogicalTopologyConfigCommand extends Command {
+
+    public OvsVpcLogicalTopologyConfigCommand() {
+
+    }
+
+    @Override
+    public boolean executeInSequence() {
+        return false;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2c778699/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcPhysicalTopologyConfigCommand.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcPhysicalTopologyConfigCommand.java b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcPhysicalTopologyConfigCommand.java
index 35d4c6e..e6f4383 100644
--- a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcPhysicalTopologyConfigCommand.java
+++ b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcPhysicalTopologyConfigCommand.java
@@ -20,8 +20,11 @@ import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 
 /**
- * This command represents view of how a VPC is laid out (on which hosts, which VM is on which host etc)
- * on the physical infrastructure.
+ * This command represents physical view of how a VPC is laid out on the physical infrastructure.
+ *   - on which hypervisor hosts VPC spans (host is running in at least one VM from the VPC)
+ *   - information of tiers, so we can figure how one VM can talk to a different VM in same tier or different tier
+ *   - information on all the VM's in the VPC.
+ *   - information of NIC's of each VM in the VPC
  */
 public class OvsVpcPhysicalTopologyConfigCommand extends Command {
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2c778699/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java b/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java
index c28d908..036c319 100644
--- a/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java
+++ b/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java
@@ -75,7 +75,6 @@ import com.cloud.vm.NicProfile;
 import com.cloud.vm.ReservationContext;
 import com.cloud.vm.VirtualMachineProfile;
 import com.cloud.vm.dao.DomainRouterDao;
-import com.cloud.vm.UserVmVO;
 import com.cloud.vm.VirtualMachine;
 
 @Local(value = {NetworkElement.class, ConnectivityProvider.class,
@@ -205,23 +204,6 @@ StaticNatServiceProvider, IpDeployer {
             return false;
         }
 
-        List<UserVmVO> userVms = _userVmDao.listByAccountIdAndHostId(vm.getVirtualMachine().getAccountId(),
-                vm.getVirtualMachine().getHostId());
-        if (vm.getType() == VirtualMachine.Type.User) {
-            if (userVms.size() > 1) {
-                return true;
-            }
-
-            List<DomainRouterVO> routers = _routerDao.findByNetwork(network.getId());
-            for (DomainRouterVO router : routers) {
-                if (router.getHostId().equals(vm.getVirtualMachine().getHostId())) {
-                    return true;
-                }
-            }
-        } else if (vm.getType() == VirtualMachine.Type.DomainRouter && userVms.size() != 0) {
-            return true;
-        }
-
         HostVO host = _hostDao.findById(vm.getVirtualMachine().getHostId());
         _ovsTunnelMgr.checkAndRemoveHostFromTunnelNetwork(network, host);
         return true;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2c778699/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java b/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java
index 2814c2a..9d2efe6 100644
--- a/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java
+++ b/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java
@@ -154,7 +154,7 @@ public class OvsGuestNetworkGuru extends GuestNetworkGuru {
         if (network.getVpcId() != null && isVpcEnabledForDistributedRouter(network.getVpcId())) {
             String keyStr = BroadcastDomainType.getValue(implemented.getBroadcastUri());
             Long vpcid= network.getVpcId();
-            implemented.setBroadcastUri(BroadcastDomainType.Vswitch.toUri(vpcid.toString()+keyStr));
+            implemented.setBroadcastUri(BroadcastDomainType.Vswitch.toUri(vpcid.toString() + "." + keyStr));
         }
 
         return implemented;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2c778699/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuru.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuru.java b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuru.java
index c410d10..122175c 100644
--- a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuru.java
+++ b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuru.java
@@ -38,6 +38,11 @@ public interface OvsNetworkTopologyGuru extends Manager {
     public  List<Long> getVpcOnHost(long hostId);
 
     /**
+     * get the list of all active Vm id's in a network
+     */
+    public List<Long> getAllActiveVmsInNetwork(long networkId);
+
+    /**
      * get the list of all active Vm id's in the VPC for all ther tiers
      */
     public List<Long> getAllActiveVmsInVpc(long vpcId);
@@ -46,4 +51,9 @@ public interface OvsNetworkTopologyGuru extends Manager {
      * get the list of all Vm id's in the VPC for all the tiers that are running on the host
      */
     public List<Long> getActiveVmsInVpcOnHost(long vpcId, long hostId);
+
+    /**
+     * get the list of all Vm id's in the network that are running on the host
+     */
+    public List<Long> getActiveVmsInNetworkOnHost(long vpcId, long hostId);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2c778699/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuruImpl.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuruImpl.java b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuruImpl.java
index 7560e35..7715641 100644
--- a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuruImpl.java
+++ b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuruImpl.java
@@ -1,14 +1,24 @@
 package com.cloud.network.ovs;
 
+import com.cloud.network.Network;
+import com.cloud.network.Networks;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.vpc.VpcManager;
 import com.cloud.utils.component.ManagerBase;
 import com.cloud.vm.DomainRouterVO;
 import com.cloud.vm.UserVmVO;
 import com.cloud.vm.VMInstanceVO;
 import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.Nic;
 import com.cloud.vm.dao.DomainRouterDao;
+import com.cloud.vm.dao.NicDao;
 import com.cloud.vm.dao.UserVmDao;
+import com.cloud.vm.dao.VMInstanceDao;
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 import javax.ejb.Local;
 import javax.inject.Inject;
 import org.springframework.stereotype.Component;
@@ -21,6 +31,14 @@ public class OvsNetworkTopologyGuruImpl extends ManagerBase implements OvsNetwor
     UserVmDao _userVmDao;
     @Inject
     DomainRouterDao _routerDao;
+    @Inject
+    VpcManager _vpcMgr;
+    @Inject
+    VMInstanceDao _vmInstanceDao;
+    @Inject
+    NicDao _nicDao;
+    @Inject
+    NetworkDao _networkDao;
 
     /**
      * get the list of hypervisor hosts on which VM's belonging to a network currently spans
@@ -52,23 +70,121 @@ public class OvsNetworkTopologyGuruImpl extends ManagerBase implements OvsNetwor
         return  hostIds;
     }
 
+    /**
+     * get the list of hypervisor hosts on which VM's belonging to a VPC currently spans
+     */
     @Override
-    public List<Long> getVpcSpannedHosts(long vpId) {
-        return null;
+    public List<Long> getVpcSpannedHosts(long vpcId) {
+        List<? extends Network> vpcNetworks =  _vpcMgr.getVpcNetworks(vpcId);
+        List<Long> vpcHostIds = new ArrayList<>();
+        for (Network vpcNetwork : vpcNetworks) {
+            List<Long> networkHostIds = new ArrayList<Long>();
+            networkHostIds = getNetworkSpanedHosts(vpcNetwork.getId());
+            if (networkHostIds != null && !networkHostIds.isEmpty()) {
+                for (Long hostId : networkHostIds) {
+                    if (!vpcHostIds.contains(hostId)) {
+                        vpcHostIds.add(hostId);
+                    }
+                }
+            }
+        }
+        return vpcHostIds;
     }
 
     @Override
     public List<Long> getVpcOnHost(long hostId) {
-        return null;
+        List<Long> vpcIds = new ArrayList<>();
+        List<VMInstanceVO> vmInstances = _vmInstanceDao.listByHostId(hostId);
+        for (VMInstanceVO instance : vmInstances) {
+            List<NicVO> nics = _nicDao.listByVmId(instance.getId());
+            for (Nic nic: nics) {
+                Network network = _networkDao.findById(nic.getNetworkId());
+                if (network.getTrafficType() == Networks.TrafficType.Guest && network.getVpcId() != null) {
+                    if (!vpcIds.contains(network.getVpcId())) {
+                        vpcIds.add(network.getVpcId());
+                    }
+                }
+            }
+        }
+        return vpcIds;
+    }
+
+    @Override
+    public List<Long> getAllActiveVmsInNetwork(long networkId) {
+        List <Long> vmIds = new ArrayList<>();
+        List<UserVmVO> vms = _userVmDao.listByNetworkIdAndStates(networkId,
+                VirtualMachine.State.Running, VirtualMachine.State.Starting, VirtualMachine.State.Stopping, VirtualMachine.State.Unknown,
+                VirtualMachine.State.Migrating);
+        // Find routers for the network
+        List<DomainRouterVO> routers = _routerDao.findByNetwork(networkId);
+        List<VMInstanceVO> ins = new ArrayList<VMInstanceVO>();
+
+        if (vms != null) {
+            for (UserVmVO vm : vms) {
+                vmIds.add(vm.getId());
+            }
+        }
+        if (routers.size() != 0) {
+            for (DomainRouterVO router: routers) {
+                vmIds.add(router.getId());
+            }
+        }
+        return  vmIds;
     }
 
     @Override
     public List<Long> getAllActiveVmsInVpc(long vpcId) {
-        return null;
+
+        Set<Long> vmIdsSet = new HashSet<>();
+        List<? extends Network> vpcNetworks =  _vpcMgr.getVpcNetworks(vpcId);
+        for (Network network : vpcNetworks) {
+            List<Long> networkVmIds = getAllActiveVmsInNetwork(network.getId());
+            if (networkVmIds  != null && !networkVmIds.isEmpty()) {
+                vmIdsSet.addAll(networkVmIds);
+            }
+        }
+        List<Long> vmIds = new ArrayList<>();
+        vmIds.addAll(vmIdsSet);
+        return vmIds;
     }
 
     @Override
     public List<Long> getActiveVmsInVpcOnHost(long vpcId, long hostId) {
-        return null;
+        Set<Long> vmIdsSet = new HashSet<>();
+        List<? extends Network> vpcNetworks =  _vpcMgr.getVpcNetworks(vpcId);
+        for (Network network : vpcNetworks) {
+            List<Long> networkVmIds = getActiveVmsInNetworkOnHost(network.getId(), hostId);
+            if (networkVmIds  != null && !networkVmIds.isEmpty()) {
+                vmIdsSet.addAll(networkVmIds);
+            }
+        }
+        List<Long> vmIds = new ArrayList<>();
+        vmIds.addAll(vmIdsSet);
+        return vmIds;
+    }
+
+    @Override
+    public List<Long> getActiveVmsInNetworkOnHost(long networkId, long hostId) {
+        List <Long> vmIds = new ArrayList<>();
+        List<UserVmVO> vms = _userVmDao.listByNetworkIdAndStates(networkId,
+                VirtualMachine.State.Running, VirtualMachine.State.Starting, VirtualMachine.State.Stopping, VirtualMachine.State.Unknown,
+                VirtualMachine.State.Migrating);
+        // Find routers for the network
+        List<DomainRouterVO> routers = _routerDao.findByNetwork(networkId);
+        List<VMInstanceVO> ins = new ArrayList<VMInstanceVO>();
+
+        if (vms != null) {
+            for (UserVmVO vm : vms) {
+                if (vm.getHostId() == hostId)
+                    vmIds.add(vm.getId());
+            }
+        }
+        if (routers.size() != 0) {
+            for (DomainRouterVO router: routers) {
+                if (router.getHostId() == hostId)
+                    vmIds.add(router.getId());
+            }
+        }
+        return  vmIds;
     }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2c778699/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
index ae37095..82dbfed 100644
--- a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
+++ b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
@@ -18,10 +18,10 @@ package com.cloud.network.ovs;
 
 import com.cloud.network.dao.NetworkDao;
 import com.cloud.network.vpc.VpcManager;
+import com.cloud.vm.dao.VMInstanceDao;
 import com.cloud.vm.Nic;
 import com.cloud.vm.NicVO;
 import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.dao.VMInstanceDao;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
@@ -260,9 +260,9 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
         int key = 0;
         try {
             //The GRE key is actually in the host part of the URI
-            String keyStr = BroadcastDomainType.getValue(network.getBroadcastUri());
+            String keyStr = network.getBroadcastUri().getAuthority();
             if (keyStr.contains(".")) {
-                String[] parts = keyStr.split(".");
+                String[] parts = keyStr.split("\\.");
                 key = Integer.parseInt(parts[1]);
             } else {
                 key = Integer.parseInt(keyStr);
@@ -445,34 +445,72 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
     @Override
     public void checkAndRemoveHostFromTunnelNetwork(Network nw, Host host) {
 
-        try {
-            /* Now we are last one on host, destroy the bridge with all
-             * the tunnels for this network  */
-            int key = getGreKey(nw);
-            String bridgeName = generateBridgeName(nw, key);
-            Command cmd = new OvsDestroyBridgeCommand(nw.getId(), bridgeName);
-            s_logger.debug("Destroying bridge for network " + nw.getId() + " on host:" + host.getId());
-            Answer ans = _agentMgr.send(host.getId(), cmd);
-            handleDestroyBridgeAnswer(ans, host.getId(), nw.getId());
-
-            /* Then ask hosts have peer tunnel with me to destroy them */
-            List<OvsTunnelNetworkVO> peers =
-                    _tunnelNetworkDao.listByToNetwork(host.getId(),
-                            nw.getId());
-            for (OvsTunnelNetworkVO p : peers) {
-                // If the tunnel was not successfully created don't bother to remove it
-                if (p.getState().equals(OvsTunnel.State.Established.name())) {
-                    cmd = new OvsDestroyTunnelCommand(p.getNetworkId(), bridgeName,
-                            p.getPortName());
-                    s_logger.debug("Destroying tunnel to " + host.getId() +
-                            " from " + p.getFrom());
-                    ans = _agentMgr.send(p.getFrom(), cmd);
-                    handleDestroyTunnelAnswer(ans, p.getFrom(),
-                            p.getTo(), p.getNetworkId());
+        if (nw.getVpcId() != null && isVpcEnabledForDistributedRouter(nw.getVpcId())) {
+            List<Long> vmIds = _ovsNetworkToplogyGuru.getActiveVmsInVpcOnHost(nw.getVpcId(), host.getId());
+            if (vmIds != null && !vmIds.isEmpty()) {
+                return;
+            }
+            List<? extends Network> vpcNetworks =  _vpcMgr.getVpcNetworks(nw.getVpcId());
+            try {
+                for (Network network: vpcNetworks) {
+                    int key = getGreKey(nw);
+                    String bridgeName = generateBridgeName(nw, key);
+                    /* Then ask hosts have peer tunnel with me to destroy them */
+                    List<OvsTunnelNetworkVO> peers = _tunnelNetworkDao.listByToNetwork(host.getId(),nw.getId());
+                    for (OvsTunnelNetworkVO p : peers) {
+                        // If the tunnel was not successfully created don't bother to remove it
+                        if (p.getState().equals(OvsTunnel.State.Established.name())) {
+                            Command cmd= new OvsDestroyTunnelCommand(p.getNetworkId(), bridgeName,
+                                    p.getPortName());
+                            s_logger.debug("Destroying tunnel to " + host.getId() +
+                                    " from " + p.getFrom());
+                            Answer ans = _agentMgr.send(p.getFrom(), cmd);
+                            handleDestroyTunnelAnswer(ans, p.getFrom(), p.getTo(), p.getNetworkId());
+                        }
+                    }
                 }
+
+                Command cmd = new OvsDestroyBridgeCommand(nw.getId(), generateBridgeNameForVpc(nw.getVpcId()));
+                s_logger.debug("Destroying bridge for network " + nw.getId() + " on host:" + host.getId());
+                Answer ans = _agentMgr.send(host.getId(), cmd);
+                handleDestroyBridgeAnswer(ans, host.getId(), nw.getId());
+            } catch (Exception e) {
+
+            }
+        } else {
+            List<Long> vmIds = _ovsNetworkToplogyGuru.getActiveVmsInNetworkOnHost(nw.getId(), host.getId());
+            if (vmIds != null && !vmIds.isEmpty()) {
+                return;
+            }
+            try {
+                /* Now we are last one on host, destroy the bridge with all
+                * the tunnels for this network  */
+                int key = getGreKey(nw);
+                String bridgeName = generateBridgeName(nw, key);
+                Command cmd = new OvsDestroyBridgeCommand(nw.getId(), bridgeName);
+                s_logger.debug("Destroying bridge for network " + nw.getId() + " on host:" + host.getId());
+                Answer ans = _agentMgr.send(host.getId(), cmd);
+                handleDestroyBridgeAnswer(ans, host.getId(), nw.getId());
+
+                /* Then ask hosts have peer tunnel with me to destroy them */
+                List<OvsTunnelNetworkVO> peers =
+                        _tunnelNetworkDao.listByToNetwork(host.getId(),
+                                nw.getId());
+                for (OvsTunnelNetworkVO p : peers) {
+                    // If the tunnel was not successfully created don't bother to remove it
+                    if (p.getState().equals(OvsTunnel.State.Established.name())) {
+                        cmd = new OvsDestroyTunnelCommand(p.getNetworkId(), bridgeName,
+                                p.getPortName());
+                        s_logger.debug("Destroying tunnel to " + host.getId() +
+                                " from " + p.getFrom());
+                        ans = _agentMgr.send(p.getFrom(), cmd);
+                        handleDestroyTunnelAnswer(ans, p.getFrom(),
+                                p.getTo(), p.getNetworkId());
+                    }
+                }
+            } catch (Exception e) {
+                s_logger.warn(String.format("Destroy tunnel failed", e));
             }
-        } catch (Exception e) {
-            s_logger.warn(String.format("Destroy tunnel failed", e));
         }
     }
 
@@ -514,9 +552,9 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
         List<Long> hostIds = _ovsNetworkToplogyGuru.getVpcSpannedHosts(vpcId);
         List<Long> vmIds = _ovsNetworkToplogyGuru.getAllActiveVmsInVpc(vpcId);
 
-        List<OvsVpcPhysicalTopologyConfigCommand.Host> hosts = new ArrayList<OvsVpcPhysicalTopologyConfigCommand.Host>();
-        List<OvsVpcPhysicalTopologyConfigCommand.Tier> tiers = new ArrayList<OvsVpcPhysicalTopologyConfigCommand.Tier>();
-        List<OvsVpcPhysicalTopologyConfigCommand.Vm> vms = new ArrayList<OvsVpcPhysicalTopologyConfigCommand.Vm>();
+        List<OvsVpcPhysicalTopologyConfigCommand.Host> hosts = new ArrayList<>();
+        List<OvsVpcPhysicalTopologyConfigCommand.Tier> tiers = new ArrayList<>();
+        List<OvsVpcPhysicalTopologyConfigCommand.Vm> vms = new ArrayList<>();
 
         for (Long hostId : hostIds) {
             HostVO hostDetails = _hostDao.findById(hostId);
@@ -533,10 +571,10 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
         }
 
         for (Network network: vpcNetworks) {
-            String key = BroadcastDomainType.getValue(network.getBroadcastUri());
+            String key = network.getBroadcastUri().getAuthority();
             long gre_key;
             if (key.contains(".")) {
-                String[] parts = key.split(".");
+                String[] parts = key.split("\\.");
                 gre_key = Long.parseLong(parts[1]);
             } else {
                 try {
@@ -580,6 +618,7 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
         List<? extends Network> vpcNetworks =  _vpcMgr.getVpcNetworks(vpcId);
         List<Long> vpcSpannedHostIds = _ovsNetworkToplogyGuru.getVpcSpannedHosts(vpcId);
         String bridgeName=generateBridgeNameForVpc(vpcId);
+        boolean bridgeNotSetup = true;
 
         for (Network vpcNetwork: vpcNetworks) {
             int key = getGreKey(vpcNetwork);
@@ -643,7 +682,7 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
                             + " to create gre tunnel to " + i);
                     Answer[] answers = _agentMgr.send(hostId, cmds);
                     handleCreateTunnelAnswer(answers);
-                    noHost = false;
+                    bridgeNotSetup = false;
                 }
 
                 for (Long i : fromHostIds) {
@@ -656,7 +695,7 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
                             + hostId);
                     Answer[] answers = _agentMgr.send(i, cmds);
                     handleCreateTunnelAnswer(answers);
-                    noHost = false;
+                    bridgeNotSetup = false;
                 }
             } catch (GreTunnelException | OperationTimedoutException | AgentUnavailableException e) {
                 // I really thing we should do a better handling of these exceptions
@@ -664,6 +703,20 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
             }
         }
 
+        // If no tunnels have been configured, perform the bridge setup
+        // anyway. This will ensure VIF rules will be triggered
+        if (bridgeNotSetup) {
+            try {
+                Commands cmds = new Commands(new OvsSetupBridgeCommand(bridgeName, hostId, null));
+                s_logger.debug("Ask host " + hostId + " to configure bridge for vpc");
+                Answer[] answers = _agentMgr.send(hostId, cmds);
+                handleSetupBridgeAnswer(answers);
+            } catch (OperationTimedoutException | AgentUnavailableException e) {
+                // I really thing we should do a better handling of these exceptions
+                s_logger.warn("Ovs Tunnel network created tunnel failed", e);
+            }
+        }
+
         OvsVpcPhysicalTopologyConfigCommand topologyConfigCommand = prepareVpcTopologyUpdate(vpcId);
         for (Long id: vpcSpannedHostIds) {
             if (!sendVpcTopologyChangeUpdate(topologyConfigCommand, id, bridgeName)) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2c778699/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py b/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py
index d2b95dc..dbcc288 100644
--- a/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py
+++ b/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py
@@ -21,7 +21,7 @@ import ConfigParser
 import logging
 import os
 import subprocess
-import json
+import simplejson as json
 
 from time import localtime, asctime
 
@@ -181,7 +181,7 @@ def _build_flow_expr(**kwargs):
     proto = 'proto' in kwargs and ",%s" % kwargs['proto'] or ''
     ip = ('nw_src' in kwargs or 'nw_dst' in kwargs) and ',ip' or ''
     flow = (flow + in_port + dl_type + dl_src + dl_dst +
-            (ip or proto) + nw_src + nw_dst)
+            (ip or proto) + nw_src + nw_dst + table)
     return flow
 
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2c778699/scripts/vm/hypervisor/xenserver/ovstunnel
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/xenserver/ovstunnel b/scripts/vm/hypervisor/xenserver/ovstunnel
index 64a2d36..9ef0f7b 100755
--- a/scripts/vm/hypervisor/xenserver/ovstunnel
+++ b/scripts/vm/hypervisor/xenserver/ovstunnel
@@ -137,8 +137,8 @@ def setup_ovs_bridge_for_distributed_routing(session, args):
 
     logging.debug("About to manually create the bridge:%s" % bridge)
     # create a bridge with the same name as the xapi network
-    res = lib.do_cmd([lib.VSCTL_PATH, "--", "--may-exist", "add-br", bridge,
-                                     "--", "set", "bridge", bridge])
+    res = lib.do_cmd([lib.VSCTL_PATH, "--", "--may-exist", "add-br", bridge])
+
     logging.debug("Bridge has been manually created:%s" % res)
     # TODO: Make sure xs-network-uuid is set into external_ids
     lib.do_cmd([lib.VSCTL_PATH, "set", "Bridge", bridge,
@@ -149,12 +149,8 @@ def setup_ovs_bridge_for_distributed_routing(session, args):
         result = "FAILURE:%s" % res
     else:
         # Verify the bridge actually exists, with the gre_key properly set
-        res = lib.do_cmd([lib.VSCTL_PATH, "get", "bridge",
-                                          bridge, "other_config:gre_key"])
-        if key in res:
-            result = "SUCCESS:%s" % bridge
-        else:
-            result = "FAILURE:%s" % res
+        res = lib.do_cmd([lib.VSCTL_PATH, "list", "bridge", bridge])
+
         # Finally note in the xenapi network object that the network has
         # been configured
         xs_nw_uuid = lib.do_cmd([lib.XE_PATH, "network-list",
@@ -191,6 +187,8 @@ def setup_ovs_bridge_for_distributed_routing(session, args):
         # add a default rule in egress table to forward packet to L3 lookup table
         lib.add_flow(bridge, priority=0, table=5, actions='drop')
 
+        result = "SUCCESS: successfully setup bridge with flow rules"
+
     logging.debug("Setup_ovs_bridge completed with result:%s" % result)
     return result
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2c778699/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java b/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java
index 414eb7b..13246a7 100644
--- a/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java
+++ b/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java
@@ -107,6 +107,10 @@ public class ExternalGuestNetworkGuru extends GuestNetworkGuru {
     @Override
     public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) {
 
+        if (_networkModel.areServicesSupportedByNetworkOffering(offering.getId(), Network.Service.Connectivity)) {
+            return null;
+        }
+
         NetworkVO config = (NetworkVO)super.design(offering, plan, userSpecified, owner);
         if (config == null) {
             return null;