You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by tu...@apache.org on 2013/12/09 17:52:29 UTC

[03/21] git commit: updated refs/heads/master to 267ff79

tuna


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

Branch: refs/heads/master
Commit: d935d3865aa2a4fb39709f6943f02f9f5a422aff
Parents: 4e914b7
Author: tuna <ng...@gmail.com>
Authored: Mon Aug 12 23:19:15 2013 +0700
Committer: tuna <ng...@gmail.com>
Committed: Mon Dec 9 23:33:14 2013 +0700

----------------------------------------------------------------------
 api/src/com/cloud/network/Network.java          |   4 +-
 api/src/com/cloud/network/OvsProvider.java      |  10 +
 .../element/VirtualRouterElementService.java    |   6 +
 .../cloudstack/api/ResponseGenerator.java       |   8 +
 .../admin/router/ConfigureOvsElementCmd.java    | 116 +++++
 .../admin/router/ListOvsElementsCmd.java        |  91 ++++
 .../api/response/OvsProviderResponse.java       |  77 ++++
 client/tomcatconf/applicationContext.xml.in     |   1 +
 client/tomcatconf/commands.properties.in        |   5 +
 .../com/cloud/network/dao/OvsProviderDao.java   |  14 +
 .../cloud/network/dao/OvsProviderDaoImpl.java   |  57 +++
 .../cloud/network/element/OvsProviderVO.java    |  83 ++++
 .../xen/resource/CitrixResourceBase.java        |  12 +
 .../cloudstack/ovs/spring-ovs-context.xml       |   1 +
 .../com/cloud/network/element/OvsElement.java   |  87 ++--
 .../cloud/network/guru/OvsGuestNetworkGuru.java |  20 +-
 .../cloud/network/ovs/OvsTunnelManagerImpl.java | 425 ++++++++++++-------
 scripts/vm/hypervisor/xenserver/ovstunnel       |  24 +-
 scripts/vm/hypervisor/xenserver/vhd-util        | Bin 0 -> 318977 bytes
 server/src/com/cloud/api/ApiResponseHelper.java |  19 +
 .../com/cloud/network/NetworkServiceImpl.java   |  31 +-
 .../network/element/VirtualRouterElement.java   |  81 +++-
 .../com/cloud/server/ManagementServerImpl.java  |   4 +
 setup/db/create-schema.sql                      |  10 -
 setup/db/db/schema-410to420.sql                 |  22 +
 tools/apidoc/gen_toc.py                         |   1 +
 ui/scripts/system.js                            | 177 ++++----
 ui/scripts/zoneWizard.js                        | 224 +++++++++-
 utils/conf/db.properties                        |   2 +-
 29 files changed, 1286 insertions(+), 326 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d935d386/api/src/com/cloud/network/Network.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/network/Network.java b/api/src/com/cloud/network/Network.java
index 74398e8..d19c999 100644
--- a/api/src/com/cloud/network/Network.java
+++ b/api/src/com/cloud/network/Network.java
@@ -126,8 +126,8 @@ public interface Network extends ControlledEntity, StateObject<Network.State>, I
         public static final Provider NiciraNvp = new Provider("NiciraNvp", false);
         public static final Provider InternalLbVm = new Provider("InternalLbVm", false);
         public static final Provider CiscoVnmc = new Provider("CiscoVnmc", true);
-		// Ovs
-		public static final Provider Ovs = new Provider("Ovs", false);
+        // add new Ovs provider
+        public static final Provider Ovs = new Provider("Ovs", false);
 
         private final String name;
         private final boolean isExternal;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d935d386/api/src/com/cloud/network/OvsProvider.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/network/OvsProvider.java b/api/src/com/cloud/network/OvsProvider.java
