You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ya...@apache.org on 2013/04/22 01:21:26 UTC
[1/2] git commit: updated refs/heads/pvlan to 4c0f775
Updated Branches:
refs/heads/pvlan [created] 4c0f775e6
PVLAN: Add pvlan in createNetworkCommand
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/c26244d1
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/c26244d1
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/c26244d1
Branch: refs/heads/pvlan
Commit: c26244d18a4ae93614195b7f1945d174a35623d1
Parents: bb841d6
Author: Sheng Yang <sh...@citrix.com>
Authored: Thu Apr 11 17:39:39 2013 -0700
Committer: Sheng Yang <sh...@citrix.com>
Committed: Thu Apr 11 17:39:39 2013 -0700
----------------------------------------------------------------------
api/src/com/cloud/network/Networks.java | 1 +
.../org/apache/cloudstack/api/ApiConstants.java | 1 +
.../api/command/user/network/CreateNetworkCmd.java | 7 +++
.../xen/resource/CitrixResourceBase.java | 5 ++
.../configuration/ConfigurationManagerImpl.java | 2 +
server/src/com/cloud/network/NetworkManager.java | 3 +-
.../src/com/cloud/network/NetworkManagerImpl.java | 35 ++++++++++-----
.../src/com/cloud/network/NetworkServiceImpl.java | 13 +++++-
.../src/com/cloud/network/vpc/VpcManagerImpl.java | 2 +-
server/src/com/cloud/vm/UserVmManagerImpl.java | 4 +-
.../com/cloud/network/MockNetworkManagerImpl.java | 2 +-
.../test/com/cloud/vpc/MockNetworkManagerImpl.java | 3 +-
utils/src/com/cloud/utils/net/NetUtils.java | 26 +++++++++++
utils/test/com/cloud/utils/net/NetUtilsTest.java | 8 +++
14 files changed, 93 insertions(+), 19 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c26244d1/api/src/com/cloud/network/Networks.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/network/Networks.java b/api/src/com/cloud/network/Networks.java
index f085e9f..5aede05 100755
--- a/api/src/com/cloud/network/Networks.java
+++ b/api/src/com/cloud/network/Networks.java
@@ -63,6 +63,7 @@ public class Networks {
Storage("storage", Integer.class),
Lswitch("lswitch", String.class),
Mido("mido", String.class),
+ Pvlan("pvlan", String.class),
UnDecided(null, null);
private String scheme;
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c26244d1/api/src/org/apache/cloudstack/api/ApiConstants.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java
index c518830..bd441eb 100755
--- a/api/src/org/apache/cloudstack/api/ApiConstants.java
+++ b/api/src/org/apache/cloudstack/api/ApiConstants.java
@@ -222,6 +222,7 @@ public class ApiConstants {
public static final String VIRTUAL_MACHINE_IDS = "virtualmachineids";
public static final String VLAN = "vlan";
public static final String VLAN_ID = "vlanid";
+ public static final String ISOLATED_PVLAN = "isolatedpvlan";
public static final String VM_AVAILABLE = "vmavailable";
public static final String VM_LIMIT = "vmlimit";
public static final String VM_TOTAL = "vmtotal";
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c26244d1/api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkCmd.java b/api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkCmd.java
index fc7bd9f..7f699fe 100644
--- a/api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkCmd.java
@@ -86,6 +86,9 @@ public class CreateNetworkCmd extends BaseCmd {
@Parameter(name=ApiConstants.VLAN, type=CommandType.STRING, description="the ID or VID of the network")
private String vlan;
+ @Parameter(name=ApiConstants.ISOLATED_PVLAN, type=CommandType.STRING, description="the isolated private vlan for this network")
+ private String isolatedPvlan;
+
@Parameter(name=ApiConstants.NETWORK_DOMAIN, type=CommandType.STRING, description="network domain")
private String networkDomain;
@@ -141,6 +144,10 @@ public class CreateNetworkCmd extends BaseCmd {
return vlan;
}
+ public String getIsolatedPvlan() {
+ return isolatedPvlan;
+ }
+
public String getAccountName() {
return accountName;
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c26244d1/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
index c50f13c..e467dc7 100644
--- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
+++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
@@ -1014,6 +1014,11 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
} else if (nic.getBroadcastType() == BroadcastDomainType.Lswitch) {
// Nicira Logical Switch
return network.getNetwork();
+ } else if (nic.getBroadcastType() == BroadcastDomainType.Pvlan) {
+ URI broadcastUri = nic.getBroadcastUri();
+ assert broadcastUri.getScheme().equals(BroadcastDomainType.Pvlan.scheme());
+ long vlan = Long.parseLong(NetUtils.getPrimaryPvlanFromUri(broadcastUri));
+ return enableVlanNetwork(conn, vlan, network);
}
throw new CloudRuntimeException("Unable to support this type of network broadcast domain: " + nic.getBroadcastUri());
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c26244d1/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
index 8dbf081..a36a100 100755
--- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
+++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
@@ -2410,6 +2410,8 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
if (uri != null) {
String[] vlan = uri.toString().split("vlan:\\/\\/");
networkVlanId = vlan[1];
+ //For pvlan
+ networkVlanId = networkVlanId.split("-")[0];
}
if (vlanId != null) {
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c26244d1/server/src/com/cloud/network/NetworkManager.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/NetworkManager.java b/server/src/com/cloud/network/NetworkManager.java
index 851f7f5..d2d2d5c 100755
--- a/server/src/com/cloud/network/NetworkManager.java
+++ b/server/src/com/cloud/network/NetworkManager.java
@@ -127,7 +127,8 @@ public interface NetworkManager {
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)
+ long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId, String ip6Gateway, String ip6Cidr,
+ String isolatedPvlan)
throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException;
/**
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c26244d1/server/src/com/cloud/network/NetworkManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java
index a16288f..60dc1f0 100755
--- a/server/src/com/cloud/network/NetworkManagerImpl.java
+++ b/server/src/com/cloud/network/NetworkManagerImpl.java
@@ -1867,7 +1867,8 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
@DB
public Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway,
String cidr, String vlanId, String networkDomain, Account owner, Long domainId,
- PhysicalNetwork pNtwk, long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId, String ip6Gateway, String ip6Cidr)
+ PhysicalNetwork pNtwk, long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId,
+ String ip6Gateway, String ip6Cidr, String isolatedPvlan)
throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException {
NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(networkOfferingId);
@@ -1957,6 +1958,9 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
if (ipv6) {
throw new InvalidParameterValueException("IPv6 is not supported with security group!");
}
+ if (isolatedPvlan != null) {
+ throw new InvalidParameterValueException("Isolated Private VLAN is not supported with security group!");
+ }
// Only Account specific Isolated network with sourceNat service disabled are allowed in security group
// enabled zone
if ( ntwkOff.getGuestType() != GuestType.Shared ){
@@ -2085,13 +2089,20 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
}
if (vlanId != null) {
- userNetwork.setBroadcastUri(URI.create("vlan://" + vlanId));
- userNetwork.setBroadcastDomainType(BroadcastDomainType.Vlan);
- if (!vlanId.equalsIgnoreCase(Vlan.UNTAGGED)) {
- userNetwork.setBroadcastDomainType(BroadcastDomainType.Vlan);
- } else {
- userNetwork.setBroadcastDomainType(BroadcastDomainType.Native);
- }
+ if (isolatedPvlan == null) {
+ userNetwork.setBroadcastUri(URI.create("vlan://" + vlanId));
+ if (!vlanId.equalsIgnoreCase(Vlan.UNTAGGED)) {
+ userNetwork.setBroadcastDomainType(BroadcastDomainType.Vlan);
+ } else {
+ userNetwork.setBroadcastDomainType(BroadcastDomainType.Native);
+ }
+ } else {
+ if (vlanId.equalsIgnoreCase(Vlan.UNTAGGED)) {
+ throw new InvalidParameterValueException("Cannot support pvlan with untagged primary vlan!");
+ }
+ userNetwork.setBroadcastUri(NetUtils.generateUriForPvlan(vlanId, isolatedPvlan));
+ userNetwork.setBroadcastDomainType(BroadcastDomainType.Pvlan);
+ }
}
List<NetworkVO> networks = setupNetwork(owner, ntwkOff, userNetwork, plan, name, displayText, true, domainId,
@@ -2675,7 +2686,7 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
guestNetwork = 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);
+ null, null, null, null, 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 " +
@@ -3516,8 +3527,10 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
nic.setGateway(ip.getGateway());
nic.setNetmask(ip.getNetmask());
nic.setIsolationUri(IsolationType.Vlan.toUri(ip.getVlanTag()));
- nic.setBroadcastType(BroadcastDomainType.Vlan);
- nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(ip.getVlanTag()));
+ //nic.setBroadcastType(BroadcastDomainType.Vlan);
+ //nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(ip.getVlanTag()));
+ nic.setBroadcastType(network.getBroadcastDomainType());
+ nic.setBroadcastUri(network.getBroadcastUri());
nic.setFormat(AddressFormat.Ip4);
nic.setReservationId(String.valueOf(ip.getVlanTag()));
nic.setMacAddress(ip.getMacAddress());
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c26244d1/server/src/com/cloud/network/NetworkServiceImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java b/server/src/com/cloud/network/NetworkServiceImpl.java
index 4eb620c..7bb7188 100755
--- a/server/src/com/cloud/network/NetworkServiceImpl.java
+++ b/server/src/com/cloud/network/NetworkServiceImpl.java
@@ -813,6 +813,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
String endIPv6 = cmd.getEndIpv6();
String ip6Gateway = cmd.getIp6Gateway();
String ip6Cidr = cmd.getIp6Cidr();
+ String isolatedPvlan = cmd.getIsolatedPvlan();
// Validate network offering
NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(networkOfferingId);
@@ -999,6 +1000,10 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
}
}
+ if (isolatedPvlan != null && (zone.getNetworkType() != NetworkType.Advanced || ntwkOff.getGuestType() != Network.GuestType.Shared)) {
+ throw new InvalidParameterValueException("Can only support create Private VLAN network with advance shared network!");
+ }
+
// Regular user can create Guest Isolated Source Nat enabled network only
if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL
&& (ntwkOff.getTrafficType() != TrafficType.Guest || ntwkOff.getGuestType() != Network.GuestType.Isolated
@@ -1030,6 +1035,9 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
if (ipv6 && providersConfiguredForExternalNetworking(ntwkProviders)) {
throw new InvalidParameterValueException("Cannot support IPv6 on network offering with external devices!");
}
+ if (isolatedPvlan != null && providersConfiguredForExternalNetworking(ntwkProviders)) {
+ throw new InvalidParameterValueException("Cannot support private vlan on network offering with external devices!");
+ }
if (cidr != null && providersConfiguredForExternalNetworking(ntwkProviders)) {
if (ntwkOff.getGuestType() == GuestType.Shared && (zone.getNetworkType() == NetworkType.Advanced) &&
@@ -1100,7 +1108,8 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
throw new InvalidParameterValueException("Network offering can be used for VPC networks only");
}
network = _networkMgr.createGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId,
- networkDomain, owner, sharedDomainId, pNtwk, zoneId, aclType, subdomainAccess, vpcId, ip6Gateway, ip6Cidr);
+ networkDomain, owner, sharedDomainId, pNtwk, zoneId, aclType, subdomainAccess, vpcId,
+ ip6Gateway, ip6Cidr, isolatedPvlan);
}
if (caller.getType() == Account.ACCOUNT_TYPE_ADMIN && createVlan) {
@@ -3214,7 +3223,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
if (privateNetwork == null) {
//create Guest network
privateNetwork = _networkMgr.createGuestNetwork(ntwkOff.getId(), networkName, displayText, gateway, cidr, vlan,
- null, owner, null, pNtwk, pNtwk.getDataCenterId(), ACLType.Account, null, null, null, null);
+ null, owner, null, pNtwk, pNtwk.getDataCenterId(), ACLType.Account, null, null, null, null, null);
s_logger.debug("Created private network " + privateNetwork);
} else {
s_logger.debug("Private network already exists: " + privateNetwork);
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c26244d1/server/src/com/cloud/network/vpc/VpcManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java
index 3948f2e..e693273 100644
--- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java
+++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java
@@ -1937,7 +1937,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
//2) Create network
Network guestNetwork = _ntwkMgr.createGuestNetwork(ntwkOffId, name, displayText, gateway, cidr, vlanId,
- networkDomain, owner, domainId, pNtwk, zoneId, aclType, subdomainAccess, vpcId, null, null);
+ networkDomain, owner, domainId, pNtwk, zoneId, aclType, subdomainAccess, vpcId, null, null, null);
return guestNetwork;
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c26244d1/server/src/com/cloud/vm/UserVmManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java
index 24bce8b..9edddb4 100755
--- a/server/src/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/com/cloud/vm/UserVmManagerImpl.java
@@ -2143,7 +2143,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
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);
+ null, null, owner, null, physicalNetwork, zone.getId(), ACLType.Account, null, null, null, null, null);
defaultNetwork = _networkDao.findById(newNetwork.getId());
} else if (virtualNetworks.size() > 1) {
throw new InvalidParameterValueException(
@@ -3807,7 +3807,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
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, null, null);
+ null, null, newAccount, null, physicalNetwork, zone.getId(), ACLType.Account, null, null, null, null, null);
// if the network offering has persistent set to true, implement the network
if (requiredOfferings.get(0).getIsPersistent()) {
DeployDestination dest = new DeployDestination(zone, null, null, null);
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c26244d1/server/test/com/cloud/network/MockNetworkManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/network/MockNetworkManagerImpl.java b/server/test/com/cloud/network/MockNetworkManagerImpl.java
index 6da48ec..f1965a4 100755
--- a/server/test/com/cloud/network/MockNetworkManagerImpl.java
+++ b/server/test/com/cloud/network/MockNetworkManagerImpl.java
@@ -256,7 +256,7 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkManage
@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) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException {
+ PhysicalNetwork physicalNetwork, long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId, String gatewayv6, String cidrv6, String isolatedPvlan) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException {
// TODO Auto-generated method stub
return null;
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c26244d1/server/test/com/cloud/vpc/MockNetworkManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java
index ead0051..9f455a6 100644
--- a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java
+++ b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java
@@ -848,7 +848,8 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkManage
@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)
+ PhysicalNetwork physicalNetwork, long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId,
+ String gatewayv6, String cidrv6, String isolatedPvlan)
throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException {
// TODO Auto-generated method stub
return null;
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c26244d1/utils/src/com/cloud/utils/net/NetUtils.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/net/NetUtils.java b/utils/src/com/cloud/utils/net/NetUtils.java
index 5988dd5..4dd404d 100755
--- a/utils/src/com/cloud/utils/net/NetUtils.java
+++ b/utils/src/com/cloud/utils/net/NetUtils.java
@@ -24,6 +24,7 @@ import java.net.InetAddress;
import java.net.InterfaceAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
+import java.net.URI;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Formatter;
@@ -1290,4 +1291,29 @@ public class NetUtils {
}
return resultIp;
}
+
+ public static URI generateUriForPvlan(String primaryVlan, String isolatedPvlan) {
+ return URI.create("pvlan://" + primaryVlan + "-i" + isolatedPvlan);
+ }
+
+ public static String getPrimaryPvlanFromUri(URI uri) {
+ String[] vlans = uri.getHost().split("-");
+ if (vlans.length < 1) {
+ return null;
+ }
+ return vlans[0];
+ }
+
+ public static String getIsolatedPvlanFromUri(URI uri) {
+ String[] vlans = uri.getHost().split("-");
+ if (vlans.length < 2) {
+ return null;
+ }
+ for (String vlan : vlans) {
+ if (vlan.startsWith("i")) {
+ return vlan.replace("i", " ").trim();
+ }
+ }
+ return null;
+ }
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c26244d1/utils/test/com/cloud/utils/net/NetUtilsTest.java
----------------------------------------------------------------------
diff --git a/utils/test/com/cloud/utils/net/NetUtilsTest.java b/utils/test/com/cloud/utils/net/NetUtilsTest.java
index 28bd71f..16d3402 100644
--- a/utils/test/com/cloud/utils/net/NetUtilsTest.java
+++ b/utils/test/com/cloud/utils/net/NetUtilsTest.java
@@ -17,6 +17,7 @@
package com.cloud.utils.net;
import java.math.BigInteger;
+import java.net.URI;
import java.util.SortedSet;
import java.util.TreeSet;
@@ -128,4 +129,11 @@ public class NetUtilsTest extends TestCase {
assertFalse(NetUtils.isIp6InRange("1234:5678:abcd::1", null));
assertTrue(NetUtils.isIp6InRange("1234:5678:abcd::1", "1234:5678::1-1234:5679::1"));
}
+
+ public void testPvlan() {
+ URI uri = NetUtils.generateUriForPvlan("123", "456");
+ assertTrue(uri.toString().equals("pvlan://123-i456"));
+ assertTrue(NetUtils.getPrimaryPvlanFromUri(uri).equals("123"));
+ assertTrue(NetUtils.getIsolatedPvlanFromUri(uri).equals("456"));
+ }
}
[2/2] git commit: updated refs/heads/pvlan to 4c0f775
Posted by ya...@apache.org.
Implement PVLAN on Xen
Start/stop vm/dhcp server are done. Not done with VM migration.
A new command(PvlanSetupCommand) is sent for setting up PVLAN for vms. Currently
it's focus on OVS implementation. Need to be more abstruct and add vSwitch part.
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/4c0f775e
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/4c0f775e
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/4c0f775e
Branch: refs/heads/pvlan
Commit: 4c0f775e6e8dc14a1f3646fb30211a6de15dd48d
Parents: c26244d
Author: Sheng Yang <sh...@citrix.com>
Authored: Thu Apr 11 17:39:57 2013 -0700
Committer: Sheng Yang <sh...@citrix.com>
Committed: Thu Apr 11 17:39:57 2013 -0700
----------------------------------------------------------------------
api/src/com/cloud/agent/api/PvlanSetupCommand.java | 130 +++++++++++
.../xen/resource/CitrixResourceBase.java | 46 ++++-
scripts/vm/hypervisor/xenserver/ovs-pvlan | 168 +++++++++++++++
scripts/vm/hypervisor/xenserver/xenserver60/patch | 6 +-
scripts/vm/network/ovs-pvlan-cleanup.sh | 23 ++
scripts/vm/network/ovs-pvlan-dhcp-host.sh | 104 +++++++++
scripts/vm/network/ovs-pvlan-vm-in-dhcp-host.sh | 88 ++++++++
scripts/vm/network/ovs-pvlan-vm.sh | 90 ++++++++
.../network/element/VirtualRouterElement.java | 11 +
.../router/VirtualNetworkApplianceManager.java | 4 +
.../router/VirtualNetworkApplianceManagerImpl.java | 87 +++++++-
server/src/com/cloud/vm/UserVmManagerImpl.java | 45 ++++
.../vpc/MockVpcVirtualNetworkApplianceManager.java | 7 +
13 files changed, 804 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4c0f775e/api/src/com/cloud/agent/api/PvlanSetupCommand.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/agent/api/PvlanSetupCommand.java b/api/src/com/cloud/agent/api/PvlanSetupCommand.java
new file mode 100644
index 0000000..22a828a
--- /dev/null
+++ b/api/src/com/cloud/agent/api/PvlanSetupCommand.java
@@ -0,0 +1,130 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.agent.api;
+
+import java.net.URI;
+
+import com.cloud.utils.net.NetUtils;
+
+public class PvlanSetupCommand extends Command {
+ public enum Type {
+ DHCP,
+ VM,
+ VM_IN_DHCP_HOST
+ }
+ private String op;
+ private String bridge;
+ private String primary;
+ private String isolated;
+ private String vmMac;
+ private String dhcpMac;
+ private String dhcpIp;
+ private boolean strict;
+ private Type type;
+
+ protected PvlanSetupCommand() {}
+
+ protected PvlanSetupCommand(Type type, String op, String bridge, URI uri)
+ {
+ this.type = type;
+ this.op = op;
+ this.bridge = bridge;
+ this.primary = NetUtils.getPrimaryPvlanFromUri(uri);
+ this.isolated = NetUtils.getIsolatedPvlanFromUri(uri);
+ this.strict = true;
+ }
+
+ static public PvlanSetupCommand createDhcpSetup(String op, String bridge, URI uri, String dhcpMac, String dhcpIp)
+ {
+ PvlanSetupCommand cmd = new PvlanSetupCommand(Type.DHCP, op, bridge, uri);
+ cmd.setDhcpMac(dhcpMac);
+ cmd.setDhcpIp(dhcpIp);
+ return cmd;
+ }
+
+ static public PvlanSetupCommand createVmSetup(String op, String bridge, URI uri, String vmMac)
+ {
+ PvlanSetupCommand cmd = new PvlanSetupCommand(Type.VM, op, bridge, uri);
+ cmd.setVmMac(vmMac);
+ return cmd;
+ }
+
+ static public PvlanSetupCommand createVmInDhcpHostSetup(String op, String bridge, URI uri, String dhcpMac, String vmMac)
+ {
+ PvlanSetupCommand cmd = new PvlanSetupCommand(Type.VM_IN_DHCP_HOST, op, bridge, uri);
+ cmd.setDhcpMac(dhcpMac);
+ cmd.setVmMac(vmMac);
+ return cmd;
+ }
+
+ @Override
+ public boolean executeInSequence() {
+ return true;
+ }
+
+ public String getOp() {
+ return op;
+ }
+
+ public String getBridge() {
+ return bridge;
+ }
+
+ public String getPrimary() {
+ return primary;
+ }
+
+ public String getIsolated() {
+ return isolated;
+ }
+
+ public String getVmMac() {
+ return vmMac;
+ }
+
+ protected void setVmMac(String vmMac) {
+ this.vmMac = vmMac;
+ }
+
+ public String getDhcpMac() {
+ return dhcpMac;
+ }
+
+ protected void setDhcpMac(String dhcpMac) {
+ this.dhcpMac = dhcpMac;
+ }
+
+ public String getDhcpIp() {
+ return dhcpIp;
+ }
+
+ protected void setDhcpIp(String dhcpIp) {
+ this.dhcpIp = dhcpIp;
+ }
+
+ public Type getType() {
+ return type;
+ }
+
+ public boolean isStrict() {
+ return strict;
+ }
+
+ public void setStrict(boolean strict) {
+ this.strict = strict;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4c0f775e/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
index e467dc7..ab26c7a 100644
--- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
+++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
@@ -604,6 +604,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
return execute((NetworkRulesVmSecondaryIpCommand)cmd);
} else if (clazz == ScaleVmCommand.class) {
return execute((ScaleVmCommand) cmd);
+ } else if (clazz == PvlanSetupCommand.class) {
+ return execute((PvlanSetupCommand) cmd);
} else {
return Answer.createUnsupportedCommandAnswer(cmd);
}
@@ -1054,7 +1056,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
vifr = vif.getRecord(conn);
s_logger.debug("Created a vif " + vifr.uuid + " on " + nic.getDeviceId());
}
-
+
return vif;
}
@@ -1465,6 +1467,48 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
}
}
}
+
+ private Answer execute(PvlanSetupCommand cmd) {
+ Connection conn = getConnection();
+
+ String primaryPvlan = cmd.getPrimary();
+ String isolatedPvlan = cmd.getIsolated();
+ String op = cmd.getOp();
+ String bridge = cmd.getBridge();
+ String result = null;
+ String dhcpMac = cmd.getDhcpMac();
+ String dhcpIp = cmd.getDhcpIp();
+ String vmMac = cmd.getVmMac();
+ if (cmd.getType() == PvlanSetupCommand.Type.DHCP) {
+ result = callHostPlugin(conn, "ovs-pvlan", "setup-pvlan-dhcp", "op", op, "bridge", bridge,
+ "primary-pvlan", primaryPvlan, "isolated-pvlan", isolatedPvlan, "dhcp-ip", dhcpIp, "dhcp-mac", dhcpMac);
+ if (result == null || result.isEmpty() || !Boolean.parseBoolean(result)) {
+ s_logger.warn("Failed to program pvlan for dhcp server with mac " + dhcpMac);
+ return new Answer(cmd, false, result);
+ } else {
+ s_logger.info("Programmed pvlan for dhcp server with mac " + dhcpMac);
+ }
+ } else if (cmd.getType() == PvlanSetupCommand.Type.VM) {
+ result = callHostPlugin(conn, "ovs-pvlan", "setup-pvlan-vm-alone", "op", op, "bridge", bridge,
+ "primary-pvlan", primaryPvlan, "isolated-pvlan", isolatedPvlan, "vm-mac", vmMac);
+ if (result == null || result.isEmpty() || !Boolean.parseBoolean(result)) {
+ s_logger.warn("Failed to program pvlan for vm with mac " + vmMac);
+ return new Answer(cmd, false, result);
+ } else {
+ s_logger.info("Programmed pvlan for vm with mac " + vmMac);
+ }
+ } else if (cmd.getType() == PvlanSetupCommand.Type.VM_IN_DHCP_HOST) {
+ result = callHostPlugin(conn, "ovs-pvlan", "setup-pvlan-vm-dhcp", "op", op, "bridge", bridge,
+ "primary-pvlan", primaryPvlan, "isolated-pvlan", isolatedPvlan, "vm-mac", vmMac, "dhcp-mac", dhcpMac);
+ if (result == null || result.isEmpty() || !Boolean.parseBoolean(result)) {
+ s_logger.warn("Failed to program pvlan for vm in dhcp host with mac " + vmMac);
+ return new Answer(cmd, false, result);
+ } else {
+ s_logger.info("Programmed pvlan for vm in dhcp host with mac " + vmMac);
+ }
+ }
+ return new Answer(cmd, true, result);
+ }
@Override
public StartAnswer execute(StartCommand cmd) {
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4c0f775e/scripts/vm/hypervisor/xenserver/ovs-pvlan
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/xenserver/ovs-pvlan b/scripts/vm/hypervisor/xenserver/ovs-pvlan
new file mode 100755
index 0000000..2c1e3af
--- /dev/null
+++ b/scripts/vm/hypervisor/xenserver/ovs-pvlan
@@ -0,0 +1,168 @@
+#!/usr/bin/python
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+
+import cloudstack_pluginlib as lib
+import logging
+import os
+import sys
+import subprocess
+import time
+import XenAPIPlugin
+
+sys.path.append("/opt/xensource/sm/")
+import util
+
+from time import localtime as _localtime, asctime as _asctime
+
+xePath = "/opt/xensource/bin/xe"
+lib.setup_logging("/var/log/ovs-pvlan.log")
+dhcpSetupPath = "/opt/xensource/bin/ovs-pvlan-dhcp-host.sh"
+vmAloneSetupPath = "/opt/xensource/bin/ovs-pvlan-vm.sh"
+vmDhcpSetupPath = "/opt/xensource/bin/ovs-pvlan-vm-in-dhcp-host.sh"
+pvlanCleanupPath = "/opt/xensource/bin/ovs-pvlan-cleanup.sh"
+
+def echo(fn):
+ def wrapped(*v, **k):
+ name = fn.__name__
+ util.SMlog("#### VMOPS enter %s ####" % name)
+ res = fn(*v, **k)
+ util.SMlog("#### VMOPS exit %s ####" % name)
+ return res
+ return wrapped
+
+
+@echo
+def setup_pvlan_dhcp(session, args):
+ op = args.pop("op")
+ bridge = args.pop("bridge")
+ primary = args.pop("primary-pvlan")
+ isolated = args.pop("isolated-pvlan")
+ dhcp_ip = args.pop("dhcp-ip");
+ dhcp_mac = args.pop("dhcp-mac");
+
+ res = lib.check_switch()
+ if res != "SUCCESS":
+ return "FAILURE:%s" % res
+
+ if op == "add":
+ logging.debug("About to setup dhcp vm on the switch:%s" % bridge)
+ res = lib.do_cmd([dhcpSetupPath, "-A", "-b", bridge, "-p", primary,
+ "-i", isolated, "-d", dhcp_ip, "-m", dhcp_mac])
+ if res:
+ result = "FAILURE:%s" % res
+ return result;
+ logging.debug("Setup dhcp vm on switch program done")
+ elif op == "delete":
+ logging.debug("About to remove dhcp the switch:%s" % bridge)
+ res = lib.do_cmd([dhcpSetupPath, "-D", "-b", bridge, "-p", primary,
+ "-i", isolated, "-d", dhcp_ip, "-m", dhcp_mac])
+ if res:
+ result = "FAILURE:%s" % res
+ return result;
+ logging.debug("Remove DHCP on switch program done")
+
+ result = "true"
+ logging.debug("Setup_pvlan_dhcp completed with result:%s" % result)
+ return result
+
+@echo
+def setup_pvlan_vm_alone(session, args):
+ op = args.pop("op")
+ bridge = args.pop("bridge")
+ isolated = args.pop("isolated-pvlan")
+ vm_mac = args.pop("vm-mac")
+ trunk_port = 1
+
+ res = lib.check_switch()
+ if res != "SUCCESS":
+ return "FAILURE:%s" % res
+
+ if op == "add":
+ logging.debug("About to setup vm alone on the switch:%s" % bridge)
+ res = lib.do_cmd([vmAloneSetupPath, "-A", "-b", bridge, "-i", isolated, "-v", vm_mac])
+ if res:
+ result = "FAILURE:%s" % res
+ return result;
+ logging.debug("Setup vm alone on switch program done")
+ elif op == "delete":
+ logging.debug("About to remove vm alone on the switch:%s" % bridge)
+ res = lib.do_cmd([vmAloneSetupPath, "-D", "-b", bridge, "-i", isolated, "-v", vm_mac])
+ if res:
+ result = "FAILURE:%s" % res
+ return result;
+ logging.debug("Remove vm alone on switch program done")
+
+ result = "true"
+ logging.debug("Setup_pvlan_vm_alone completed with result:%s" % result)
+ return result
+
+@echo
+def setup_pvlan_vm_dhcp(session, args):
+ op = args.pop("op")
+ bridge = args.pop("bridge")
+ isolated = args.pop("isolated-pvlan")
+ vm_mac = args.pop("vm-mac")
+ dhcp_mac = args.pop("dhcp-mac");
+ trunk_port = 1
+
+ res = lib.check_switch()
+ if res != "SUCCESS":
+ return "FAILURE:%s" % res
+
+ if op == "add":
+ logging.debug("About to setup vm dhcp on the switch:%s" % bridge)
+ res = lib.do_cmd([vmDhcpSetupPath, "-A", "-b", bridge, "-i", isolated,
+ "-v", vm_mac, "-m", dhcp_mac])
+ if res:
+ result = "FAILURE:%s" % res
+ return result;
+ logging.debug("Setup vm dhcp on switch program done")
+ elif op == "delete":
+ logging.debug("About to remove vm dhcp on the switch:%s" % bridge)
+ res = lib.do_cmd([vmDhcpSetupPath, "-D", "-b", bridge, "-i", isolated,
+ "-v", vm_mac, "-m", dhcp_mac])
+ if res:
+ result = "FAILURE:%s" % res
+ return result;
+ logging.debug("Remove vm dhcp on switch program done")
+
+ result = "true"
+ logging.debug("Setup_pvlan_vm_dhcp completed with result:%s" % result)
+ return result
+
+@echo
+def cleanup(session, args):
+ res = lib.check_switch()
+ if res != "SUCCESS":
+ return "FAILURE:%s" % res
+
+ res = lib.do_cmd([pvlanCleanUpPath])
+ if res:
+ result = "FAILURE:%s" % res
+ return result;
+
+ result = "true"
+ logging.debug("Setup_pvlan_vm_dhcp completed with result:%s" % result)
+ return result
+
+if __name__ == "__main__":
+ XenAPIPlugin.dispatch({"setup-pvlan-dhcp": setup_pvlan_dhcp,
+ "setup-pvlan-vm-alone": setup_pvlan_vm_alone,
+ "setup-pvlan-vm-dhcp": setup_pvlan_vm_dhcp,
+ "cleanup":cleanup})
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4c0f775e/scripts/vm/hypervisor/xenserver/xenserver60/patch
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/xenserver/xenserver60/patch b/scripts/vm/hypervisor/xenserver/xenserver60/patch
index c9125f4..c767f1a 100644
--- a/scripts/vm/hypervisor/xenserver/xenserver60/patch
+++ b/scripts/vm/hypervisor/xenserver/xenserver60/patch
@@ -67,4 +67,8 @@ bumpUpPriority.sh=../../../../network/domr/,0755,/opt/xensource/bin
swift=..,0755,/opt/xensource/bin
swiftxen=..,0755,/etc/xapi.d/plugins
s3xen=..,0755,/etc/xapi.d/plugins
-
+ovs-pvlan=..,0755,/etc/xapi.d/plugins
+ovs-pvlan-dhcp-host.sh=../../../network,0755,/opt/xensource/bin
+ovs-pvlan-vm-in-dhcp-host.sh=../../../network,0755,/opt/xensource/bin
+ovs-pvlan-vm.sh=../../../network,0755,/opt/xensource/bin
+ovs-pvlan-cleanup.sh=../../../network,0755,/opt/xensource/bin
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4c0f775e/scripts/vm/network/ovs-pvlan-cleanup.sh
----------------------------------------------------------------------
diff --git a/scripts/vm/network/ovs-pvlan-cleanup.sh b/scripts/vm/network/ovs-pvlan-cleanup.sh
new file mode 100755
index 0000000..7493bed
--- /dev/null
+++ b/scripts/vm/network/ovs-pvlan-cleanup.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+#!/bin/bash
+
+ovs-ofctl del-flows xenbr0
+ovs-ofctl add-flow xenbr0 priority=0,actions=NORMAL
+
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4c0f775e/scripts/vm/network/ovs-pvlan-dhcp-host.sh
----------------------------------------------------------------------
diff --git a/scripts/vm/network/ovs-pvlan-dhcp-host.sh b/scripts/vm/network/ovs-pvlan-dhcp-host.sh
new file mode 100755
index 0000000..e12fbce
--- /dev/null
+++ b/scripts/vm/network/ovs-pvlan-dhcp-host.sh
@@ -0,0 +1,104 @@
+#!/bin/bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+usage() {
+ printf "Usage: %s: (-A|-D) -b <bridge/switch> -p <primary vlan> -i <secondary isolated vlan> -d <DHCP server IP> -m <DHCP server MAC> -v <VM MAC> -h \n" $(basename $0) >&2
+ exit 2
+}
+
+br=
+pri_vlan=
+sec_iso_vlan=
+dhcp_ip=
+dhcp_mac=
+vm_mac=
+op=
+
+while getopts 'ADb:p:i:d:m:v:h' OPTION
+do
+ case $OPTION in
+ A) op="add"
+ ;;
+ D) op="del"
+ ;;
+ b) br="$OPTARG"
+ ;;
+ p) pri_vlan="$OPTARG"
+ ;;
+ i) sec_iso_vlan="$OPTARG"
+ ;;
+ d) dhcp_ip="$OPTARG"
+ ;;
+ m) dhcp_mac="$OPTARG"
+ ;;
+ v) vm_mac="$OPTARG"
+ ;;
+ h) usage
+ exit 1
+ ;;
+ esac
+done
+
+if [ -z "$op" ]
+then
+ echo Missing operation pararmeter!
+ exit 1
+fi
+
+if [ -z "$br" ]
+then
+ echo Missing parameter bridge!
+ exit 1
+fi
+
+if [ -z "$pri_vlan" ]
+then
+ echo Missing parameter primary vlan!
+ exit 1
+fi
+
+if [ -z "$sec_iso_vlan" ]
+then
+ echo Missing parameter secondary isolate vlan!
+ exit 1
+fi
+
+if [ -z "$dhcp_ip" ]
+then
+ echo Missing parameter DHCP IP!
+ exit 1
+fi
+
+if [ -z "$dhcp_mac" ]
+then
+ echo Missing parameter DHCP MAC!
+ exit 1
+fi
+
+if [ "$op" == "add" ]
+then
+ ovs-ofctl add-flow $br priority=200,arp,dl_vlan=$sec_iso_vlan,nw_dst=$dhcp_ip,actions=mod_vlan_vid:$pri_vlan,NORMAL
+ ovs-ofctl add-flow $br priority=180,arp,nw_dst=$dhcp_ip,actions=NORMAL
+ ovs-ofctl add-flow $br priority=150,dl_vlan=$sec_iso_vlan,dl_dst=$dhcp_mac,actions=mod_vlan_vid:$pri_vlan,NORMAL
+ ovs-ofctl add-flow $br priority=100,udp,dl_vlan=$sec_iso_vlan,nw_dst=255.255.255.255,tp_dst=67,actions=mod_vlan_vid:$pri_vlan,NORMAL
+else
+ ovs-ofctl del-flows --strict $br priority=200,arp,dl_vlan=$sec_iso_vlan,nw_dst=$dhcp_ip
+ ovs-ofctl del-flows --strict $br priority=180,arp,nw_dst=$dhcp_ip
+ ovs-ofctl del-flows --strict $br priority=150,dl_vlan=$sec_iso_vlan,dl_dst=$dhcp_mac
+ ovs-ofctl del-flows --strict $br priority=100,udp,dl_vlan=$sec_iso_vlan,nw_dst=255.255.255.255,tp_dst=67
+fi
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4c0f775e/scripts/vm/network/ovs-pvlan-vm-in-dhcp-host.sh
----------------------------------------------------------------------
diff --git a/scripts/vm/network/ovs-pvlan-vm-in-dhcp-host.sh b/scripts/vm/network/ovs-pvlan-vm-in-dhcp-host.sh
new file mode 100755
index 0000000..de37882
--- /dev/null
+++ b/scripts/vm/network/ovs-pvlan-vm-in-dhcp-host.sh
@@ -0,0 +1,88 @@
+#!/bin/bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+usage() {
+ printf "Usage: %s: (-A|-D) -b <bridge/switch> -p <primary vlan> -i <secondary isolated vlan> -d <DHCP server IP> -m <DHCP server MAC> -v <VM MAC> -h \n" $(basename $0) >&2
+ exit 2
+}
+
+br=
+pri_vlan=
+sec_iso_vlan=
+dhcp_ip=
+dhcp_mac=
+vm_mac=
+op=
+
+while getopts 'ADb:p:i:d:m:v:h' OPTION
+do
+ case $OPTION in
+ A) op="add"
+ ;;
+ D) op="del"
+ ;;
+ b) br="$OPTARG"
+ ;;
+ p) pri_vlan="$OPTARG"
+ ;;
+ i) sec_iso_vlan="$OPTARG"
+ ;;
+ d) dhcp_ip="$OPTARG"
+ ;;
+ m) dhcp_mac="$OPTARG"
+ ;;
+ v) vm_mac="$OPTARG"
+ ;;
+ h) usage
+ exit 1
+ ;;
+ esac
+done
+
+if [ -z "$op" ]
+then
+ echo Missing operation pararmeter!
+ exit 1
+fi
+
+if [ -z "$br" ]
+then
+ echo Missing parameter bridge!
+ exit 1
+fi
+
+if [ -z "$vm_mac" ]
+then
+ echo Missing parameter VM MAC!
+ exit 1
+fi
+
+if [ -z "$dhcp_mac" ]
+then
+ echo Missing parameter DHCP MAC!
+ exit 1
+fi
+
+if [ "$op" == "add" ]
+then
+ ovs-ofctl add-flow $br priority=120,dl_src=$vm_mac,dl_dst=$dhcp_mac,actions=NORMAL
+ ovs-ofctl add-flow $br priority=80,udp,dl_src=$vm_mac,nw_dst=255.255.255.255,tp_dst=67,actions=NORMAL
+else
+ ovs-ofctl del-flows --strict $br priority=120,dl_src=$vm_mac,dl_dst=$dhcp_mac
+ ovs-ofctl del-flows --strict $br priority=80,udp,dl_src=$vm_mac,nw_dst=255.255.255.255,tp_dst=67
+fi
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4c0f775e/scripts/vm/network/ovs-pvlan-vm.sh
----------------------------------------------------------------------
diff --git a/scripts/vm/network/ovs-pvlan-vm.sh b/scripts/vm/network/ovs-pvlan-vm.sh
new file mode 100755
index 0000000..8ac20df
--- /dev/null
+++ b/scripts/vm/network/ovs-pvlan-vm.sh
@@ -0,0 +1,90 @@
+#!/bin/bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+usage() {
+ printf "Usage: %s: (-A|-D) -b <bridge/switch> -p <primary vlan> -i <secondary isolated vlan> -d <DHCP server IP> -m <DHCP server MAC> -v <VM MAC> -h \n" $(basename $0) >&2
+ exit 2
+}
+
+br=
+pri_vlan=
+sec_iso_vlan=
+dhcp_ip=
+dhcp_mac=
+vm_mac=
+op=
+
+while getopts 'ADb:p:i:d:m:v:h' OPTION
+do
+ case $OPTION in
+ A) op="add"
+ ;;
+ D) op="del"
+ ;;
+ b) br="$OPTARG"
+ ;;
+ p) pri_vlan="$OPTARG"
+ ;;
+ i) sec_iso_vlan="$OPTARG"
+ ;;
+ d) dhcp_ip="$OPTARG"
+ ;;
+ m) dhcp_mac="$OPTARG"
+ ;;
+ v) vm_mac="$OPTARG"
+ ;;
+ h) usage
+ exit 1
+ ;;
+ esac
+done
+
+if [ -z "$op" ]
+then
+ echo Missing operation pararmeter!
+ exit 1
+fi
+
+if [ -z "$br" ]
+then
+ echo Missing parameter bridge!
+ exit 1
+fi
+
+if [ -z "$vm_mac" ]
+then
+ echo Missing parameter VM MAC!
+ exit 1
+fi
+
+if [ -z "$sec_iso_vlan" ]
+then
+ echo Missing parameter secondary isolate vlan!
+ exit 1
+fi
+
+trunk_port=1
+
+if [ "$op" == "add" ]
+then
+ ovs-ofctl add-flow $br priority=50,dl_src=$vm_mac,actions=mod_vlan_vid:$sec_iso_vlan,output:$trunk_port
+else
+ # it would delete any rule related to this vm, not only the rule added above
+ ovs-ofctl del-flows $br dl_src=$vm_mac
+fi
+
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4c0f775e/server/src/com/cloud/network/element/VirtualRouterElement.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/element/VirtualRouterElement.java b/server/src/com/cloud/network/element/VirtualRouterElement.java
index 169db32..7f956e5 100755
--- a/server/src/com/cloud/network/element/VirtualRouterElement.java
+++ b/server/src/com/cloud/network/element/VirtualRouterElement.java
@@ -31,6 +31,7 @@ import org.apache.cloudstack.api.command.admin.router.CreateVirtualRouterElement
import org.apache.cloudstack.api.command.admin.router.ListVirtualRouterElementsCmd;
import org.apache.log4j.Logger;
+import com.cloud.agent.api.PvlanSetupCommand;
import com.cloud.agent.api.to.LoadBalancerTO;
import com.cloud.configuration.ConfigurationManager;
import com.cloud.configuration.dao.ConfigurationDao;
@@ -48,6 +49,7 @@ import com.cloud.network.Network.Capability;
import com.cloud.network.Network.Provider;
import com.cloud.network.Network.Service;
import com.cloud.network.NetworkModel;
+import com.cloud.network.Networks.BroadcastDomainType;
import com.cloud.network.Networks.TrafficType;
import com.cloud.network.PhysicalNetworkServiceProvider;
import com.cloud.network.PublicIpAddress;
@@ -214,6 +216,15 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl
DataCenter.class, network.getDataCenterId());
}
+ // Setup PVlan for vm if necessary
+ if (network.getTrafficType() == TrafficType.Guest && network.getBroadcastDomainType() == BroadcastDomainType.Pvlan) {
+ assert routers.size() == 1;
+ DomainRouterVO router = routers.get(0);
+ if (router.getHostId() == dest.getHost().getId()) {
+ _routerMgr.setupVmWithDhcpHostForPvlan(true, router, nic);
+ }
+ }
+
return true;
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4c0f775e/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java
index f49ab79..4dfd78c 100644
--- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java
+++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java
@@ -19,6 +19,7 @@ package com.cloud.network.router;
import java.util.List;
import java.util.Map;
+import com.cloud.agent.api.PvlanSetupCommand;
import com.cloud.deploy.DeployDestination;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
@@ -35,6 +36,7 @@ import com.cloud.user.User;
import com.cloud.uservm.UserVm;
import com.cloud.utils.component.Manager;
import com.cloud.vm.DomainRouterVO;
+import com.cloud.vm.Nic;
import com.cloud.vm.NicProfile;
import com.cloud.vm.VirtualMachineProfile;
@@ -103,4 +105,6 @@ public interface VirtualNetworkApplianceManager extends Manager, VirtualNetworkA
boolean applyUserData(Network config, NicProfile nic, VirtualMachineProfile<UserVm> vm, DeployDestination dest,
List<DomainRouterVO> routers) throws ResourceUnavailableException;
+
+ void setupVmWithDhcpHostForPvlan(boolean add, DomainRouterVO router, NicProfile profile) throws ResourceUnavailableException;
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4c0f775e/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
index afdbbca..c9ce83c 100755
--- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
+++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
@@ -61,6 +61,7 @@ import com.cloud.agent.api.GetDomRVersionCmd;
import com.cloud.agent.api.ModifySshKeysCommand;
import com.cloud.agent.api.NetworkUsageAnswer;
import com.cloud.agent.api.NetworkUsageCommand;
+import com.cloud.agent.api.PvlanSetupCommand;
import com.cloud.agent.api.StartupCommand;
import com.cloud.agent.api.StopAnswer;
import com.cloud.agent.api.check.CheckSshAnswer;
@@ -2196,6 +2197,72 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V
return dhcpRange;
}
+ private boolean setupDhcpForPvlanOnHost(boolean add, DomainRouterVO router, Nic routerNic) {
+ if (!routerNic.getBroadcastUri().getScheme().equals("pvlan")) {
+ return false;
+ }
+ setupDhcpForPvlan(add, router, routerNic);
+ Long hostId = router.getHostId();
+ List<UserVmVO> vms = _userVmDao.listByHostId(hostId);
+ for (UserVmVO vm : vms) {
+ if (vm.getState() != State.Running) {
+ continue;
+ }
+ List<NicVO> nics = _nicDao.listByVmId(vm.getId());
+ for (NicVO nic : nics) {
+ if (nic.getNetworkId() == routerNic.getNetworkId()) {
+ try {
+ Network network = _networkDao.findById(routerNic.getNetworkId());
+ NicProfile profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(),
+ null, _networkModel.isSecurityGroupSupportedInNetwork(network), _networkModel.getNetworkTag(vm.getHypervisorType(), network));
+ setupVmWithDhcpHostForPvlan(add, router, profile);
+ } catch (ResourceUnavailableException e) {
+ s_logger.warn("Fail to program pvlan on nic " + nic.getMacAddress(), e);
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ private boolean setupDhcpForPvlan(boolean add, DomainRouterVO router, Nic nic) {
+ if (!nic.getBroadcastUri().getScheme().equals("pvlan")) {
+ return false;
+ }
+ String op = "add";
+ if (!add) {
+ op = "delete";
+ }
+ PvlanSetupCommand cmd = PvlanSetupCommand.createDhcpSetup(op, "xenbr0", nic.getBroadcastUri(), nic.getMacAddress(), nic.getIp4Address());
+ Commands cmds = new Commands(cmd);
+ // In fact we send command to the host of router, we're not programming router but the host
+ try {
+ sendCommandsToRouter(router, cmds);
+ } catch (AgentUnavailableException e) {
+ s_logger.warn("Agent Unavailable ", e);
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public void setupVmWithDhcpHostForPvlan(boolean add, DomainRouterVO router, NicProfile profile) throws ResourceUnavailableException
+ {
+ if (!profile.getBroadCastUri().getScheme().equals("pvlan")) {
+ return;
+ }
+ String op = "add";
+ if (!add) {
+ op = "delete";
+ }
+ NicVO routerNic = _nicDao.findByInstanceIdAndNetworkId(profile.getNetworkId(), router.getId());
+ PvlanSetupCommand cmd = PvlanSetupCommand.createVmInDhcpHostSetup(op, "xenbr0", profile.getBroadCastUri(), routerNic.getMacAddress(), profile.getMacAddress());
+ Commands cmds = new Commands(cmd);
+ // In fact we send command to the host of router, we're not programming router but the host
+ sendCommandsToRouter(router, cmds);
+ }
+
@Override
public boolean finalizeDeployment(Commands cmds, VirtualMachineProfile<DomainRouterVO> profile,
DeployDestination dest, ReservationContext context) throws ResourceUnavailableException {
@@ -2491,11 +2558,18 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V
List<Network> guestNetworks = new ArrayList<Network>();
List<? extends Nic> routerNics = _nicDao.listByVmId(profile.getId());
- for (Nic routerNic : routerNics) {
- Network network = _networkModel.getNetwork(routerNic.getNetworkId());
+ for (Nic nic : routerNics) {
+ Network network = _networkModel.getNetwork(nic.getNetworkId());
if (network.getTrafficType() == TrafficType.Guest) {
guestNetworks.add(network);
- }
+ if (nic.getBroadcastUri().getScheme().equals("pvlan")) {
+ result = setupDhcpForPvlanOnHost(true, router, nic);
+ }
+ }
+ }
+
+ if (!result) {
+ return result;
}
answer = cmds.getAnswer("getDomRVersion");
@@ -2523,6 +2597,13 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V
VMInstanceVO vm = profile.getVirtualMachine();
DomainRouterVO domR = _routerDao.findById(vm.getId());
processStopOrRebootAnswer(domR, answer);
+ List<? extends Nic> routerNics = _nicDao.listByVmId(profile.getId());
+ for (Nic nic : routerNics) {
+ Network network = _networkModel.getNetwork(nic.getNetworkId());
+ if (network.getTrafficType() == TrafficType.Guest && nic.getBroadcastUri().getScheme().equals("pvlan")) {
+ setupDhcpForPvlanOnHost(false, domR, nic);
+ }
+ }
}
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4c0f775e/server/src/com/cloud/vm/UserVmManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java
index 9edddb4..ae9c7c7 100755
--- a/server/src/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/com/cloud/vm/UserVmManagerImpl.java
@@ -53,6 +53,7 @@ import com.cloud.agent.api.GetVmStatsAnswer;
import com.cloud.agent.api.GetVmStatsCommand;
import com.cloud.agent.api.PlugNicAnswer;
import com.cloud.agent.api.PlugNicCommand;
+import com.cloud.agent.api.PvlanSetupCommand;
import com.cloud.agent.api.StartAnswer;
import com.cloud.agent.api.StopAnswer;
import com.cloud.agent.api.UnPlugNicAnswer;
@@ -2681,6 +2682,34 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
return true;
}
+ private boolean setupVmForPvlan(boolean add, Long hostId, NicVO nic) {
+ if (!nic.getBroadcastUri().getScheme().equals("pvlan")) {
+ return false;
+ }
+ String op = "add";
+ if (!add) {
+ // "delete" would remove all the rules(if using ovs) related to this vm
+ op = "delete";
+ }
+ PvlanSetupCommand cmd = PvlanSetupCommand.createVmSetup(op, "xenbr0", nic.getBroadcastUri(), nic.getMacAddress());
+ Answer answer = null;
+ try {
+ answer = _agentMgr.send(hostId, cmd);
+ } catch (OperationTimedoutException e) {
+ s_logger.warn("Timed Out", e);
+ return false;
+ } catch (AgentUnavailableException e) {
+ s_logger.warn("Agent Unavailable ", e);
+ return false;
+ }
+
+ boolean result = true;
+ if (answer == null || !answer.getResult()) {
+ result = false;
+ }
+ return result;
+ }
+
@Override
public boolean finalizeDeployment(Commands cmds,
VirtualMachineProfile<UserVmVO> profile, DeployDestination dest,
@@ -2742,6 +2771,11 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
originalIp = nic.getIp4Address();
guestNic = nic;
guestNetwork = network;
+ if (nic.getBroadcastUri().getScheme().equals("pvlan")) {
+ if (!setupVmForPvlan(true, hostId, nic)) {
+ return false;
+ }
+ }
}
}
boolean ipChanged = false;
@@ -2865,6 +2899,17 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
+ " stop due to exception ", ex);
}
}
+
+ VMInstanceVO vm = profile.getVirtualMachine();
+ List<NicVO> nics = _nicDao.listByVmId(vm.getId());
+ for (NicVO nic : nics) {
+ NetworkVO network = _networkDao.findById(nic.getNetworkId());
+ if (network.getTrafficType() == TrafficType.Guest) {
+ if (nic.getBroadcastUri().getScheme().equals("pvlan")) {
+ setupVmForPvlan(false, vm.getHostId(), nic);
+ }
+ }
+ }
}
public String generateRandomPassword() {
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4c0f775e/server/test/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java b/server/test/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java
index ef5478b..5278b33 100644
--- a/server/test/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java
+++ b/server/test/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java
@@ -402,4 +402,11 @@ VpcVirtualNetworkApplianceService {
return null;
}
+ @Override
+ public void setupVmWithDhcpHostForPvlan(boolean add,
+ DomainRouterVO router, NicProfile nic) throws ResourceUnavailableException {
+ // TODO Auto-generated method stub
+
+ }
+
}