You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ha...@apache.org on 2013/08/24 03:56:53 UTC
git commit: updated refs/heads/master to 34ae32e
Updated Branches:
refs/heads/master c6e569755 -> 34ae32e0c
CLOUDSTACK-2328: Linux native VXLAN support on KVM hypervisor
Initial patch for VXLAN support.
Fully functional, hopefully, for GuestNetwork - AdvancedZone.
Patch Note:
in cloudstack-server
- Add isolation method VXLAN
- Add VxlanGuestNetworkGuru as plugin for VXLAN isolation
- Modify NetworkServiceImpl to handle extended vNet range for VXLAN isolation
- Add VXLAN isolation option in zoneWizard UI
in cloudstack-agent (kvm)
- Add modifyvxlan.sh script that handle bridge/vxlan interface manipulation script
-- Usage is exactly same to modifyvlan.sh
- BridgeVifDriver will call modifyvxlan.sh instead of modifyvlan.sh when VXLAN is used for isolation
Database changes:
- No change in database structure.
- VXLAN isolation uses same tables that VLAN uses to store vNet allocation status.
Known Issue:
- Some resource still says 'VLAN' in log even if VXLAN is used
- in UI, "Network - GuestNetworks" dosen't display VNI
-- VLAN ID field displays "N/A"
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/34ae32e0
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/34ae32e0
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/34ae32e0
Branch: refs/heads/master
Commit: 34ae32e0c24777f9ac9cf265447688a3e21680c7
Parents: c6e5697
Author: Toshiaki Hatano <to...@verio.net>
Authored: Wed Aug 21 02:48:15 2013 +0000
Committer: Toshiaki Hatano <to...@verio.net>
Committed: Sat Aug 24 01:39:11 2013 +0000
----------------------------------------------------------------------
api/src/com/cloud/network/Networks.java | 1 +
api/src/com/cloud/network/PhysicalNetwork.java | 3 +-
client/pom.xml | 5 +
client/tomcatconf/componentContext.xml.in | 8 +
.../kvm/resource/BridgeVifDriver.java | 64 +++--
.../kvm/resource/LibvirtComputingResource.java | 10 +-
.../hypervisor/kvm/resource/OvsVifDriver.java | 6 +-
plugins/network-elements/vxlan/pom.xml | 29 ++
.../network/guru/VxlanGuestNetworkGuru.java | 180 ++++++++++++
.../network/guru/VxlanGuestNetworkGuruTest.java | 273 +++++++++++++++++++
plugins/pom.xml | 1 +
scripts/vm/network/vnet/modifyvlan.sh | 32 +--
scripts/vm/network/vnet/modifyvxlan.sh | 230 ++++++++++++++++
.../com/cloud/network/NetworkManagerImpl.java | 21 +-
.../com/cloud/network/NetworkServiceImpl.java | 6 +-
15 files changed, 812 insertions(+), 57 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/34ae32e0/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 f8166c6..cdc0f17 100755
--- a/api/src/com/cloud/network/Networks.java
+++ b/api/src/com/cloud/network/Networks.java
@@ -108,6 +108,7 @@ public class Networks {
},
Mido("mido", String.class),
Pvlan("pvlan", String.class),
+ Vxlan("vxlan", Long.class),
UnDecided(null, null);
private final String scheme;
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/34ae32e0/api/src/com/cloud/network/PhysicalNetwork.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/network/PhysicalNetwork.java b/api/src/com/cloud/network/PhysicalNetwork.java
index f6cb1a6..55b18e6 100644
--- a/api/src/com/cloud/network/PhysicalNetwork.java
+++ b/api/src/com/cloud/network/PhysicalNetwork.java
@@ -39,7 +39,8 @@ public interface PhysicalNetwork extends Identity, InternalIdentity {
STT,
VNS,
MIDO,
- SSP;
+ SSP,
+ VXLAN;
}
public enum BroadcastDomainRange {
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/34ae32e0/client/pom.xml
----------------------------------------------------------------------
diff --git a/client/pom.xml b/client/pom.xml
index 1afe5b8..eb27fd2 100644
--- a/client/pom.xml
+++ b/client/pom.xml
@@ -106,6 +106,11 @@
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
+ <artifactId>cloud-plugin-network-vxlan</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-plugin-hypervisor-xen</artifactId>
<version>${project.version}</version>
</dependency>
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/34ae32e0/client/tomcatconf/componentContext.xml.in
----------------------------------------------------------------------
diff --git a/client/tomcatconf/componentContext.xml.in b/client/tomcatconf/componentContext.xml.in
index f36d0ee..6e4ac66 100644
--- a/client/tomcatconf/componentContext.xml.in
+++ b/client/tomcatconf/componentContext.xml.in
@@ -91,6 +91,13 @@
<bean id="ucsBladeDaoImpl" class="com.cloud.ucs.database.UcsBladeDaoImpl" />
<bean id="ucsManagerDaoImpl" class="com.cloud.ucs.database.UcsManagerDaoImpl" />
+ <!--
+ VXLAN support components
+ -->
+ <bean id="VxlanGuestNetworkGuru" class="com.cloud.network.guru.VxlanGuestNetworkGuru">
+ <property name="name" value="VxlanGuestNetworkGuru"/>
+ </bean>
+
<!--
Deployment configurations of various adapters
@@ -265,6 +272,7 @@
<ref bean="NiciraNvpGuestNetworkGuru"/>
<ref bean="MidoNetGuestNetworkGuru"/>
<ref bean="SspGuestNetworkGuru"/>
+ <ref bean="VxlanGuestNetworkGuru"/>
</list>
</property>
</bean>
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/34ae32e0/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java
index 195cf40..81e041c 100644
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java
@@ -45,6 +45,8 @@ public class BridgeVifDriver extends VifDriverBase {
private static final Object _vnetBridgeMonitor = new Object();
private String _modifyVlanPath;
+ private String _modifyVxlanPath;
+
@Override
public void configure(Map<String, Object> params) throws ConfigurationException {
@@ -67,7 +69,11 @@ public class BridgeVifDriver extends VifDriverBase {
if (_modifyVlanPath == null) {
throw new ConfigurationException("Unable to find modifyvlan.sh");
}
-
+ _modifyVxlanPath = Script.findScript(networkScriptsDir, "modifyvxlan.sh");
+ if (_modifyVxlanPath == null) {
+ throw new ConfigurationException("Unable to find modifyvxlan.sh");
+ }
+
try {
createControlNetwork();
} catch (LibvirtException e) {
@@ -85,10 +91,16 @@ public class BridgeVifDriver extends VifDriverBase {
LibvirtVMDef.InterfaceDef intf = new LibvirtVMDef.InterfaceDef();
- String vlanId = null;
- if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan) {
+ String vNetId = null;
+ String protocol = null;
+ if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan || nic.getBroadcastType() == Networks.BroadcastDomainType.Vxlan) {
URI broadcastUri = nic.getBroadcastUri();
- vlanId = broadcastUri.getHost();
+ if(broadcastUri.isOpaque()) {
+ vNetId = broadcastUri.getSchemeSpecificPart();
+ } else {
+ vNetId = broadcastUri.getHost();
+ }
+ protocol = nic.getBroadcastType().scheme();
}
else if (nic.getBroadcastType() == Networks.BroadcastDomainType.Lswitch) {
throw new InternalErrorException("Nicira NVP Logicalswitches are not supported by the BridgeVifDriver");
@@ -96,14 +108,14 @@ public class BridgeVifDriver extends VifDriverBase {
String trafficLabel = nic.getName();
if (nic.getType() == Networks.TrafficType.Guest) {
Integer networkRateKBps = (nic.getNetworkRateMbps() != null && nic.getNetworkRateMbps().intValue() != -1)? nic.getNetworkRateMbps().intValue() * 128: 0;
- if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan
- && !vlanId.equalsIgnoreCase("untagged")) {
+ if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan && !vNetId.equalsIgnoreCase("untagged")
+ || nic.getBroadcastType() == Networks.BroadcastDomainType.Vxlan) {
if(trafficLabel != null && !trafficLabel.isEmpty()) {
- s_logger.debug("creating a vlan dev and bridge for guest traffic per traffic label " + trafficLabel);
- String brName = createVlanBr(vlanId, _pifs.get(trafficLabel));
+ s_logger.debug("creating a vNet dev and bridge for guest traffic per traffic label " + trafficLabel);
+ String brName = createVnetBr(vNetId, _pifs.get(trafficLabel), protocol);
intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType), networkRateKBps);
} else {
- String brName = createVlanBr(vlanId, _pifs.get("private"));
+ String brName = createVnetBr(vNetId, _pifs.get("private"), protocol);
intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType), networkRateKBps);
}
} else {
@@ -116,13 +128,13 @@ public class BridgeVifDriver extends VifDriverBase {
} else if (nic.getType() == Networks.TrafficType.Public) {
Integer networkRateKBps = (nic.getNetworkRateMbps() != null && nic.getNetworkRateMbps().intValue() != -1)? nic.getNetworkRateMbps().intValue() * 128: 0;
if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan
- && !vlanId.equalsIgnoreCase("untagged")) {
+ && !vNetId.equalsIgnoreCase("untagged")) {
if(trafficLabel != null && !trafficLabel.isEmpty()){
- s_logger.debug("creating a vlan dev and bridge for public traffic per traffic label " + trafficLabel);
- String brName = createVlanBr(vlanId, _pifs.get(trafficLabel));
+ s_logger.debug("creating a vNet dev and bridge for public traffic per traffic label " + trafficLabel);
+ String brName = createVnetBr(vNetId, _pifs.get(trafficLabel), protocol);
intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType), networkRateKBps);
} else {
- String brName = createVlanBr(vlanId, _pifs.get("public"));
+ String brName = createVnetBr(vNetId, _pifs.get("public"), protocol);
intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType), networkRateKBps);
}
} else {
@@ -149,24 +161,29 @@ public class BridgeVifDriver extends VifDriverBase {
String cmdout = Script.runSimpleBashScript("brctl show | grep " + oldStyleBrName);
if (cmdout != null && cmdout.contains(oldStyleBrName)) {
- s_logger.info("Using old style bridge name for vlan " + vnetId + " because existing bridge " + oldStyleBrName + " was found");
+ s_logger.info("Using old style bridge name for vNet " + vnetId + " because existing bridge " + oldStyleBrName + " was found");
brName = oldStyleBrName;
}
return brName;
}
- private String createVlanBr(String vlanId, String nic)
+ private String createVnetBr(String vNetId, String nic, String protocol)
throws InternalErrorException {
- String brName = setVnetBrName(nic, vlanId);
- createVnet(vlanId, nic, brName);
+ String brName = setVnetBrName(nic, vNetId);
+ createVnet(vNetId, nic, brName, protocol);
return brName;
}
- private void createVnet(String vnetId, String pif, String brName)
+
+ private void createVnet(String vnetId, String pif, String brName, String protocol)
throws InternalErrorException {
synchronized (_vnetBridgeMonitor) {
- final Script command = new Script(_modifyVlanPath, _timeout, s_logger);
+ String script = _modifyVlanPath;
+ if(protocol.equals(Networks.BroadcastDomainType.Vxlan.scheme())) {
+ script = _modifyVxlanPath;
+ }
+ final Script command = new Script(script, _timeout, s_logger);
command.add("-v", vnetId);
command.add("-p", pif);
command.add("-b", brName);
@@ -182,7 +199,7 @@ public class BridgeVifDriver extends VifDriverBase {
private void deleteVnetBr(String brName){
synchronized (_vnetBridgeMonitor) {
- String cmdout = Script.runSimpleBashScript("ls /sys/class/net/" + brName + "/brif | grep vnet");
+ String cmdout = Script.runSimpleBashScript("ls /sys/class/net/" + brName + "/brif | tr '\n' ' '");
if (cmdout != null && cmdout.contains("vnet")) {
// Active VM remains on that bridge
return;
@@ -213,7 +230,12 @@ public class BridgeVifDriver extends VifDriverBase {
return;
}
- final Script command = new Script(_modifyVlanPath, _timeout, s_logger);
+ String script = _modifyVlanPath;
+ if (cmdout != null && cmdout.contains("vxlan")) {
+ script = _modifyVxlanPath;
+ }
+
+ final Script command = new Script(script, _timeout, s_logger);
command.add("-o", "delete");
command.add("-v", vNetId);
command.add("-p", pName);
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/34ae32e0/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
index a156ae6..9f84196 100755
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
@@ -1028,12 +1028,12 @@ ServerResource {
if (! f.isDirectory()){
s_logger.debug("failing to get physical interface from bridge "
+ bridgeName + ", does " + f.getAbsolutePath()
- + "exist?");
+ + " exist?");
return "";
}
File[] interfaces = f.listFiles();
-
+
for (int i = 0; i < interfaces.length; i++) {
String fname = interfaces[i].getName();
s_logger.debug("matchPifFileInDirectory: file name '"+fname+"'");
@@ -1050,7 +1050,6 @@ ServerResource {
return "";
}
-
private boolean checkNetwork(String networkName) {
if (networkName == null) {
return true;
@@ -1655,7 +1654,7 @@ ServerResource {
return pifparts[1];
} else {
s_logger.debug("failed to get vlan id from bridge " + brName
- + "attached to physical interface" + pif);
+ + " attached to physical interface " + pif);
return "";
}
}
@@ -3031,7 +3030,6 @@ ServerResource {
getUsage.add("-d", vif);
}
-
final OutputInterpreter.OneLineParser usageParser = new OutputInterpreter.OneLineParser();
String result = getUsage.execute(usageParser);
if (result != null) {
@@ -4460,7 +4458,7 @@ ServerResource {
s_logger.trace("Ignoring libvirt error.", e);
}
}
-
+
return null;
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/34ae32e0/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/OvsVifDriver.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/OvsVifDriver.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/OvsVifDriver.java
index 7038d7e..323bd05 100644
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/OvsVifDriver.java
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/OvsVifDriver.java
@@ -66,7 +66,11 @@ public class OvsVifDriver extends VifDriverBase {
String logicalSwitchUuid = null;
if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan) {
URI broadcastUri = nic.getBroadcastUri();
- vlanId = broadcastUri.getHost();
+ if(broadcastUri.isOpaque()) {
+ vlanId = broadcastUri.getSchemeSpecificPart();
+ } else {
+ vlanId = broadcastUri.getHost();
+ }
}
else if (nic.getBroadcastType() == Networks.BroadcastDomainType.Lswitch) {
logicalSwitchUuid = nic.getBroadcastUri().getSchemeSpecificPart();
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/34ae32e0/plugins/network-elements/vxlan/pom.xml
----------------------------------------------------------------------
diff --git a/plugins/network-elements/vxlan/pom.xml b/plugins/network-elements/vxlan/pom.xml
new file mode 100644
index 0000000..fe3bbd4
--- /dev/null
+++ b/plugins/network-elements/vxlan/pom.xml
@@ -0,0 +1,29 @@
+<!--
+ 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>cloud-plugin-network-vxlan</artifactId>
+ <name>Apache CloudStack Plugin - Network VXLAN</name>
+ <parent>
+ <groupId>org.apache.cloudstack</groupId>
+ <artifactId>cloudstack-plugins</artifactId>
+ <version>4.3.0-SNAPSHOT</version>
+ <relativePath>../../pom.xml</relativePath>
+ </parent>
+</project>
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/34ae32e0/plugins/network-elements/vxlan/src/com/cloud/network/guru/VxlanGuestNetworkGuru.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/vxlan/src/com/cloud/network/guru/VxlanGuestNetworkGuru.java b/plugins/network-elements/vxlan/src/com/cloud/network/guru/VxlanGuestNetworkGuru.java
new file mode 100644
index 0000000..69e04e1
--- /dev/null
+++ b/plugins/network-elements/vxlan/src/com/cloud/network/guru/VxlanGuestNetworkGuru.java
@@ -0,0 +1,180 @@
+// 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.network.guru;
+
+import javax.ejb.Local;
+
+import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.deploy.DeploymentPlan;
+import com.cloud.event.ActionEventUtils;
+import com.cloud.event.EventTypes;
+import com.cloud.event.EventVO;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InsufficientVirtualNetworkCapcityException;
+import com.cloud.network.Network;
+import com.cloud.network.NetworkProfile;
+import com.cloud.network.Network.GuestType;
+import com.cloud.network.Network.State;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.PhysicalNetwork;
+import com.cloud.network.PhysicalNetwork.IsolationMethod;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.user.Account;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachineProfile;
+
+@Component
+@Local(value=NetworkGuru.class)
+public class VxlanGuestNetworkGuru extends GuestNetworkGuru {
+ private static final Logger s_logger = Logger.getLogger(VxlanGuestNetworkGuru.class);
+
+ public VxlanGuestNetworkGuru() {
+ super();
+ _isolationMethods = new IsolationMethod[] { IsolationMethod.VXLAN };
+ }
+
+ @Override
+ protected boolean canHandle(NetworkOffering offering, final NetworkType networkType, final PhysicalNetwork physicalNetwork) {
+ // This guru handles only Guest Isolated network that supports Source nat service
+ if (networkType == NetworkType.Advanced
+ && isMyTrafficType(offering.getTrafficType())
+ && offering.getGuestType() == Network.GuestType.Isolated
+ && isMyIsolationMethod(physicalNetwork)) {
+ return true;
+ } else {
+ s_logger.trace("We only take care of Guest networks of type " + GuestType.Isolated + " in zone of type " + NetworkType.Advanced);
+ return false;
+ }
+ }
+
+ @Override
+ public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) {
+
+ NetworkVO network = (NetworkVO) super.design(offering, plan, userSpecified, owner);
+ if (network == null) {
+ return null;
+ }
+
+ network.setBroadcastDomainType(BroadcastDomainType.Vxlan);
+
+ return network;
+ }
+
+ protected void allocateVnet(Network network, NetworkVO implemented, long dcId,
+ long physicalNetworkId, String reservationId) throws InsufficientVirtualNetworkCapcityException {
+ if (network.getBroadcastUri() == null) {
+ String vnet = _dcDao.allocateVnet(dcId, physicalNetworkId, network.getAccountId(), reservationId,
+ canUseSystemGuestVlan(network.getAccountId()));
+ if (vnet == null) {
+ throw new InsufficientVirtualNetworkCapcityException("Unable to allocate vnet as a " +
+ "part of network " + network + " implement ", DataCenter.class, dcId);
+ }
+ implemented.setBroadcastUri(BroadcastDomainType.Vxlan.toUri(vnet));
+ allocateVnetComplete(network, implemented, dcId, physicalNetworkId, reservationId, vnet);
+ } else {
+ implemented.setBroadcastUri(network.getBroadcastUri());
+ }
+ }
+
+ // For Test: Mockit cannot mock static method, wrap it
+ protected void allocateVnetComplete(Network network, NetworkVO implemented, long dcId,
+ long physicalNetworkId, String reservationId, String vnet) {
+ //TODO(VXLAN): Add new event type for vxlan?
+ ActionEventUtils.onCompletedActionEvent(CallContext.current().getCallingUserId(), network.getAccountId(),
+ EventVO.LEVEL_INFO, EventTypes.EVENT_ZONE_VLAN_ASSIGN, "Assigned Zone vNet: " + vnet + " Network Id: " + network.getId(), 0);
+ }
+
+ @Override
+ public Network implement(Network network, NetworkOffering offering,
+ DeployDestination dest, ReservationContext context)
+ throws InsufficientVirtualNetworkCapcityException {
+ assert (network.getState() == State.Implementing) : "Why are we implementing " + network;
+
+ long dcId = dest.getDataCenter().getId();
+
+ //get physical network id
+ Long physicalNetworkId = network.getPhysicalNetworkId();
+
+ // physical network id can be null in Guest Network in Basic zone, so locate the physical network
+ if (physicalNetworkId == null) {
+ physicalNetworkId = _networkModel.findPhysicalNetworkId(dcId, offering.getTags(), offering.getTrafficType());
+ }
+
+ NetworkVO implemented = new NetworkVO(network.getTrafficType(), network.getMode(), network.getBroadcastDomainType(), network.getNetworkOfferingId(), State.Allocated,
+ network.getDataCenterId(), physicalNetworkId);
+
+ allocateVnet(network, implemented, dcId, physicalNetworkId, context.getReservationId());
+
+ if (network.getGateway() != null) {
+ implemented.setGateway(network.getGateway());
+ }
+
+ if (network.getCidr() != null) {
+ implemented.setCidr(network.getCidr());
+ }
+
+ return implemented;
+ }
+
+ @Override
+ public void reserve(NicProfile nic, Network network,
+ VirtualMachineProfile vm,
+ DeployDestination dest, ReservationContext context)
+ throws InsufficientVirtualNetworkCapcityException,
+ InsufficientAddressCapacityException {
+ super.reserve(nic, network, vm, dest, context);
+ }
+
+ @Override
+ public boolean release(NicProfile nic,
+ VirtualMachineProfile vm,
+ String reservationId) {
+ return super.release(nic, vm, reservationId);
+ }
+
+ @Override
+ public void shutdown(NetworkProfile profile, NetworkOffering offering) {
+ NetworkVO networkObject = _networkDao.findById(profile.getId());
+ if (networkObject.getBroadcastDomainType() != BroadcastDomainType.Vxlan ||
+ networkObject.getBroadcastUri() == null) {
+ s_logger.warn("BroadcastUri is empty or incorrect for guestnetwork " + networkObject.getDisplayText());
+ return;
+ }
+
+ super.shutdown(profile, offering);
+ }
+
+ @Override
+ public boolean trash(Network network, NetworkOffering offering,
+ Account owner) {
+ return super.trash(network, offering, owner);
+ }
+
+
+
+
+
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/34ae32e0/plugins/network-elements/vxlan/test/com/cloud/network/guru/VxlanGuestNetworkGuruTest.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/vxlan/test/com/cloud/network/guru/VxlanGuestNetworkGuruTest.java b/plugins/network-elements/vxlan/test/com/cloud/network/guru/VxlanGuestNetworkGuruTest.java
new file mode 100644
index 0000000..1172a36
--- /dev/null
+++ b/plugins/network-elements/vxlan/test/com/cloud/network/guru/VxlanGuestNetworkGuruTest.java
@@ -0,0 +1,273 @@
+// 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.network.guru;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Command;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.deploy.DeploymentPlan;
+import com.cloud.domain.Domain;
+import com.cloud.exception.InsufficientVirtualNetworkCapcityException;
+import com.cloud.network.Network;
+import com.cloud.network.Network.GuestType;
+import com.cloud.network.Network.Service;
+import com.cloud.network.Network.State;
+import com.cloud.network.NetworkManager;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.NetworkProfile;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.dao.PhysicalNetworkDao;
+import com.cloud.network.dao.PhysicalNetworkVO;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
+import com.cloud.server.ConfigurationServer;
+import com.cloud.user.Account;
+import com.cloud.vm.ReservationContext;
+
+import java.util.Arrays;
+
+public class VxlanGuestNetworkGuruTest {
+ PhysicalNetworkDao physnetdao = mock (PhysicalNetworkDao.class);
+ DataCenterDao dcdao = mock(DataCenterDao.class);
+ AgentManager agentmgr = mock (AgentManager.class);
+ NetworkManager netmgr = mock (NetworkManager.class);
+ NetworkModel netmodel = mock (NetworkModel.class);
+ ConfigurationServer confsvr = mock(ConfigurationServer.class);
+
+ NetworkDao netdao = mock(NetworkDao.class);
+ VxlanGuestNetworkGuru guru;
+
+ @Before
+ public void setUp() {
+ guru = spy( new VxlanGuestNetworkGuru() );
+ ((GuestNetworkGuru) guru)._physicalNetworkDao = physnetdao;
+ guru._physicalNetworkDao = physnetdao;
+ guru._dcDao = dcdao;
+ guru._networkModel = netmodel;
+ guru._networkDao = netdao;
+ ((GuestNetworkGuru) guru)._configServer = confsvr;
+
+ DataCenterVO dc = mock(DataCenterVO.class);
+ when(dc.getNetworkType()).thenReturn(NetworkType.Advanced);
+ when(dc.getGuestNetworkCidr()).thenReturn("10.1.1.1/24");
+
+ when(dcdao.findById(anyLong())).thenReturn((DataCenterVO) dc);
+ }
+
+ @Test
+ public void testCanHandle() {
+ NetworkOffering offering = mock(NetworkOffering.class);
+ when(offering.getId()).thenReturn(42L);
+ when(offering.getTrafficType()).thenReturn(TrafficType.Guest);
+ when(offering.getGuestType()).thenReturn(GuestType.Isolated);
+
+ PhysicalNetworkVO physnet = mock(PhysicalNetworkVO.class);
+ when(physnet.getIsolationMethods()).thenReturn(Arrays.asList(new String[] { "VXLAN" }));
+ when(physnet.getId()).thenReturn(42L);
+
+ assertTrue(guru.canHandle(offering, NetworkType.Advanced, physnet) == true);
+
+ // Not supported TrafficType != Guest
+ when(offering.getTrafficType()).thenReturn(TrafficType.Management);
+ assertFalse(guru.canHandle(offering, NetworkType.Advanced, physnet) == true);
+
+ // Not supported: GuestType Shared
+ when(offering.getTrafficType()).thenReturn(TrafficType.Guest);
+ when(offering.getGuestType()).thenReturn(GuestType.Shared);
+ assertFalse(guru.canHandle(offering, NetworkType.Advanced, physnet) == true);
+
+ // Not supported: Basic networking
+ when(offering.getGuestType()).thenReturn(GuestType.Isolated);
+ assertFalse(guru.canHandle(offering, NetworkType.Basic, physnet) == true);
+
+ // Not supported: IsolationMethod != VXLAN
+ when(physnet.getIsolationMethods()).thenReturn(Arrays.asList(new String[] { "VLAN" }));
+ assertFalse(guru.canHandle(offering, NetworkType.Advanced, physnet) == true);
+
+ }
+
+ @Test
+ public void testDesign() {
+ PhysicalNetworkVO physnet = mock(PhysicalNetworkVO.class);
+ when(physnetdao.findById(anyLong())).thenReturn(physnet);
+ when(physnet.getIsolationMethods()).thenReturn(Arrays.asList(new String[] { "VXLAN" }));
+ when(physnet.getId()).thenReturn(42L);
+
+ NetworkOffering offering = mock(NetworkOffering.class);
+ when(offering.getId()).thenReturn(42L);
+ when(offering.getTrafficType()).thenReturn(TrafficType.Guest);
+ when(offering.getGuestType()).thenReturn(GuestType.Isolated);
+
+ DeploymentPlan plan = mock(DeploymentPlan.class);
+ Network network = mock(Network.class);
+ Account account = mock(Account.class);
+
+ Network designednetwork = guru.design(offering, plan, network, account);
+ assertTrue(designednetwork != null);
+ assertTrue(designednetwork.getBroadcastDomainType() == BroadcastDomainType.Vxlan);
+ }
+
+ @Test
+ public void testImplement() throws InsufficientVirtualNetworkCapcityException {
+ PhysicalNetworkVO physnet = mock(PhysicalNetworkVO.class);
+ when(physnetdao.findById(anyLong())).thenReturn(physnet);
+ when(physnet.getIsolationMethods()).thenReturn(Arrays.asList(new String[] { "VXLAN" }));
+ when(physnet.getId()).thenReturn(42L);
+
+ NetworkOffering offering = mock(NetworkOffering.class);
+ when(offering.getId()).thenReturn(42L);
+ when(offering.getTrafficType()).thenReturn(TrafficType.Guest);
+ when(offering.getGuestType()).thenReturn(GuestType.Isolated);
+
+ NetworkVO network = mock(NetworkVO.class);
+ when(network.getName()).thenReturn("testnetwork");
+ when(network.getState()).thenReturn(State.Implementing);
+ when(network.getPhysicalNetworkId()).thenReturn(42L);
+
+ DeployDestination dest = mock(DeployDestination.class);
+
+ DataCenter dc = mock(DataCenter.class);
+ when(dest.getDataCenter()).thenReturn(dc);
+
+ when(netmodel.findPhysicalNetworkId(anyLong(), (String) any(), (TrafficType) any())).thenReturn(42L);
+ //TODO(VXLAN): doesn't support VNI specified
+ when(confsvr.getConfigValue((String) any(), (String) any(), anyLong())).thenReturn("true");
+ when(dcdao.allocateVnet(anyLong(), anyLong(), anyLong(), (String) any(), eq(true))).thenReturn("42");
+ doNothing().when(guru).allocateVnetComplete((Network) any(), (NetworkVO) any(), anyLong(), anyLong(), (String) any(), eq("42"));
+
+ Domain dom = mock(Domain.class);
+ when(dom.getName()).thenReturn("domain");
+
+ Account acc = mock(Account.class);
+ when(acc.getAccountName()).thenReturn("accountname");
+
+ ReservationContext res = mock(ReservationContext.class);
+ when(res.getDomain()).thenReturn(dom);
+ when(res.getAccount()).thenReturn(acc);
+
+ Network implementednetwork = guru.implement(network, offering, dest, res);
+ assertTrue(implementednetwork != null);
+ }
+
+ @Test
+ public void testImplementWithCidr() throws InsufficientVirtualNetworkCapcityException {
+ PhysicalNetworkVO physnet = mock(PhysicalNetworkVO.class);
+ when(physnetdao.findById(anyLong())).thenReturn(physnet);
+ when(physnet.getIsolationMethods()).thenReturn(Arrays.asList(new String[] { "VXLAN" }));
+ when(physnet.getId()).thenReturn(42L);
+
+ NetworkOffering offering = mock(NetworkOffering.class);
+ when(offering.getId()).thenReturn(42L);
+ when(offering.getTrafficType()).thenReturn(TrafficType.Guest);
+ when(offering.getGuestType()).thenReturn(GuestType.Isolated);
+
+ NetworkVO network = mock(NetworkVO.class);
+ when(network.getName()).thenReturn("testnetwork");
+ when(network.getState()).thenReturn(State.Implementing);
+ when(network.getGateway()).thenReturn("10.1.1.1");
+ when(network.getCidr()).thenReturn("10.1.1.0/24");
+ when(network.getPhysicalNetworkId()).thenReturn(42L);
+
+ DeployDestination dest = mock(DeployDestination.class);
+
+ DataCenter dc = mock(DataCenter.class);
+ when(dest.getDataCenter()).thenReturn(dc);
+
+ when(netmodel.findPhysicalNetworkId(anyLong(), (String) any(), (TrafficType) any())).thenReturn(42L);
+
+ //TODO(VXLAN): doesn't support VNI specified
+ when(confsvr.getConfigValue((String) any(), (String) any(), anyLong())).thenReturn("true");
+ when(dcdao.allocateVnet(anyLong(), anyLong(), anyLong(), (String) any(), eq(true))).thenReturn("42");
+ doNothing().when(guru).allocateVnetComplete((Network) any(), (NetworkVO) any(), anyLong(), anyLong(), (String) any(), eq("42"));
+
+ Domain dom = mock(Domain.class);
+ when(dom.getName()).thenReturn("domain");
+
+ Account acc = mock(Account.class);
+ when(acc.getAccountName()).thenReturn("accountname");
+
+ ReservationContext res = mock(ReservationContext.class);
+ when(res.getDomain()).thenReturn(dom);
+ when(res.getAccount()).thenReturn(acc);
+
+ Network implementednetwork = guru.implement(network, offering, dest, res);
+ assertTrue(implementednetwork != null);
+ assertTrue(implementednetwork.getCidr().equals("10.1.1.0/24"));
+ assertTrue(implementednetwork.getGateway().equals("10.1.1.1"));
+ }
+
+ @Test
+ public void testShutdown() throws InsufficientVirtualNetworkCapcityException, URISyntaxException {
+ PhysicalNetworkVO physnet = mock(PhysicalNetworkVO.class);
+ when(physnetdao.findById(anyLong())).thenReturn(physnet);
+ when(physnet.getIsolationMethods()).thenReturn(Arrays.asList(new String[] { "VXLAN" }));
+ when(physnet.getId()).thenReturn(42L);
+
+ NetworkOffering offering = mock(NetworkOffering.class);
+ when(offering.getId()).thenReturn(42L);
+ when(offering.getTrafficType()).thenReturn(TrafficType.Guest);
+ when(offering.getGuestType()).thenReturn(GuestType.Isolated);
+
+ NetworkVO network = mock(NetworkVO.class);
+ when(network.getName()).thenReturn("testnetwork");
+ when(network.getState()).thenReturn(State.Implementing);
+ when(network.getBroadcastDomainType()).thenReturn(BroadcastDomainType.Vxlan);
+ when(network.getBroadcastUri()).thenReturn(new URI("vxlan:12345"));
+ when(network.getPhysicalNetworkId()).thenReturn(42L);
+ when(netdao.findById(42L)).thenReturn(network);
+
+ DeployDestination dest = mock(DeployDestination.class);
+
+ DataCenter dc = mock(DataCenter.class);
+ when(dest.getDataCenter()).thenReturn(dc);
+
+ when(netmodel.findPhysicalNetworkId(anyLong(), (String) any(), (TrafficType) any())).thenReturn(42L);
+
+ Domain dom = mock(Domain.class);
+ when(dom.getName()).thenReturn("domain");
+
+ Account acc = mock(Account.class);
+ when(acc.getAccountName()).thenReturn("accountname");
+
+ ReservationContext res = mock(ReservationContext.class);
+ when(res.getDomain()).thenReturn(dom);
+ when(res.getAccount()).thenReturn(acc);
+
+ NetworkProfile implementednetwork = mock(NetworkProfile.class);
+ when(implementednetwork.getId()).thenReturn(42L);
+ when(implementednetwork.getBroadcastUri()).thenReturn(new URI("vxlan:12345"));
+ when(offering.getSpecifyVlan()).thenReturn(false);
+
+ guru.shutdown(implementednetwork, offering);
+ verify(implementednetwork, times(1)).setBroadcastUri(null);
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/34ae32e0/plugins/pom.xml
----------------------------------------------------------------------
diff --git a/plugins/pom.xml b/plugins/pom.xml
index 0812642..032f0e9 100755
--- a/plugins/pom.xml
+++ b/plugins/pom.xml
@@ -62,6 +62,7 @@
<module>alert-handlers/snmp-alerts</module>
<module>alert-handlers/syslog-alerts</module>
<module>network-elements/internal-loadbalancer</module>
+ <module>network-elements/vxlan</module>
</modules>
<dependencies>
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/34ae32e0/scripts/vm/network/vnet/modifyvlan.sh
----------------------------------------------------------------------
diff --git a/scripts/vm/network/vnet/modifyvlan.sh b/scripts/vm/network/vnet/modifyvlan.sh
index 8ed3905..8463d46 100755
--- a/scripts/vm/network/vnet/modifyvlan.sh
+++ b/scripts/vm/network/vnet/modifyvlan.sh
@@ -30,8 +30,8 @@ addVlan() {
local pif=$2
local vlanDev=$pif.$vlanId
local vlanBr=$3
-
- vconfig set_name_type DEV_PLUS_VID_NO_PAD
+
+ vconfig set_name_type DEV_PLUS_VID_NO_PAD
if [ ! -d /sys/class/net/$vlanDev ]
then
@@ -39,17 +39,17 @@ addVlan() {
if [ $? -gt 0 ]
then
- # race condition that someone already creates the vlan
+ # race condition that someone already creates the vlan
if [ ! -d /sys/class/net/$vlanDev ]
- then
- printf "Failed to create vlan $vlanId on pif: $pif."
- return 1
- fi
+ then
+ printf "Failed to create vlan $vlanId on pif: $pif."
+ return 1
+ fi
fi
fi
# is up?
- ifconfig |grep -w $vlanDev > /dev/null
+ ifconfig |grep -w $vlanDev > /dev/null
if [ $? -gt 0 ]
then
ifconfig $vlanDev up > /dev/null
@@ -67,7 +67,7 @@ addVlan() {
return 2
fi
fi
-
+
brctl setfd $vlanBr 0
fi
@@ -92,7 +92,7 @@ addVlan() {
then
ifconfig $vlanBr up
fi
-
+
return 0
}
@@ -100,7 +100,7 @@ deleteVlan() {
local vlanId=$1
local pif=$2
local vlanDev=$pif.$vlanId
- local vlanBr=$3
+ local vlanBr=$3
vconfig rem $vlanDev > /dev/null
@@ -142,12 +142,12 @@ do
v) vflag=1
vlanId="$OPTARG"
;;
- p) pflag=1
+ p) pflag=1
pif="$OPTARG"
;;
- b) bflag=1
- brName="$OPTARG"
- ;;
+ b) bflag=1
+ brName="$OPTARG"
+ ;;
?) usage
exit 2
;;
@@ -183,7 +183,7 @@ else
then
# Delete the vlan
deleteVlan $vlanId $pif $brName
-
+
# Always exit with success
exit 0
fi
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/34ae32e0/scripts/vm/network/vnet/modifyvxlan.sh
----------------------------------------------------------------------
diff --git a/scripts/vm/network/vnet/modifyvxlan.sh b/scripts/vm/network/vnet/modifyvxlan.sh
new file mode 100755
index 0000000..45d141a
--- /dev/null
+++ b/scripts/vm/network/vnet/modifyvxlan.sh
@@ -0,0 +1,230 @@
+#!/usr/bin/env 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.
+
+# modifyvnet.sh -- adds and deletes VXLANs from a Routing Server
+# set -x
+
+## TODO(VXLAN): MTU, IPv6 underlying
+
+usage() {
+ printf "Usage: %s: -o <op>(add | delete) -v <vxlan id> -p <pif> -b <bridge name>\n"
+}
+
+addVxlan() {
+ local vxlanId=$1
+ local pif=$2
+ local vxlanDev=vxlan$vxlanId
+ local vxlanBr=$3
+ local mcastGrp="239.$(( $vxlanId >> 16 % 256 )).$(( $vxlanId >> 8 % 256 )).$(( $vxlanId % 256 ))"
+
+ ## TODO(VXLAN): $brif (trafficlabel) should be passed from caller because we cannot assume 1:1 mapping between pif and brif.
+ # lookup bridge interface
+ local sysfs_dir=/sys/devices/virtual/net/
+ local brif=`find ${sysfs_dir}*/brif/ -name $pif | sed -e "s,$sysfs_dir,," | sed -e 's,/brif/.*$,,'`
+
+ if [ "$brif " == " " ]
+ then
+ printf "Failed to lookup bridge interface which includes pif: $pif."
+ return 1
+ fi
+
+ # confirm ip address of $brif
+ ip addr show $brif | grep -w inet
+ if [ $? -gt 0 ]
+ then
+ printf "Failed to find vxlan multicast source ip address on brif: $brif."
+ return 1
+ fi
+
+ # mcast route
+ ## TODO(VXLAN): Can we assume there're only one IP address which can be multicast src IP on the IF?
+ ip route get $mcastGrp | grep -w "dev $brif"
+ if [ $? -gt 0 ]
+ then
+ ip route add $mcastGrp/32 dev $brif
+ if [ $? -gt 0 ]
+ then
+ printf "Failed to add vxlan multicast route on brif: $brif."
+ return 1
+ fi
+ fi
+
+ if [ ! -d /sys/class/net/$vxlanDev ]
+ then
+ ip link add $vxlanDev type vxlan id $vxlanId group $mcastGrp ttl 10 dev $brif
+
+ if [ $? -gt 0 ]
+ then
+ # race condition that someone already creates the vxlan
+ if [ ! -d /sys/class/net/$vxlanDev ]
+ then
+ printf "Failed to create vxlan $vxlanId on brif: $brif."
+ return 1
+ fi
+ fi
+ fi
+
+ # is up?
+ ip link show $vxlanDev | grep -w UP > /dev/null
+ if [ $? -gt 0 ]
+ then
+ ip link set $vxlanDev up > /dev/null
+ fi
+
+ if [ ! -d /sys/class/net/$vxlanBr ]
+ then
+ brctl addbr $vxlanBr > /dev/null
+
+ if [ $? -gt 0 ]
+ then
+ if [ ! -d /sys/class/net/$vxlanBr ]
+ then
+ printf "Failed to create br: $vxlanBr"
+ return 2
+ fi
+ fi
+
+ brctl setfd $vxlanBr 0
+ fi
+
+ #pif is eslaved into vxlanBr?
+ ls /sys/class/net/$vxlanBr/brif/ | grep -w "$vxlanDev" > /dev/null
+ if [ $? -gt 0 ]
+ then
+ brctl addif $vxlanBr $vxlanDev > /dev/null
+ if [ $? -gt 0 ]
+ then
+ ls /sys/class/net/$vxlanBr/brif/ | grep -w "$vxlanDev" > /dev/null
+ if [ $? -gt 0 ]
+ then
+ printf "Failed to add vxlan: $vxlanDev to $vxlanBr"
+ return 3
+ fi
+ fi
+ fi
+
+ # is vxlanBr up?
+ ip link show $vxlanBr | grep -w UP > /dev/null
+ if [ $? -gt 0 ]
+ then
+ ip link set $vxlanBr up
+ fi
+
+ return 0
+}
+
+deleteVxlan() {
+ local vxlanId=$1
+ local pif=$2
+ local vxlanDev=vxlan$vxlanId
+ local vxlanBr=$3
+ local mcastGrp="239.$(( $vxlanId >> 16 % 256 )).$(( $vxlanId >> 8 % 256 )).$(( $vxlanId % 256 ))"
+
+ ip route del $mcastGrp/32 dev $brif
+
+ ip link delete $vxlanDev
+
+ if [ $? -gt 0 ]
+ then
+ printf "Failed to del vxlan: $vxlanId"
+ printf "Continue..."
+ fi
+
+ ip link set $vxlanBr down
+
+ if [ $? -gt 0 ]
+ then
+ return 1
+ fi
+
+ brctl delbr $vxlanBr
+
+ if [ $? -gt 0 ]
+ then
+ printf "Failed to del bridge $vxlanBr"
+ return 1
+ fi
+
+ return 0
+}
+
+op=
+vxlanId=
+option=$@
+
+while getopts 'o:v:p:b:' OPTION
+do
+ case $OPTION in
+ o) oflag=1
+ op="$OPTARG"
+ ;;
+ v) vflag=1
+ vxlanId="$OPTARG"
+ ;;
+ p) pflag=1
+ pif="$OPTARG"
+ ;;
+ b) bflag=1
+ brName="$OPTARG"
+ ;;
+ ?) usage
+ exit 2
+ ;;
+ esac
+done
+
+# Check that all arguments were passed in
+if [ "$oflag$vflag$pflag$bflag" != "1111" ]
+then
+ usage
+ exit 2
+fi
+
+# Do we support Vxlan?
+lsmod|grep ^vxlan >& /dev/null
+if [ $? -gt 0 ]
+then
+ modprobe=`modprobe vxlan 2>&1`
+ if [ $? -gt 0 ]
+ then
+ printf "Failed to load vxlan kernel module: $modprobe"
+ exit 1
+ fi
+fi
+
+if [ "$op" == "add" ]
+then
+ # Add the vxlan
+ addVxlan $vxlanId $pif $brName
+
+ # If the add fails then return failure
+ if [ $? -gt 0 ]
+ then
+ exit 1
+ fi
+else
+ if [ "$op" == "delete" ]
+ then
+ # Delete the vxlan
+ deleteVxlan $vxlanId $pif $brName
+
+ # Always exit with success
+ exit 0
+ fi
+fi
+
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/34ae32e0/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 00103e3..15f413b 100755
--- a/server/src/com/cloud/network/NetworkManagerImpl.java
+++ b/server/src/com/cloud/network/NetworkManagerImpl.java
@@ -327,7 +327,7 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
UsageEventDao _usageEventDao;
@Inject
NetworkModel _networkModel;
- @Inject
+ @Inject
NicSecondaryIpDao _nicSecondaryIpDao;
@Inject
UserIpv6AddressDao _ipv6Dao;
@@ -631,7 +631,8 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
try {
if (predefined == null
|| (offering.getTrafficType() != TrafficType.Guest && predefined.getCidr() == null && predefined.getBroadcastUri() == null &&
- !(predefined.getBroadcastDomainType() == BroadcastDomainType.Vlan || predefined.getBroadcastDomainType() == BroadcastDomainType.Lswitch))) {
+ !(predefined.getBroadcastDomainType() == BroadcastDomainType.Vlan || predefined.getBroadcastDomainType() == BroadcastDomainType.Lswitch ||
+ predefined.getBroadcastDomainType() == BroadcastDomainType.Vxlan))) {
List<NetworkVO> configs = _networksDao.listBy(owner.getId(), offering.getId(), plan.getDataCenterId());
if (configs.size() > 0) {
if (s_logger.isDebugEnabled()) {
@@ -1729,12 +1730,12 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
} else if (zone.getNetworkType() == NetworkType.Advanced) {
if (zone.isSecurityGroupEnabled()) {
- 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!");
- }
+ 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 ){
@@ -1754,6 +1755,7 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
}
}
+ //TODO(VXLAN): Support VNI specified
// VlanId can be specified only when network offering supports it
boolean vlanSpecified = (vlanId != null);
if (vlanSpecified != ntwkOff.getSpecifyVlan()) {
@@ -1812,9 +1814,6 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
vlanId + " already exists " + "in zone " + zoneId);
}
}
-
-
-
}
// If networkDomain is not specified, take it from the global configuration
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/34ae32e0/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 eadd7bc..27f1b08 100755
--- a/server/src/com/cloud/network/NetworkServiceImpl.java
+++ b/server/src/com/cloud/network/NetworkServiceImpl.java
@@ -187,7 +187,8 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
private static final long MAX_VLAN_ID = 4095L; // 2^12 - 1
private static final long MIN_GRE_KEY = 0L;
private static final long MAX_GRE_KEY = 4294967295L; // 2^32 -1
-
+ private static final long MIN_VXLAN_VNI = 0L;
+ private static final long MAX_VXLAN_VNI = 16777215L; // 2^24 -1
@Inject
DataCenterDao _dcDao = null;
@@ -2645,6 +2646,9 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
if (network.getIsolationMethods().contains("GRE")) {
minVnet = MIN_GRE_KEY;
maxVnet = MAX_GRE_KEY;
+ } else if (network.getIsolationMethods().contains("VXLAN")) {
+ minVnet = MIN_VXLAN_VNI;
+ maxVnet = MAX_VXLAN_VNI;
}
String rangeMessage = " between " + minVnet + " and " + maxVnet;
if (VnetRange.length == 1 && VnetRange[0].equals("")) {