new file mode 100644
index 0000000..c993728
--- /dev/null
+++ b/api/src/com/cloud/network/OvsProvider.java
@@ -0,0 +1,10 @@
+package com.cloud.network;
+
+import org.apache.cloudstack.api.Identity;
+import org.apache.cloudstack.api.InternalIdentity;
+
+public interface OvsProvider extends InternalIdentity, Identity {
+	public boolean isEnabled();
+
+	public long getNspId();
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d935d386/api/src/com/cloud/network/element/VirtualRouterElementService.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/network/element/VirtualRouterElementService.java b/api/src/com/cloud/network/element/VirtualRouterElementService.java
index e929d14..c8d45ca 100644
--- a/api/src/com/cloud/network/element/VirtualRouterElementService.java
+++ b/api/src/com/cloud/network/element/VirtualRouterElementService.java
@@ -18,9 +18,12 @@ package com.cloud.network.element;
 
 import java.util.List;
 
+import org.apache.cloudstack.api.command.admin.router.ConfigureOvsElementCmd;
 import org.apache.cloudstack.api.command.admin.router.ConfigureVirtualRouterElementCmd;
+import org.apache.cloudstack.api.command.admin.router.ListOvsElementsCmd;
 import org.apache.cloudstack.api.command.admin.router.ListVirtualRouterElementsCmd;
 
+import com.cloud.network.OvsProvider;
 import com.cloud.network.VirtualRouterProvider;
 import com.cloud.network.VirtualRouterProvider.Type;
 import com.cloud.utils.component.PluggableService;
@@ -28,9 +31,12 @@ import com.cloud.utils.component.PluggableService;
 public interface VirtualRouterElementService extends PluggableService {
     VirtualRouterProvider configure(ConfigureVirtualRouterElementCmd cmd);
 
+	OvsProvider configure(ConfigureOvsElementCmd cmd);
     VirtualRouterProvider addElement(Long nspId, Type providerType);
 
     VirtualRouterProvider getCreatedElement(long id);
 
     List<? extends VirtualRouterProvider> searchForVirtualRouterElement(ListVirtualRouterElementsCmd cmd);
+
+	List<? extends OvsProvider> searchForOvsElement(ListOvsElementsCmd cmd);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d935d386/api/src/org/apache/cloudstack/api/ResponseGenerator.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/ResponseGenerator.java b/api/src/org/apache/cloudstack/api/ResponseGenerator.java
index 2d37b6a..64b703e 100644
--- a/api/src/org/apache/cloudstack/api/ResponseGenerator.java
+++ b/api/src/org/apache/cloudstack/api/ResponseGenerator.java
@@ -67,6 +67,7 @@ import org.apache.cloudstack.api.response.NetworkOfferingResponse;
 import org.apache.cloudstack.api.response.NetworkResponse;
 import org.apache.cloudstack.api.response.NicResponse;
 import org.apache.cloudstack.api.response.NicSecondaryIpResponse;
+import org.apache.cloudstack.api.response.OvsProviderResponse;
 import org.apache.cloudstack.api.response.PhysicalNetworkResponse;
 import org.apache.cloudstack.api.response.PodResponse;
 import org.apache.cloudstack.api.response.PortableIpRangeResponse;
@@ -118,7 +119,9 @@ import org.apache.cloudstack.region.PortableIpRange;
 import org.apache.cloudstack.region.Region;
 import org.apache.cloudstack.usage.Usage;
 
+import com.cloud.async.AsyncJob;
 import com.cloud.capacity.Capacity;
+import com.cloud.configuration.Configuration;
 import com.cloud.configuration.ResourceCount;
 import com.cloud.configuration.ResourceLimit;
 import com.cloud.dc.DataCenter;
@@ -134,6 +137,7 @@ import com.cloud.network.IpAddress;
 import com.cloud.network.Network;
 import com.cloud.network.Network.Service;
 import com.cloud.network.Networks.IsolationType;
+import com.cloud.network.OvsProvider;
 import com.cloud.network.PhysicalNetwork;
 import com.cloud.network.PhysicalNetworkServiceProvider;
 import com.cloud.network.PhysicalNetworkTrafficType;
@@ -353,6 +357,10 @@ public interface ResponseGenerator {
 
     VirtualRouterProviderResponse createVirtualRouterProviderResponse(VirtualRouterProvider result);
 
+	OvsProviderResponse createOvsProviderResponse(OvsProvider result);
+
+    LDAPConfigResponse createLDAPConfigResponse(String hostname, Integer port, Boolean useSSL, String queryFilter, String baseSearch, String dn);
+
     StorageNetworkIpRangeResponse createStorageNetworkIpRangeResponse(StorageNetworkIpRange result);
 
     RegionResponse createRegionResponse(Region region);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d935d386/api/src/org/apache/cloudstack/api/command/admin/router/ConfigureOvsElementCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/admin/router/ConfigureOvsElementCmd.java b/api/src/org/apache/cloudstack/api/command/admin/router/ConfigureOvsElementCmd.java
new file mode 100644
index 0000000..0419154
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/command/admin/router/ConfigureOvsElementCmd.java
@@ -0,0 +1,116 @@
+package org.apache.cloudstack.api.command.admin.router;
+
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.OvsProviderResponse;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.OvsProvider;
+import com.cloud.network.element.VirtualRouterElementService;
+import com.cloud.user.Account;
+import com.cloud.user.UserContext;
+
+@APICommand(name = "configureOvsElement", responseObject = OvsProviderResponse.class, description = "Configures an ovs element.")
+public class ConfigureOvsElementCmd extends BaseAsyncCmd {
+	public static final Logger s_logger = Logger
+			.getLogger(ConfigureOvsElementCmd.class.getName());
+	private static final String s_name = "configureovselementresponse";
+	@Inject
+	private List<VirtualRouterElementService> _service;
+
+	// ///////////////////////////////////////////////////
+	// ////////////// API parameters /////////////////////
+	// ///////////////////////////////////////////////////
+
+	@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = OvsProviderResponse.class, required = true, description = "the ID of the ovs provider")
+	private Long id;
+
+	@Parameter(name = ApiConstants.ENABLED, type = CommandType.BOOLEAN, required = true, description = "Enabled/Disabled the service provider")
+	private Boolean enabled;
+
+	// ///////////////////////////////////////////////////
+	// ///////////////// Accessors ///////////////////////
+	// ///////////////////////////////////////////////////
+	public void setId(Long id) {
+		this.id = id;
+	}
+
+	public Long getId() {
+		return id;
+	}
+
+	public void setEnabled(Boolean enabled) {
+		this.enabled = enabled;
+	}
+
+	public Boolean getEnabled() {
+		return enabled;
+	}
+
+	// ///////////////////////////////////////////////////
+	// ///////////// API Implementation///////////////////
+	// ///////////////////////////////////////////////////
+
+	@Override
+	public String getCommandName() {
+		return s_name;
+	}
+
+	public static String getResultObjectName() {
+		return "boolean";
+	}
+
+	@Override
+	public long getEntityOwnerId() {
+		return Account.ACCOUNT_ID_SYSTEM;
+	}
+
+	@Override
+	public String getEventType() {
+		return EventTypes.EVENT_NETWORK_ELEMENT_CONFIGURE;
+	}
+
+	@Override
+	public String getEventDescription() {
+		return "configuring ovs provider: " + id;
+	}
+
+	@Override
+	public ApiCommandJobType getInstanceType() {
+		return ApiCommandJobType.None;
+	}
+
+	@Override
+	public Long getInstanceId() {
+		return id;
+	}
+
+	@Override
+	public void execute() throws ConcurrentOperationException,
+			ResourceUnavailableException, InsufficientCapacityException {
+		UserContext.current().setEventDetails("Ovs element: " + id);
+		OvsProvider result = _service.get(0).configure(this);
+		if (result != null) {
+			OvsProviderResponse ovsResponse = _responseGenerator
+					.createOvsProviderResponse(result);
+			ovsResponse.setResponseName(getCommandName());
+			this.setResponseObject(ovsResponse);
+		} else {
+			throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR,
+					"Failed to configure the ovs provider");
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d935d386/api/src/org/apache/cloudstack/api/command/admin/router/ListOvsElementsCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/admin/router/ListOvsElementsCmd.java b/api/src/org/apache/cloudstack/api/command/admin/router/ListOvsElementsCmd.java
new file mode 100644
index 0000000..3e3ee63
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/command/admin/router/ListOvsElementsCmd.java
@@ -0,0 +1,91 @@
+package org.apache.cloudstack.api.command.admin.router;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseListCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.command.user.network.ListNetworkOfferingsCmd;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.api.response.OvsProviderResponse;
+import org.apache.cloudstack.api.response.ProviderResponse;
+import org.apache.log4j.Logger;
+
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.OvsProvider;
+import com.cloud.network.element.VirtualRouterElementService;
+
+@APICommand(name = "listOvsElements", description = "Lists all available ovs elements.", responseObject = OvsProviderResponse.class)
+public class ListOvsElementsCmd extends BaseListCmd {
+	public static final Logger s_logger = Logger
+			.getLogger(ListNetworkOfferingsCmd.class.getName());
+	private static final String _name = "listovselementsresponse";
+	@Inject
+	private List<VirtualRouterElementService> _service;
+	// ///////////////////////////////////////////////////
+	// ////////////// API parameters /////////////////////
+	// ///////////////////////////////////////////////////
+	@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = OvsProviderResponse.class, description = "list ovs elements by id")
+	private Long id;
+
+	@Parameter(name = ApiConstants.NSP_ID, type = CommandType.UUID, entityType = ProviderResponse.class, description = "list ovs elements by network service provider id")
+	private Long nspId;
+
+	@Parameter(name = ApiConstants.ENABLED, type = CommandType.BOOLEAN, description = "list network offerings by enabled state")
+	private Boolean enabled;
+
+	// ///////////////////////////////////////////////////
+	// ///////////////// Accessors ///////////////////////
+	// ///////////////////////////////////////////////////
+
+	public void setId(Long id) {
+		this.id = id;
+	}
+
+	public Long getId() {
+		return id;
+	}
+
+	public void setNspId(Long nspId) {
+		this.nspId = nspId;
+	}
+
+	public Long getNspId() {
+		return nspId;
+	}
+
+	public void setEnabled(Boolean enabled) {
+		this.enabled = enabled;
+	}
+
+	public Boolean getEnabled() {
+		return enabled;
+	}
+
+	@Override
+	public String getCommandName() {
+		return _name;
+	}
+	@Override
+    public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException {
+        List<? extends OvsProvider> providers = _service.get(0).searchForOvsElement(this);
+        ListResponse<OvsProviderResponse> response = new ListResponse<OvsProviderResponse>();
+        List<OvsProviderResponse> providerResponses = new ArrayList<OvsProviderResponse>();
+        for (OvsProvider provider : providers) {
+        	OvsProviderResponse providerResponse = _responseGenerator.createOvsProviderResponse(provider);
+            providerResponses.add(providerResponse);
+        }
+        response.setResponses(providerResponses);
+        response.setResponseName(getCommandName());
+        this.setResponseObject(response);
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d935d386/api/src/org/apache/cloudstack/api/response/OvsProviderResponse.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/response/OvsProviderResponse.java b/api/src/org/apache/cloudstack/api/response/OvsProviderResponse.java
new file mode 100644
index 0000000..23e6134
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/response/OvsProviderResponse.java
@@ -0,0 +1,77 @@
+package org.apache.cloudstack.api.response;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseResponse;
+import org.apache.cloudstack.api.EntityReference;
+
+import com.cloud.network.OvsProvider;
+import com.cloud.serializer.Param;
+import com.google.gson.annotations.SerializedName;
+
+@EntityReference(value = OvsProvider.class)
+@SuppressWarnings("unused")
+public class OvsProviderResponse extends BaseResponse implements
+		ControlledEntityResponse {
+	@SerializedName(ApiConstants.ID)
+	@Param(description = "the id of the ovs")
+	private String id;
+	@SerializedName(ApiConstants.NSP_ID)
+	@Param(description = "the physical network service provider id of the provider")
+	private String nspId;
+	@SerializedName(ApiConstants.ENABLED)
+	@Param(description = "Enabled/Disabled the service provider")
+	private Boolean enabled;
+	@SerializedName(ApiConstants.ACCOUNT)
+	@Param(description = "the account associated with the provider")
+	private String accountName;
+	@SerializedName(ApiConstants.PROJECT_ID)
+	@Param(description = "the project id of the ipaddress")
+	private String projectId;
+	@SerializedName(ApiConstants.PROJECT)
+	@Param(description = "the project name of the address")
+	private String projectName;
+	@SerializedName(ApiConstants.DOMAIN_ID)
+	@Param(description = "the domain ID associated with the provider")
+	private String domainId;
+
+	@SerializedName(ApiConstants.DOMAIN)
+	@Param(description = "the domain associated with the provider")
+	private String domainName;
+
+	@Override
+	public void setAccountName(String accountName) {
+		this.accountName = accountName;
+	}
+
+	public void setId(String id) {
+		this.id = id;
+	}
+
+	@Override
+	public void setDomainId(String domainId) {
+		this.domainId = domainId;
+	}
+
+	@Override
+	public void setDomainName(String domainName) {
+		this.domainName = domainName;
+	}
+
+	@Override
+	public void setProjectId(String projectId) {
+		this.projectId = projectId;
+	}
+
+	@Override
+	public void setProjectName(String projectName) {
+		this.projectName = projectName;
+	}
+
+	public void setNspId(String nspId) {
+		this.nspId = nspId;
+	}
+
+	public void setEnabled(Boolean enabled) {
+		this.enabled = enabled;
+	}
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d935d386/client/tomcatconf/applicationContext.xml.in
----------------------------------------------------------------------
diff --git a/client/tomcatconf/applicationContext.xml.in b/client/tomcatconf/applicationContext.xml.in
index 5260681..b3778d4 100644
--- a/client/tomcatconf/applicationContext.xml.in
+++ b/client/tomcatconf/applicationContext.xml.in
@@ -355,6 +355,7 @@
   <bean id="vMTemplateZoneDaoImpl" class="com.cloud.storage.dao.VMTemplateZoneDaoImpl" />
   <bean id="versionDaoImpl" class="com.cloud.upgrade.dao.VersionDaoImpl" />
   <bean id="virtualRouterProviderDaoImpl" class="com.cloud.network.dao.VirtualRouterProviderDaoImpl" />
+  <bean id="ovsProviderDaoImpl" class="com.cloud.network.dao.OvsProviderDaoImpl" />
   <bean id="vmRulesetLogDaoImpl" class="com.cloud.network.security.dao.VmRulesetLogDaoImpl" />
   <bean id="volumeDaoImpl" class="com.cloud.storage.dao.VolumeDaoImpl" />
   <bean id="volumeDetailsDaoImpl" class="com.cloud.storage.dao.VolumeDetailsDaoImpl" />

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d935d386/client/tomcatconf/commands.properties.in
----------------------------------------------------------------------
diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in
index da4c03f..bd46fa2 100644
--- a/client/tomcatconf/commands.properties.in
+++ b/client/tomcatconf/commands.properties.in
@@ -503,6 +503,11 @@ createVirtualRouterElement=7
 configureVirtualRouterElement=7
 listVirtualRouterElements=7
 
+#### ovs commands
+createOvsElement=7
+configureOvsElement=7
+listOvsElements=7
+
 #### usage commands
 generateUsageRecords=1
 listUsageRecords=7

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d935d386/engine/schema/src/com/cloud/network/dao/OvsProviderDao.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/network/dao/OvsProviderDao.java b/engine/schema/src/com/cloud/network/dao/OvsProviderDao.java
new file mode 100644
index 0000000..b23e3d3
--- /dev/null
+++ b/engine/schema/src/com/cloud/network/dao/OvsProviderDao.java
@@ -0,0 +1,14 @@
+package com.cloud.network.dao;
+
+import java.util.List;
+
+import com.cloud.network.element.OvsProviderVO;
+import com.cloud.utils.db.GenericDao;
+
+public interface OvsProviderDao extends GenericDao<OvsProviderVO, Long> {
+	public OvsProviderVO findByNspId(long nspId);
+
+	public List<OvsProviderVO> listByEnabled(boolean enabled);
+
+	public OvsProviderVO findByIdAndEnabled(long id, boolean enabled);
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d935d386/engine/schema/src/com/cloud/network/dao/OvsProviderDaoImpl.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/network/dao/OvsProviderDaoImpl.java b/engine/schema/src/com/cloud/network/dao/OvsProviderDaoImpl.java
new file mode 100644
index 0000000..b00d5c1
--- /dev/null
+++ b/engine/schema/src/com/cloud/network/dao/OvsProviderDaoImpl.java
@@ -0,0 +1,57 @@
+package com.cloud.network.dao;
+
+import java.util.List;
+
+import javax.ejb.Local;
+
+import org.springframework.stereotype.Component;
+
+import com.cloud.network.element.OvsProviderVO;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+
+@Component
+@Local(value = OvsProviderDao.class)
+@DB(txn = false)
+public class OvsProviderDaoImpl extends GenericDaoBase<OvsProviderVO, Long>
+		implements OvsProviderDao {
+	final SearchBuilder<OvsProviderVO> AllFieldsSearch;
+
+	public OvsProviderDaoImpl() {
+		super();
+		AllFieldsSearch = createSearchBuilder();
+		AllFieldsSearch.and("id", AllFieldsSearch.entity().getId(),
+				SearchCriteria.Op.EQ);
+		AllFieldsSearch.and("nsp_id", AllFieldsSearch.entity().getNspId(),
+				SearchCriteria.Op.EQ);
+		AllFieldsSearch.and("uuid", AllFieldsSearch.entity().getUuid(),
+				SearchCriteria.Op.EQ);
+		AllFieldsSearch.and("enabled", AllFieldsSearch.entity().isEnabled(),
+				SearchCriteria.Op.EQ);
+		AllFieldsSearch.done();
+	}
+
+	@Override
+	public OvsProviderVO findByNspId(long nspId) {
+		SearchCriteria<OvsProviderVO> sc = AllFieldsSearch.create();
+		sc.setParameters("nsp_id", nspId);
+		return findOneBy(sc);
+	}
+
+	@Override
+	public List<OvsProviderVO> listByEnabled(boolean enabled) {
+		SearchCriteria<OvsProviderVO> sc = AllFieldsSearch.create();
+		sc.setParameters("enabled", enabled);
+		return listBy(sc);
+	}
+
+	@Override
+	public OvsProviderVO findByIdAndEnabled(long id, boolean enabled) {
+		SearchCriteria<OvsProviderVO> sc = AllFieldsSearch.create();
+		sc.setParameters("id", id);
+		sc.setParameters("enabled", enabled);
+		return findOneBy(sc);
+	}
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d935d386/engine/schema/src/com/cloud/network/element/OvsProviderVO.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/network/element/OvsProviderVO.java b/engine/schema/src/com/cloud/network/element/OvsProviderVO.java
new file mode 100644
index 0000000..bc3455a
--- /dev/null
+++ b/engine/schema/src/com/cloud/network/element/OvsProviderVO.java
@@ -0,0 +1,83 @@
+package com.cloud.network.element;
+
+import java.util.Date;
+import java.util.UUID;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import com.cloud.network.OvsProvider;
+import com.cloud.utils.db.GenericDao;
+
+@Entity
+@Table(name = ("ovs_providers"))
+public class OvsProviderVO implements OvsProvider {
+	@Id
+	@GeneratedValue(strategy = GenerationType.IDENTITY)
+	@Column(name = "id")
+	long id;
+
+	@Column(name = "nsp_id")
+	private long nspId;
+
+	@Column(name = "uuid")
+	private String uuid;
+
+	@Column(name = "enabled")
+	private boolean enabled;
+
+	@Column(name = GenericDao.REMOVED_COLUMN)
+	Date removed;
+
+	public OvsProviderVO() {
+		this.uuid = UUID.randomUUID().toString();
+	}
+
+	public OvsProviderVO(long nspId) {
+		this.nspId = nspId;
+		this.uuid = UUID.randomUUID().toString();
+	}
+
+	@Override
+	public long getNspId() {
+		return nspId;
+	}
+
+	public String getUuid() {
+		return uuid;
+	}
+
+	@Override
+	public long getId() {
+		return id;
+	}
+
+	public Date getRemoved() {
+		return removed;
+	}
+
+	public void setEnabled(boolean enabled) {
+		this.enabled = enabled;
+	}
+
+	@Override
+	public boolean isEnabled() {
+		return this.enabled;
+	}
+
+	public void setId(long id) {
+		this.id = id;
+	}
+
+	public void setNspId(long nspId) {
+		this.nspId = nspId;
+	}
+
+	public void setUuid(String uuid) {
+		this.uuid = uuid;
+	}
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d935d386/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 25f30f4..e093253 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
@@ -156,6 +156,18 @@ import com.cloud.agent.api.ModifyStoragePoolAnswer;
 import com.cloud.agent.api.ModifyStoragePoolCommand;
 import com.cloud.agent.api.NetworkRulesSystemVmCommand;
 import com.cloud.agent.api.NetworkRulesVmSecondaryIpCommand;
+import com.cloud.agent.api.OvsCreateGreTunnelCommand;
+import com.cloud.agent.api.OvsCreateGreTunnelAnswer;
+import com.cloud.agent.api.OvsCreateTunnelCommand;
+import com.cloud.agent.api.OvsDestroyTunnelCommand;
+import com.cloud.agent.api.OvsSetupBridgeCommand;
+import com.cloud.agent.api.OvsDestroyBridgeCommand;
+import com.cloud.agent.api.OvsCreateTunnelAnswer;
+import com.cloud.agent.api.OvsDeleteFlowCommand;
+import com.cloud.agent.api.OvsSetTagAndFlowAnswer;
+import com.cloud.agent.api.OvsFetchInterfaceAnswer;
+import com.cloud.agent.api.OvsSetTagAndFlowCommand;
+import com.cloud.agent.api.OvsFetchInterfaceCommand;
 import com.cloud.agent.api.PingCommand;
 import com.cloud.agent.api.PingRoutingCommand;
 import com.cloud.agent.api.PingRoutingWithNwGroupsCommand;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d935d386/plugins/network-elements/ovs/resources/META-INF/cloudstack/ovs/spring-ovs-context.xml
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/resources/META-INF/cloudstack/ovs/spring-ovs-context.xml b/plugins/network-elements/ovs/resources/META-INF/cloudstack/ovs/spring-ovs-context.xml
index e60d93e..c6012d9 100644
--- a/plugins/network-elements/ovs/resources/META-INF/cloudstack/ovs/spring-ovs-context.xml
+++ b/plugins/network-elements/ovs/resources/META-INF/cloudstack/ovs/spring-ovs-context.xml
@@ -38,5 +38,6 @@
     <bean id="ovsTunnelManagerImpl" class="com.cloud.network.ovs.OvsTunnelManagerImpl" />
     <bean id="ovsTunnelInterfaceDaoImpl" class="com.cloud.network.ovs.dao.OvsTunnelInterfaceDaoImpl" />
     <bean id="ovsTunnelNetworkDaoImpl" class="com.cloud.network.ovs.dao.OvsTunnelNetworkDaoImpl" />
+    <bean id="ovsProviderDaoImpl" class="com.cloud.network.dao.OvsProviderDaoImpl" />
     
 </beans>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d935d386/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 263a214..06965e8 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
@@ -16,6 +16,7 @@
 // under the License.
 package com.cloud.network.element;
 
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -46,6 +47,8 @@ import com.cloud.network.PhysicalNetworkServiceProvider;
 import com.cloud.network.PublicIpAddress;
 import com.cloud.network.dao.NetworkServiceMapDao;
 import com.cloud.network.ovs.OvsTunnelManager;
+import com.cloud.network.router.VirtualRouter.Role;
+import com.cloud.network.router.VpcVirtualNetworkApplianceManager;
 import com.cloud.network.rules.PortForwardingRule;
 import com.cloud.network.rules.StaticNat;
 import com.cloud.offering.NetworkOffering;
@@ -54,9 +57,11 @@ import com.cloud.resource.ResourceStateAdapter;
 import com.cloud.resource.ServerResource;
 import com.cloud.resource.UnableDeleteHostException;
 import com.cloud.utils.component.AdapterBase;
+import com.cloud.vm.DomainRouterVO;
 import com.cloud.vm.NicProfile;
 import com.cloud.vm.ReservationContext;
 import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.dao.DomainRouterDao;
 
 @Local(value = { NetworkElement.class, ConnectivityProvider.class,
 		SourceNatServiceProvider.class, StaticNatServiceProvider.class,
@@ -73,6 +78,10 @@ public class OvsElement extends AdapterBase implements NetworkElement,
 	NetworkServiceMapDao _ntwkSrvcDao;
 	@Inject
 	ResourceManager _resourceMgr;
+	@Inject
+	DomainRouterDao _routerDao;
+	@Inject
+	VpcVirtualNetworkApplianceManager _routerMgr;
 
 	private static final Logger s_logger = Logger.getLogger(OvsElement.class);
 	private static final Map<Service, Map<Capability, String>> capabilities = setCapabilities();
@@ -130,8 +139,6 @@ public class OvsElement extends AdapterBase implements NetworkElement,
 		if (!canHandle(network, Service.Connectivity)) {
 			return false;
 		}
-		// TODO: implement SourceNat immediately when we code L3 services
-
 		return true;
 	}
 
@@ -221,35 +228,35 @@ public class OvsElement extends AdapterBase implements NetworkElement,
 			return false;
 		}
 
-		if ((services.contains(Service.PortForwarding) || services
-				.contains(Service.StaticNat))
-				&& !services.contains(Service.SourceNat)) {
-			s_logger.warn("Unable to provide StaticNat and/or PortForwarding without the SourceNat service");
-			return false;
-		}
+		// if ((services.contains(Service.PortForwarding) || services
+		// .contains(Service.StaticNat))
+		// && !services.contains(Service.SourceNat)) {
+		// s_logger.warn("Unable to provide StaticNat and/or PortForwarding without the SourceNat service");
+		// return false;
+		// }
 		return true;
 	}
 
 	private static Map<Service, Map<Capability, String>> setCapabilities() {
 		Map<Service, Map<Capability, String>> capabilities = new HashMap<Service, Map<Capability, String>>();
 
-		// we need L3 support for coding L3 services in next period
-
 		// L2 Support : SDN provisioning
 		capabilities.put(Service.Connectivity, null);
 
+		// TODO: we need L3 support for coding L3 services in next period
 		// L3 Support : Generic?
-		capabilities.put(Service.Gateway, null);
+		// capabilities.put(Service.Gateway, null);
 
 		// L3 Support : SourceNat
-		Map<Capability, String> sourceNatCapabilities = new HashMap<Capability, String>();
-		sourceNatCapabilities.put(Capability.SupportedSourceNatTypes,
-				"peraccount");
-		sourceNatCapabilities.put(Capability.RedundantRouter, "false");
-		capabilities.put(Service.SourceNat, sourceNatCapabilities);
+		// Map<Capability, String> sourceNatCapabilities = new
+		// HashMap<Capability, String>();
+		// sourceNatCapabilities.put(Capability.SupportedSourceNatTypes,
+		// "peraccount");
+		// sourceNatCapabilities.put(Capability.RedundantRouter, "false");
+		// capabilities.put(Service.SourceNat, sourceNatCapabilities);
 
 		// L3 Support : Port Forwarding
-		capabilities.put(Service.PortForwarding, null);
+		// capabilities.put(Service.PortForwarding, null);
 
 		// L3 support : StaticNat
 		capabilities.put(Service.StaticNat, null);
@@ -259,7 +266,8 @@ public class OvsElement extends AdapterBase implements NetworkElement,
 
 	@Override
 	public List<Class<?>> getCommands() {
-		return null;
+		List<Class<?>> cmdList = new ArrayList<Class<?>>();
+		return cmdList;
 	}
 
 	@Override
@@ -291,24 +299,53 @@ public class OvsElement extends AdapterBase implements NetworkElement,
 	// TODO: Adding L3 services below
 	@Override
 	public IpDeployer getIpDeployer(Network network) {
-		// TODO Auto-generated method stub
-		return null;
+		return this;
 	}
 
 	@Override
 	public boolean applyIps(Network network,
 			List<? extends PublicIpAddress> ipAddress, Set<Service> services)
 			throws ResourceUnavailableException {
-		// TODO Auto-generated method stub
-		return false;
+		boolean canHandle = true;
+		for (Service service : services) {
+			// check if Ovs can handle services except SourceNat
+			if (!canHandle(network, service) && service != Service.SourceNat) {
+				canHandle = false;
+				break;
+			}
+		}
+		if (canHandle) {
+			List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(
+					network.getId(), Role.VIRTUAL_ROUTER);
+			if (routers == null || routers.isEmpty()) {
+				s_logger.debug("Virtual router element doesn't need to associate ip addresses on the backend; virtual "
+						+ "router doesn't exist in the network "
+						+ network.getId());
+				return true;
+			}
+
+			return _routerMgr.associatePublicIP(network, ipAddress, routers);
+		} else {
+			return false;
+		}
 	}
 
 	@Override
-	public boolean applyStaticNats(Network config,
+	public boolean applyStaticNats(Network network,
 			List<? extends StaticNat> rules)
 			throws ResourceUnavailableException {
-		// TODO Auto-generated method stub
-		return false;
+		if (!canHandle(network, Service.StaticNat)) {
+			return false;
+		}
+		List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(
+				network.getId(), Role.VIRTUAL_ROUTER);
+		if (routers == null || routers.isEmpty()) {
+			s_logger.debug("Ovs element doesn't need to apply static nat on the backend; virtual "
+					+ "router doesn't exist in the network " + network.getId());
+			return true;
+		}
+
+		return _routerMgr.applyStaticNats(network, rules, routers);
 	}
 
 	@Override

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d935d386/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 635aff1..939f98a 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
@@ -91,9 +91,9 @@ public class OvsGuestNetworkGuru extends GuestNetworkGuru {
 	public Network design(NetworkOffering offering, DeploymentPlan plan,
 			Network userSpecified, Account owner) {
 
-		if (!_ovsTunnelMgr.isOvsTunnelEnabled()) {
-			return null;
-		}
+		// if (!_ovsTunnelMgr.isOvsTunnelEnabled()) {
+		// return null;
+		// }
 		PhysicalNetworkVO physnet = _physicalNetworkDao.findById(plan
 				.getPhysicalNetworkId());
 		DataCenter dc = _dcDao.findById(plan.getDataCenterId());
@@ -118,10 +118,11 @@ public class OvsGuestNetworkGuru extends GuestNetworkGuru {
 			throws InsufficientVirtualNetworkCapcityException {
 		assert (network.getState() == State.Implementing) : "Why are we implementing "
 				+ network;
-		if (!_ovsTunnelMgr.isOvsTunnelEnabled()) {
-			return null;
-		}
+		// if (!_ovsTunnelMgr.isOvsTunnelEnabled()) {
+		// return null;
+		// }
 		long dcId = dest.getDataCenter().getId();
+		NetworkType nwType = dest.getDataCenter().getNetworkType();
 		// get physical network id
 		Long physicalNetworkId = network.getPhysicalNetworkId();
 		// physical network id can be null in Guest Network in Basic zone, so
@@ -130,6 +131,13 @@ public class OvsGuestNetworkGuru extends GuestNetworkGuru {
 			physicalNetworkId = _networkModel.findPhysicalNetworkId(dcId,
 					offering.getTags(), offering.getTrafficType());
 		}
+		PhysicalNetworkVO physnet = _physicalNetworkDao
+				.findById(physicalNetworkId);
+
+		if (!canHandle(offering, nwType, physnet)) {
+			s_logger.debug("Refusing to design this network");
+			return null;
+		}
 		NetworkVO implemented = (NetworkVO) super.implement(network, offering,
 				dest, context);
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d935d386/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 81518fb..a03055f 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
@@ -19,7 +19,6 @@ package com.cloud.network.ovs;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
-import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 
 import javax.ejb.Local;
@@ -61,7 +60,6 @@ import com.cloud.network.ovs.dao.OvsTunnelInterfaceVO;
 import com.cloud.network.ovs.dao.OvsTunnelNetworkDao;
 import com.cloud.network.ovs.dao.OvsTunnelNetworkVO;
 import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.concurrency.NamedThreadFactory;
 import com.cloud.utils.db.DB;
 import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.vm.DomainRouterVO;
@@ -79,32 +77,94 @@ import com.cloud.vm.dao.UserVmDao;
 public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManager {
     public static final Logger s_logger = Logger.getLogger(OvsTunnelManagerImpl.class.getName());
 
-    boolean _isEnabled;
-    ScheduledExecutorService _executorPool;
+	// boolean _isEnabled;
+	ScheduledExecutorService _executorPool;
     ScheduledExecutorService _cleanupExecutor;
 
-    @Inject
-    ConfigurationDao _configDao;
-    @Inject
-    NicDao _nicDao;
-    @Inject
-    HostDao _hostDao;
-    @Inject
-    PhysicalNetworkTrafficTypeDao _physNetTTDao;
-    @Inject
-    UserVmDao _userVmDao;
-    @Inject
-    DomainRouterDao _routerDao;
-    @Inject
-    OvsTunnelNetworkDao _tunnelNetworkDao;
-    @Inject
-    OvsTunnelInterfaceDao _tunnelInterfaceDao;
-    @Inject
-    AgentManager _agentMgr;
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        _isEnabled = Boolean.parseBoolean(_configDao.getValue(Config.OvsTunnelNetwork.key()));
+	@Inject ConfigurationDao _configDao;
+	@Inject NicDao _nicDao;
+	@Inject HostDao _hostDao;
+	@Inject PhysicalNetworkTrafficTypeDao _physNetTTDao;
+	@Inject UserVmDao _userVmDao;
+	@Inject DomainRouterDao _routerDao;
+	@Inject OvsTunnelNetworkDao _tunnelNetworkDao;
+	@Inject OvsTunnelInterfaceDao _tunnelInterfaceDao;
+	@Inject AgentManager _agentMgr;
+
+	@Override
+	public boolean configure(String name, Map<String, Object> params)
+			throws ConfigurationException {
+		// _isEnabled =
+		// Boolean.parseBoolean(_configDao.getValue(Config.OvsTunnelNetwork.key()));
+		//
+		// if (_isEnabled) {
+		// _executorPool = Executors.newScheduledThreadPool(10, new
+		// NamedThreadFactory("OVS"));
+		// _cleanupExecutor = Executors.newScheduledThreadPool(1, new
+		// NamedThreadFactory("OVS-Cleanup"));
+		// }
+
+		return true;
+	}
+
+	@DB
+	protected OvsTunnelNetworkVO createTunnelRecord(long from, long to, long networkId, int key) {
+		OvsTunnelNetworkVO ta = null;
+		try {
+			ta = new OvsTunnelNetworkVO(from, to, key, networkId);
+			OvsTunnelNetworkVO lock =
+					_tunnelNetworkDao.acquireInLockTable(Long.valueOf(1));
+			if (lock == null) {
+			    s_logger.warn("Cannot lock table ovs_tunnel_account");
+			    return null;
+			}
+			_tunnelNetworkDao.persist(ta);
+			_tunnelNetworkDao.releaseFromLockTable(lock.getId());
+		} catch (EntityExistsException e) {
+			s_logger.debug("A record for the tunnel from " + from +
+						   " to " + to + " already exists");
+		}
+		return ta;
+	}
+
+	@DB
+	protected OvsTunnelInterfaceVO createInterfaceRecord(String ip,
+			String netmask,String mac,long hostId, String label) {
+		OvsTunnelInterfaceVO ti = null;
+		try {
+			ti = new OvsTunnelInterfaceVO(ip, netmask, mac, hostId, label);
+			//TODO: Is locking really necessary here?
+			OvsTunnelInterfaceVO lock =
+					_tunnelInterfaceDao.acquireInLockTable(Long.valueOf(1));
+			if (lock == null) {
+			    s_logger.warn("Cannot lock table ovs_tunnel_account");
+			    return null;
+			}
+			_tunnelInterfaceDao.persist(ti);
+			_tunnelInterfaceDao.releaseFromLockTable(lock.getId());
+		} catch (EntityExistsException e) {
+			s_logger.debug("A record for the interface for network " + label +
+					       " on host id " + hostId + " already exists");
+		}
+		return ti;
+	}
+
+	private String handleFetchInterfaceAnswer(Answer[] answers, Long hostId){
+		OvsFetchInterfaceAnswer ans = (OvsFetchInterfaceAnswer) answers[0];
+		if (ans.getResult()) {
+			if (ans.getIp() != null &&
+				!("".equals(ans.getIp()))) {
+				OvsTunnelInterfaceVO ti =
+						createInterfaceRecord(ans.getIp(), ans.getNetmask(),
+											  ans.getMac(), hostId, ans.getLabel());
+				return ti.getIp();
+			}
+		}
+		// Fetch interface failed!
+	    s_logger.warn("Unable to fetch the IP address for the GRE tunnel endpoint" +
+	    			  ans.getDetails());
+		return null;
+	}
 
         if (_isEnabled) {
             _executorPool = Executors.newScheduledThreadPool(10, new NamedThreadFactory("OVS"));
@@ -174,47 +234,61 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
         long networkId = r.getNetworkId();
         OvsTunnelNetworkVO tunnel = _tunnelNetworkDao.getByFromToNetwork(from, to, networkId);
         if (tunnel == null) {
-            throw new CloudRuntimeException(String.format("Unable find tunnelNetwork record" + "(from=%1$s,to=%2$s, account=%3$s", from, to, networkId));
-        }
-        if (!r.getResult()) {
-            tunnel.setState("FAILED");
-            s_logger.warn("Create GRE tunnel failed due to " + r.getDetails() + s);
-        } else {
-            tunnel.setState("SUCCESS");
-            tunnel.setPortName(r.getInPortName());
-            s_logger.warn("Create GRE tunnel " + r.getDetails() + s);
-        }
-        _tunnelNetworkDao.update(tunnel.getId(), tunnel);
-    }
-
-    private String getGreEndpointIP(Host host, Network nw) throws AgentUnavailableException, OperationTimedoutException {
-        String endpointIp = null;
-        // Fetch fefault name for network label from configuration
-        String physNetLabel = _configDao.getValue(Config.OvsTunnelNetworkDefaultLabel.key());
+            throw new CloudRuntimeException(
+            		String.format("Unable find tunnelNetwork record" +
+            					  "(from=%1$s,to=%2$s, account=%3$s",
+            					  from, to, networkId));
+		}
+		if (!r.getResult()) {
+		    tunnel.setState("FAILED");
+			s_logger.warn("Create GRE tunnel failed due to " +
+					r.getDetails() + s);
+		} else {
+		    tunnel.setState("SUCCESS");
+		    tunnel.setPortName(r.getInPortName());
+		    s_logger.warn("Create GRE tunnel " +
+		    		r.getDetails() + s);
+		}
+		_tunnelNetworkDao.update(tunnel.getId(), tunnel);
+	}
+
+	private String getGreEndpointIP(Host host, Network nw) throws
+		AgentUnavailableException, OperationTimedoutException {
+		String endpointIp = null;
+		// Fetch fefault name for network label from configuration
+		String physNetLabel = _configDao.getValue(Config.OvsTunnelNetworkDefaultLabel.key());
         Long physNetId = nw.getPhysicalNetworkId();
-        PhysicalNetworkTrafficType physNetTT = _physNetTTDao.findBy(physNetId, TrafficType.Guest);
+        PhysicalNetworkTrafficType physNetTT =
+        		_physNetTTDao.findBy(physNetId, TrafficType.Guest);
         HypervisorType hvType = host.getHypervisorType();
 
         switch (hvType) {
-            case XenServer:
-                String label = physNetTT.getXenNetworkLabel();
-                if ((label != null) && (!label.equals(""))) {
-                    physNetLabel = label;
-                }
-                break;
-            default:
-                throw new CloudRuntimeException("Hypervisor " + hvType.toString() + " unsupported by OVS Tunnel Manager");
+        	case XenServer:
+        		String label = physNetTT.getXenNetworkLabel();
+        		if ((label!=null) && (!label.equals(""))) {
+        			physNetLabel = label;
+        		}
+        		break;
+        	default:
+        		throw new CloudRuntimeException("Hypervisor " +
+        				hvType.toString() +
+        				" unsupported by OVS Tunnel Manager");
         }
 
         // Try to fetch GRE endpoint IP address for cloud db
         // If not found, then find it on the hypervisor
-        OvsTunnelInterfaceVO tunnelIface = _tunnelInterfaceDao.getByHostAndLabel(host.getId(), physNetLabel);
+        OvsTunnelInterfaceVO tunnelIface =
+                _tunnelInterfaceDao.getByHostAndLabel(host.getId(),
+                        physNetLabel);
         if (tunnelIface == null) {
             //Now find and fetch configuration for physical interface
-            //for network with label on target host
-            Commands fetchIfaceCmds = new Commands(new OvsFetchInterfaceCommand(physNetLabel));
-            s_logger.debug("Ask host " + host.getId() + " to retrieve interface for phy net with label:" + physNetLabel);
-            Answer[] fetchIfaceAnswers = _agentMgr.send(host.getId(), fetchIfaceCmds);
+        	//for network with label on target host
+			Commands fetchIfaceCmds =
+					new Commands(new OvsFetchInterfaceCommand(physNetLabel));
+			s_logger.debug("Ask host " + host.getId() +
+						   " to retrieve interface for phy net with label:" +
+						   physNetLabel);
+			Answer[] fetchIfaceAnswers = _agentMgr.send(host.getId(), fetchIfaceCmds);
             //And finally save it for future use
             endpointIp = handleFetchInterfaceAnswer(fetchIfaceAnswers, host.getId());
         } else {
@@ -223,51 +297,59 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
         return endpointIp;
     }
 
-    private int getGreKey(Network network) {
-        int key = 0;
-        try {
-            //The GRE key is actually in the host part of the URI
+	private int getGreKey(Network network) {
+		int key = 0;
+		try {
+		//The GRE key is actually in the host part of the URI
             // this is not true for lswitch/NiciraNvp!
             String keyStr = BroadcastDomainType.getValue(network.getBroadcastUri());
             // The key is most certainly and int if network is a vlan.
             // !! not in the case of lswitch/pvlan/(possibly)vswitch
             // So we now feel quite safe in converting it into a string
             // by calling the appropriate BroadcastDomainType method
-            key = Integer.valueOf(keyStr);
-            return key;
-        } catch (NumberFormatException e) {
-            s_logger.debug("Well well, how did '" + key + "' end up in the broadcast URI for the network?");
-            throw new CloudRuntimeException(String.format("Invalid GRE key parsed from" + "network broadcast URI (%s)", network.getBroadcastUri().toString()));
-        }
-    }
-
-    @DB
+    		key = Integer.valueOf(keyStr);
+    		return key;
+		} catch (NumberFormatException e) {
+			s_logger.debug("Well well, how did '" + key +
+					       "' end up in the broadcast URI for the network?");
+			throw new CloudRuntimeException(
+					String.format("Invalid GRE key parsed from" +
+							"network broadcast URI (%s)",
+							network.getBroadcastUri().toString()));
+		}
+	}
+
+	@DB
     protected void CheckAndCreateTunnel(VirtualMachine instance, Network nw, DeployDestination dest) {
-        if (!_isEnabled) {
-            return;
-        }
-
-        s_logger.debug("Creating tunnels with OVS tunnel manager");
-        if (instance.getType() != VirtualMachine.Type.User && instance.getType() != VirtualMachine.Type.DomainRouter) {
-            s_logger.debug("Will not work if you're not" + "an instance or a virtual router");
-            return;
-        }
-
-        long hostId = dest.getHost().getId();
-        int key = getGreKey(nw);
-        // Find active VMs with a NIC on the target network
-        List<UserVmVO> vms = _userVmDao.listByNetworkIdAndStates(nw.getId(), State.Running, State.Starting, State.Stopping, State.Unknown, State.Migrating);
-        // Find routers for the network
-        List<DomainRouterVO> routers = _routerDao.findByNetwork(nw.getId());
-        List<VMInstanceVO> ins = new ArrayList<VMInstanceVO>();
-        if (vms != null) {
-            ins.addAll(vms);
-        }
-        if (routers.size() != 0) {
-            ins.addAll(routers);
-        }
-        List<Long> toHostIds = new ArrayList<Long>();
-        List<Long> fromHostIds = new ArrayList<Long>();
+		// if (!_isEnabled) {
+		// return;
+		// }
+
+		s_logger.debug("Creating tunnels with OVS tunnel manager");
+		if (instance.getType() != VirtualMachine.Type.User
+				&& instance.getType() != VirtualMachine.Type.DomainRouter) {
+			s_logger.debug("Will not work if you're not" +
+						   "an instance or a virtual router");
+			return;
+		}
+
+		long hostId = dest.getHost().getId();
+		int key = getGreKey(nw);
+		// Find active VMs with a NIC on the target network
+		List<UserVmVO> vms = _userVmDao.listByNetworkIdAndStates(nw.getId(),
+							  State.Running, State.Starting,
+							  State.Stopping, State.Unknown, State.Migrating);
+		// Find routers for the network
+		List<DomainRouterVO> routers = _routerDao.findByNetwork(nw.getId());
+		List<VMInstanceVO>ins = new ArrayList<VMInstanceVO>();
+		if (vms != null) {
+			ins.addAll(vms);
+		}
+		if (routers.size() != 0) {
+			ins.addAll(routers);
+		}
+		List<Long> toHostIds = new ArrayList<Long>();
+		List<Long> fromHostIds = new ArrayList<Long>();
         for (VMInstanceVO v : ins) {
             Long rh = v.getHostId();
             if (rh == null || rh.longValue() == hostId) {
@@ -285,13 +367,16 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
                 }
             }
 
-            ta = _tunnelNetworkDao.getByFromToNetwork(rh.longValue(), hostId, nw.getId());
+            ta = _tunnelNetworkDao.getByFromToNetwork(rh.longValue(),
+            		hostId, nw.getId());
             // Try and create the tunnel even if a previous attempt failed
             if (ta == null || ta.getState().equals("FAILED")) {
-                s_logger.debug("Attempting to create tunnel from:" + rh.longValue() + " to:" + hostId);
-                if (ta == null) {
-                    this.createTunnelRecord(rh.longValue(), hostId, nw.getId(), key);
-                }
+            	s_logger.debug("Attempting to create tunnel from:" +
+            			rh.longValue() + " to:" + hostId);
+            	if (ta == null) {
+            		this.createTunnelRecord(rh.longValue(), hostId,
+            				nw.getId(), key);
+            	}
                 if (!fromHostIds.contains(rh)) {
                     fromHostIds.add(rh);
                 }
@@ -303,48 +388,62 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
             if (myIp == null)
                 throw new GreTunnelException("Unable to retrieve the source " + "endpoint for the GRE tunnel." + "Failure is on host:" + dest.getHost().getId());
             boolean noHost = true;
-            for (Long i : toHostIds) {
-                HostVO rHost = _hostDao.findById(i);
-                String otherIp = getGreEndpointIP(rHost, nw);
-                if (otherIp == null)
-                    throw new GreTunnelException("Unable to retrieve the remote " + "endpoint for the GRE tunnel." + "Failure is on host:" + rHost.getId());
-                Commands cmds = new Commands(new OvsCreateTunnelCommand(otherIp, key, Long.valueOf(hostId), i, nw.getId(), myIp));
-                s_logger.debug("Ask host " + hostId + " to create gre tunnel to " + i);
-                Answer[] answers = _agentMgr.send(hostId, cmds);
-                handleCreateTunnelAnswer(answers);
-                noHost = false;
-            }
-
-            for (Long i : fromHostIds) {
-                HostVO rHost = _hostDao.findById(i);
-                String otherIp = getGreEndpointIP(rHost, nw);
-                Commands cmds = new Commands(new OvsCreateTunnelCommand(myIp, key, i, Long.valueOf(hostId), nw.getId(), otherIp));
-                s_logger.debug("Ask host " + i + " to create gre tunnel to " + hostId);
-                Answer[] answers = _agentMgr.send(i, cmds);
-                handleCreateTunnelAnswer(answers);
-                noHost = false;
-            }
-            // If no tunnels have been configured, perform the bridge setup anyway
-            // This will ensure VIF rules will be triggered
-            if (noHost) {
-                Commands cmds = new Commands(new OvsSetupBridgeCommand(key, hostId, nw.getId()));
-                s_logger.debug("Ask host " + hostId + " to configure bridge for network:" + nw.getId());
-                Answer[] answers = _agentMgr.send(hostId, cmds);
-                handleSetupBridgeAnswer(answers);
-            }
-        } catch (Exception e) {
-            // I really thing we should do a better handling of these exceptions
-            s_logger.warn("Ovs Tunnel network created tunnel failed", e);
-        }
-    }
+			for (Long i : toHostIds) {
+				HostVO rHost = _hostDao.findById(i);
+				String otherIp = getGreEndpointIP(rHost, nw);
+	            if (otherIp == null)
+	            	throw new GreTunnelException("Unable to retrieve the remote " +
+	            								 "endpoint for the GRE tunnel." +
+	            								 "Failure is on host:" + rHost.getId());
+				Commands cmds = new Commands(
+						new OvsCreateTunnelCommand(otherIp, key,
+								Long.valueOf(hostId), i, nw.getId(), myIp));
+				s_logger.debug("Ask host " + hostId +
+						" to create gre tunnel to " + i);
+				Answer[] answers = _agentMgr.send(hostId, cmds);
+				handleCreateTunnelAnswer(answers);
+				noHost = false;
+			}
+
+			for (Long i : fromHostIds) {
+			    HostVO rHost = _hostDao.findById(i);
+			    String otherIp = getGreEndpointIP(rHost, nw);
+				Commands cmds = new Commands(
+				        new OvsCreateTunnelCommand(myIp, key, i,
+				        						   Long.valueOf(hostId),
+				        		                   nw.getId(), otherIp));
+				s_logger.debug("Ask host " + i +
+						" to create gre tunnel to " + hostId);
+				Answer[] answers = _agentMgr.send(i, cmds);
+				handleCreateTunnelAnswer(answers);
+				noHost = false;
+			}
+			// If no tunnels have been configured, perform the bridge setup anyway
+			// This will ensure VIF rules will be triggered
+			if (noHost) {
+				Commands cmds = new Commands(
+						new OvsSetupBridgeCommand(key, hostId, nw.getId()));
+				s_logger.debug("Ask host " + hostId +
+						" to configure bridge for network:" + nw.getId());
+				Answer[] answers = _agentMgr.send(hostId, cmds);
+				handleSetupBridgeAnswer(answers);
+			}
+		} catch (Exception e) {
+		    // I really thing we should do a better handling of these exceptions
+			s_logger.warn("Ovs Tunnel network created tunnel failed", e);
+		}
+	}
+
+	@Override
+	public boolean isOvsTunnelEnabled() {
+		// return _isEnabled;
+		return true;
+	}
 
     @Override
-    public boolean isOvsTunnelEnabled() {
-        return _isEnabled;
-    }
-
-    @Override
-    public void VmCheckAndCreateTunnel(VirtualMachineProfile vm, Network nw, DeployDestination dest) {
+    public void VmCheckAndCreateTunnel(
+    		VirtualMachineProfile<? extends VirtualMachine> vm,
+    		Network nw, DeployDestination dest) {
         CheckAndCreateTunnel(vm.getVirtualMachine(), nw, dest);
     }
 
@@ -353,22 +452,27 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
         if (ans.getResult()) {
             OvsTunnelNetworkVO lock = _tunnelNetworkDao.acquireInLockTable(Long.valueOf(1));
             if (lock == null) {
-                s_logger.warn(String.format("failed to lock" + "ovs_tunnel_account, remove record of " + "tunnel(from=%1$s, to=%2$s account=%3$s) failed", from, to,
-                    network_id));
+                s_logger.warn(String.format("failed to lock" +
+                		"ovs_tunnel_account, remove record of " +
+                         "tunnel(from=%1$s, to=%2$s account=%3$s) failed",
+                         from, to, network_id));
                 return;
             }
 
             _tunnelNetworkDao.removeByFromToNetwork(from, to, network_id);
             _tunnelNetworkDao.releaseFromLockTable(lock.getId());
 
-            s_logger.debug(String.format("Destroy tunnel(account:%1$s," + "from:%2$s, to:%3$s) successful", network_id, from, to));
+            s_logger.debug(String.format("Destroy tunnel(account:%1$s," +
+            		"from:%2$s, to:%3$s) successful",
+            		network_id, from, to));
         } else {
             s_logger.debug(String.format("Destroy tunnel(account:%1$s," + "from:%2$s, to:%3$s) failed", network_id, from, to));
         }
     }
 
     @DB
-    private void handleDestroyBridgeAnswer(Answer ans, long host_id, long network_id) {
+    private void handleDestroyBridgeAnswer(Answer ans,
+    		long host_id, long network_id) {
 
         if (ans.getResult()) {
             OvsTunnelNetworkVO lock = _tunnelNetworkDao.acquireInLockTable(Long.valueOf(1));
@@ -380,9 +484,11 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
             _tunnelNetworkDao.removeByFromNetwork(host_id, network_id);
             _tunnelNetworkDao.releaseFromLockTable(lock.getId());
 
-            s_logger.debug(String.format("Destroy bridge for" + "network %1$s successful", network_id));
+            s_logger.debug(String.format("Destroy bridge for" +
+            		"network %1$s successful", network_id));
         } else {
-            s_logger.debug(String.format("Destroy bridge for" + "network %1$s failed", network_id));
+        	s_logger.debug(String.format("Destroy bridge for" +
+        			"network %1$s failed", network_id));
         }
     }
 
@@ -393,9 +499,9 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
 
     @Override
     public void CheckAndDestroyTunnel(VirtualMachine vm, Network nw) {
-        if (!_isEnabled) {
-            return;
-        }
+		// if (!_isEnabled) {
+		// return;
+		// }
 
         List<UserVmVO> userVms = _userVmDao.listByAccountIdAndHostId(vm.getAccountId(), vm.getHostId());
         if (vm.getType() == VirtualMachine.Type.User) {
@@ -422,15 +528,20 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
             handleDestroyBridgeAnswer(ans, vm.getHostId(), nw.getId());
 
             /* Then ask hosts have peer tunnel with me to destroy them */
-            List<OvsTunnelNetworkVO> peers = _tunnelNetworkDao.listByToNetwork(vm.getHostId(), nw.getId());
+            List<OvsTunnelNetworkVO> peers =
+            		_tunnelNetworkDao.listByToNetwork(vm.getHostId(),
+            				nw.getId());
             for (OvsTunnelNetworkVO p : peers) {
-                // If the tunnel was not successfully created don't bother to remove it
-                if (p.getState().equals("SUCCESS")) {
-                    cmd = new OvsDestroyTunnelCommand(p.getNetworkId(), key, p.getPortName());
-                    s_logger.debug("Destroying tunnel to " + vm.getHostId() + " from " + p.getFrom());
-                    ans = _agentMgr.send(p.getFrom(), cmd);
-                    handleDestroyTunnelAnswer(ans, p.getFrom(), p.getTo(), p.getNetworkId());
-                }
+            	// If the tunnel was not successfully created don't bother to remove it
+            	if (p.getState().equals("SUCCESS")) {
+	                cmd = new OvsDestroyTunnelCommand(p.getNetworkId(), key,
+	                		p.getPortName());
+	                s_logger.debug("Destroying tunnel to " + vm.getHostId() +
+	                		" 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(account:%1$s," + "hostId:%2$s) failed", vm.getAccountId(), vm.getHostId()), e);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d935d386/scripts/vm/hypervisor/xenserver/ovstunnel
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/xenserver/ovstunnel b/scripts/vm/hypervisor/xenserver/ovstunnel
index a4760b2..2b26ed6 100755
--- a/scripts/vm/hypervisor/xenserver/ovstunnel
+++ b/scripts/vm/hypervisor/xenserver/ovstunnel
@@ -271,17 +271,23 @@ def is_xcp(session, args):
     return platform
 
 def getLabel(session, args):
+    i = 0
     pif_list_cmd = [lib.XE_PATH, 'pif-list', '--minimal']
     pif_list_str = lib.do_cmd(pif_list_cmd)
-    pif_uuid = pif_list_str.split(',')[0].strip()
-    network_cmd = [lib.XE_PATH, 'pif-param-get', 'uuid=%s' % pif_uuid,
-                               'param-name=network-uuid']
-    network_uuid = lib.do_cmd(network_cmd).split('.')[0]
-
-    label_cmd = [lib.XE_PATH, 'network-param-get', 'uuid=%s' % network_uuid,
-                               'param-name=name-label']
-    label = lib.do_cmd(label_cmd).split('.')[0]
-    return label
+    while True:
+		pif_uuid = pif_list_str.split(',')[i].strip()
+		network_cmd = [lib.XE_PATH, 'pif-param-get', 'uuid=%s' % pif_uuid, 'param-name=network-uuid']
+		network_uuid = lib.do_cmd(network_cmd).split('.')[0]
+		iface_cmd = [lib.XE_PATH, 'network-param-get', 'uuid=%s' % network_uuid, 'param-name=bridge']
+		iface = lib.do_cmd(iface_cmd)
+		status,output = commands.getstatusoutput("ifconfig "+iface+" | grep inet")
+		if (status != 0):
+			i += 1
+			continue
+    	label_cmd = [lib.XE_PATH, 'network-param-get', 'uuid=%s' % network_uuid, 'param-name=name-label']
+    	label = lib.do_cmd(label_cmd).split('.')[0]
+    	return label
+    return False
 
 if __name__ == "__main__":
     XenAPIPlugin.dispatch({"create_tunnel": create_tunnel,

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d935d386/scripts/vm/hypervisor/xenserver/vhd-util
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/xenserver/vhd-util b/scripts/vm/hypervisor/xenserver/vhd-util
new file mode 100755
index 0000000..46d62dd
Binary files /dev/null and b/scripts/vm/hypervisor/xenserver/vhd-util differ

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d935d386/server/src/com/cloud/api/ApiResponseHelper.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java
index 9700b26..c2a0491 100755
--- a/server/src/com/cloud/api/ApiResponseHelper.java
+++ b/server/src/com/cloud/api/ApiResponseHelper.java
@@ -89,6 +89,7 @@ import org.apache.cloudstack.api.response.NetworkOfferingResponse;
 import org.apache.cloudstack.api.response.NetworkResponse;
 import org.apache.cloudstack.api.response.NicResponse;
 import org.apache.cloudstack.api.response.NicSecondaryIpResponse;
+import org.apache.cloudstack.api.response.OvsProviderResponse;
 import org.apache.cloudstack.api.response.PhysicalNetworkResponse;
 import org.apache.cloudstack.api.response.PodResponse;
 import org.apache.cloudstack.api.response.PortableIpRangeResponse;
@@ -206,6 +207,7 @@ import com.cloud.network.NetworkProfile;
 import com.cloud.network.Networks.BroadcastDomainType;
 import com.cloud.network.Networks.IsolationType;
 import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.OvsProvider;
 import com.cloud.network.PhysicalNetwork;
 import com.cloud.network.PhysicalNetworkServiceProvider;
 import com.cloud.network.PhysicalNetworkTrafficType;
@@ -270,6 +272,7 @@ import com.cloud.storage.Snapshot;
 import com.cloud.storage.SnapshotVO;
 import com.cloud.storage.Storage.StoragePoolType;
 import com.cloud.storage.StoragePool;
+import com.cloud.storage.Swift;
 import com.cloud.storage.Upload;
 import com.cloud.storage.UploadVO;
 import com.cloud.storage.VMTemplateVO;
@@ -2726,6 +2729,22 @@ public class ApiResponseHelper implements ResponseGenerator {
         return response;
     }
 
+	@Override
+	public OvsProviderResponse createOvsProviderResponse(OvsProvider result) {
+
+		OvsProviderResponse response = new OvsProviderResponse();
+		response.setId(result.getUuid());
+		PhysicalNetworkServiceProvider nsp = ApiDBUtils
+				.findPhysicalNetworkServiceProviderById(result.getNspId());
+		if (nsp != null) {
+			response.setNspId(nsp.getUuid());
+		}
+		response.setEnabled(result.isEnabled());
+
+		response.setObjectName("ovselement");
+		return response;
+	}
+
     @Override
     public LBStickinessResponse createLBStickinessPolicyResponse(StickinessPolicy stickinessPolicy, LoadBalancer lb) {
         LBStickinessResponse spResponse = new LBStickinessResponse();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d935d386/server/src/com/cloud/network/NetworkServiceImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java b/server/src/com/cloud/network/NetworkServiceImpl.java
index 6855587..c24b650 100755
--- a/server/src/com/cloud/network/NetworkServiceImpl.java
+++ b/server/src/com/cloud/network/NetworkServiceImpl.java
@@ -19,6 +19,7 @@ package com.cloud.network;
 import java.net.Inet6Address;
 import java.net.InetAddress;
 import java.net.URI;
+
 import java.net.UnknownHostException;
 import java.security.InvalidParameterException;
 import java.sql.PreparedStatement;
@@ -109,6 +110,7 @@ import com.cloud.network.dao.NetworkDomainDao;
 import com.cloud.network.dao.NetworkDomainVO;
 import com.cloud.network.dao.NetworkServiceMapDao;
 import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.dao.OvsProviderDao;
 import com.cloud.network.dao.PhysicalNetworkDao;
 import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
 import com.cloud.network.dao.PhysicalNetworkServiceProviderVO;
@@ -116,6 +118,7 @@ import com.cloud.network.dao.PhysicalNetworkTrafficTypeDao;
 import com.cloud.network.dao.PhysicalNetworkTrafficTypeVO;
 import com.cloud.network.dao.PhysicalNetworkVO;
 import com.cloud.network.element.NetworkElement;
+import com.cloud.network.element.OvsProviderVO;
 import com.cloud.network.element.VirtualRouterElement;
 import com.cloud.network.element.VpcVirtualRouterElement;
 import com.cloud.network.guru.NetworkGuru;
@@ -298,10 +301,8 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
     VpcDao _vpcDao;
     @Inject
     NetworkACLDao _networkACLDao;
-    @Inject
-    IpAddressManager _ipAddrMgr;
-    @Inject
-    EntityManager _entityMgr;
+	@Inject
+	OvsProviderDao _ovsProviderDao;
 
     int _cidrLimit;
     boolean _allowSubdomainNetworkAccess;
@@ -2511,6 +2512,9 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
                     // add VirtualRouter as the default network service provider
                     addDefaultVirtualRouterToPhysicalNetwork(pNetwork.getId());
 
+                    if (pNetwork.getIsolationMethods().contains("GRE"))
+                        addDefaultOvsToPhysicalNetwork(pNetwork.getId());
+
                     // add security group provider to the physical network
                     addDefaultSecurityGroupProviderToPhysicalNetwork(pNetwork.getId());
 
@@ -2532,7 +2536,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
         }
     }
 
-    @Override
+	@Override
     public Pair<List<? extends PhysicalNetwork>, Integer> searchPhysicalNetworks(Long id, Long zoneId, String keyword, Long startIndex, Long pageSize, String name) {
         Filter searchFilter = new Filter(PhysicalNetworkVO.class, "id", Boolean.TRUE, startIndex, pageSize);
         SearchCriteria<PhysicalNetworkVO> sc = _physicalNetworkDao.createSearchCriteria();
@@ -3756,6 +3760,23 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
         return nsp;
     }
 
+	private PhysicalNetworkServiceProvider addDefaultOvsToPhysicalNetwork(long physicalNetworkId) {
+		PhysicalNetworkServiceProvider nsp = addProviderToPhysicalNetwork(physicalNetworkId, Network.Provider.Ovs.getName(), null, null);
+		NetworkElement networkElement = _networkModel.getElementImplementingProvider(Network.Provider.Ovs.getName());
+		if (networkElement == null) {
+            throw new CloudRuntimeException("Unable to find the Network Element implementing the Ovs Provider");
+        }
+		OvsProviderVO element = _ovsProviderDao.findByNspId(nsp.getId());
+		if (element != null) {
+			s_logger.debug("There is already a Ovs element with service provider id "
+					+ nsp.getId());
+			return nsp;
+		}
+		element = new OvsProviderVO(nsp.getId());
+		_ovsProviderDao.persist(element);
+		return nsp;
+	}
+
     protected PhysicalNetworkServiceProvider addDefaultVpcVirtualRouterToPhysicalNetwork(long physicalNetworkId) {
 
         PhysicalNetworkServiceProvider nsp = addProviderToPhysicalNetwork(physicalNetworkId, Network.Provider.VPCVirtualRouter.getName(), null, null);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d935d386/server/src/com/cloud/network/element/VirtualRouterElement.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/element/VirtualRouterElement.java b/server/src/com/cloud/network/element/VirtualRouterElement.java
index bcd4ce2..923094b 100755
--- a/server/src/com/cloud/network/element/VirtualRouterElement.java
+++ b/server/src/com/cloud/network/element/VirtualRouterElement.java
@@ -29,8 +29,10 @@ import org.apache.log4j.Logger;
 
 import com.google.gson.Gson;
 
+import org.apache.cloudstack.api.command.admin.router.ConfigureOvsElementCmd;
 import org.apache.cloudstack.api.command.admin.router.ConfigureVirtualRouterElementCmd;
 import org.apache.cloudstack.api.command.admin.router.CreateVirtualRouterElementCmd;
+import org.apache.cloudstack.api.command.admin.router.ListOvsElementsCmd;
 import org.apache.cloudstack.api.command.admin.router.ListVirtualRouterElementsCmd;
 import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
 
@@ -53,6 +55,7 @@ import com.cloud.network.NetworkMigrationResponder;
 import com.cloud.network.NetworkModel;
 import com.cloud.network.Networks;
 import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.OvsProvider;
 import com.cloud.network.PhysicalNetworkServiceProvider;
 import com.cloud.network.PublicIpAddress;
 import com.cloud.network.RemoteAccessVpn;
@@ -62,6 +65,7 @@ import com.cloud.network.VpnUser;
 import com.cloud.network.dao.IPAddressDao;
 import com.cloud.network.dao.LoadBalancerDao;
 import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.OvsProviderDao;
 import com.cloud.network.dao.VirtualRouterProviderDao;
 import com.cloud.network.lb.LoadBalancingRule;
 import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy;
@@ -96,10 +100,16 @@ import com.cloud.vm.VirtualMachineProfile;
 import com.cloud.vm.dao.DomainRouterDao;
 import com.cloud.vm.dao.UserVmDao;
 
-@Local(value = {NetworkElement.class, FirewallServiceProvider.class, DhcpServiceProvider.class, UserDataServiceProvider.class, StaticNatServiceProvider.class,
-    LoadBalancingServiceProvider.class, PortForwardingServiceProvider.class, IpDeployer.class, RemoteAccessVPNServiceProvider.class, NetworkMigrationResponder.class})
-public class VirtualRouterElement extends AdapterBase implements VirtualRouterElementService, DhcpServiceProvider, UserDataServiceProvider, SourceNatServiceProvider,
-        StaticNatServiceProvider, FirewallServiceProvider, LoadBalancingServiceProvider, PortForwardingServiceProvider, RemoteAccessVPNServiceProvider, IpDeployer,
+import com.google.gson.Gson;
+
+@Local(value = {NetworkElement.class, FirewallServiceProvider.class,
+		        DhcpServiceProvider.class, UserDataServiceProvider.class,
+		        StaticNatServiceProvider.class, LoadBalancingServiceProvider.class,
+		        PortForwardingServiceProvider.class, IpDeployer.class,
+		        RemoteAccessVPNServiceProvider.class, NetworkMigrationResponder.class} )
+public class VirtualRouterElement extends AdapterBase implements VirtualRouterElementService, DhcpServiceProvider,
+    UserDataServiceProvider, SourceNatServiceProvider, StaticNatServiceProvider, FirewallServiceProvider,
+        LoadBalancingServiceProvider, PortForwardingServiceProvider, RemoteAccessVPNServiceProvider, IpDeployer,
         NetworkMigrationResponder {
     private static final Logger s_logger = Logger.getLogger(VirtualRouterElement.class);
 
@@ -137,6 +147,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl
     @Inject
     VirtualRouterProviderDao _vrProviderDao;
     @Inject
+	OvsProviderDao _ovsProviderDao;
+	@Inject
     IPAddressDao _ipAddressDao;
 
     protected boolean canHandle(Network network, Service service) {
@@ -712,6 +724,21 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl
         return element;
     }
 
+	@Override
+	public OvsProvider configure(ConfigureOvsElementCmd cmd) {
+		OvsProviderVO element = _ovsProviderDao.findById(cmd.getId());
+		if (element == null) {
+			s_logger.debug("Can't find Ovs element with network service provider id "
+					+ cmd.getId());
+			return null;
+		}
+
+		element.setEnabled(cmd.getEnabled());
+		_ovsProviderDao.persist(element);
+
+		return element;
+	}
+
     @Override
     public VirtualRouterProvider addElement(Long nspId, Type providerType) {
         if (!(providerType == Type.VirtualRouter || providerType == Type.VPCVirtualRouter)) {
@@ -942,20 +969,42 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl
         return sc.list();
     }
 
+	@Override
+	public List<? extends OvsProvider> searchForOvsElement(
+			ListOvsElementsCmd cmd) {
+		Long id = cmd.getId();
+		Long nspId = cmd.getNspId();
+		Boolean enabled = cmd.getEnabled();
+
+		SearchCriteriaService<OvsProviderVO, OvsProviderVO> sc = SearchCriteria2
+				.create(OvsProviderVO.class);
+		if (id != null) {
+			sc.addAnd(sc.getEntity().getId(), Op.EQ, id);
+		}
+		if (nspId != null) {
+			sc.addAnd(sc.getEntity().getNspId(), Op.EQ, nspId);
+		}
+		if (enabled != null) {
+			sc.addAnd(sc.getEntity().isEnabled(), Op.EQ, enabled);
+		}
+
+		return sc.list();
+	}
+
     @Override
     public boolean verifyServicesCombination(Set<Service> services) {
-        if (!services.contains(Service.SourceNat)) {
-            if (services.contains(Service.StaticNat) || services.contains(Service.Firewall) || services.contains(Service.Lb) ||
-                services.contains(Service.PortForwarding) || services.contains(Service.Vpn)) {
-                String servicesList = "[";
-                for (Service service : services) {
-                    servicesList += service.getName() + " ";
-                }
-                servicesList += "]";
-                s_logger.warn("Virtual router can't enable services " + servicesList + " without source NAT service");
-                return false;
-            }
-        }
+//        if (!services.contains(Service.SourceNat)) {
+//            if (services.contains(Service.StaticNat) || services.contains(Service.Firewall) || services.contains(Service.Lb) ||
+//                    services.contains(Service.PortForwarding) || services.contains(Service.Vpn)) {
+//                String servicesList = "[";
+//                for (Service service : services) {
+//                    servicesList += service.getName() + " ";
+//                }
+//                servicesList += "]";
+//                s_logger.warn("Virtual router can't enable services " + servicesList + " without source NAT service");
+//                return false;
+//            }
+//        }
         return true;
     }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d935d386/server/src/com/cloud/server/ManagementServerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java
index c0f10aa..2b0f0b8 100755
--- a/server/src/com/cloud/server/ManagementServerImpl.java
+++ b/server/src/com/cloud/server/ManagementServerImpl.java
@@ -138,9 +138,11 @@ import org.apache.cloudstack.api.command.admin.resource.DeleteAlertsCmd;
 import org.apache.cloudstack.api.command.admin.resource.ListAlertsCmd;
 import org.apache.cloudstack.api.command.admin.resource.ListCapacityCmd;
 import org.apache.cloudstack.api.command.admin.resource.UploadCustomCertificateCmd;
+import org.apache.cloudstack.api.command.admin.router.ConfigureOvsElementCmd;
 import org.apache.cloudstack.api.command.admin.router.ConfigureVirtualRouterElementCmd;
 import org.apache.cloudstack.api.command.admin.router.CreateVirtualRouterElementCmd;
 import org.apache.cloudstack.api.command.admin.router.DestroyRouterCmd;
+import org.apache.cloudstack.api.command.admin.router.ListOvsElementsCmd;
 import org.apache.cloudstack.api.command.admin.router.ListRoutersCmd;
 import org.apache.cloudstack.api.command.admin.router.ListVirtualRouterElementsCmd;
 import org.apache.cloudstack.api.command.admin.router.RebootRouterCmd;
@@ -2864,6 +2866,8 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
         cmdList.add(AssignCertToLoadBalancerCmd.class);
         cmdList.add(RemoveCertFromLoadBalancerCmd.class);
         cmdList.add(GenerateAlertCmd.class);
+	cmdList.add(ListOvsElementsCmd.class);
+	cmdList.add(ConfigureOvsElementCmd.class);
         return cmdList;
     }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d935d386/setup/db/create-schema.sql
----------------------------------------------------------------------
diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql
index 8d3aa20..55cb4cc 100755
--- a/setup/db/create-schema.sql
+++ b/setup/db/create-schema.sql
@@ -196,7 +196,6 @@ DROP TABLE IF EXISTS `cloud`.`vm_network_map`;
 DROP TABLE IF EXISTS `cloud`.`netapp_volume`;
 DROP TABLE IF EXISTS `cloud`.`netapp_pool`;
 DROP TABLE IF EXISTS `cloud`.`netapp_lun`;
-DROP TABLE IF EXISTS `cloud`.`ovs_nic_map`;
 
 CREATE TABLE `cloud`.`version` (
   `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id',
@@ -2476,14 +2475,5 @@ CREATE TABLE `cloud`.`nicira_nvp_nic_map` (
   CONSTRAINT `fk_nicira_nvp_nic_map__nic` FOREIGN KEY(`nic`) REFERENCES `nics`(`uuid`) ON DELETE CASCADE
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
-CREATE TABLE `cloud`.`ovs_nic_map` (
-  `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
-  `logicalswitch` varchar(255) NOT NULL COMMENT 'uuid of logical switch this port is provisioned on',
-  `logicalswitchport` varchar(255) UNIQUE COMMENT 'uuid of this logical switch port',
-  `nic` varchar(255) UNIQUE COMMENT 'cloudstack uuid of the nic connected to this logical switch port',
-  PRIMARY KEY (`id`),
-  CONSTRAINT `fk_ovs_nic_map__nic` FOREIGN KEY(`nic`) REFERENCES `nics`(`uuid`) ON DELETE CASCADE
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-
 SET foreign_key_checks = 1;
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d935d386/setup/db/db/schema-410to420.sql
----------------------------------------------------------------------
diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql
index 522ccc4..6ec5723 100644
--- a/setup/db/db/schema-410to420.sql
+++ b/setup/db/db/schema-410to420.sql
@@ -2103,6 +2103,28 @@ CREATE TABLE `cloud`.`vm_disk_statistics` (
 insert into `cloud`.`vm_disk_statistics`(data_center_id,account_id,vm_id,volume_id) 
 select volumes.data_center_id, volumes.account_id, vm_instance.id, volumes.id from volumes,vm_instance where vm_instance.vm_type="User" and vm_instance.state<>"Expunging" and volumes.instance_id=vm_instance.id order by vm_instance.id;
 
+DROP TABLE IF EXISTS `cloud`.`ovs_nic_map`;
+CREATE TABLE `cloud`.`ovs_nic_map` (
+  `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
+  `logicalswitch` varchar(255) NOT NULL COMMENT 'uuid of logical switch this port is provisioned on',
+  `logicalswitchport` varchar(255) UNIQUE COMMENT 'uuid of this logical switch port',
+  `nic` varchar(255) UNIQUE COMMENT 'cloudstack uuid of the nic connected to this logical switch port',
+  PRIMARY KEY (`id`),
+  CONSTRAINT `fk_ovs_nic_map__nic` FOREIGN KEY(`nic`) REFERENCES `nics`(`uuid`) ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+DROP TABLE IF EXISTS `cloud`.`ovs_providers`;
+CREATE TABLE `cloud`.`ovs_providers` (
+  `id` bigint unsigned NOT NULL auto_increment COMMENT 'id',
+  `nsp_id` bigint unsigned NOT NULL COMMENT 'Network Service Provider ID',
+  `uuid` varchar(40),
+  `enabled` int(1) NOT NULL COMMENT 'Enabled or disabled',
+  `removed` datetime COMMENT 'date removed if not null',
+  PRIMARY KEY  (`id`),
+  CONSTRAINT `fk_ovs_providers__nsp_id` FOREIGN KEY (`nsp_id`) REFERENCES `physical_network_service_providers` (`id`) ON DELETE CASCADE,
+  CONSTRAINT `uc_ovs_providers__uuid` UNIQUE (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
 DROP TABLE IF EXISTS `cloud_usage`.`vm_disk_statistics`;
 CREATE TABLE `cloud_usage`.`vm_disk_statistics` (
   `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d935d386/tools/apidoc/gen_toc.py
----------------------------------------------------------------------
diff --git a/tools/apidoc/gen_toc.py b/tools/apidoc/gen_toc.py
index d58252c..dcf132d 100644
--- a/tools/apidoc/gen_toc.py
+++ b/tools/apidoc/gen_toc.py
@@ -160,6 +160,7 @@ known_categories = {
     'Ucs' : 'UCS',
     'CacheStores' : 'Cache Stores',
     'CacheStore' : 'Cache Store'
+    'OvsElement' : 'Ovs Element'
     }