cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bhais...@apache.org
Subject [cloudstack] branch master updated: CLOUDSTACK-10047: DVSwitch fixes and improvements (#2293)
Date Wed, 25 Oct 2017 09:44:47 GMT
This is an automated email from the ASF dual-hosted git repository.

bhaisaab pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cloudstack.git


The following commit(s) were added to refs/heads/master by this push:
     new 41fdb88  CLOUDSTACK-10047: DVSwitch fixes and improvements (#2293)
41fdb88 is described below

commit 41fdb88970d1a33d57ff08a3ecc239ec898956dc
Author: Rohit Yadav <bhaisaab@apache.org>
AuthorDate: Wed Oct 25 15:14:42 2017 +0530

    CLOUDSTACK-10047: DVSwitch fixes and improvements (#2293)
    
    Allow security policies to apply on port groups:
    - Accepts security policies while creating network offering
    - Deployed network will have security policies from the network offering
      applied on the port group (in vmware environment)
    - Global settings as fallback when security policies are not defined for a network
      offering
    - Default promiscuous mode security policy set to REJECT as it's the default
      for standard/default vswitch
    
    Portgroup vlan-trunking options for dvswitch: This allows admins to define
    a network with comma separated vlan id and vlan
    range such as vlan://200-400,21,30-50 and use the provided vlan range to
    configure vlan-trunking for a portgroup in dvswitch based environment.
    
    VLAN overlap checks are performed for:
    - isolated network against existing shared and isolated networks
    - dedicated vlan ranges for the physical/public network for the zone
    - shared network against existing isolated network
    
    Allow shared networks to bypass vlan overlap checks: This allows admins
    to create shared networks with a `bypassvlanoverlapcheck` API flag
    which when set to 'true' will create a shared network without
    performing vlan overlap checks against isolated network and against
    the vlans allocated to the datacenter's physical network (vlan ranges).
    
    Notes:
    - No vlan-range overlap checks are performed when creating shared networks
    - Multiple vlan id/ranges should include the vlan:// scheme prefix
    
    Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
---
 api/src/com/cloud/agent/api/to/NicTO.java          |  12 +
 api/src/com/cloud/network/Networks.java            |   4 +
 api/src/com/cloud/offering/NetworkOffering.java    |   2 +-
 .../org/apache/cloudstack/api/ApiConstants.java    |   1 +
 .../admin/network/CreateNetworkCmdByAdmin.java     |  10 +
 .../admin/network/CreateNetworkOfferingCmd.java    |   3 +-
 api/test/com/cloud/network/NetworksTest.java       |  19 +-
 .../service/NetworkOrchestrationService.java       |  15 +-
 .../cloud/configuration/ConfigurationManager.java  |   2 +-
 .../engine/orchestration/NetworkOrchestrator.java  |  44 ++--
 .../src/com/cloud/dc/dao/DataCenterVnetDao.java    |   4 +-
 .../com/cloud/dc/dao/DataCenterVnetDaoImpl.java    |  45 +++-
 .../src/com/cloud/network/dao/NetworkDao.java      |   4 +-
 .../src/com/cloud/network/dao/NetworkDaoImpl.java  |  54 ++--
 .../vmware/manager/VmwareManagerImpl.java          |   4 +-
 .../hypervisor/vmware/resource/VmwareResource.java |   8 +-
 .../configuration/ConfigurationManagerImpl.java    |  17 +-
 .../com/cloud/hypervisor/HypervisorGuruBase.java   |  20 +-
 .../com/cloud/network/IpAddressManagerImpl.java    |   2 +-
 .../src/com/cloud/network/NetworkServiceImpl.java  |  25 +-
 .../src/com/cloud/network/vpc/VpcManagerImpl.java  |   2 +-
 server/src/com/cloud/vm/UserVmManagerImpl.java     |   4 +-
 .../cloud/network/CreatePrivateNetworkTest.java    |   2 +-
 .../cloud/vpc/MockConfigurationManagerImpl.java    |   2 +-
 .../test/com/cloud/vpc/MockNetworkManagerImpl.java |   6 +-
 .../test/com/cloud/vpc/dao/MockNetworkDaoImpl.java |   9 +-
 ui/l10n/en.js                                      |   3 +
 ui/scripts/configuration.js                        |  80 ++++++
 utils/src/main/java/com/cloud/utils/UriUtils.java  |  50 ++++
 .../test/java/com/cloud/utils/UriUtilsTest.java    |  46 +++-
 vmware-base/pom.xml                                |   5 +
 .../hypervisor/vmware/mo/HypervisorHostHelper.java | 283 ++++++++++++++++-----
 .../vmware/mo/HypervisorHostHelperTest.java        | 139 ++++++++--
 33 files changed, 736 insertions(+), 190 deletions(-)

diff --git a/api/src/com/cloud/agent/api/to/NicTO.java b/api/src/com/cloud/agent/api/to/NicTO.java
index bd681f2..3863e1b 100644
--- a/api/src/com/cloud/agent/api/to/NicTO.java
+++ b/api/src/com/cloud/agent/api/to/NicTO.java
@@ -16,7 +16,10 @@
 // under the License.
 package com.cloud.agent.api.to;
 
+import com.cloud.offering.NetworkOffering;
+
 import java.util.List;
+import java.util.Map;
 
 public class NicTO extends NetworkTO {
     int deviceId;
@@ -26,6 +29,7 @@ public class NicTO extends NetworkTO {
     boolean pxeDisable;
     String nicUuid;
     List<String> nicSecIps;
+    Map<NetworkOffering.Detail, String> details;
 
     public NicTO() {
         super();
@@ -97,4 +101,12 @@ public class NicTO extends NetworkTO {
     public void setNetworkUuid(String uuid) {
         super.setUuid(uuid);
     }
+
+    public Map<NetworkOffering.Detail, String> getDetails() {
+        return details;
+    }
+
+    public void setDetails(final Map<NetworkOffering.Detail, String> details) {
+        this.details = details;
+    }
 }
diff --git a/api/src/com/cloud/network/Networks.java b/api/src/com/cloud/network/Networks.java
index f027cf9..37746f0 100644
--- a/api/src/com/cloud/network/Networks.java
+++ b/api/src/com/cloud/network/Networks.java
@@ -75,6 +75,10 @@ public class Networks {
                     throw new CloudRuntimeException("Unable to convert to broadcast URI: " + value);
                 }
             }
+            @Override
+            public String getValueFrom(URI uri) {
+                return uri.getAuthority();
+            }
         },
         Vswitch("vs", String.class), LinkLocal(null, null), Vnet("vnet", Long.class), Storage("storage", Integer.class), Lswitch("lswitch", String.class) {
             @Override
diff --git a/api/src/com/cloud/offering/NetworkOffering.java b/api/src/com/cloud/offering/NetworkOffering.java
index 59045dc..4028462 100644
--- a/api/src/com/cloud/offering/NetworkOffering.java
+++ b/api/src/com/cloud/offering/NetworkOffering.java
@@ -38,7 +38,7 @@ public interface NetworkOffering extends InfrastructureEntity, InternalIdentity,
     }
 
     public enum Detail {
-        InternalLbProvider, PublicLbProvider, servicepackageuuid, servicepackagedescription
+        InternalLbProvider, PublicLbProvider, servicepackageuuid, servicepackagedescription, PromiscuousMode, MacAddressChanges, ForgedTransmits
     }
 
     public final static String SystemPublicNetwork = "System-Public-Network";
diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java
index 582ead6..1ec340d 100644
--- a/api/src/org/apache/cloudstack/api/ApiConstants.java
+++ b/api/src/org/apache/cloudstack/api/ApiConstants.java
@@ -38,6 +38,7 @@ public class ApiConstants {
     public static final String BIND_PASSWORD = "bindpass";
     public static final String BYTES_READ_RATE = "bytesreadrate";
     public static final String BYTES_WRITE_RATE = "byteswriterate";
+    public static final String BYPASS_VLAN_OVERLAP_CHECK = "bypassvlanoverlapcheck";
     public static final String CATEGORY = "category";
     public static final String CAN_REVERT = "canrevert";
     public static final String CA_CERTIFICATES = "cacertificates";
diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkCmdByAdmin.java b/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkCmdByAdmin.java
index 6cf9e23..6d346e9 100644
--- a/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkCmdByAdmin.java
+++ b/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkCmdByAdmin.java
@@ -40,6 +40,9 @@ public class CreateNetworkCmdByAdmin extends CreateNetworkCmd {
     @Parameter(name=ApiConstants.VLAN, type=CommandType.STRING, description="the ID or VID of the network")
     private String vlan;
 
+    @Parameter(name=ApiConstants.BYPASS_VLAN_OVERLAP_CHECK, type=CommandType.BOOLEAN, description="when true bypasses VLAN id/range overlap check during network creation for shared networks")
+    private Boolean bypassVlanOverlapCheck;
+
     /////////////////////////////////////////////////////
     /////////////////// Accessors ///////////////////////
     /////////////////////////////////////////////////////
@@ -48,6 +51,13 @@ public class CreateNetworkCmdByAdmin extends CreateNetworkCmd {
         return vlan;
     }
 
+    public Boolean getBypassVlanOverlapCheck() {
+        if (bypassVlanOverlapCheck != null) {
+            return bypassVlanOverlapCheck;
+        }
+        return false;
+    }
+
     /////////////////////////////////////////////////////
     /////////////// API Implementation///////////////////
     /////////////////////////////////////////////////////
diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java b/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java
index d1a3418..259c490 100644
--- a/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java
@@ -113,7 +113,8 @@ public class CreateNetworkOfferingCmd extends BaseCmd {
     private Boolean isPersistent;
 
     @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, since = "4.2.0", description = "Network offering details in key/value pairs."
-        + " Supported keys are internallbprovider/publiclbprovider with service provider as a value")
+        + " Supported keys are internallbprovider/publiclbprovider with service provider as a value, and"
+        + " promiscuousmode/macaddresschanges/forgedtransmits with true/false as value to accept/reject the security settings if available for a nic/portgroup")
     protected Map details;
 
     @Parameter(name = ApiConstants.EGRESS_DEFAULT_POLICY,
diff --git a/api/test/com/cloud/network/NetworksTest.java b/api/test/com/cloud/network/NetworksTest.java
index c9102d3..ef58292 100644
--- a/api/test/com/cloud/network/NetworksTest.java
+++ b/api/test/com/cloud/network/NetworksTest.java
@@ -16,16 +16,16 @@
 // under the License.
 package com.cloud.network;
 
-import java.net.URISyntaxException;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
 import com.cloud.dc.Vlan;
 import com.cloud.network.Networks.BroadcastDomainType;
 import com.cloud.network.Networks.IsolationType;
 import com.cloud.utils.exception.CloudRuntimeException;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.net.URI;
+import java.net.URISyntaxException;
 
 /**
  * @author dhoogland
@@ -44,6 +44,13 @@ public class NetworksTest {
     }
 
     @Test
+    public void vlanCommaSeparatedTest() throws URISyntaxException {
+        Assert.assertEquals(BroadcastDomainType.getValue(new URI("vlan://100")), "100");
+        Assert.assertEquals(BroadcastDomainType.getValue(new URI("vlan://100-200")), "100-200");
+        Assert.assertEquals(BroadcastDomainType.getValue(new URI("vlan://10-50,12,11,112-170")), "10-50,12,11,112-170");
+    }
+
+    @Test
     public void vlanBroadcastDomainTypeTest() throws URISyntaxException {
         String uri1 = "vlan://1";
         Long value2 = 2L;
diff --git a/engine/api/src/org/apache/cloudstack/engine/orchestration/service/NetworkOrchestrationService.java b/engine/api/src/org/apache/cloudstack/engine/orchestration/service/NetworkOrchestrationService.java
index 68531e3..8a7a516 100644
--- a/engine/api/src/org/apache/cloudstack/engine/orchestration/service/NetworkOrchestrationService.java
+++ b/engine/api/src/org/apache/cloudstack/engine/orchestration/service/NetworkOrchestrationService.java
@@ -77,6 +77,15 @@ public interface NetworkOrchestrationService {
     ConfigKey<Integer> NetworkThrottlingRate = new ConfigKey<Integer>("Network", Integer.class, NetworkThrottlingRateCK, "200",
         "Default data transfer rate in megabits per second allowed in network.", true, ConfigKey.Scope.Zone);
 
+    ConfigKey<Boolean> PromiscuousMode = new ConfigKey<Boolean>("Advanced", Boolean.class, "network.promiscuous.mode", "false",
+            "Whether to allow or deny promiscuous mode on nics for applicable network elements such as for vswitch/dvswitch portgroups.", true);
+
+    ConfigKey<Boolean> MacAddressChanges = new ConfigKey<Boolean>("Advanced", Boolean.class, "network.mac.address.changes", "true",
+            "Whether to allow or deny mac address changes on nics for applicable network elements such as for vswitch/dvswitch porgroups.", true);
+
+    ConfigKey<Boolean> ForgedTransmits = new ConfigKey<Boolean>("Advanced", Boolean.class, "network.forged.transmits", "true",
+            "Whether to allow or deny forged transmits on nics for applicable network elements such as for vswitch/dvswitch portgroups.", true);
+
     List<? extends Network> setupNetwork(Account owner, NetworkOffering offering, DeploymentPlan plan, String name, String displayText, boolean isDefault)
         throws ConcurrentOperationException;
 
@@ -136,9 +145,9 @@ public interface NetworkOrchestrationService {
 
     boolean destroyNetwork(long networkId, ReservationContext context, boolean forced);
 
-    Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway, String cidr, String vlanId, String networkDomain, Account owner,
-        Long domainId, PhysicalNetwork physicalNetwork, long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId, String ip6Gateway, String ip6Cidr,
-        Boolean displayNetworkEnabled, String isolatedPvlan) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException;
+    Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway, String cidr, String vlanId, boolean bypassVlanOverlapCheck, String networkDomain, Account owner,
+                               Long domainId, PhysicalNetwork physicalNetwork, long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId, String ip6Gateway, String ip6Cidr,
+                               Boolean displayNetworkEnabled, String isolatedPvlan) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException;
 
     UserDataServiceProvider getPasswordResetProvider(Network network);
 
diff --git a/engine/components-api/src/com/cloud/configuration/ConfigurationManager.java b/engine/components-api/src/com/cloud/configuration/ConfigurationManager.java
index 46be654..eee1595 100644
--- a/engine/components-api/src/com/cloud/configuration/ConfigurationManager.java
+++ b/engine/components-api/src/com/cloud/configuration/ConfigurationManager.java
@@ -214,7 +214,7 @@ public interface ConfigurationManager {
         Map<NetworkOffering.Detail, String> details, boolean egressDefaultPolicy, Integer maxconn, boolean enableKeepAlive);
 
     Vlan createVlanAndPublicIpRange(long zoneId, long networkId, long physicalNetworkId, boolean forVirtualNetwork, Long podId, String startIP, String endIP,
-        String vlanGateway, String vlanNetmask, String vlanId, Domain domain, Account vlanOwner, String startIPv6, String endIPv6, String vlanIp6Gateway, String vlanIp6Cidr)
+        String vlanGateway, String vlanNetmask, String vlanId, boolean bypassVlanOverlapCheck, Domain domain, Account vlanOwner, String startIPv6, String endIPv6, String vlanIp6Gateway, String vlanIp6Cidr)
         throws InsufficientCapacityException, ConcurrentOperationException, InvalidParameterValueException;
 
     void createDefaultSystemNetworks(long zoneId) throws ConcurrentOperationException;
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
index 3956617..755fba2 100644
--- a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
+++ b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
@@ -32,18 +32,10 @@ import java.util.UUID;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
+
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
-import com.cloud.network.dao.NetworkDetailsDao;
-import com.cloud.network.dao.RemoteAccessVpnDao;
-import com.cloud.network.dao.RemoteAccessVpnVO;
-import com.cloud.network.dao.VpnUserDao;
-import com.cloud.network.element.RedundantResource;
-import com.cloud.network.router.VirtualRouter;
-import com.cloud.vm.DomainRouterVO;
-import com.cloud.vm.dao.DomainRouterDao;
-import org.apache.log4j.Logger;
 import org.apache.cloudstack.acl.ControlledEntity.ACLType;
 import org.apache.cloudstack.context.CallContext;
 import org.apache.cloudstack.engine.cloud.entity.api.db.VMNetworkMapVO;
@@ -58,6 +50,8 @@ import org.apache.cloudstack.framework.messagebus.MessageBus;
 import org.apache.cloudstack.framework.messagebus.PublishScope;
 import org.apache.cloudstack.managed.context.ManagedContextRunnable;
 import org.apache.cloudstack.region.PortableIpDao;
+import org.apache.log4j.Logger;
+
 import com.cloud.agent.AgentManager;
 import com.cloud.agent.Listener;
 import com.cloud.agent.api.AgentControlAnswer;
@@ -129,6 +123,7 @@ import com.cloud.network.dao.IPAddressVO;
 import com.cloud.network.dao.NetworkAccountDao;
 import com.cloud.network.dao.NetworkAccountVO;
 import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkDetailsDao;
 import com.cloud.network.dao.NetworkDomainDao;
 import com.cloud.network.dao.NetworkDomainVO;
 import com.cloud.network.dao.NetworkServiceMapDao;
@@ -139,17 +134,22 @@ import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
 import com.cloud.network.dao.PhysicalNetworkTrafficTypeDao;
 import com.cloud.network.dao.PhysicalNetworkTrafficTypeVO;
 import com.cloud.network.dao.PhysicalNetworkVO;
+import com.cloud.network.dao.RemoteAccessVpnDao;
+import com.cloud.network.dao.RemoteAccessVpnVO;
+import com.cloud.network.dao.VpnUserDao;
 import com.cloud.network.element.AggregatedCommandExecutor;
 import com.cloud.network.element.DhcpServiceProvider;
 import com.cloud.network.element.DnsServiceProvider;
 import com.cloud.network.element.IpDeployer;
 import com.cloud.network.element.LoadBalancingServiceProvider;
 import com.cloud.network.element.NetworkElement;
+import com.cloud.network.element.RedundantResource;
 import com.cloud.network.element.StaticNatServiceProvider;
 import com.cloud.network.element.UserDataServiceProvider;
 import com.cloud.network.guru.NetworkGuru;
 import com.cloud.network.guru.NetworkGuruAdditionalFunctions;
 import com.cloud.network.lb.LoadBalancingRulesManager;
+import com.cloud.network.router.VirtualRouter;
 import com.cloud.network.rules.FirewallManager;
 import com.cloud.network.rules.FirewallRule;
 import com.cloud.network.rules.FirewallRule.Purpose;
@@ -197,6 +197,7 @@ import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.utils.fsm.NoTransitionException;
 import com.cloud.utils.fsm.StateMachine2;
 import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.DomainRouterVO;
 import com.cloud.vm.Nic;
 import com.cloud.vm.Nic.ReservationStrategy;
 import com.cloud.vm.NicIpAlias;
@@ -209,6 +210,7 @@ import com.cloud.vm.VMInstanceVO;
 import com.cloud.vm.VirtualMachine;
 import com.cloud.vm.VirtualMachine.Type;
 import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.dao.DomainRouterDao;
 import com.cloud.vm.dao.NicDao;
 import com.cloud.vm.dao.NicIpAliasDao;
 import com.cloud.vm.dao.NicIpAliasVO;
@@ -2017,9 +2019,9 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
     @Override
     @DB
     public Network createGuestNetwork(final long networkOfferingId, final String name, final String displayText, final String gateway, final String cidr, String vlanId,
-            String networkDomain, final Account owner, final Long domainId, final PhysicalNetwork pNtwk, final long zoneId, final ACLType aclType, Boolean subdomainAccess,
-            final Long vpcId, final String ip6Gateway, final String ip6Cidr, final Boolean isDisplayNetworkEnabled, final String isolatedPvlan)
-                    throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException {
+                                      boolean bypassVlanOverlapCheck, String networkDomain, final Account owner, final Long domainId, final PhysicalNetwork pNtwk,
+                                      final long zoneId, final ACLType aclType, Boolean subdomainAccess, final Long vpcId, final String ip6Gateway, final String ip6Cidr,
+                                      final Boolean isDisplayNetworkEnabled, final String isolatedPvlan) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException {
 
         final NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(networkOfferingId);
         // this method supports only guest network creation
@@ -2136,19 +2138,19 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
         }
 
         if (vlanSpecified) {
+            URI uri = BroadcastDomainType.fromString(vlanId);
             //don't allow to specify vlan tag used by physical network for dynamic vlan allocation
-            if (_dcDao.findVnet(zoneId, pNtwk.getId(), vlanId).size() > 0) {
+            if (!(bypassVlanOverlapCheck && ntwkOff.getGuestType() == GuestType.Shared) && _dcDao.findVnet(zoneId, pNtwk.getId(), BroadcastDomainType.getValue(uri)).size() > 0) {
                 throw new InvalidParameterValueException("The VLAN tag " + vlanId + " is already being used for dynamic vlan allocation for the guest network in zone "
                         + zone.getName());
             }
             if (! UuidUtils.validateUUID(vlanId)){
-                final String uri = BroadcastDomainType.fromString(vlanId).toString();
                 // For Isolated networks, don't allow to create network with vlan that already exists in the zone
                 if (ntwkOff.getGuestType() == GuestType.Isolated) {
-                    if (_networksDao.countByZoneAndUri(zoneId, uri) > 0) {
-                        throw new InvalidParameterValueException("Network with vlan " + vlanId + " already exists in zone " + zoneId);
+                    if (_networksDao.listByZoneAndUriAndGuestType(zoneId, uri.toString(), null).size() > 0) {
+                        throw new InvalidParameterValueException("Network with vlan " + vlanId + " already exists or overlaps with other network vlans in zone " + zoneId);
                     } else {
-                        final List<DataCenterVnetVO> dcVnets = _datacenterVnetDao.findVnet(zoneId, vlanId.toString());
+                        final List<DataCenterVnetVO> dcVnets = _datacenterVnetDao.findVnet(zoneId, BroadcastDomainType.getValue(uri));
                         //for the network that is created as part of private gateway,
                         //the vnet is not coming from the data center vnet table, so the list can be empty
                         if (!dcVnets.isEmpty()) {
@@ -2177,8 +2179,8 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
                 } else {
                     // don't allow to creating shared network with given Vlan ID, if there already exists a isolated network or
                     // shared network with same Vlan ID in the zone
-                    if (_networksDao.countByZoneUriAndGuestType(zoneId, uri, GuestType.Isolated) > 0 ) {
-                        throw new InvalidParameterValueException("There is a isolated/shared network with vlan id: " + vlanId + " already exists " + "in zone " + zoneId);
+                    if (!bypassVlanOverlapCheck && _networksDao.listByZoneAndUriAndGuestType(zoneId, uri.toString(), GuestType.Isolated).size() > 0 ) {
+                        throw new InvalidParameterValueException("There is an existing isolated/shared network that overlaps with vlan id:" + vlanId + " in zone " + zoneId);
                     }
                 }
             }
@@ -3663,6 +3665,8 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
 
     @Override
     public ConfigKey<?>[] getConfigKeys() {
-        return new ConfigKey<?>[] {NetworkGcWait, NetworkGcInterval, NetworkLockTimeout, GuestDomainSuffix, NetworkThrottlingRate, MinVRVersion};
+        return new ConfigKey<?>[] {NetworkGcWait, NetworkGcInterval, NetworkLockTimeout,
+                GuestDomainSuffix, NetworkThrottlingRate, MinVRVersion,
+                PromiscuousMode, MacAddressChanges, ForgedTransmits};
     }
 }
diff --git a/engine/schema/src/com/cloud/dc/dao/DataCenterVnetDao.java b/engine/schema/src/com/cloud/dc/dao/DataCenterVnetDao.java
index 1783231..556ab45 100644
--- a/engine/schema/src/com/cloud/dc/dao/DataCenterVnetDao.java
+++ b/engine/schema/src/com/cloud/dc/dao/DataCenterVnetDao.java
@@ -27,10 +27,10 @@ public interface DataCenterVnetDao extends GenericDao<DataCenterVnetVO, Long> {
 
     public List<DataCenterVnetVO> listAllocatedVnetsInRange(long dcId, long physicalNetworkId, Integer start, Integer end);
 
-    public List<DataCenterVnetVO> findVnet(long dcId, String vnet);
-
     public int countZoneVlans(long dcId, boolean onlyCountAllocated);
 
+    public List<DataCenterVnetVO> findVnet(long dcId, String vnet);
+
     public List<DataCenterVnetVO> findVnet(long dcId, long physicalNetworkId, String vnet);
 
     public void add(long dcId, long physicalNetworkId, List<String> vnets);
diff --git a/engine/schema/src/com/cloud/dc/dao/DataCenterVnetDaoImpl.java b/engine/schema/src/com/cloud/dc/dao/DataCenterVnetDaoImpl.java
index 3205fcd..1c29e6a 100644
--- a/engine/schema/src/com/cloud/dc/dao/DataCenterVnetDaoImpl.java
+++ b/engine/schema/src/com/cloud/dc/dao/DataCenterVnetDaoImpl.java
@@ -18,6 +18,7 @@ package com.cloud.dc.dao;
 
 import java.sql.PreparedStatement;
 import java.sql.SQLException;
+import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
@@ -30,6 +31,8 @@ import org.springframework.stereotype.Component;
 import com.cloud.dc.DataCenterVnetVO;
 import com.cloud.network.dao.AccountGuestVlanMapDao;
 import com.cloud.network.dao.AccountGuestVlanMapVO;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.UriUtils;
 import com.cloud.utils.db.DB;
 import com.cloud.utils.db.GenericDaoBase;
 import com.cloud.utils.db.GenericSearchBuilder;
@@ -100,29 +103,43 @@ public class DataCenterVnetDaoImpl extends GenericDaoBase<DataCenterVnetVO, Long
     }
 
     @Override
-    public List<DataCenterVnetVO> findVnet(long dcId, String vnet) {
-        SearchCriteria<DataCenterVnetVO> sc = VnetDcSearch.create();
-        ;
-        sc.setParameters("dc", dcId);
-        sc.setParameters("vnet", vnet);
-        return listBy(sc);
-    }
-
-    @Override
     public int countZoneVlans(long dcId, boolean onlyCountAllocated) {
         SearchCriteria<Integer> sc = onlyCountAllocated ? countAllocatedZoneVlans.create() : countZoneVlans.create();
         sc.setParameters("dc", dcId);
         return customSearch(sc, null).get(0);
     }
 
-    @Override
-    public List<DataCenterVnetVO> findVnet(long dcId, long physicalNetworkId, String vnet) {
+    private List<DataCenterVnetVO> findOverlappingVnets(final long dcId, final Long physicalNetworkId, final String vnet) {
+        final List<Integer> searchVnets = UriUtils.expandVlanUri(vnet);
+        final List<DataCenterVnetVO> overlappingVnets = new ArrayList<>();
+        if (searchVnets == null || searchVnets.isEmpty()) {
+            return overlappingVnets;
+        }
         SearchCriteria<DataCenterVnetVO> sc = VnetDcSearch.create();
         sc.setParameters("dc", dcId);
-        sc.setParameters("physicalNetworkId", physicalNetworkId);
-        sc.setParameters("vnet", vnet);
+        if (physicalNetworkId != null) {
+            sc.setParameters("physicalNetworkId", physicalNetworkId);
+        }
+        for (final DataCenterVnetVO dcVNet : listBy(sc)) {
+            if (dcVNet == null || dcVNet.getVnet() == null) {
+                continue;
+            }
+            final Integer vnetValue = NumbersUtil.parseInt(dcVNet.getVnet(), -1);
+            if (vnetValue != -1 && searchVnets.contains(vnetValue)) {
+                overlappingVnets.add(dcVNet);
+            }
+        }
+        return overlappingVnets;
+    }
 
-        return listBy(sc);
+    @Override
+    public List<DataCenterVnetVO> findVnet(long dcId, String vnet) {
+        return findOverlappingVnets(dcId, null, vnet);
+    }
+
+    @Override
+    public List<DataCenterVnetVO> findVnet(long dcId, long physicalNetworkId, String vnet) {
+        return findOverlappingVnets(dcId, physicalNetworkId, vnet);
     }
 
     @Override
diff --git a/engine/schema/src/com/cloud/network/dao/NetworkDao.java b/engine/schema/src/com/cloud/network/dao/NetworkDao.java
index 85544e7..5091ebd 100644
--- a/engine/schema/src/com/cloud/network/dao/NetworkDao.java
+++ b/engine/schema/src/com/cloud/network/dao/NetworkDao.java
@@ -61,9 +61,7 @@ public interface NetworkDao extends GenericDao<NetworkVO, Long>, StateDao<State,
 
     List<NetworkVO> listBy(long accountId, long networkId);
 
-    long countByZoneAndUri(long zoneId, String broadcastUri);
-
-    long countByZoneUriAndGuestType(long zoneId, String broadcastUri, GuestType guestType);
+    List<NetworkVO> listByZoneAndUriAndGuestType(long zoneId, String broadcastUri, GuestType guestType);
 
     List<NetworkVO> listByZone(long zoneId);
 
diff --git a/engine/schema/src/com/cloud/network/dao/NetworkDaoImpl.java b/engine/schema/src/com/cloud/network/dao/NetworkDaoImpl.java
index 49a5944..11444b0 100644
--- a/engine/schema/src/com/cloud/network/dao/NetworkDaoImpl.java
+++ b/engine/schema/src/com/cloud/network/dao/NetworkDaoImpl.java
@@ -16,6 +16,8 @@
 // under the License.
 package com.cloud.network.dao;
 
+import java.net.URI;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.Random;
@@ -24,9 +26,8 @@ import javax.annotation.PostConstruct;
 import javax.inject.Inject;
 import javax.persistence.TableGenerator;
 
-import org.springframework.stereotype.Component;
-
 import org.apache.cloudstack.acl.ControlledEntity.ACLType;
+import org.springframework.stereotype.Component;
 
 import com.cloud.network.Network;
 import com.cloud.network.Network.Event;
@@ -42,6 +43,7 @@ import com.cloud.offerings.NetworkOfferingVO;
 import com.cloud.offerings.dao.NetworkOfferingDao;
 import com.cloud.server.ResourceTag.ResourceObjectType;
 import com.cloud.tags.dao.ResourceTagDao;
+import com.cloud.utils.UriUtils;
 import com.cloud.utils.db.DB;
 import com.cloud.utils.db.Filter;
 import com.cloud.utils.db.GenericDaoBase;
@@ -71,7 +73,6 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long>implements Ne
     GenericSearchBuilder<NetworkVO, Long> NetworksRegularUserCanCreateSearch;
     GenericSearchBuilder<NetworkVO, Integer> NetworksCount;
     SearchBuilder<NetworkVO> SourceNATSearch;
-    GenericSearchBuilder<NetworkVO, Long> CountByZoneAndURI;
     GenericSearchBuilder<NetworkVO, Long> VpcNetworksCount;
     SearchBuilder<NetworkVO> OfferingAccountNetworkSearch;
 
@@ -152,14 +153,6 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long>implements Ne
         ZoneBroadcastUriSearch.and("guestType", ZoneBroadcastUriSearch.entity().getGuestType(), Op.EQ);
         ZoneBroadcastUriSearch.done();
 
-        CountByZoneAndURI = createSearchBuilder(Long.class);
-        CountByZoneAndURI.select(null, Func.COUNT, null);
-        CountByZoneAndURI.and("dataCenterId", CountByZoneAndURI.entity().getDataCenterId(), Op.EQ);
-        CountByZoneAndURI.and("broadcastUri", CountByZoneAndURI.entity().getBroadcastUri(), Op.EQ);
-        CountByZoneAndURI.and("guestType", CountByZoneAndURI.entity().getGuestType(), Op.EQ);
-
-        CountByZoneAndURI.done();
-
         ZoneSecurityGroupSearch = createSearchBuilder();
         ZoneSecurityGroupSearch.and("dataCenterId", ZoneSecurityGroupSearch.entity().getDataCenterId(), Op.EQ);
         final SearchBuilder<NetworkServiceMapVO> offJoin = _ntwkSvcMap.createSearchBuilder();
@@ -399,13 +392,35 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long>implements Ne
     }
 
     @Override
-    public long countByZoneAndUri(final long zoneId, final String broadcastUri) {
+    public List<NetworkVO> listByZoneAndUriAndGuestType(long zoneId, String broadcastUri, GuestType guestType) {
+        final URI searchUri = BroadcastDomainType.fromString(broadcastUri);
+        final String searchRange = BroadcastDomainType.getValue(searchUri);
+        final List<Integer> searchVlans = UriUtils.expandVlanUri(searchRange);
+        final List<NetworkVO> overlappingNetworks = new ArrayList<>();
 
-        final SearchCriteria<Long> sc = CountByZoneAndURI.create();
+        final SearchCriteria<NetworkVO> sc = ZoneBroadcastUriSearch.create();
         sc.setParameters("dataCenterId", zoneId);
-        sc.setParameters("broadcastUri", broadcastUri);
+        if (guestType != null) {
+            sc.setParameters("guestType", guestType);
+        }
 
-        return customSearch(sc, null).get(0);
+        for (final NetworkVO network : listBy(sc)) {
+            if (network.getBroadcastUri() == null || !network.getBroadcastUri().getScheme().equalsIgnoreCase(searchUri.getScheme())) {
+                continue;
+            }
+            final String networkVlanRange = BroadcastDomainType.getValue(network.getBroadcastUri());
+            if (networkVlanRange == null || networkVlanRange.isEmpty()) {
+                continue;
+            }
+            for (final Integer networkVlan : UriUtils.expandVlanUri(networkVlanRange)) {
+                if (searchVlans.contains(networkVlan)) {
+                    overlappingNetworks.add(network);
+                    break;
+                }
+            }
+        }
+
+        return overlappingNetworks;
     }
 
     @Override
@@ -416,15 +431,6 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long>implements Ne
     }
 
     @Override
-    public long countByZoneUriAndGuestType(final long zoneId, final String broadcastUri, final GuestType guestType) {
-        final SearchCriteria<Long> sc = CountByZoneAndURI.create();
-        sc.setParameters("dataCenterId", zoneId);
-        sc.setParameters("broadcastUri", broadcastUri);
-        sc.setParameters("guestType", guestType);
-        return customSearch(sc, null).get(0);
-    }
-
-    @Override
     public List<NetworkVO> listByZoneSecurityGroup(final Long zoneId) {
         final SearchCriteria<NetworkVO> sc = ZoneSecurityGroupSearch.create();
         if (zoneId != null) {
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
index 53e3239..b7149ab 100644
--- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
@@ -392,11 +392,11 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
         VirtualSwitchType vsType = VirtualSwitchType.getType(vSwitchType);
         //The management network is probably always going to be a physical network with islation type of vlans, so assume BroadcastDomainType VLAN
         if (VirtualSwitchType.StandardVirtualSwitch == vsType) {
-            HypervisorHostHelper.prepareNetwork(vSwitchName, "cloud.private", hostMo, vlanId, null, null, 180000, false, BroadcastDomainType.Vlan, null);
+            HypervisorHostHelper.prepareNetwork(vSwitchName, "cloud.private", hostMo, vlanId, null, null, 180000, false, BroadcastDomainType.Vlan, null, null);
         }
         else {
             HypervisorHostHelper.prepareNetwork(vSwitchName, "cloud.private", hostMo, vlanId, null, null, null, 180000,
-                    vsType, _portsPerDvPortGroup, null, false, BroadcastDomainType.Vlan, null);
+                    vsType, _portsPerDvPortGroup, null, false, BroadcastDomainType.Vlan, null, null);
         }
     }
 
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
index 17064ff..9d32f34 100644
--- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
@@ -1178,11 +1178,11 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
         if (VirtualSwitchType.StandardVirtualSwitch == vSwitchType) {
             networkInfo = HypervisorHostHelper.prepareNetwork(_publicTrafficInfo.getVirtualSwitchName(),
                     "cloud.public", vmMo.getRunningHost(), vlanId, null, null,
-                    _opsTimeout, true, BroadcastDomainType.Vlan, null);
+                    _opsTimeout, true, BroadcastDomainType.Vlan, null, null);
         } else {
             networkInfo =
                     HypervisorHostHelper.prepareNetwork(_publicTrafficInfo.getVirtualSwitchName(), "cloud.public", vmMo.getRunningHost(), vlanId, null, null, null,
-                            _opsTimeout, vSwitchType, _portsPerDvPortGroup, null, false, BroadcastDomainType.Vlan, _vsmCredentials);
+                            _opsTimeout, vSwitchType, _portsPerDvPortGroup, null, false, BroadcastDomainType.Vlan, _vsmCredentials, null);
         }
 
         int nicIndex = allocPublicNicIndex(vmMo);
@@ -3032,7 +3032,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
         if (VirtualSwitchType.StandardVirtualSwitch == switchType) {
             networkInfo = HypervisorHostHelper.prepareNetwork(switchName, namePrefix, hostMo,
                     getVlanInfo(nicTo, vlanToken), nicTo.getNetworkRateMbps(), nicTo.getNetworkRateMulticastMbps(),
-                    _opsTimeout, !namePrefix.startsWith("cloud.private"), nicTo.getBroadcastType(), nicTo.getUuid());
+                    _opsTimeout, true, nicTo.getBroadcastType(), nicTo.getUuid(), nicTo.getDetails());
         }
         else {
             String vlanId = getVlanInfo(nicTo, vlanToken);
@@ -3047,7 +3047,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
             }
             networkInfo = HypervisorHostHelper.prepareNetwork(switchName, namePrefix, hostMo, vlanId, svlanId,
                     nicTo.getNetworkRateMbps(), nicTo.getNetworkRateMulticastMbps(), _opsTimeout, switchType,
-                    _portsPerDvPortGroup, nicTo.getGateway(), configureVServiceInNexus, nicTo.getBroadcastType(), _vsmCredentials);
+                    _portsPerDvPortGroup, nicTo.getGateway(), configureVServiceInNexus, nicTo.getBroadcastType(), _vsmCredentials, nicTo.getDetails());
         }
 
         return networkInfo;
diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
index 3d2c236..4dd5263 100755
--- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
+++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
@@ -199,6 +199,7 @@ import com.cloud.user.dao.UserDao;
 import com.cloud.utils.NumbersUtil;
 import com.cloud.utils.Pair;
 import com.cloud.utils.StringUtils;
+import com.cloud.utils.UriUtils;
 import com.cloud.utils.component.ManagerBase;
 import com.cloud.utils.db.DB;
 import com.cloud.utils.db.EntityManager;
@@ -2893,7 +2894,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
                     newVlanNetmask = sameSubnet.second().second();
                 }
                 final Vlan vlan = createVlanAndPublicIpRange(zoneId, networkId, physicalNetworkId, forVirtualNetwork, podId, startIP, endIP, newVlanGateway, newVlanNetmask, vlanId,
-                        domain, vlanOwner, startIPv6, endIPv6, ip6Gateway, ip6Cidr);
+                        false, domain, vlanOwner, startIPv6, endIPv6, ip6Gateway, ip6Cidr);
                 // create an entry in the nic_secondary table. This will be the new
                 // gateway that will be configured on the corresponding routervm.
                 return vlan;
@@ -3010,7 +3011,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
     @Override
     @DB
     public Vlan createVlanAndPublicIpRange(final long zoneId, final long networkId, final long physicalNetworkId, final boolean forVirtualNetwork, final Long podId, final String startIP, final String endIP,
-            final String vlanGateway, final String vlanNetmask, String vlanId, Domain domain, final Account vlanOwner, final String startIPv6, final String endIPv6, final String vlanIp6Gateway, final String vlanIp6Cidr) {
+            final String vlanGateway, final String vlanNetmask, String vlanId, boolean bypassVlanOverlapCheck, Domain domain, final Account vlanOwner, final String startIPv6, final String endIPv6, final String vlanIp6Gateway, final String vlanIp6Cidr) {
         final Network network = _networkModel.getNetwork(networkId);
 
         boolean ipv4 = false, ipv6 = false;
@@ -3077,8 +3078,10 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
                     final String[] vlan = uri.toString().split("vlan:\\/\\/");
                     networkVlanId = vlan[1];
                     // For pvlan
-                    networkVlanId = networkVlanId.split("-")[0];
-                }
+                    if (network.getBroadcastDomainType() != BroadcastDomainType.Vlan) {
+                        networkVlanId = networkVlanId.split("-")[0];
+                    }
+               }
             }
 
             if (vlanId != null && !connectivityWithoutVlan) {
@@ -3168,7 +3171,9 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
                     continue;
                 }
                 // from here, subnet overlaps
-                if ( !vlanId.equals(vlan.getVlanTag()) ) {
+                if (!UriUtils.checkVlanUriOverlap(
+                        BroadcastDomainType.getValue(BroadcastDomainType.fromString(vlanId)),
+                        BroadcastDomainType.getValue(BroadcastDomainType.fromString(vlan.getVlanTag())))) {
                     boolean overlapped = false;
                     if( network.getTrafficType() == TrafficType.Public ) {
                         overlapped = true;
@@ -3239,7 +3244,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
         }
 
         // Check if the vlan is being used
-        if (_zoneDao.findVnet(zoneId, physicalNetworkId, vlanId).size() > 0) {
+        if (!bypassVlanOverlapCheck && _zoneDao.findVnet(zoneId, physicalNetworkId, BroadcastDomainType.getValue(BroadcastDomainType.fromString(vlanId))).size() > 0) {
             throw new InvalidParameterValueException("The VLAN tag " + vlanId + " is already being used for dynamic vlan allocation for the guest network in zone "
                     + zone.getName());
         }
diff --git a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java b/server/src/com/cloud/hypervisor/HypervisorGuruBase.java
index d84c104..0bf1c70 100644
--- a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java
+++ b/server/src/com/cloud/hypervisor/HypervisorGuruBase.java
@@ -22,6 +22,7 @@ import java.util.UUID;
 
 import javax.inject.Inject;
 
+import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
 import org.apache.log4j.Logger;
 
 import com.cloud.agent.api.Command;
@@ -29,9 +30,12 @@ import com.cloud.agent.api.to.DiskTO;
 import com.cloud.agent.api.to.NicTO;
 import com.cloud.agent.api.to.VirtualMachineTO;
 import com.cloud.gpu.GPU;
+import com.cloud.network.Networks.BroadcastDomainType;
 import com.cloud.network.dao.NetworkDao;
 import com.cloud.network.dao.NetworkVO;
+import com.cloud.offering.NetworkOffering;
 import com.cloud.offering.ServiceOffering;
+import com.cloud.offerings.dao.NetworkOfferingDetailsDao;
 import com.cloud.resource.ResourceManager;
 import com.cloud.service.ServiceOfferingDetailsVO;
 import com.cloud.service.dao.ServiceOfferingDao;
@@ -48,7 +52,6 @@ import com.cloud.vm.dao.NicDao;
 import com.cloud.vm.dao.NicSecondaryIpDao;
 import com.cloud.vm.dao.UserVmDetailsDao;
 import com.cloud.vm.dao.VMInstanceDao;
-import com.cloud.network.Networks.BroadcastDomainType;
 
 public abstract class HypervisorGuruBase extends AdapterBase implements HypervisorGuru {
     public static final Logger s_logger = Logger.getLogger(HypervisorGuruBase.class);
@@ -58,6 +61,8 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
     @Inject
     private NetworkDao _networkDao;
     @Inject
+    private NetworkOfferingDetailsDao networkOfferingDetailsDao;
+    @Inject
     private VMInstanceDao _virtualMachineDao;
     @Inject
     private UserVmDetailsDao _userVmDetailsDao;
@@ -138,7 +143,18 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
             if(vm.getType() == VirtualMachine.Type.NetScalerVm) {
                 nicProfile.setBroadcastType(BroadcastDomainType.Native);
             }
-            nics[i++] = toNicTO(nicProfile);
+            NicTO nicTo = toNicTO(nicProfile);
+            final NetworkVO network = _networkDao.findByUuid(nicTo.getNetworkUuid());
+            if (network != null) {
+                final Map<NetworkOffering.Detail, String> details = networkOfferingDetailsDao.getNtwkOffDetails(network.getNetworkOfferingId());
+                if (details != null) {
+                    details.putIfAbsent(NetworkOffering.Detail.PromiscuousMode, NetworkOrchestrationService.PromiscuousMode.value().toString());
+                    details.putIfAbsent(NetworkOffering.Detail.MacAddressChanges, NetworkOrchestrationService.MacAddressChanges.value().toString());
+                    details.putIfAbsent(NetworkOffering.Detail.ForgedTransmits, NetworkOrchestrationService.ForgedTransmits.value().toString());
+                }
+                nicTo.setDetails(details);
+            }
+            nics[i++] = nicTo;
         }
 
         to.setNics(nics);
diff --git a/server/src/com/cloud/network/IpAddressManagerImpl.java b/server/src/com/cloud/network/IpAddressManagerImpl.java
index 9056ed5..e34f908 100644
--- a/server/src/com/cloud/network/IpAddressManagerImpl.java
+++ b/server/src/com/cloud/network/IpAddressManagerImpl.java
@@ -1631,7 +1631,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
                             s_logger.debug("Creating network for account " + owner + " from the network offering id=" + requiredOfferings.get(0).getId()
                                     + " as a part of createVlanIpRange process");
                             guestNetwork = _networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(), owner.getAccountName() + "-network", owner.getAccountName()
-                                    + "-network", null, null, null, null, owner, null, physicalNetwork, zoneId, ACLType.Account, null, null, null, null, true, null);
+                                    + "-network", null, null, null, false, null, owner, null, physicalNetwork, zoneId, ACLType.Account, null, null, null, null, true, null);
                             if (guestNetwork == null) {
                                 s_logger.warn("Failed to create default Virtual network for the account " + accountId + "in zone " + zoneId);
                                 throw new CloudRuntimeException("Failed to create a Guest Isolated Networks with SourceNAT "
diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java b/server/src/com/cloud/network/NetworkServiceImpl.java
index 36dd53f..966c0e4 100644
--- a/server/src/com/cloud/network/NetworkServiceImpl.java
+++ b/server/src/com/cloud/network/NetworkServiceImpl.java
@@ -1038,9 +1038,14 @@ public class NetworkServiceImpl extends ManagerBase implements  NetworkService {
         String netmask = cmd.getNetmask();
         String networkDomain = cmd.getNetworkDomain();
         String vlanId = null;
+        boolean bypassVlanOverlapCheck = false;
         if (cmd instanceof CreateNetworkCmdByAdmin) {
             vlanId = ((CreateNetworkCmdByAdmin)cmd).getVlan();
         }
+        if (cmd instanceof CreateNetworkCmdByAdmin) {
+            bypassVlanOverlapCheck = ((CreateNetworkCmdByAdmin)cmd).getBypassVlanOverlapCheck();
+        }
+
         String name = cmd.getNetworkName();
         String displayText = cmd.getDisplayText();
         Account caller = CallContext.current().getCallingAccount();
@@ -1259,8 +1264,8 @@ public class NetworkServiceImpl extends ManagerBase implements  NetworkService {
         }
 
         // Don't allow to specify vlan if the caller is not ROOT admin
-        if (!_accountMgr.isRootAdmin(caller.getId()) && (ntwkOff.getSpecifyVlan() || vlanId != null)) {
-            throw new InvalidParameterValueException("Only ROOT admin is allowed to specify vlanId");
+        if (!_accountMgr.isRootAdmin(caller.getId()) && (ntwkOff.getSpecifyVlan() || vlanId != null || bypassVlanOverlapCheck)) {
+            throw new InvalidParameterValueException("Only ROOT admin is allowed to specify vlanId or bypass vlan overlap check");
         }
 
         if (ipv4) {
@@ -1319,7 +1324,7 @@ public class NetworkServiceImpl extends ManagerBase implements  NetworkService {
             throw ex;
         }
 
-        Network network = commitNetwork(networkOfferingId, gateway, startIP, endIP, netmask, networkDomain, vlanId, name, displayText, caller, physicalNetworkId, zoneId, domainId,
+        Network network = commitNetwork(networkOfferingId, gateway, startIP, endIP, netmask, networkDomain, vlanId, bypassVlanOverlapCheck, name, displayText, caller, physicalNetworkId, zoneId, domainId,
                 isDomainSpecific, subdomainAccess, vpcId, startIPv6, endIPv6, ip6Gateway, ip6Cidr, displayNetwork, aclId, isolatedPvlan, ntwkOff, pNtwk, aclType, owner, cidr,
                 createVlan);
 
@@ -1351,10 +1356,10 @@ public class NetworkServiceImpl extends ManagerBase implements  NetworkService {
     }
 
     private Network commitNetwork(final Long networkOfferingId, final String gateway, final String startIP, final String endIP, final String netmask, final String networkDomain,
-            final String vlanId, final String name, final String displayText, final Account caller, final Long physicalNetworkId, final Long zoneId, final Long domainId,
-            final boolean isDomainSpecific, final Boolean subdomainAccessFinal, final Long vpcId, final String startIPv6, final String endIPv6, final String ip6Gateway,
-            final String ip6Cidr, final Boolean displayNetwork, final Long aclId, final String isolatedPvlan, final NetworkOfferingVO ntwkOff, final PhysicalNetwork pNtwk,
-            final ACLType aclType, final Account ownerFinal, final String cidr, final boolean createVlan) throws InsufficientCapacityException, ResourceAllocationException {
+                                  final String vlanId, final Boolean bypassVlanOverlapCheck, final String name, final String displayText, final Account caller, final Long physicalNetworkId, final Long zoneId, final Long domainId,
+                                  final boolean isDomainSpecific, final Boolean subdomainAccessFinal, final Long vpcId, final String startIPv6, final String endIPv6, final String ip6Gateway,
+                                  final String ip6Cidr, final Boolean displayNetwork, final Long aclId, final String isolatedPvlan, final NetworkOfferingVO ntwkOff, final PhysicalNetwork pNtwk,
+                                  final ACLType aclType, final Account ownerFinal, final String cidr, final boolean createVlan) throws InsufficientCapacityException, ResourceAllocationException {
         try {
             Network network = Transaction.execute(new TransactionCallbackWithException<Network, Exception>() {
                 @Override
@@ -1408,14 +1413,14 @@ public class NetworkServiceImpl extends ManagerBase implements  NetworkService {
                             throw new InvalidParameterValueException("Internal Lb can be enabled on vpc networks only");
                         }
 
-                        network = _networkMgr.createGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId, networkDomain, owner, sharedDomainId, pNtwk, zoneId,
+                        network = _networkMgr.createGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId, bypassVlanOverlapCheck, networkDomain, owner, sharedDomainId, pNtwk, zoneId,
                                 aclType, subdomainAccess, vpcId, ip6Gateway, ip6Cidr, displayNetwork, isolatedPvlan);
                     }
 
                     if (_accountMgr.isRootAdmin(caller.getId()) && createVlan && network != null) {
                         // Create vlan ip range
                         _configMgr.createVlanAndPublicIpRange(pNtwk.getDataCenterId(), network.getId(), physicalNetworkId, false, null, startIP, endIP, gateway, netmask, vlanId,
-                                null, null, startIPv6, endIPv6, ip6Gateway, ip6Cidr);
+                                bypassVlanOverlapCheck, null, null, startIPv6, endIPv6, ip6Gateway, ip6Cidr);
                     }
                     return network;
                 }
@@ -4079,7 +4084,7 @@ public class NetworkServiceImpl extends ManagerBase implements  NetworkService {
                     Network privateNetwork = _networksDao.getPrivateNetwork(uriString, cidr, networkOwnerId, pNtwk.getDataCenterId(), networkOfferingId);
                     if (privateNetwork == null) {
                         //create Guest network
-                        privateNetwork = _networkMgr.createGuestNetwork(ntwkOffFinal.getId(), networkName, displayText, gateway, cidr, uriString, null, owner, null, pNtwk,
+                        privateNetwork = _networkMgr.createGuestNetwork(ntwkOffFinal.getId(), networkName, displayText, gateway, cidr, uriString, false, null, owner, null, pNtwk,
                                 pNtwk.getDataCenterId(), ACLType.Account, null, vpcId, null, null, true, null);
                         if (privateNetwork != null) {
                             s_logger.debug("Successfully created guest network " + privateNetwork);
diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java
index 706f4c4..9f5ff83 100644
--- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java
+++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java
@@ -2359,7 +2359,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
         validateNtwkOffForNtwkInVpc(null, ntwkOffId, cidr, networkDomain, vpc, gateway, owner, aclId);
 
         // 2) Create network
-        final Network guestNetwork = _ntwkMgr.createGuestNetwork(ntwkOffId, name, displayText, gateway, cidr, vlanId, networkDomain, owner, domainId, pNtwk, zoneId, aclType,
+        final Network guestNetwork = _ntwkMgr.createGuestNetwork(ntwkOffId, name, displayText, gateway, cidr, vlanId, false, networkDomain, owner, domainId, pNtwk, zoneId, aclType,
                 subdomainAccess, vpcId, null, null, isDisplayNetworkEnabled, null);
 
         if (guestNetwork != null) {
diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java
index e4fc56f..07dd0ea 100644
--- a/server/src/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/com/cloud/vm/UserVmManagerImpl.java
@@ -3103,7 +3103,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
                     }
                     s_logger.debug("Creating network for account " + owner + " from the network offering id=" + requiredOfferings.get(0).getId() + " as a part of deployVM process");
                     Network newNetwork = _networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(), owner.getAccountName() + "-network", owner.getAccountName() + "-network",
-                            null, null, null, null, owner, null, physicalNetwork, zone.getId(), ACLType.Account, null, null, null, null, true, null);
+                            null, null, null, false, null, owner, null, physicalNetwork, zone.getId(), ACLType.Account, null, null, null, null, true, null);
                     if (newNetwork != null) {
                         defaultNetwork = _networkDao.findById(newNetwork.getId());
                     }
@@ -5723,7 +5723,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
                             s_logger.debug("Creating network for account " + newAccount + " from the network offering id=" + requiredOfferings.get(0).getId()
                                     + " as a part of deployVM process");
                             Network newNetwork = _networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(), newAccount.getAccountName() + "-network",
-                                    newAccount.getAccountName() + "-network", null, null, null, null, newAccount, null, physicalNetwork, zone.getId(), ACLType.Account, null, null,
+                                    newAccount.getAccountName() + "-network", null, null, null, false, null, newAccount, null, physicalNetwork, zone.getId(), ACLType.Account, null, null,
                                     null, null, true, null);
                             // if the network offering has persistent set to true, implement the network
                             if (requiredOfferings.get(0).getIsPersistent()) {
diff --git a/server/test/com/cloud/network/CreatePrivateNetworkTest.java b/server/test/com/cloud/network/CreatePrivateNetworkTest.java
index 8a7b54c..178ed84 100644
--- a/server/test/com/cloud/network/CreatePrivateNetworkTest.java
+++ b/server/test/com/cloud/network/CreatePrivateNetworkTest.java
@@ -121,7 +121,7 @@ public class CreatePrivateNetworkTest {
             new NetworkVO(1L, TrafficType.Guest, Mode.None, BroadcastDomainType.Vlan, 1L, 1L, 1L, 1L, "bla", "fake", "eet.net", GuestType.Isolated, 1L, 1L,
                 ACLType.Account, false, 1L, false);
         when(
-            networkService._networkMgr.createGuestNetwork(eq(ntwkOff.getId()), eq("bla"), eq("fake"), eq("10.1.1.1"), eq("10.1.1.0/24"), anyString(), anyString(),
+            networkService._networkMgr.createGuestNetwork(eq(ntwkOff.getId()), eq("bla"), eq("fake"), eq("10.1.1.1"), eq("10.1.1.0/24"), anyString(), anyBoolean(), anyString(),
                 eq(account), anyLong(), eq(physicalNetwork), eq(physicalNetwork.getDataCenterId()), eq(ACLType.Account), anyBoolean(), eq(1L), anyString(), anyString(),
                 anyBoolean(), anyString())).thenReturn(net);
 
diff --git a/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java b/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java
index bcee896..9ac0648 100644
--- a/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java
+++ b/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java
@@ -440,7 +440,7 @@ public class MockConfigurationManagerImpl extends ManagerBase implements Configu
      */
     @Override
     public Vlan createVlanAndPublicIpRange(long zoneId, long networkId, long physicalNetworkId, boolean forVirtualNetwork, Long podId, String startIP, String endIP,
-        String vlanGateway, String vlanNetmask, String vlanId, Domain domain, Account vlanOwner, String startIPv6, String endIPv6, String vlanGatewayv6, String vlanCidrv6)
+        String vlanGateway, String vlanNetmask, String vlanId, boolean bypassVlanOverlapCheck, Domain domain, Account vlanOwner, String startIPv6, String endIPv6, String vlanGatewayv6, String vlanCidrv6)
         throws InsufficientCapacityException, ConcurrentOperationException, InvalidParameterValueException {
         // TODO Auto-generated method stub
         return null;
diff --git a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java
index f6f818d..9b895c2 100644
--- a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java
+++ b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java
@@ -611,9 +611,9 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkOrches
      * @see com.cloud.network.NetworkManager#createGuestNetwork(long, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, com.cloud.user.Account, java.lang.Long, com.cloud.network.PhysicalNetwork, long, org.apache.cloudstack.acl.ControlledEntity.ACLType, java.lang.Boolean, java.lang.Long)
      */
     @Override
-    public Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway, String cidr, String vlanId, String networkDomain,
-        Account owner, Long domainId, PhysicalNetwork physicalNetwork, long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId, String gatewayv6,
-        String cidrv6, Boolean displayNetworkEnabled, String isolatedPvlan ) throws ConcurrentOperationException, InsufficientCapacityException,
+    public Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway, String cidr, String vlanId, boolean bypassVlanOverlapCheck, String networkDomain,
+                                      Account owner, Long domainId, PhysicalNetwork physicalNetwork, long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId, String gatewayv6,
+                                      String cidrv6, Boolean displayNetworkEnabled, String isolatedPvlan) throws ConcurrentOperationException, InsufficientCapacityException,
         ResourceAllocationException {
         // TODO Auto-generated method stub
         return null;
diff --git a/server/test/com/cloud/vpc/dao/MockNetworkDaoImpl.java b/server/test/com/cloud/vpc/dao/MockNetworkDaoImpl.java
index 4c4a0a1..11f3f81 100644
--- a/server/test/com/cloud/vpc/dao/MockNetworkDaoImpl.java
+++ b/server/test/com/cloud/vpc/dao/MockNetworkDaoImpl.java
@@ -85,13 +85,8 @@ public class MockNetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implemen
     }
 
     @Override
-    public long countByZoneAndUri(final long zoneId, final String broadcastUri) {
-        return 0;
-    }
-
-    @Override
-    public long countByZoneUriAndGuestType(final long zoneId, final String broadcastUri, final GuestType guestType) {
-        return 0;
+    public List<NetworkVO> listByZoneAndUriAndGuestType(long zoneId, String broadcastUri, GuestType guestType) {
+        return null;
     }
 
     @Override
diff --git a/ui/l10n/en.js b/ui/l10n/en.js
index 16e0b88..3727dc6 100644
--- a/ui/l10n/en.js
+++ b/ui/l10n/en.js
@@ -761,6 +761,7 @@ var dictionary = {"ICMP.code":"ICMP Code",
 "label.firewall":"Firewall",
 "label.first.name":"First Name",
 "label.firstname.lower":"firstname",
+"label.forged.transmits":"Forged Transmits",
 "label.format":"Format",
 "label.format.lower":"format",
 "label.friday":"Friday",
@@ -991,6 +992,7 @@ var dictionary = {"ICMP.code":"ICMP Code",
 "label.management":"Management",
 "label.management.ips":"Management IP Addresses",
 "label.management.server":"Management Server",
+"label.mac.address.changes":"MAC Address Changes",
 "label.max.cpus":"Max. CPU cores",
 "label.max.guest.limit":"Max guest limit",
 "label.max.instances":"Max Instances",
@@ -1299,6 +1301,7 @@ var dictionary = {"ICMP.code":"ICMP Code",
 "label.project.name":"Project name",
 "label.project.view":"Project View",
 "label.projects":"Projects",
+"label.promiscuous.mode":"Promiscuous Mode",
 "label.protocol":"Protocol",
 "label.protocol.number":"Protocol Number",
 "label.provider":"Provider",
diff --git a/ui/scripts/configuration.js b/ui/scripts/configuration.js
index 8fb7ebe..6c3ffd8 100644
--- a/ui/scripts/configuration.js
+++ b/ui/scripts/configuration.js
@@ -2811,6 +2811,60 @@
                                         }
                                     },
 
+                                    promiscuousMode: {
+                                        label: 'label.promiscuous.mode',
+                                        select: function(args) {
+                                            args.response.success({
+                                                data: [{
+                                                    id: '',
+                                                    description: ''
+                                                }, {
+                                                    id: 'true',
+                                                    description: 'Accept'
+                                                }, {
+                                                    id: 'false',
+                                                    description: 'Reject'
+                                                }]
+                                            });
+                                        }
+                                    },
+
+                                    macAddressChanges: {
+                                        label: 'label.mac.address.changes',
+                                        select: function(args) {
+                                            args.response.success({
+                                                data: [{
+                                                    id: '',
+                                                    description: ''
+                                                }, {
+                                                    id: 'true',
+                                                    description: 'Accept'
+                                                }, {
+                                                    id: 'false',
+                                                    description: 'Reject'
+                                                }]
+                                            });
+                                        }
+                                    },
+
+                                    forgedTransmits: {
+                                        label: 'label.forged.transmits',
+                                        select: function(args) {
+                                            args.response.success({
+                                                data: [{
+                                                    id: '',
+                                                    description: ''
+                                                }, {
+                                                    id: 'true',
+                                                    description: 'Accept'
+                                                }, {
+                                                    id: 'false',
+                                                    description: 'Reject'
+                                                }]
+                                            });
+                                        }
+                                    },
+
                                     supportedServices: {
                                         label: 'label.supported.services',
 
@@ -3341,6 +3395,22 @@
                                     delete inputData.egressdefaultpolicy;
                                 }
 
+                                if ("promiscuousMode" in inputData) {
+                                    inputData['details[0].promiscuousMode'] = inputData.promiscuousMode;
+                                    delete inputData.promiscuousMode;
+                                }
+
+                                if ("macAddressChanges" in inputData) {
+                                    inputData['details[0].macAddressChanges'] = inputData.macAddressChanges;
+                                    delete inputData.macAddressChanges;
+                                }
+
+                                if ("forgedTransmits" in inputData) {
+                                    inputData['details[0].forgedTransmits'] = inputData.forgedTransmits;
+                                    delete inputData.forgedTransmits;
+                                }
+
+
                                 if (args.$form.find('.form-item[rel=serviceofferingid]').css("display") == "none")
                                     delete inputData.serviceofferingid;
 
@@ -3639,6 +3709,9 @@
                                     },
                                     tags: {
                                         label: 'label.tags'
+                                    },
+                                    details: {
+                                        label: 'label.details'
                                     }
                                 }],
 
@@ -3649,9 +3722,16 @@
                                         async: true,
                                         success: function(json) {
                                             var item = json.listnetworkofferingsresponse.networkoffering[0];
+                                            if (!item.hasOwnProperty('details')) {
+                                                item.details = {};
+                                            }
                                             args.response.success({
                                                 actionFilter: networkOfferingActionfilter,
                                                 data: $.extend(item, {
+                                                    details: $.map(item.details, function(val, key) {
+                                                        return key + "=" + val;
+                                                    }).join(', '),
+
                                                     supportedServices: $.map(item.service, function(service) {
                                                         return service.name;
                                                     }).join(', '),
diff --git a/utils/src/main/java/com/cloud/utils/UriUtils.java b/utils/src/main/java/com/cloud/utils/UriUtils.java
index 631c629..8805891 100644
--- a/utils/src/main/java/com/cloud/utils/UriUtils.java
+++ b/utils/src/main/java/com/cloud/utils/UriUtils.java
@@ -30,6 +30,7 @@ import java.net.URISyntaxException;
 import java.net.URLEncoder;
 import java.net.UnknownHostException;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.ListIterator;
 import java.util.StringTokenizer;
@@ -55,6 +56,7 @@ import org.apache.log4j.Logger;
 
 import com.cloud.utils.crypt.DBEncryptionUtil;
 import com.cloud.utils.exception.CloudRuntimeException;
+import com.google.common.base.Strings;
 
 public class UriUtils {
 
@@ -391,4 +393,52 @@ public class UriUtils {
             return null;
         }
     }
+
+    /**
+     * Expands a given vlan URI to a list of vlan IDs
+     * @param vlanAuthority the URI part without the vlan:// scheme
+     * @return returns list of vlan integer ids
+     */
+    public static List<Integer> expandVlanUri(final String vlanAuthority) {
+        final List<Integer> expandedVlans = new ArrayList<>();
+        if (Strings.isNullOrEmpty(vlanAuthority)) {
+            return expandedVlans;
+        }
+        for (final String vlanPart: vlanAuthority.split(",")) {
+            if (Strings.isNullOrEmpty(vlanPart)) {
+                continue;
+            }
+            final String[] range = vlanPart.split("-");
+            if (range.length == 2) {
+                Integer start = NumbersUtil.parseInt(range[0], -1);
+                Integer end = NumbersUtil.parseInt(range[1], -1);
+                if (start <= end && end > -1 && start > -1) {
+                    while (start <= end) {
+                        expandedVlans.add(start++);
+                    }
+                }
+            } else {
+                final Integer value = NumbersUtil.parseInt(range[0], -1);
+                if (value > -1) {
+                    expandedVlans.add(value);
+                }
+            }
+        }
+        return expandedVlans;
+    }
+
+    /**
+     * Checks if given vlan URI authorities overlap
+     * @param vlanRange1
+     * @param vlanRange2
+     * @return true if they overlap
+     */
+    public static boolean checkVlanUriOverlap(final String vlanRange1, final String vlanRange2) {
+        final List<Integer> vlans1 = expandVlanUri(vlanRange1);
+        final List<Integer> vlans2 = expandVlanUri(vlanRange2);
+        if (vlans1 == null || vlans2 == null) {
+            return true;
+        }
+        return !Collections.disjoint(vlans1, vlans2);
+    }
 }
diff --git a/utils/src/test/java/com/cloud/utils/UriUtilsTest.java b/utils/src/test/java/com/cloud/utils/UriUtilsTest.java
index d2fd997..b8d951d 100644
--- a/utils/src/test/java/com/cloud/utils/UriUtilsTest.java
+++ b/utils/src/test/java/com/cloud/utils/UriUtilsTest.java
@@ -20,9 +20,12 @@
 package com.cloud.utils;
 
 import junit.framework.Assert;
-
 import org.junit.Test;
 
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
 public class UriUtilsTest {
     @Test
     public void encodeURIComponent() {
@@ -57,4 +60,45 @@ public class UriUtilsTest {
         //XXX: Interesting cases not covered:
         // * port is ignored and left out from the return value
     }
+
+    @Test
+    public void expandVlanEmpty() {
+        List<Integer> vlans = UriUtils.expandVlanUri("");
+        Assert.assertTrue(vlans.size() == 0);
+    }
+
+    @Test
+    public void expandVlanSingleValue() {
+        List<Integer> vlans = UriUtils.expandVlanUri("10");
+        Assert.assertTrue(vlans.size() == 1);
+        Assert.assertEquals(vlans, Collections.singletonList(10));
+    }
+
+    @Test
+    public void expandVlanValidRange() {
+        List<Integer> vlans = UriUtils.expandVlanUri("10-12,14,17,40-43");
+        Assert.assertEquals(vlans, Arrays.asList(10,11,12,14,17,40,41,42,43));
+    }
+
+    @Test
+    public void expandVlanInvalidRange() {
+        List<Integer> vlans = UriUtils.expandVlanUri("10-,12-14,-4,5-2");
+        Assert.assertEquals(vlans, Arrays.asList(10,12,13,14));
+    }
+
+    @Test
+    public void testVlanUriOverlap() {
+        Assert.assertTrue(UriUtils.checkVlanUriOverlap("10-30,45,50,12,31", "10"));
+        Assert.assertTrue(UriUtils.checkVlanUriOverlap("10-30,45,50,12,31", "32,33-44,30-31"));
+        Assert.assertTrue(UriUtils.checkVlanUriOverlap("10-30", "25-35"));
+    }
+
+    @Test
+    public void testVlanUriNoOverlap() {
+        Assert.assertFalse(UriUtils.checkVlanUriOverlap("10-30,45,50,12,31", null));
+        Assert.assertFalse(UriUtils.checkVlanUriOverlap("10-30,45,50,12,31", ""));
+        Assert.assertFalse(UriUtils.checkVlanUriOverlap("10-30,45,50,12,31", "32"));
+        Assert.assertFalse(UriUtils.checkVlanUriOverlap("10,22,111", "12"));
+        Assert.assertFalse(UriUtils.checkVlanUriOverlap("100-200", "30-40,50,201-250"));
+    }
 }
diff --git a/vmware-base/pom.xml b/vmware-base/pom.xml
index 44681e9..01cfb3a 100644
--- a/vmware-base/pom.xml
+++ b/vmware-base/pom.xml
@@ -43,6 +43,11 @@
         <version>${project.version}</version>
     </dependency>
     <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-engine-api</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
       <groupId>com.google.code.gson</groupId>
       <artifactId>gson</artifactId>
     </dependency>
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java
index ef3f0ae..bece91a 100644
--- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java
+++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java
@@ -16,11 +16,45 @@
 // under the License.
 package com.cloud.hypervisor.vmware.mo;
 
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.security.InvalidParameterException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.traversal.DocumentTraversal;
+import org.w3c.dom.traversal.NodeFilter;
+import org.w3c.dom.traversal.NodeIterator;
+import org.xml.sax.SAXException;
+
 import com.cloud.exception.CloudException;
 import com.cloud.hypervisor.vmware.util.VmwareContext;
 import com.cloud.hypervisor.vmware.util.VmwareHelper;
 import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.offering.NetworkOffering;
 import com.cloud.utils.ActionDelegate;
+import com.cloud.utils.NumbersUtil;
 import com.cloud.utils.Pair;
 import com.cloud.utils.cisco.n1kv.vsm.NetconfHelper;
 import com.cloud.utils.cisco.n1kv.vsm.PolicyMap;
@@ -54,6 +88,7 @@ import com.vmware.vim25.LocalizedMethodFault;
 import com.vmware.vim25.LongPolicy;
 import com.vmware.vim25.ManagedObjectReference;
 import com.vmware.vim25.MethodFault;
+import com.vmware.vim25.NumericRange;
 import com.vmware.vim25.ObjectContent;
 import com.vmware.vim25.OvfCreateImportSpecParams;
 import com.vmware.vim25.OvfCreateImportSpecResult;
@@ -79,35 +114,9 @@ import com.vmware.vim25.VirtualMachineVideoCard;
 import com.vmware.vim25.VirtualSCSIController;
 import com.vmware.vim25.VirtualSCSISharing;
 import com.vmware.vim25.VmwareDistributedVirtualSwitchPvlanSpec;
+import com.vmware.vim25.VmwareDistributedVirtualSwitchTrunkVlanSpec;
 import com.vmware.vim25.VmwareDistributedVirtualSwitchVlanIdSpec;
 import com.vmware.vim25.VmwareDistributedVirtualSwitchVlanSpec;
-import org.apache.log4j.Logger;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.traversal.DocumentTraversal;
-import org.w3c.dom.traversal.NodeFilter;
-import org.w3c.dom.traversal.NodeIterator;
-import org.xml.sax.SAXException;
-
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.StringWriter;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.security.InvalidParameterException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
 
 public class HypervisorHostHelper {
     private static final Logger s_logger = Logger.getLogger(HypervisorHostHelper.class);
@@ -452,13 +461,14 @@ public class HypervisorHostHelper {
      * @param timeOutMs
      * @param vSwitchType
      * @param numPorts
+     * @param details
      * @return
      * @throws Exception
      */
 
     public static Pair<ManagedObjectReference, String> prepareNetwork(String physicalNetwork, String namePrefix, HostMO hostMo, String vlanId, String secondaryvlanId,
-            Integer networkRateMbps, Integer networkRateMulticastMbps, long timeOutMs, VirtualSwitchType vSwitchType, int numPorts, String gateway,
-            boolean configureVServiceInNexus, BroadcastDomainType broadcastDomainType, Map<String, String> vsmCredentials) throws Exception {
+                                                                      Integer networkRateMbps, Integer networkRateMulticastMbps, long timeOutMs, VirtualSwitchType vSwitchType, int numPorts, String gateway,
+                                                                      boolean configureVServiceInNexus, BroadcastDomainType broadcastDomainType, Map<String, String> vsmCredentials, Map<NetworkOffering.Detail, String> details) throws Exception {
         ManagedObjectReference morNetwork = null;
         VmwareContext context = hostMo.getContext();
         ManagedObjectReference dcMor = hostMo.getHyperHostDatacenter();
@@ -501,12 +511,18 @@ public class HypervisorHostHelper {
             // No doubt about this, depending on vid=null to avoid lots of code below
             vid = null;
         } else {
+            if (vlanId != null) {
+                vlanId = vlanId.replace("vlan://", "");
+            }
             networkName = composeCloudNetworkName(namePrefix, vlanId, secondaryvlanId, networkRateMbps, physicalNetwork);
 
-            if (vlanId != null && !UNTAGGED_VLAN_NAME.equalsIgnoreCase(vlanId)) {
+            if (vlanId != null && !UNTAGGED_VLAN_NAME.equalsIgnoreCase(vlanId) && !StringUtils.containsAny(vlanId, ",-")) {
                 createGCTag = true;
                 vid = Integer.parseInt(vlanId);
             }
+            if (vlanId != null && StringUtils.containsAny(vlanId, ",-")) {
+                createGCTag = true;
+            }
             if (secondaryvlanId != null) {
                 spvlanid = Integer.parseInt(secondaryvlanId);
             }
@@ -544,7 +560,7 @@ public class HypervisorHostHelper {
                 dvSwitchMo = new DistributedVirtualSwitchMO(context, morDvSwitch);
 
                 shapingPolicy = getDVSShapingPolicy(networkRateMbps);
-                secPolicy = createDVSSecurityPolicy();
+                secPolicy = createDVSSecurityPolicy(details);
 
                 // First, if both vlan id and pvlan id are provided, we need to
                 // reconfigure the DVSwitch to have a tuple <vlan id, pvlan id> of
@@ -562,7 +578,7 @@ public class HypervisorHostHelper {
                     portGroupPolicy.setPortConfigResetAtDisconnect(true);
                 }
                 // Next, create the port group. For this, we need to create a VLAN spec.
-                createPortGroup(physicalNetwork, networkName, vid, spvlanid, dataCenterMo, shapingPolicy, secPolicy, portGroupPolicy, dvSwitchMo, numPorts, autoExpandSupported);
+                createPortGroup(physicalNetwork, networkName, vlanId, vid, spvlanid, dataCenterMo, shapingPolicy, secPolicy, portGroupPolicy, dvSwitchMo, numPorts, autoExpandSupported);
                 bWaitPortGroupReady = true;
             }
         } else if (vSwitchType == VirtualSwitchType.NexusDistributedVirtualSwitch) {
@@ -699,8 +715,8 @@ public class HypervisorHostHelper {
 
     }
 
-    private static void createPortGroup(String physicalNetwork, String networkName, Integer vid, Integer spvlanid, DatacenterMO dataCenterMo,
-            DVSTrafficShapingPolicy shapingPolicy, DVSSecurityPolicy secPolicy, VMwareDVSPortgroupPolicy portGroupPolicy, DistributedVirtualSwitchMO dvSwitchMo, int numPorts, boolean autoExpandSupported)
+    private static void createPortGroup(String physicalNetwork, String networkName, String vlanRange, Integer vid, Integer spvlanid, DatacenterMO dataCenterMo,
+                                        DVSTrafficShapingPolicy shapingPolicy, DVSSecurityPolicy secPolicy, VMwareDVSPortgroupPolicy portGroupPolicy, DistributedVirtualSwitchMO dvSwitchMo, int numPorts, boolean autoExpandSupported)
                     throws Exception {
         VmwareDistributedVirtualSwitchVlanSpec vlanSpec = null;
         VmwareDistributedVirtualSwitchPvlanSpec pvlanSpec = null;
@@ -710,7 +726,7 @@ public class HypervisorHostHelper {
         // Next, create the port group. For this, we need to create a VLAN spec.
         // NOTE - VmwareDistributedVirtualSwitchPvlanSpec extends VmwareDistributedVirtualSwitchVlanSpec.
         if (vid == null || spvlanid == null) {
-            vlanSpec = createDVPortVlanIdSpec(vid);
+            vlanSpec = createDVPortVlanSpec(vid, vlanRange);
             dvsPortSetting = createVmwareDVPortSettingSpec(shapingPolicy, secPolicy, vlanSpec);
         } else if (spvlanid != null) {
             // Create a pvlan spec. The pvlan spec is different from the pvlan config spec
@@ -851,12 +867,57 @@ public class HypervisorHostHelper {
             }
         }
 
-        VmwareDistributedVirtualSwitchVlanIdSpec oldVlanSpec = (VmwareDistributedVirtualSwitchVlanIdSpec)((
-                VMwareDVSPortSetting)currentDvPortgroupInfo.getDefaultPortConfig()).getVlan();
-        VmwareDistributedVirtualSwitchVlanIdSpec newVlanSpec = (VmwareDistributedVirtualSwitchVlanIdSpec)((
-                VMwareDVSPortSetting)newDvPortGroupSpec.getDefaultPortConfig()).getVlan();
-        int oldVlanId = oldVlanSpec.getVlanId();
-        int newVlanId = newVlanSpec.getVlanId();
+        VMwareDVSPortSetting currentPortSetting = ((VMwareDVSPortSetting)currentDvPortgroupInfo.getDefaultPortConfig());
+        VMwareDVSPortSetting newPortSetting = ((VMwareDVSPortSetting)newDvPortGroupSpec.getDefaultPortConfig());
+        if ((currentPortSetting.getSecurityPolicy() == null && newPortSetting.getSecurityPolicy() != null) ||
+                (currentPortSetting.getSecurityPolicy() != null && newPortSetting.getSecurityPolicy() == null)) {
+            specMatches = false;
+        }
+        if (currentPortSetting.getSecurityPolicy() != null && newPortSetting.getSecurityPolicy() != null) {
+            if (currentPortSetting.getSecurityPolicy().getAllowPromiscuous() != null &&
+                    newPortSetting.getSecurityPolicy().getAllowPromiscuous() != null &&
+                    newPortSetting.getSecurityPolicy().getAllowPromiscuous().isValue() != null &&
+                    !newPortSetting.getSecurityPolicy().getAllowPromiscuous().isValue().equals(currentPortSetting.getSecurityPolicy().getAllowPromiscuous().isValue())) {
+                specMatches = false;
+            }
+            if (currentPortSetting.getSecurityPolicy().getForgedTransmits() != null &&
+                    newPortSetting.getSecurityPolicy().getForgedTransmits() != null &&
+                    newPortSetting.getSecurityPolicy().getForgedTransmits().isValue() != null &&
+                    !newPortSetting.getSecurityPolicy().getForgedTransmits().isValue().equals(currentPortSetting.getSecurityPolicy().getForgedTransmits().isValue())) {
+                specMatches = false;
+            }
+            if (currentPortSetting.getSecurityPolicy().getMacChanges() != null &&
+                    newPortSetting.getSecurityPolicy().getMacChanges() != null &&
+                    newPortSetting.getSecurityPolicy().getMacChanges().isValue() != null &&
+                    !newPortSetting.getSecurityPolicy().getMacChanges().isValue().equals(currentPortSetting.getSecurityPolicy().getMacChanges().isValue())) {
+                specMatches = false;
+            }
+        }
+
+        VmwareDistributedVirtualSwitchVlanSpec oldVlanSpec = currentPortSetting.getVlan();
+        VmwareDistributedVirtualSwitchVlanSpec newVlanSpec = newPortSetting.getVlan();
+
+        int oldVlanId, newVlanId;
+        if (oldVlanSpec instanceof VmwareDistributedVirtualSwitchPvlanSpec && newVlanSpec instanceof VmwareDistributedVirtualSwitchPvlanSpec) {
+            VmwareDistributedVirtualSwitchPvlanSpec oldpVlanSpec = (VmwareDistributedVirtualSwitchPvlanSpec) oldVlanSpec;
+            VmwareDistributedVirtualSwitchPvlanSpec newpVlanSpec = (VmwareDistributedVirtualSwitchPvlanSpec) newVlanSpec;
+            oldVlanId = oldpVlanSpec.getPvlanId();
+            newVlanId = newpVlanSpec.getPvlanId();
+        } else if (oldVlanSpec instanceof VmwareDistributedVirtualSwitchTrunkVlanSpec && newVlanSpec instanceof VmwareDistributedVirtualSwitchTrunkVlanSpec) {
+            VmwareDistributedVirtualSwitchTrunkVlanSpec oldpVlanSpec = (VmwareDistributedVirtualSwitchTrunkVlanSpec) oldVlanSpec;
+            VmwareDistributedVirtualSwitchTrunkVlanSpec newpVlanSpec = (VmwareDistributedVirtualSwitchTrunkVlanSpec) newVlanSpec;
+            oldVlanId = oldpVlanSpec.getVlanId().get(0).getStart();
+            newVlanId = newpVlanSpec.getVlanId().get(0).getStart();
+        } else if (oldVlanSpec instanceof VmwareDistributedVirtualSwitchVlanIdSpec && newVlanSpec instanceof VmwareDistributedVirtualSwitchVlanIdSpec) {
+            VmwareDistributedVirtualSwitchVlanIdSpec oldVlanIdSpec = (VmwareDistributedVirtualSwitchVlanIdSpec) oldVlanSpec;
+            VmwareDistributedVirtualSwitchVlanIdSpec newVlanIdSpec = (VmwareDistributedVirtualSwitchVlanIdSpec) newVlanSpec;
+            oldVlanId = oldVlanIdSpec.getVlanId();
+            newVlanId = newVlanIdSpec.getVlanId();
+        } else {
+            s_logger.debug("Old and new vlan spec type mismatch found for [" + dvPortGroupName + "] has changed. Old spec type is: " + oldVlanSpec.getClass() + ", and new spec type is:" + newVlanSpec.getClass());
+            return false;
+        }
+
         if (oldVlanId != newVlanId) {
             s_logger.info("Detected that new VLAN [" + newVlanId + "] of dvPortGroup [" + dvPortGroupName +
                         "] is different from current VLAN [" + oldVlanId + "]");
@@ -994,25 +1055,114 @@ public class HypervisorHostHelper {
         return pvlanConfigSpec;
     }
 
-    public static VmwareDistributedVirtualSwitchVlanIdSpec createDVPortVlanIdSpec(Integer vlanId) {
+    public static VmwareDistributedVirtualSwitchVlanSpec createDVPortVlanSpec(Integer vlanId, String vlanRange) {
+        if (vlanId == null && vlanRange != null && !vlanRange.isEmpty()) {
+            s_logger.debug("Creating dvSwitch port vlan-trunk spec with range: " + vlanRange);
+            VmwareDistributedVirtualSwitchTrunkVlanSpec trunkVlanSpec = new VmwareDistributedVirtualSwitchTrunkVlanSpec();
+            for (final String vlanRangePart : vlanRange.split(",")) {
+                if (vlanRangePart == null || vlanRange.isEmpty()) {
+                    continue;
+                }
+                final NumericRange numericRange = new NumericRange();
+                if (vlanRangePart.contains("-")) {
+                    final String[] range = vlanRangePart.split("-");
+                    if (range.length == 2 && range[0] != null && range[1] != null) {
+                        numericRange.setStart(NumbersUtil.parseInt(range[0], 0));
+                        numericRange.setEnd(NumbersUtil.parseInt(range[1], 0));
+                    } else {
+                        continue;
+                    }
+                } else {
+                    numericRange.setStart(NumbersUtil.parseInt(vlanRangePart, 0));
+                    numericRange.setEnd(NumbersUtil.parseInt(vlanRangePart, 0));
+                }
+                trunkVlanSpec.getVlanId().add(numericRange);
+            }
+            if (trunkVlanSpec.getVlanId().size() != 0) {
+                return trunkVlanSpec;
+            }
+        }
         VmwareDistributedVirtualSwitchVlanIdSpec vlanIdSpec = new VmwareDistributedVirtualSwitchVlanIdSpec();
-        vlanIdSpec.setVlanId(vlanId == null ? 0 : vlanId.intValue());
+        vlanIdSpec.setVlanId(vlanId == null ? 0 : vlanId);
+        s_logger.debug("Creating dvSwitch port vlan-id spec with id: " + vlanIdSpec.getVlanId());
         return vlanIdSpec;
     }
 
-    public static DVSSecurityPolicy createDVSSecurityPolicy() {
+    public static Map<NetworkOffering.Detail, String> getDefaultSecurityDetails() {
+        final Map<NetworkOffering.Detail, String> details = new HashMap<>();
+        details.put(NetworkOffering.Detail.PromiscuousMode, NetworkOrchestrationService.PromiscuousMode.value().toString());
+        details.put(NetworkOffering.Detail.MacAddressChanges, NetworkOrchestrationService.MacAddressChanges.value().toString());
+        details.put(NetworkOffering.Detail.ForgedTransmits, NetworkOrchestrationService.ForgedTransmits.value().toString());
+        return details;
+    }
+
+    public static DVSSecurityPolicy createDVSSecurityPolicy(Map<NetworkOffering.Detail, String> nicDetails) {
         DVSSecurityPolicy secPolicy = new DVSSecurityPolicy();
         BoolPolicy allow = new BoolPolicy();
         allow.setValue(true);
+        BoolPolicy deny = new BoolPolicy();
+        deny.setValue(false);
 
+        secPolicy.setAllowPromiscuous(deny);
         secPolicy.setForgedTransmits(allow);
-        secPolicy.setAllowPromiscuous(allow);
         secPolicy.setMacChanges(allow);
+
+        if (nicDetails == null) {
+            nicDetails = getDefaultSecurityDetails();
+        }
+
+        if (nicDetails.containsKey(NetworkOffering.Detail.PromiscuousMode)) {
+            if (Boolean.valueOf(nicDetails.get(NetworkOffering.Detail.PromiscuousMode))) {
+                secPolicy.setAllowPromiscuous(allow);
+            } else {
+                secPolicy.setAllowPromiscuous(deny);
+            }
+        }
+        if (nicDetails.containsKey(NetworkOffering.Detail.ForgedTransmits)) {
+            if (Boolean.valueOf(nicDetails.get(NetworkOffering.Detail.ForgedTransmits))) {
+                secPolicy.setForgedTransmits(allow);
+            } else {
+                secPolicy.setForgedTransmits(deny);
+            }
+        }
+        if (nicDetails.containsKey(NetworkOffering.Detail.MacAddressChanges)) {
+            if (Boolean.valueOf(nicDetails.get(NetworkOffering.Detail.MacAddressChanges))) {
+                secPolicy.setMacChanges(allow);
+            } else {
+                secPolicy.setMacChanges(deny);
+            }
+        }
+
+        return secPolicy;
+    }
+
+    public static HostNetworkSecurityPolicy createVSSecurityPolicy(Map<NetworkOffering.Detail, String> nicDetails) {
+        HostNetworkSecurityPolicy secPolicy = new HostNetworkSecurityPolicy();
+        secPolicy.setAllowPromiscuous(Boolean.FALSE);
+        secPolicy.setForgedTransmits(Boolean.TRUE);
+        secPolicy.setMacChanges(Boolean.TRUE);
+
+        if (nicDetails == null) {
+            nicDetails = getDefaultSecurityDetails();
+        }
+
+        if (nicDetails.containsKey(NetworkOffering.Detail.PromiscuousMode)) {
+            secPolicy.setAllowPromiscuous(Boolean.valueOf(nicDetails.get(NetworkOffering.Detail.PromiscuousMode)));
+        }
+
+        if (nicDetails.containsKey(NetworkOffering.Detail.ForgedTransmits)) {
+            secPolicy.setForgedTransmits(Boolean.valueOf(nicDetails.get(NetworkOffering.Detail.ForgedTransmits)));
+        }
+
+        if (nicDetails.containsKey(NetworkOffering.Detail.MacAddressChanges)) {
+            secPolicy.setMacChanges(Boolean.valueOf(nicDetails.get(NetworkOffering.Detail.MacAddressChanges)));
+        }
+
         return secPolicy;
     }
 
     public static Pair<ManagedObjectReference, String> prepareNetwork(String vSwitchName, String namePrefix, HostMO hostMo, String vlanId, Integer networkRateMbps,
-            Integer networkRateMulticastMbps, long timeOutMs, boolean syncPeerHosts, BroadcastDomainType broadcastDomainType, String nicUuid) throws Exception {
+                                                                      Integer networkRateMulticastMbps, long timeOutMs, boolean syncPeerHosts, BroadcastDomainType broadcastDomainType, String nicUuid, Map<NetworkOffering.Detail, String> nicDetails) throws Exception {
 
         HostVirtualSwitch vSwitch;
         if (vSwitchName == null) {
@@ -1059,13 +1209,8 @@ public class HypervisorHostHelper {
             }
         }
 
-        HostNetworkSecurityPolicy secPolicy = null;
-        if (namePrefix.equalsIgnoreCase("cloud.private")) {
-            secPolicy = new HostNetworkSecurityPolicy();
-            secPolicy.setAllowPromiscuous(Boolean.TRUE);
-            secPolicy.setForgedTransmits(Boolean.TRUE);
-            secPolicy.setMacChanges(Boolean.TRUE);
-        }
+        HostNetworkSecurityPolicy secPolicy = createVSSecurityPolicy(nicDetails);
+
         HostNetworkTrafficShapingPolicy shapingPolicy = null;
         if (networkRateMbps != null && networkRateMbps.intValue() > 0) {
             shapingPolicy = new HostNetworkTrafficShapingPolicy();
@@ -1105,7 +1250,7 @@ public class HypervisorHostHelper {
                 bWaitPortGroupReady = false;
             } else {
                 HostPortGroupSpec spec = hostMo.getPortGroupSpec(networkName);
-                if (!isSpecMatch(spec, vid, shapingPolicy)) {
+                if (!isSpecMatch(spec, vid, secPolicy, shapingPolicy)) {
                     hostMo.updatePortGroup(vSwitch, networkName, vid, secPolicy, shapingPolicy);
                     bWaitPortGroupReady = true;
                 }
@@ -1149,7 +1294,7 @@ public class HypervisorHostHelper {
                                             if (s_logger.isDebugEnabled())
                                                 s_logger.debug("Prepare network on other host, vlan: " + vlanId + ", host: " + otherHostMo.getHostName());
                                             prepareNetwork(vSwitchName, namePrefix, otherHostMo, vlanId, networkRateMbps, networkRateMulticastMbps, timeOutMs, false,
-                                                    broadcastDomainType, nicUuid);
+                                                    broadcastDomainType, nicUuid, nicDetails);
                                         } catch (Exception e) {
                                             s_logger.warn("Unable to prepare network on other host, vlan: " + vlanId + ", host: " + otherHostMo.getHostName());
                                         }
@@ -1172,7 +1317,7 @@ public class HypervisorHostHelper {
         return new Pair<ManagedObjectReference, String>(morNetwork, networkName);
     }
 
-    private static boolean isSpecMatch(HostPortGroupSpec spec, Integer vlanId, HostNetworkTrafficShapingPolicy shapingPolicy) {
+    private static boolean isSpecMatch(HostPortGroupSpec spec, Integer vlanId, HostNetworkSecurityPolicy securityPolicy, HostNetworkTrafficShapingPolicy shapingPolicy) {
         // check VLAN configuration
         if (vlanId != null) {
             if (vlanId.intValue() != spec.getVlanId())
@@ -1182,16 +1327,36 @@ public class HypervisorHostHelper {
                 return false;
         }
 
+        // check security policy for the portgroup
+        HostNetworkSecurityPolicy secPolicyInSpec = null;
+        if (spec.getPolicy() != null) {
+            secPolicyInSpec = spec.getPolicy().getSecurity();
+        }
+
+        if ((secPolicyInSpec != null && securityPolicy == null) || (secPolicyInSpec == null && securityPolicy != null)) {
+            return false;
+        }
+
+        if (secPolicyInSpec != null && securityPolicy != null
+                && ((securityPolicy.isAllowPromiscuous() != null && !securityPolicy.isAllowPromiscuous().equals(secPolicyInSpec.isAllowPromiscuous()))
+                    || (securityPolicy.isForgedTransmits() != null && !securityPolicy.isForgedTransmits().equals(secPolicyInSpec.isForgedTransmits()))
+                    || (securityPolicy.isMacChanges() != null && securityPolicy.isMacChanges().equals(secPolicyInSpec.isMacChanges())))) {
+            return false;
+        }
+
         // check traffic shaping configuration
         HostNetworkTrafficShapingPolicy policyInSpec = null;
-        if (spec.getPolicy() != null)
+        if (spec.getPolicy() != null) {
             policyInSpec = spec.getPolicy().getShapingPolicy();
+        }
 
-        if (policyInSpec != null && shapingPolicy == null || policyInSpec == null && shapingPolicy != null)
+        if ((policyInSpec != null && shapingPolicy == null) || (policyInSpec == null && shapingPolicy != null)) {
             return false;
+        }
 
-        if (policyInSpec == null && shapingPolicy == null)
+        if (policyInSpec == null && shapingPolicy == null) {
             return true;
+        }
 
         // so far policyInSpec and shapingPolicy should both not be null
         if (policyInSpec.isEnabled() == null || !policyInSpec.isEnabled().booleanValue())
diff --git a/vmware-base/test/com/cloud/hypervisor/vmware/mo/HypervisorHostHelperTest.java b/vmware-base/test/com/cloud/hypervisor/vmware/mo/HypervisorHostHelperTest.java
index 2fc9995..545104d 100644
--- a/vmware-base/test/com/cloud/hypervisor/vmware/mo/HypervisorHostHelperTest.java
+++ b/vmware-base/test/com/cloud/hypervisor/vmware/mo/HypervisorHostHelperTest.java
@@ -16,31 +16,40 @@
 // under the License.
 package com.cloud.hypervisor.vmware.mo;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
 import com.cloud.hypervisor.vmware.util.VmwareContext;
+import com.cloud.offering.NetworkOffering;
 import com.vmware.vim25.AboutInfo;
 import com.vmware.vim25.BoolPolicy;
 import com.vmware.vim25.DVPortgroupConfigInfo;
 import com.vmware.vim25.DVPortgroupConfigSpec;
+import com.vmware.vim25.DVSSecurityPolicy;
 import com.vmware.vim25.DVSTrafficShapingPolicy;
+import com.vmware.vim25.HostNetworkSecurityPolicy;
 import com.vmware.vim25.LongPolicy;
 import com.vmware.vim25.ServiceContent;
 import com.vmware.vim25.VMwareDVSPortSetting;
+import com.vmware.vim25.VmwareDistributedVirtualSwitchTrunkVlanSpec;
 import com.vmware.vim25.VmwareDistributedVirtualSwitchVlanIdSpec;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
+import com.vmware.vim25.VmwareDistributedVirtualSwitchVlanSpec;
 
 public class HypervisorHostHelperTest {
     @Mock
@@ -774,4 +783,104 @@ public class HypervisorHostHelperTest {
                 "</Envelope>";
         assertEquals(expected, HypervisorHostHelper.removeOVFNetwork(ovfString));
     }
+
+    private Map<NetworkOffering.Detail, String> getSecurityDetails() {
+        final Map<NetworkOffering.Detail, String> details = new HashMap<>();
+        details.put(NetworkOffering.Detail.PromiscuousMode, "false");
+        details.put(NetworkOffering.Detail.ForgedTransmits, "false");
+        details.put(NetworkOffering.Detail.MacAddressChanges, "false");
+        return details;
+    }
+
+    @Test
+    public void testVSSecurityPolicyDefault() {
+        HostNetworkSecurityPolicy secPolicy = HypervisorHostHelper.createVSSecurityPolicy(null);
+        assertFalse(secPolicy.isAllowPromiscuous());
+        assertTrue(secPolicy.isForgedTransmits());
+        assertTrue(secPolicy.isMacChanges());
+    }
+
+    @Test
+    public void testVSSecurityPolicyDefaultWithDetail() {
+        HostNetworkSecurityPolicy secPolicy = HypervisorHostHelper.createVSSecurityPolicy(getSecurityDetails());
+        assertFalse(secPolicy.isAllowPromiscuous());
+        assertFalse(secPolicy.isForgedTransmits());
+        assertFalse(secPolicy.isMacChanges());
+    }
+
+    @Test
+    public void testVSSecurityPolicyWithDetail() {
+        Map<NetworkOffering.Detail, String> details = getSecurityDetails();
+        details.put(NetworkOffering.Detail.MacAddressChanges, "true");
+        HostNetworkSecurityPolicy secPolicy = HypervisorHostHelper.createVSSecurityPolicy(details);
+        assertFalse(secPolicy.isAllowPromiscuous());
+        assertFalse(secPolicy.isForgedTransmits());
+        assertTrue(secPolicy.isMacChanges());
+    }
+
+    @Test
+    public void testDVSSecurityPolicyDefault() {
+        DVSSecurityPolicy secPolicy = HypervisorHostHelper.createDVSSecurityPolicy(null);
+        assertFalse(secPolicy.getAllowPromiscuous().isValue());
+        assertTrue(secPolicy.getForgedTransmits().isValue());
+        assertTrue(secPolicy.getMacChanges().isValue());
+    }
+
+    @Test
+    public void testDVSSecurityPolicyDefaultWithDetail() {
+        Map<NetworkOffering.Detail, String> details = getSecurityDetails();
+        details.remove(NetworkOffering.Detail.ForgedTransmits);
+        details.remove(NetworkOffering.Detail.PromiscuousMode);
+        DVSSecurityPolicy secPolicy = HypervisorHostHelper.createDVSSecurityPolicy(details);
+        assertFalse(secPolicy.getAllowPromiscuous().isValue());
+        assertFalse(secPolicy.getMacChanges().isValue());
+        assertTrue(secPolicy.getForgedTransmits().isValue());
+    }
+
+    @Test
+    public void testDVSSecurityPolicyWithDetail() {
+        Map<NetworkOffering.Detail, String> details = getSecurityDetails();
+        details.put(NetworkOffering.Detail.ForgedTransmits, "true");
+        DVSSecurityPolicy secPolicy = HypervisorHostHelper.createDVSSecurityPolicy(details);
+        assertFalse(secPolicy.getAllowPromiscuous().isValue());
+        assertTrue(secPolicy.getForgedTransmits().isValue());
+        assertFalse(secPolicy.getMacChanges().isValue());
+    }
+
+    @Test
+    public void testCreateDVPortVlanSpecNullVlanId() {
+        VmwareDistributedVirtualSwitchVlanSpec spec = HypervisorHostHelper.createDVPortVlanSpec(null, null);
+        assertTrue(spec instanceof VmwareDistributedVirtualSwitchVlanIdSpec);
+        assertTrue(((VmwareDistributedVirtualSwitchVlanIdSpec) spec).getVlanId() == 0);
+    }
+
+    @Test
+    public void testCreateDVPortVlanSpecValidVlanId() {
+        VmwareDistributedVirtualSwitchVlanSpec spec = HypervisorHostHelper.createDVPortVlanSpec(100, "400");
+        assertTrue(spec instanceof VmwareDistributedVirtualSwitchVlanIdSpec);
+        assertTrue(((VmwareDistributedVirtualSwitchVlanIdSpec) spec).getVlanId() == 100);
+    }
+
+    @Test
+    public void testCreateDVPortVlanSpecValidVlanRange() {
+        VmwareDistributedVirtualSwitchVlanSpec spec = HypervisorHostHelper.createDVPortVlanSpec(null, "200-250");
+        assertTrue(spec instanceof VmwareDistributedVirtualSwitchTrunkVlanSpec);
+        assertTrue(((VmwareDistributedVirtualSwitchTrunkVlanSpec) spec).getVlanId().get(0).getStart() == 200);
+        assertTrue(((VmwareDistributedVirtualSwitchTrunkVlanSpec) spec).getVlanId().get(0).getEnd() == 250);
+    }
+
+    @Test
+    public void testCreateDVPortVlanSpecInvalidMissingVlanRange() {
+        VmwareDistributedVirtualSwitchVlanSpec spec = HypervisorHostHelper.createDVPortVlanSpec(null, "200-");
+        assertTrue(spec instanceof VmwareDistributedVirtualSwitchVlanIdSpec);
+        assertTrue(((VmwareDistributedVirtualSwitchVlanIdSpec) spec).getVlanId() == 0);
+    }
+
+    @Test
+    public void testCreateDVPortVlanSpecInvalidInputVlanRange() {
+        VmwareDistributedVirtualSwitchVlanSpec spec = HypervisorHostHelper.createDVPortVlanSpec(null, "a-b");
+        assertTrue(spec instanceof VmwareDistributedVirtualSwitchTrunkVlanSpec);
+        assertTrue(((VmwareDistributedVirtualSwitchTrunkVlanSpec) spec).getVlanId().get(0).getStart() == 0);
+        assertTrue(((VmwareDistributedVirtualSwitchTrunkVlanSpec) spec).getVlanId().get(0).getEnd() == 0);
+    }
 }

-- 
To stop receiving notification emails like this one, please contact
['"commits@cloudstack.apache.org" <commits@cloudstack.apache.org>'].

Mime
View raw message