mirror of
https://github.com/apache/cloudstack.git
synced 2025-11-02 20:02:29 +01:00
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"
This commit is contained in:
parent
c6e569755f
commit
34ae32e0c2
@ -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;
|
||||
|
||||
@ -39,7 +39,8 @@ public interface PhysicalNetwork extends Identity, InternalIdentity {
|
||||
STT,
|
||||
VNS,
|
||||
MIDO,
|
||||
SSP;
|
||||
SSP,
|
||||
VXLAN;
|
||||
}
|
||||
|
||||
public enum BroadcastDomainRange {
|
||||
|
||||
@ -104,6 +104,11 @@
|
||||
<artifactId>cloud-plugin-network-internallb</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</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>
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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();
|
||||
|
||||
29
plugins/network-elements/vxlan/pom.xml
Normal file
29
plugins/network-elements/vxlan/pom.xml
Normal file
@ -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>
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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>
|
||||
|
||||
@ -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
|
||||
|
||||
230
scripts/vm/network/vnet/modifyvxlan.sh
Executable file
230
scripts/vm/network/vnet/modifyvxlan.sh
Executable file
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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("")) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user