cloudstack-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "ASF GitHub Bot (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (CLOUDSTACK-10047) DVSwitch improvements
Date Wed, 25 Oct 2017 09:45:01 GMT

    [ https://issues.apache.org/jira/browse/CLOUDSTACK-10047?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16218310#comment-16218310 ] 

ASF GitHub Bot commented on CLOUDSTACK-10047:
---------------------------------------------

rhtyd closed pull request #2293: CLOUDSTACK-10047: DVSwitch fixes and improvements
URL: https://github.com/apache/cloudstack/pull/2293
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/api/src/com/cloud/agent/api/to/NicTO.java b/api/src/com/cloud/agent/api/to/NicTO.java
index bd681f282cd..3863e1bafe7 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 @@
     boolean pxeDisable;
     String nicUuid;
     List<String> nicSecIps;
+    Map<NetworkOffering.Detail, String> details;
 
     public NicTO() {
         super();
@@ -97,4 +101,12 @@ public String getNetworkUuid() {
     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 f027cf9fe99..37746f0d0f7 100644
--- a/api/src/com/cloud/network/Networks.java
+++ b/api/src/com/cloud/network/Networks.java
@@ -75,6 +75,10 @@
                     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 59045dccd97..402846202e7 100644
--- a/api/src/com/cloud/offering/NetworkOffering.java
+++ b/api/src/com/cloud/offering/NetworkOffering.java
@@ -38,7 +38,7 @@
     }
 
     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 582ead6693d..1ec340df1e8 100644
--- a/api/src/org/apache/cloudstack/api/ApiConstants.java
+++ b/api/src/org/apache/cloudstack/api/ApiConstants.java
@@ -38,6 +38,7 @@
     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 6cf9e2308dc..6d346e9a4db 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 @@
     @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 String getVlan() {
         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 d1a34185eed..259c4905ed1 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 @@
     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 c9102d3a02a..ef582924342 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 void emptyBroadcastDomainTypeTest() throws URISyntaxException {
     }
 
     @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 68531e3ab3d..8a7a516f3d7 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 @@
     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 @@ void prepare(VirtualMachineProfile profile, DeployDestination dest, ReservationC
 
     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 46be654f581..eee159523cb 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 @@ NetworkOfferingVO createNetworkOffering(String name, String displayText, Traffic
         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 3956617859c..755fba2f74c 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.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.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.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.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.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.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 void expungeNics(final VirtualMachineProfile vm) {
     @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 Network createGuestNetwork(final long networkOfferingId, final String nam
         }
 
         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 Network createGuestNetwork(final long networkOfferingId, final String nam
                 } 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 String getConfigComponentName() {
 
     @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 1783231f4fb..556ab451391 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 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 3205fcd6af6..1c29e6a944c 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 @@
 
 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 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 void lockRange(long dcId, long physicalNetworkId, Integer start, Integer
     }
 
     @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 85544e78901..5091ebd75df 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 @@
 
     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 49a5944f838..11444b0d008 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.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.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 @@
     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 @@ protected void init() {
         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 String getNextAvailableMacAddress(final long networkConfigId, Integer zon
     }
 
     @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 long countByZoneAndUri(final long zoneId, final String broadcastUri) {
     }
 
     @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 53e3239113e..b7149ab2bf9 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 @@ private void prepareHost(HostMO hostMo, String privateTrafficLabel) throws Excep
         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 17064ff0d1e..9d32f3424de 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 @@ private void plugPublicNic(VirtualMachineMO vmMo, final String vlanId, final Str
         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 @@ private String getVlanInfo(NicTO nicTo, String defaultVlan) {
         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 @@ private String getVlanInfo(NicTO nicTo, String defaultVlan) {
             }
             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 3d2c236c39c..4dd52632338 100755
--- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
+++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
@@ -199,6 +199,7 @@
 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 Vlan doInTransaction(final TransactionStatus status) {
                     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 boolean hasSameSubnet(boolean ipv4, String vlanGateway, String vlanNetmas
     @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 Vlan createVlanAndPublicIpRange(final long zoneId, final long networkId,
                     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 Vlan createVlanAndPublicIpRange(final long zoneId, final long networkId,
                     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 Vlan createVlanAndPublicIpRange(final long zoneId, final long networkId,
         }
 
         // 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 d84c104f76b..0bf1c705759 100644
--- a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java
+++ b/server/src/com/cloud/hypervisor/HypervisorGuruBase.java
@@ -22,6 +22,7 @@
 
 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.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.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 @@
     @Inject
     private NetworkDao _networkDao;
     @Inject
+    private NetworkOfferingDetailsDao networkOfferingDetailsDao;
+    @Inject
     private VMInstanceDao _virtualMachineDao;
     @Inject
     private UserVmDetailsDao _userVmDetailsDao;
@@ -138,7 +143,18 @@ protected VirtualMachineTO toVirtualMachineTO(VirtualMachineProfile vmProfile) {
             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 9056ed5cdfc..e34f90861c3 100644
--- a/server/src/com/cloud/network/IpAddressManagerImpl.java
+++ b/server/src/com/cloud/network/IpAddressManagerImpl.java
@@ -1631,7 +1631,7 @@ public boolean associateIpAddressListToAccount(long userId, final long accountId
                             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 36dd53fe33e..966c0e4475b 100644
--- a/server/src/com/cloud/network/NetworkServiceImpl.java
+++ b/server/src/com/cloud/network/NetworkServiceImpl.java
@@ -1038,9 +1038,14 @@ public Network createGuestNetwork(CreateNetworkCmd cmd) throws InsufficientCapac
         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 Network createGuestNetwork(CreateNetworkCmd cmd) throws InsufficientCapac
         }
 
         // 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 Network createGuestNetwork(CreateNetworkCmd cmd) throws InsufficientCapac
             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 Network createGuestNetwork(CreateNetworkCmd cmd) throws InsufficientCapac
     }
 
     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 Network doInTransaction(TransactionStatus status) throws InsufficientCapa
                             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 Network doInTransaction(TransactionStatus status) throws ResourceAllocati
                     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 706f4c4abff..9f5ff834c06 100644
--- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java
+++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java
@@ -2359,7 +2359,7 @@ public Network createVpcGuestNetwork(final long ntwkOffId, final String name, fi
         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 e4fc56fe6af..07dd0ea8466 100644
--- a/server/src/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/com/cloud/vm/UserVmManagerImpl.java
@@ -3103,7 +3103,7 @@ public UserVm createAdvancedVirtualMachine(DataCenter zone, ServiceOffering serv
                     }
                     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 void doInTransactionWithoutResult(TransactionStatus status) {
                             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 8a7b54cb20f..178ed84d748 100644
--- a/server/test/com/cloud/network/CreatePrivateNetworkTest.java
+++ b/server/test/com/cloud/network/CreatePrivateNetworkTest.java
@@ -121,7 +121,7 @@ public void setup() throws Exception {
             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 bcee896ca30..9ac0648a533 100644
--- a/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java
+++ b/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java
@@ -440,7 +440,7 @@ public NetworkOfferingVO createNetworkOffering(String name, String displayText,
      */
     @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 f6f818d1733..9b895c25541 100644
--- a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java
+++ b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java
@@ -611,9 +611,9 @@ public boolean destroyNetwork(long networkId, ReservationContext context, boolea
      * @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 4c4a0a19026..11f3f81f357 100644
--- a/server/test/com/cloud/vpc/dao/MockNetworkDaoImpl.java
+++ b/server/test/com/cloud/vpc/dao/MockNetworkDaoImpl.java
@@ -85,13 +85,8 @@ public String getNextAvailableMacAddress(final long networkConfigId, Integer zon
     }
 
     @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 16e0b8894ef..3727dc6a313 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 8fb7ebefb7a..6c3ffd81687 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 631c629aed3..8805891cd2a 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.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 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 static InputStream getInputStreamFromUrl(String url, String user, String
             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 d2fd9976558..b8d951db340 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 void getUpdateUri() {
         //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 44681e9a8b3..01cfb3a52f1 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 ef3f0ae327c..bece91a98f5 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.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.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 static void updatePortProfile(VmwareContext context, String ethPortProfil
      * @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 static void updatePortProfile(VmwareContext context, String ethPortProfil
             // 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 static void updatePortProfile(VmwareContext context, String ethPortProfil
                 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 static void updatePortProfile(VmwareContext context, String ethPortProfil
                     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 @@ private static void setupPVlanPair(DistributedVirtualSwitchMO dvSwitchMo, Manage
 
     }
 
-    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 @@ private static void createPortGroup(String physicalNetwork, String networkName,
         // 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 static boolean isSpecMatch(DVPortgroupConfigInfo currentDvPortgroupInfo,
             }
         }
 
-        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 static VMwareDVSPvlanConfigSpec createDVPortPvlanConfigSpec(int vlanId, i
         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 static DVSSecurityPolicy createDVSSecurityPolicy() {
             }
         }
 
-        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 static DVSSecurityPolicy createDVSSecurityPolicy() {
                 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 static DVSSecurityPolicy createDVSSecurityPolicy() {
                                             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 static DVSSecurityPolicy createDVSSecurityPolicy() {
         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 @@ private static boolean isSpecMatch(HostPortGroupSpec spec, Integer vlanId, HostN
                 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 2fc9995091b..545104d91fc 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 void testOvfDomRewriter() {
                 "</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);
+    }
 }


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


> DVSwitch improvements
> ---------------------
>
>                 Key: CLOUDSTACK-10047
>                 URL: https://issues.apache.org/jira/browse/CLOUDSTACK-10047
>             Project: CloudStack
>          Issue Type: Bug
>      Security Level: Public(Anyone can view this level - this is the default.) 
>            Reporter: Rohit Yadav
>            Assignee: Rohit Yadav
>             Fix For: Future, 4.11.0.0
>
>
> All vlan trunking and list of vlan id/range, along with security policy settings on dvswitches.



--
This message was sent by Atlassian JIRA
(v6.4.14#64029)

Mime
View raw message