mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Merge branch 'pvlan'
Conflicts: scripts/vm/hypervisor/xenserver/xenserver60/patch server/src/com/cloud/network/NetworkManager.java server/src/com/cloud/network/NetworkManagerImpl.java server/src/com/cloud/network/NetworkServiceImpl.java server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java server/src/com/cloud/network/vpc/VpcManagerImpl.java server/src/com/cloud/vm/UserVmManagerImpl.java server/test/com/cloud/network/MockNetworkManagerImpl.java server/test/com/cloud/vpc/MockNetworkManagerImpl.java server/test/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java
This commit is contained in:
commit
2d2c0c48cd
121
api/src/com/cloud/agent/api/PvlanSetupCommand.java
Normal file
121
api/src/com/cloud/agent/api/PvlanSetupCommand.java
Normal file
@ -0,0 +1,121 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package com.cloud.agent.api;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import com.cloud.utils.net.NetUtils;
|
||||
|
||||
public class PvlanSetupCommand extends Command {
|
||||
public enum Type {
|
||||
DHCP,
|
||||
VM
|
||||
}
|
||||
private String op;
|
||||
private String primary;
|
||||
private String isolated;
|
||||
private String vmMac;
|
||||
private String dhcpName;
|
||||
private String dhcpMac;
|
||||
private String dhcpIp;
|
||||
private Type type;
|
||||
private String networkTag;
|
||||
|
||||
protected PvlanSetupCommand() {}
|
||||
|
||||
protected PvlanSetupCommand(Type type, String op, URI uri, String networkTag)
|
||||
{
|
||||
this.type = type;
|
||||
this.op = op;
|
||||
this.primary = NetUtils.getPrimaryPvlanFromUri(uri);
|
||||
this.isolated = NetUtils.getIsolatedPvlanFromUri(uri);
|
||||
this.networkTag = networkTag;
|
||||
}
|
||||
|
||||
static public PvlanSetupCommand createDhcpSetup(String op, URI uri, String networkTag, String dhcpName, String dhcpMac, String dhcpIp)
|
||||
{
|
||||
PvlanSetupCommand cmd = new PvlanSetupCommand(Type.DHCP, op, uri, networkTag);
|
||||
cmd.setDhcpName(dhcpName);
|
||||
cmd.setDhcpMac(dhcpMac);
|
||||
cmd.setDhcpIp(dhcpIp);
|
||||
return cmd;
|
||||
}
|
||||
|
||||
static public PvlanSetupCommand createVmSetup(String op, URI uri, String networkTag, String vmMac)
|
||||
{
|
||||
PvlanSetupCommand cmd = new PvlanSetupCommand(Type.VM, op, uri, networkTag);
|
||||
cmd.setVmMac(vmMac);
|
||||
return cmd;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeInSequence() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String getOp() {
|
||||
return op;
|
||||
}
|
||||
|
||||
public String getPrimary() {
|
||||
return primary;
|
||||
}
|
||||
|
||||
public String getIsolated() {
|
||||
return isolated;
|
||||
}
|
||||
|
||||
public String getVmMac() {
|
||||
return vmMac;
|
||||
}
|
||||
|
||||
protected void setVmMac(String vmMac) {
|
||||
this.vmMac = vmMac;
|
||||
}
|
||||
|
||||
public String getDhcpMac() {
|
||||
return dhcpMac;
|
||||
}
|
||||
|
||||
protected void setDhcpMac(String dhcpMac) {
|
||||
this.dhcpMac = dhcpMac;
|
||||
}
|
||||
|
||||
public String getDhcpIp() {
|
||||
return dhcpIp;
|
||||
}
|
||||
|
||||
protected void setDhcpIp(String dhcpIp) {
|
||||
this.dhcpIp = dhcpIp;
|
||||
}
|
||||
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getDhcpName() {
|
||||
return dhcpName;
|
||||
}
|
||||
|
||||
public void setDhcpName(String dhcpName) {
|
||||
this.dhcpName = dhcpName;
|
||||
}
|
||||
|
||||
public String getNetworkTag() {
|
||||
return networkTag;
|
||||
}
|
||||
}
|
||||
@ -63,6 +63,7 @@ public class Networks {
|
||||
Storage("storage", Integer.class),
|
||||
Lswitch("lswitch", String.class),
|
||||
Mido("mido", String.class),
|
||||
Pvlan("pvlan", String.class),
|
||||
UnDecided(null, null);
|
||||
|
||||
private String scheme;
|
||||
|
||||
@ -230,6 +230,7 @@ public class ApiConstants {
|
||||
public static final String VLAN_RANGE = "vlanrange";
|
||||
public static final String REMOVE_VLAN="removevlan";
|
||||
public static final String VLAN_ID = "vlanid";
|
||||
public static final String ISOLATED_PVLAN = "isolatedpvlan";
|
||||
public static final String VM_AVAILABLE = "vmavailable";
|
||||
public static final String VM_LIMIT = "vmlimit";
|
||||
public static final String VM_TOTAL = "vmtotal";
|
||||
|
||||
@ -80,6 +80,9 @@ public class CreateNetworkCmd extends BaseCmd {
|
||||
@Parameter(name=ApiConstants.VLAN, type=CommandType.STRING, description="the ID or VID of the network")
|
||||
private String vlan;
|
||||
|
||||
@Parameter(name=ApiConstants.ISOLATED_PVLAN, type=CommandType.STRING, description="the isolated private vlan for this network")
|
||||
private String isolatedPvlan;
|
||||
|
||||
@Parameter(name=ApiConstants.NETWORK_DOMAIN, type=CommandType.STRING, description="network domain")
|
||||
private String networkDomain;
|
||||
|
||||
@ -141,6 +144,10 @@ public class CreateNetworkCmd extends BaseCmd {
|
||||
return vlan;
|
||||
}
|
||||
|
||||
public String getIsolatedPvlan() {
|
||||
return isolatedPvlan;
|
||||
}
|
||||
|
||||
public String getAccountName() {
|
||||
return accountName;
|
||||
}
|
||||
|
||||
@ -125,6 +125,7 @@ import com.cloud.agent.api.PlugNicAnswer;
|
||||
import com.cloud.agent.api.PlugNicCommand;
|
||||
import com.cloud.agent.api.PrepareForMigrationAnswer;
|
||||
import com.cloud.agent.api.PrepareForMigrationCommand;
|
||||
import com.cloud.agent.api.PvlanSetupCommand;
|
||||
import com.cloud.agent.api.ReadyAnswer;
|
||||
import com.cloud.agent.api.ReadyCommand;
|
||||
import com.cloud.agent.api.RebootAnswer;
|
||||
@ -267,6 +268,8 @@ ServerResource {
|
||||
private String _createTmplPath;
|
||||
private String _heartBeatPath;
|
||||
private String _securityGroupPath;
|
||||
private String _ovsPvlanDhcpHostPath;
|
||||
private String _ovsPvlanVmPath;
|
||||
private String _routerProxyPath;
|
||||
private String _host;
|
||||
private String _dcId;
|
||||
@ -587,6 +590,18 @@ ServerResource {
|
||||
"Unable to find the router_proxy.sh");
|
||||
}
|
||||
|
||||
_ovsPvlanDhcpHostPath = Script.findScript(networkScriptsDir, "ovs-pvlan-dhcp-host.sh");
|
||||
if ( _ovsPvlanDhcpHostPath == null) {
|
||||
throw new ConfigurationException(
|
||||
"Unable to find the ovs-pvlan-dhcp-host.sh");
|
||||
}
|
||||
|
||||
_ovsPvlanVmPath = Script.findScript(networkScriptsDir, "ovs-pvlan-vm.sh");
|
||||
if ( _ovsPvlanVmPath == null) {
|
||||
throw new ConfigurationException(
|
||||
"Unable to find the ovs-pvlan-vm.sh");
|
||||
}
|
||||
|
||||
String value = (String) params.get("developer");
|
||||
boolean isDeveloper = Boolean.parseBoolean(value);
|
||||
|
||||
@ -1202,6 +1217,8 @@ ServerResource {
|
||||
return execute((CheckNetworkCommand) cmd);
|
||||
} else if (cmd instanceof NetworkRulesVmSecondaryIpCommand) {
|
||||
return execute((NetworkRulesVmSecondaryIpCommand) cmd);
|
||||
} else if (cmd instanceof PvlanSetupCommand) {
|
||||
return execute((PvlanSetupCommand) cmd);
|
||||
} else {
|
||||
s_logger.warn("Unsupported command ");
|
||||
return Answer.createUnsupportedCommandAnswer(cmd);
|
||||
@ -1517,6 +1534,65 @@ ServerResource {
|
||||
}
|
||||
}
|
||||
|
||||
private Answer execute(PvlanSetupCommand cmd) {
|
||||
String primaryPvlan = cmd.getPrimary();
|
||||
String isolatedPvlan = cmd.getIsolated();
|
||||
String op = cmd.getOp();
|
||||
String dhcpName = cmd.getDhcpName();
|
||||
String dhcpMac = cmd.getDhcpMac();
|
||||
String dhcpIp = cmd.getDhcpIp();
|
||||
String vmMac = cmd.getVmMac();
|
||||
boolean add = true;
|
||||
|
||||
String opr = "-A";
|
||||
if (op.equals("delete")) {
|
||||
opr = "-D";
|
||||
add = false;
|
||||
}
|
||||
|
||||
String result = null;
|
||||
Connect conn;
|
||||
try {
|
||||
if (cmd.getType() == PvlanSetupCommand.Type.DHCP) {
|
||||
Script script = new Script(_ovsPvlanDhcpHostPath, _timeout, s_logger);
|
||||
if (add) {
|
||||
conn = LibvirtConnection.getConnectionByVmName(dhcpName);
|
||||
List<InterfaceDef> ifaces = getInterfaces(conn, dhcpName);
|
||||
InterfaceDef guestNic = ifaces.get(0);
|
||||
script.add(opr, "-b", _guestBridgeName,
|
||||
"-p", primaryPvlan, "-i", isolatedPvlan, "-n", dhcpName,
|
||||
"-d", dhcpIp, "-m", dhcpMac, "-I", guestNic.getDevName());
|
||||
} else {
|
||||
script.add(opr, "-b", _guestBridgeName,
|
||||
"-p", primaryPvlan, "-i", isolatedPvlan, "-n", dhcpName,
|
||||
"-d", dhcpIp, "-m", dhcpMac);
|
||||
}
|
||||
result = script.execute();
|
||||
if (result != null) {
|
||||
s_logger.warn("Failed to program pvlan for dhcp server with mac " + dhcpMac);
|
||||
return new Answer(cmd, false, result);
|
||||
} else {
|
||||
s_logger.info("Programmed pvlan for dhcp server with mac " + dhcpMac);
|
||||
}
|
||||
} else if (cmd.getType() == PvlanSetupCommand.Type.VM) {
|
||||
Script script = new Script(_ovsPvlanVmPath, _timeout, s_logger);
|
||||
script.add(opr, "-b", _guestBridgeName,
|
||||
"-p", primaryPvlan, "-i", isolatedPvlan, "-v", vmMac);
|
||||
result = script.execute();
|
||||
if (result != null) {
|
||||
s_logger.warn("Failed to program pvlan for vm with mac " + vmMac);
|
||||
return new Answer(cmd, false, result);
|
||||
} else {
|
||||
s_logger.info("Programmed pvlan for vm with mac " + vmMac);
|
||||
}
|
||||
}
|
||||
} catch (LibvirtException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
return new Answer(cmd, true, result);
|
||||
}
|
||||
|
||||
private void VifHotPlug(Connect conn, String vmName, String vlanId,
|
||||
String macAddr) throws InternalErrorException, LibvirtException {
|
||||
NicTO nicTO = new NicTO();
|
||||
|
||||
@ -76,10 +76,12 @@ public class OvsVifDriver extends VifDriverBase {
|
||||
}
|
||||
else if (nic.getBroadcastType() == Networks.BroadcastDomainType.Lswitch) {
|
||||
logicalSwitchUuid = nic.getBroadcastUri().getSchemeSpecificPart();
|
||||
} else if (nic.getBroadcastType() == Networks.BroadcastDomainType.Pvlan) {
|
||||
vlanId = NetUtils.getPrimaryPvlanFromUri(nic.getBroadcastUri());
|
||||
}
|
||||
String trafficLabel = nic.getName();
|
||||
if (nic.getType() == Networks.TrafficType.Guest) {
|
||||
if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan
|
||||
if ((nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan || nic.getBroadcastType() == Networks.BroadcastDomainType.Pvlan)
|
||||
&& !vlanId.equalsIgnoreCase("untagged")) {
|
||||
if(trafficLabel != null && !trafficLabel.isEmpty()) {
|
||||
s_logger.debug("creating a vlan dev and bridge for guest traffic per traffic label " + trafficLabel);
|
||||
|
||||
@ -83,6 +83,7 @@ import com.cloud.agent.api.PlugNicCommand;
|
||||
import com.cloud.agent.api.PoolEjectCommand;
|
||||
import com.cloud.agent.api.PrepareForMigrationAnswer;
|
||||
import com.cloud.agent.api.PrepareForMigrationCommand;
|
||||
import com.cloud.agent.api.PvlanSetupCommand;
|
||||
import com.cloud.agent.api.ReadyAnswer;
|
||||
import com.cloud.agent.api.ReadyCommand;
|
||||
import com.cloud.agent.api.RebootAnswer;
|
||||
@ -614,6 +615,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
||||
return execute((NetworkRulesVmSecondaryIpCommand)cmd);
|
||||
} else if (clazz == ScaleVmCommand.class) {
|
||||
return execute((ScaleVmCommand) cmd);
|
||||
} else if (clazz == PvlanSetupCommand.class) {
|
||||
return execute((PvlanSetupCommand) cmd);
|
||||
} else {
|
||||
return Answer.createUnsupportedCommandAnswer(cmd);
|
||||
}
|
||||
@ -1030,6 +1033,11 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
||||
} else if (nic.getBroadcastType() == BroadcastDomainType.Lswitch) {
|
||||
// Nicira Logical Switch
|
||||
return network.getNetwork();
|
||||
} else if (nic.getBroadcastType() == BroadcastDomainType.Pvlan) {
|
||||
URI broadcastUri = nic.getBroadcastUri();
|
||||
assert broadcastUri.getScheme().equals(BroadcastDomainType.Pvlan.scheme());
|
||||
long vlan = Long.parseLong(NetUtils.getPrimaryPvlanFromUri(broadcastUri));
|
||||
return enableVlanNetwork(conn, vlan, network);
|
||||
}
|
||||
|
||||
throw new CloudRuntimeException("Unable to support this type of network broadcast domain: " + nic.getBroadcastUri());
|
||||
@ -1065,7 +1073,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
||||
vifr = vif.getRecord(conn);
|
||||
s_logger.debug("Created a vif " + vifr.uuid + " on " + nic.getDeviceId());
|
||||
}
|
||||
|
||||
|
||||
return vif;
|
||||
}
|
||||
|
||||
@ -1476,6 +1484,55 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Answer execute(PvlanSetupCommand cmd) {
|
||||
Connection conn = getConnection();
|
||||
|
||||
String primaryPvlan = cmd.getPrimary();
|
||||
String isolatedPvlan = cmd.getIsolated();
|
||||
String op = cmd.getOp();
|
||||
String dhcpName = cmd.getDhcpName();
|
||||
String dhcpMac = cmd.getDhcpMac();
|
||||
String dhcpIp = cmd.getDhcpIp();
|
||||
String vmMac = cmd.getVmMac();
|
||||
String networkTag = cmd.getNetworkTag();
|
||||
|
||||
XsLocalNetwork nw = null;
|
||||
String nwNameLabel = null;
|
||||
try {
|
||||
nw = getNativeNetworkForTraffic(conn, TrafficType.Guest, networkTag);
|
||||
nwNameLabel = nw.getNetwork().getNameLabel(conn);
|
||||
} catch (XenAPIException e) {
|
||||
s_logger.warn("Fail to get network", e);
|
||||
return new Answer(cmd, false, e.toString());
|
||||
} catch (XmlRpcException e) {
|
||||
s_logger.warn("Fail to get network", e);
|
||||
return new Answer(cmd, false, e.toString());
|
||||
}
|
||||
|
||||
String result = null;
|
||||
if (cmd.getType() == PvlanSetupCommand.Type.DHCP) {
|
||||
result = callHostPlugin(conn, "ovs-pvlan", "setup-pvlan-dhcp", "op", op, "nw-label", nwNameLabel,
|
||||
"primary-pvlan", primaryPvlan, "isolated-pvlan", isolatedPvlan, "dhcp-name", dhcpName,
|
||||
"dhcp-ip", dhcpIp, "dhcp-mac", dhcpMac);
|
||||
if (result == null || result.isEmpty() || !Boolean.parseBoolean(result)) {
|
||||
s_logger.warn("Failed to program pvlan for dhcp server with mac " + dhcpMac);
|
||||
return new Answer(cmd, false, result);
|
||||
} else {
|
||||
s_logger.info("Programmed pvlan for dhcp server with mac " + dhcpMac);
|
||||
}
|
||||
} else if (cmd.getType() == PvlanSetupCommand.Type.VM) {
|
||||
result = callHostPlugin(conn, "ovs-pvlan", "setup-pvlan-vm", "op", op, "nw-label", nwNameLabel,
|
||||
"primary-pvlan", primaryPvlan, "isolated-pvlan", isolatedPvlan, "vm-mac", vmMac);
|
||||
if (result == null || result.isEmpty() || !Boolean.parseBoolean(result)) {
|
||||
s_logger.warn("Failed to program pvlan for vm with mac " + vmMac);
|
||||
return new Answer(cmd, false, result);
|
||||
} else {
|
||||
s_logger.info("Programmed pvlan for vm with mac " + vmMac);
|
||||
}
|
||||
}
|
||||
return new Answer(cmd, true, result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StartAnswer execute(StartCommand cmd) {
|
||||
|
||||
27
scripts/vm/hypervisor/xenserver/ovs-get-bridge.sh
Executable file
27
scripts/vm/hypervisor/xenserver/ovs-get-bridge.sh
Executable file
@ -0,0 +1,27 @@
|
||||
#!/bin/bash
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
nw_label=$1
|
||||
br=`xe network-list name-label="$nw_label" params=bridge |cut -d ':' -f 2 |tr -d ' ' `
|
||||
pbr=`ovs-vsctl br-to-parent $br`
|
||||
while [ "$br" != "$pbr" ]
|
||||
do
|
||||
br=$pbr
|
||||
pbr=`ovs-vsctl br-to-parent $br`
|
||||
done
|
||||
echo $pbr
|
||||
25
scripts/vm/hypervisor/xenserver/ovs-get-dhcp-iface.sh
Executable file
25
scripts/vm/hypervisor/xenserver/ovs-get-dhcp-iface.sh
Executable file
@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
#!/bin/bash
|
||||
|
||||
bridge=$1
|
||||
dhcp_name=$2
|
||||
dom_id=`xe vm-list is-control-domain=false power-state=running params=dom-id name-label=$dhcp_name|cut -d ':' -f 2 |tr -d ' ' `
|
||||
iface="vif${dom_id}.0"
|
||||
echo $iface
|
||||
145
scripts/vm/hypervisor/xenserver/ovs-pvlan
Executable file
145
scripts/vm/hypervisor/xenserver/ovs-pvlan
Executable file
@ -0,0 +1,145 @@
|
||||
#!/usr/bin/python
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
import cloudstack_pluginlib as lib
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import time
|
||||
import XenAPIPlugin
|
||||
|
||||
sys.path.append("/opt/xensource/sm/")
|
||||
import util
|
||||
|
||||
from time import localtime as _localtime, asctime as _asctime
|
||||
|
||||
xePath = "/opt/xensource/bin/xe"
|
||||
lib.setup_logging("/var/log/ovs-pvlan.log")
|
||||
dhcpSetupPath = "/opt/xensource/bin/ovs-pvlan-dhcp-host.sh"
|
||||
vmSetupPath = "/opt/xensource/bin/ovs-pvlan-vm.sh"
|
||||
getDhcpIfacePath = "/opt/xensource/bin/ovs-get-dhcp-iface.sh"
|
||||
pvlanCleanupPath = "/opt/xensource/bin/ovs-pvlan-cleanup.sh"
|
||||
getBridgePath = "/opt/xensource/bin/ovs-get-bridge.sh"
|
||||
|
||||
def echo(fn):
|
||||
def wrapped(*v, **k):
|
||||
name = fn.__name__
|
||||
util.SMlog("#### VMOPS enter %s ####" % name)
|
||||
res = fn(*v, **k)
|
||||
util.SMlog("#### VMOPS exit %s ####" % name)
|
||||
return res
|
||||
return wrapped
|
||||
|
||||
@echo
|
||||
def setup_pvlan_dhcp(session, args):
|
||||
op = args.pop("op")
|
||||
nw_label = args.pop("nw-label")
|
||||
primary = args.pop("primary-pvlan")
|
||||
isolated = args.pop("isolated-pvlan")
|
||||
dhcp_name = args.pop("dhcp-name")
|
||||
dhcp_ip = args.pop("dhcp-ip")
|
||||
dhcp_mac = args.pop("dhcp-mac")
|
||||
|
||||
res = lib.check_switch()
|
||||
if res != "SUCCESS":
|
||||
return "FAILURE:%s" % res
|
||||
|
||||
logging.debug("Network is:%s" % (nw_label))
|
||||
bridge = lib.do_cmd([getBridgePath, nw_label])
|
||||
logging.debug("Determine bridge/switch is :%s" % (bridge))
|
||||
|
||||
if op == "add":
|
||||
logging.debug("Try to get dhcp vm %s port on the switch:%s" % (dhcp_name, bridge))
|
||||
dhcp_iface = lib.do_cmd([getDhcpIfacePath, bridge, dhcp_name])
|
||||
logging.debug("About to setup dhcp vm on the switch:%s" % bridge)
|
||||
res = lib.do_cmd([dhcpSetupPath, "-A", "-b", bridge, "-p", primary,
|
||||
"-i", isolated, "-n", dhcp_name, "-d", dhcp_ip, "-m", dhcp_mac,
|
||||
"-I", dhcp_iface])
|
||||
if res:
|
||||
result = "FAILURE:%s" % res
|
||||
return result;
|
||||
logging.debug("Setup dhcp vm on switch program done")
|
||||
elif op == "delete":
|
||||
logging.debug("About to remove dhcp the switch:%s" % bridge)
|
||||
res = lib.do_cmd([dhcpSetupPath, "-D", "-b", bridge, "-p", primary,
|
||||
"-i", isolated, "-n", dhcp_name, "-d", dhcp_ip, "-m", dhcp_mac])
|
||||
if res:
|
||||
result = "FAILURE:%s" % res
|
||||
return result;
|
||||
logging.debug("Remove DHCP on switch program done")
|
||||
|
||||
result = "true"
|
||||
logging.debug("Setup_pvlan_dhcp completed with result:%s" % result)
|
||||
return result
|
||||
|
||||
@echo
|
||||
def setup_pvlan_vm(session, args):
|
||||
op = args.pop("op")
|
||||
nw_label = args.pop("nw-label")
|
||||
primary = args.pop("primary-pvlan")
|
||||
isolated = args.pop("isolated-pvlan")
|
||||
vm_mac = args.pop("vm-mac")
|
||||
trunk_port = 1
|
||||
|
||||
res = lib.check_switch()
|
||||
if res != "SUCCESS":
|
||||
return "FAILURE:%s" % res
|
||||
|
||||
bridge = lib.do_cmd([getBridgePath, nw_label])
|
||||
logging.debug("Determine bridge/switch is :%s" % (bridge))
|
||||
|
||||
if op == "add":
|
||||
logging.debug("About to setup vm on the switch:%s" % bridge)
|
||||
res = lib.do_cmd([vmSetupPath, "-A", "-b", bridge, "-p", primary, "-i", isolated, "-v", vm_mac])
|
||||
if res:
|
||||
result = "FAILURE:%s" % res
|
||||
return result;
|
||||
logging.debug("Setup vm on switch program done")
|
||||
elif op == "delete":
|
||||
logging.debug("About to remove vm on the switch:%s" % bridge)
|
||||
res = lib.do_cmd([vmSetupPath, "-D", "-b", bridge, "-p", primary, "-i", isolated, "-v", vm_mac])
|
||||
if res:
|
||||
result = "FAILURE:%s" % res
|
||||
return result;
|
||||
logging.debug("Remove vm on switch program done")
|
||||
|
||||
result = "true"
|
||||
logging.debug("Setup_pvlan_vm_alone completed with result:%s" % result)
|
||||
return result
|
||||
|
||||
@echo
|
||||
def cleanup(session, args):
|
||||
res = lib.check_switch()
|
||||
if res != "SUCCESS":
|
||||
return "FAILURE:%s" % res
|
||||
|
||||
res = lib.do_cmd([pvlanCleanUpPath])
|
||||
if res:
|
||||
result = "FAILURE:%s" % res
|
||||
return result;
|
||||
|
||||
result = "true"
|
||||
logging.debug("Setup_pvlan_vm_dhcp completed with result:%s" % result)
|
||||
return result
|
||||
|
||||
if __name__ == "__main__":
|
||||
XenAPIPlugin.dispatch({"setup-pvlan-dhcp": setup_pvlan_dhcp,
|
||||
"setup-pvlan-vm": setup_pvlan_vm,
|
||||
"cleanup":cleanup})
|
||||
@ -70,4 +70,9 @@ swift=..,0755,/opt/xensource/bin
|
||||
swiftxen=..,0755,/etc/xapi.d/plugins
|
||||
s3xen=..,0755,/etc/xapi.d/plugins
|
||||
add_to_vcpus_params_live.sh=..,0755,/opt/xensource/bin
|
||||
|
||||
ovs-pvlan=..,0755,/etc/xapi.d/plugins
|
||||
ovs-pvlan-dhcp-host.sh=../../../network,0755,/opt/xensource/bin
|
||||
ovs-pvlan-vm.sh=../../../network,0755,/opt/xensource/bin
|
||||
ovs-pvlan-cleanup.sh=../../../network,0755,/opt/xensource/bin
|
||||
ovs-get-dhcp-iface.sh=..,0755,/opt/xensource/bin
|
||||
ovs-get-bridge.sh=..,0755,/opt/xensource/bin
|
||||
|
||||
23
scripts/vm/network/ovs-pvlan-cleanup.sh
Executable file
23
scripts/vm/network/ovs-pvlan-cleanup.sh
Executable file
@ -0,0 +1,23 @@
|
||||
#!/bin/bash
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
#!/bin/bash
|
||||
|
||||
ovs-ofctl del-flows xenbr0
|
||||
ovs-ofctl add-flow xenbr0 priority=0,actions=NORMAL
|
||||
|
||||
123
scripts/vm/network/ovs-pvlan-dhcp-host.sh
Executable file
123
scripts/vm/network/ovs-pvlan-dhcp-host.sh
Executable file
@ -0,0 +1,123 @@
|
||||
#!/bin/bash
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
#!/bin/bash
|
||||
|
||||
usage() {
|
||||
printf "Usage: %s: (-A|-D) -b <bridge/switch> -p <primary vlan> -i <secondary isolated vlan> -n <DHCP server name> -d <DHCP server IP> -m <DHCP server MAC> -I <interface> -v <VM MAC> -h \n" $(basename $0) >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
br=
|
||||
pri_vlan=
|
||||
sec_iso_vlan=
|
||||
dhcp_name=
|
||||
dhcp_ip=
|
||||
dhcp_mac=
|
||||
vm_mac=
|
||||
iface=
|
||||
op=
|
||||
|
||||
while getopts 'ADb:p:i:d:m:v:n:I:h' OPTION
|
||||
do
|
||||
case $OPTION in
|
||||
A) op="add"
|
||||
;;
|
||||
D) op="del"
|
||||
;;
|
||||
b) br="$OPTARG"
|
||||
;;
|
||||
p) pri_vlan="$OPTARG"
|
||||
;;
|
||||
i) sec_iso_vlan="$OPTARG"
|
||||
;;
|
||||
n) dhcp_name="$OPTARG"
|
||||
;;
|
||||
d) dhcp_ip="$OPTARG"
|
||||
;;
|
||||
m) dhcp_mac="$OPTARG"
|
||||
;;
|
||||
I) iface="$OPTARG"
|
||||
;;
|
||||
v) vm_mac="$OPTARG"
|
||||
;;
|
||||
h) usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -z "$op" ]
|
||||
then
|
||||
echo Missing operation pararmeter!
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$br" ]
|
||||
then
|
||||
echo Missing parameter bridge!
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$pri_vlan" ]
|
||||
then
|
||||
echo Missing parameter primary vlan!
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$sec_iso_vlan" ]
|
||||
then
|
||||
echo Missing parameter secondary isolate vlan!
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$dhcp_name" ]
|
||||
then
|
||||
echo Missing parameter DHCP NAME!
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$dhcp_ip" ]
|
||||
then
|
||||
echo Missing parameter DHCP IP!
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$dhcp_mac" ]
|
||||
then
|
||||
echo Missing parameter DHCP MAC!
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$op" == "add" -a -z "$iface" ]
|
||||
then
|
||||
echo Missing parameter DHCP VM interface!
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$op" == "add" ]
|
||||
then
|
||||
dhcp_port=`ovs-ofctl show $br | grep $iface | cut -d '(' -f 1|tr -d ' '`
|
||||
ovs-ofctl add-flow $br priority=200,arp,dl_vlan=$sec_iso_vlan,nw_dst=$dhcp_ip,actions=strip_vlan,output:$dhcp_port
|
||||
ovs-ofctl add-flow $br priority=150,dl_vlan=$sec_iso_vlan,dl_dst=$dhcp_mac,actions=strip_vlan,output:$dhcp_port
|
||||
ovs-ofctl add-flow $br priority=100,udp,dl_vlan=$sec_iso_vlan,nw_dst=255.255.255.255,tp_dst=67,actions=strip_vlan,output:$dhcp_port
|
||||
else
|
||||
ovs-ofctl del-flows --strict $br priority=200,arp,dl_vlan=$sec_iso_vlan,nw_dst=$dhcp_ip
|
||||
ovs-ofctl del-flows --strict $br priority=150,dl_vlan=$sec_iso_vlan,dl_dst=$dhcp_mac
|
||||
ovs-ofctl del-flows --strict $br priority=100,udp,dl_vlan=$sec_iso_vlan,nw_dst=255.255.255.255,tp_dst=67
|
||||
fi
|
||||
99
scripts/vm/network/ovs-pvlan-vm.sh
Executable file
99
scripts/vm/network/ovs-pvlan-vm.sh
Executable file
@ -0,0 +1,99 @@
|
||||
#!/bin/bash
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
#!/bin/bash
|
||||
|
||||
usage() {
|
||||
printf "Usage: %s: (-A|-D) -b <bridge/switch> -p <primary vlan> -i <secondary isolated vlan> -d <DHCP server IP> -m <DHCP server MAC> -v <VM MAC> -h \n" $(basename $0) >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
br=
|
||||
pri_vlan=
|
||||
sec_iso_vlan=
|
||||
dhcp_ip=
|
||||
dhcp_mac=
|
||||
vm_mac=
|
||||
op=
|
||||
|
||||
while getopts 'ADb:p:i:d:m:v:h' OPTION
|
||||
do
|
||||
case $OPTION in
|
||||
A) op="add"
|
||||
;;
|
||||
D) op="del"
|
||||
;;
|
||||
b) br="$OPTARG"
|
||||
;;
|
||||
p) pri_vlan="$OPTARG"
|
||||
;;
|
||||
i) sec_iso_vlan="$OPTARG"
|
||||
;;
|
||||
d) dhcp_ip="$OPTARG"
|
||||
;;
|
||||
m) dhcp_mac="$OPTARG"
|
||||
;;
|
||||
v) vm_mac="$OPTARG"
|
||||
;;
|
||||
h) usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -z "$op" ]
|
||||
then
|
||||
echo Missing operation pararmeter!
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$br" ]
|
||||
then
|
||||
echo Missing parameter bridge!
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$vm_mac" ]
|
||||
then
|
||||
echo Missing parameter VM MAC!
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$pri_vlan" ]
|
||||
then
|
||||
echo Missing parameter secondary isolate vlan!
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$sec_iso_vlan" ]
|
||||
then
|
||||
echo Missing parameter secondary isolate vlan!
|
||||
exit 1
|
||||
fi
|
||||
|
||||
trunk_port=1
|
||||
|
||||
if [ "$op" == "add" ]
|
||||
then
|
||||
ovs-ofctl add-flow $br priority=50,dl_vlan=0xffff,dl_src=$vm_mac,actions=mod_vlan_vid:$sec_iso_vlan,resubmit:$trunk_port
|
||||
ovs-ofctl add-flow $br priority=60,dl_vlan=$sec_iso_vlan,dl_src=$vm_mac,actions=output:$trunk_port
|
||||
else
|
||||
ovs-ofctl del-flows --strict $br priority=50,dl_vlan=0xffff,dl_src=$vm_mac
|
||||
ovs-ofctl del-flows --strict $br priority=60,dl_vlan=$sec_iso_vlan,dl_src=$vm_mac
|
||||
fi
|
||||
|
||||
@ -2657,6 +2657,8 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
||||
if (uri != null) {
|
||||
String[] vlan = uri.toString().split("vlan:\\/\\/");
|
||||
networkVlanId = vlan[1];
|
||||
//For pvlan
|
||||
networkVlanId = networkVlanId.split("-")[0];
|
||||
}
|
||||
|
||||
if (vlanId != null) {
|
||||
|
||||
@ -130,7 +130,8 @@ public interface NetworkManager {
|
||||
|
||||
Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway, String cidr,
|
||||
String vlanId, String networkDomain, Account owner, Long domainId, PhysicalNetwork physicalNetwork,
|
||||
long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId, String ip6Gateway, String ip6Cidr, Boolean displayNetworkEnabled)
|
||||
long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId, String ip6Gateway, String ip6Cidr,
|
||||
Boolean displayNetworkEnabled, String isolatedPvlan)
|
||||
throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException;
|
||||
|
||||
/**
|
||||
|
||||
@ -1900,7 +1900,8 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
|
||||
@DB
|
||||
public Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway,
|
||||
String cidr, String vlanId, String networkDomain, Account owner, Long domainId,
|
||||
PhysicalNetwork pNtwk, long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId, String ip6Gateway, String ip6Cidr, Boolean isDisplayNetworkEnabled)
|
||||
PhysicalNetwork pNtwk, long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId, String ip6Gateway, String ip6Cidr,
|
||||
Boolean isDisplayNetworkEnabled, String isolatedPvlan)
|
||||
throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException {
|
||||
|
||||
NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(networkOfferingId);
|
||||
@ -1990,6 +1991,9 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
|
||||
if (ipv6) {
|
||||
throw new InvalidParameterValueException("IPv6 is not supported with security group!");
|
||||
}
|
||||
if (isolatedPvlan != null) {
|
||||
throw new InvalidParameterValueException("Isolated Private VLAN is not supported with security group!");
|
||||
}
|
||||
// Only Account specific Isolated network with sourceNat service disabled are allowed in security group
|
||||
// enabled zone
|
||||
if ( ntwkOff.getGuestType() != GuestType.Shared ){
|
||||
@ -2149,13 +2153,20 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
|
||||
}
|
||||
|
||||
if (vlanId != null) {
|
||||
userNetwork.setBroadcastUri(URI.create("vlan://" + vlanId));
|
||||
userNetwork.setBroadcastDomainType(BroadcastDomainType.Vlan);
|
||||
if (!vlanId.equalsIgnoreCase(Vlan.UNTAGGED)) {
|
||||
userNetwork.setBroadcastDomainType(BroadcastDomainType.Vlan);
|
||||
} else {
|
||||
userNetwork.setBroadcastDomainType(BroadcastDomainType.Native);
|
||||
}
|
||||
if (isolatedPvlan == null) {
|
||||
userNetwork.setBroadcastUri(URI.create("vlan://" + vlanId));
|
||||
if (!vlanId.equalsIgnoreCase(Vlan.UNTAGGED)) {
|
||||
userNetwork.setBroadcastDomainType(BroadcastDomainType.Vlan);
|
||||
} else {
|
||||
userNetwork.setBroadcastDomainType(BroadcastDomainType.Native);
|
||||
}
|
||||
} else {
|
||||
if (vlanId.equalsIgnoreCase(Vlan.UNTAGGED)) {
|
||||
throw new InvalidParameterValueException("Cannot support pvlan with untagged primary vlan!");
|
||||
}
|
||||
userNetwork.setBroadcastUri(NetUtils.generateUriForPvlan(vlanId, isolatedPvlan));
|
||||
userNetwork.setBroadcastDomainType(BroadcastDomainType.Pvlan);
|
||||
}
|
||||
}
|
||||
|
||||
List<NetworkVO> networks = setupNetwork(owner, ntwkOff, userNetwork, plan, name, displayText, true, domainId,
|
||||
@ -2758,7 +2769,7 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
|
||||
guestNetwork = createGuestNetwork(requiredOfferings.get(0).getId(), owner.getAccountName() + "-network"
|
||||
, owner.getAccountName() + "-network", null, null, null, null, owner, null, physicalNetwork,
|
||||
zoneId, ACLType.Account,
|
||||
null, null, null, null, true);
|
||||
null, null, null, null, true, null);
|
||||
if (guestNetwork == null) {
|
||||
s_logger.warn("Failed to create default Virtual network for the account " + accountId + "in zone " + zoneId);
|
||||
throw new CloudRuntimeException("Failed to create a Guest Isolated Networks with SourceNAT " +
|
||||
@ -3634,8 +3645,10 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
|
||||
nic.setGateway(ip.getGateway());
|
||||
nic.setNetmask(ip.getNetmask());
|
||||
nic.setIsolationUri(IsolationType.Vlan.toUri(ip.getVlanTag()));
|
||||
nic.setBroadcastType(BroadcastDomainType.Vlan);
|
||||
nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(ip.getVlanTag()));
|
||||
//nic.setBroadcastType(BroadcastDomainType.Vlan);
|
||||
//nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(ip.getVlanTag()));
|
||||
nic.setBroadcastType(network.getBroadcastDomainType());
|
||||
nic.setBroadcastUri(network.getBroadcastUri());
|
||||
nic.setFormat(AddressFormat.Ip4);
|
||||
nic.setReservationId(String.valueOf(ip.getVlanTag()));
|
||||
nic.setMacAddress(ip.getMacAddress());
|
||||
|
||||
@ -952,6 +952,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
|
||||
String ip6Cidr = cmd.getIp6Cidr();
|
||||
Boolean displayNetwork = cmd.getDisplayNetwork();
|
||||
Long aclId = cmd.getAclId();
|
||||
String isolatedPvlan = cmd.getIsolatedPvlan();
|
||||
|
||||
// Validate network offering
|
||||
NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(networkOfferingId);
|
||||
@ -1143,6 +1144,14 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
|
||||
}
|
||||
}
|
||||
|
||||
if (isolatedPvlan != null && (zone.getNetworkType() != NetworkType.Advanced || ntwkOff.getGuestType() != Network.GuestType.Shared)) {
|
||||
throw new InvalidParameterValueException("Can only support create Private VLAN network with advance shared network!");
|
||||
}
|
||||
|
||||
if (isolatedPvlan != null && ipv6) {
|
||||
throw new InvalidParameterValueException("Can only support create Private VLAN network with IPv4!");
|
||||
}
|
||||
|
||||
// Regular user can create Guest Isolated Source Nat enabled network only
|
||||
if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL
|
||||
&& (ntwkOff.getTrafficType() != TrafficType.Guest || ntwkOff.getGuestType() != Network.GuestType.Isolated
|
||||
@ -1175,6 +1184,10 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
|
||||
throw new InvalidParameterValueException("Cannot support IPv6 on network offering with external devices!");
|
||||
}
|
||||
|
||||
if (isolatedPvlan != null && providersConfiguredForExternalNetworking(ntwkProviders)) {
|
||||
throw new InvalidParameterValueException("Cannot support private vlan on network offering with external devices!");
|
||||
}
|
||||
|
||||
if (cidr != null && providersConfiguredForExternalNetworking(ntwkProviders)) {
|
||||
if (ntwkOff.getGuestType() == GuestType.Shared && (zone.getNetworkType() == NetworkType.Advanced) &&
|
||||
isSharedNetworkOfferingWithServices(networkOfferingId)) {
|
||||
@ -1265,8 +1278,9 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
|
||||
throw new InvalidParameterValueException("Internal Lb can be enabled on vpc networks only");
|
||||
}
|
||||
|
||||
network = _networkMgr.createGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId,
|
||||
networkDomain, owner, sharedDomainId, pNtwk, zoneId, aclType, subdomainAccess, vpcId, ip6Gateway, ip6Cidr, displayNetwork);
|
||||
network = _networkMgr.createGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId,
|
||||
networkDomain, owner, sharedDomainId, pNtwk, zoneId, aclType, subdomainAccess, vpcId,
|
||||
ip6Gateway, ip6Cidr, displayNetwork, isolatedPvlan);
|
||||
}
|
||||
|
||||
if (caller.getType() == Account.ACCOUNT_TYPE_ADMIN && createVlan) {
|
||||
@ -3813,8 +3827,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
|
||||
if (privateNetwork == null) {
|
||||
//create Guest network
|
||||
privateNetwork = _networkMgr.createGuestNetwork(ntwkOff.getId(), networkName, displayText, gateway, cidr, vlan,
|
||||
null, owner, null, pNtwk, pNtwk.getDataCenterId(), ACLType.Account, null, vpcId, null, null, true);
|
||||
|
||||
null, owner, null, pNtwk, pNtwk.getDataCenterId(), ACLType.Account, null, vpcId, null, null, true, null);
|
||||
s_logger.debug("Created private network " + privateNetwork);
|
||||
} else {
|
||||
s_logger.debug("Private network already exists: " + privateNetwork);
|
||||
|
||||
@ -30,6 +30,7 @@ import org.apache.cloudstack.api.command.admin.router.CreateVirtualRouterElement
|
||||
import org.apache.cloudstack.api.command.admin.router.ListVirtualRouterElementsCmd;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.agent.api.PvlanSetupCommand;
|
||||
import com.cloud.agent.api.to.LoadBalancerTO;
|
||||
import com.cloud.configuration.ConfigurationManager;
|
||||
import com.cloud.configuration.dao.ConfigurationDao;
|
||||
@ -47,6 +48,7 @@ import com.cloud.network.Network.Capability;
|
||||
import com.cloud.network.Network.Provider;
|
||||
import com.cloud.network.Network.Service;
|
||||
import com.cloud.network.NetworkModel;
|
||||
import com.cloud.network.Networks.BroadcastDomainType;
|
||||
import com.cloud.network.Networks.TrafficType;
|
||||
import com.cloud.network.PhysicalNetworkServiceProvider;
|
||||
import com.cloud.network.PublicIpAddress;
|
||||
@ -228,7 +230,6 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl
|
||||
throw new ResourceUnavailableException("Can't find at least one running router!",
|
||||
DataCenter.class, network.getDataCenterId());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -33,6 +33,7 @@ import com.cloud.user.User;
|
||||
import com.cloud.uservm.UserVm;
|
||||
import com.cloud.utils.component.Manager;
|
||||
import com.cloud.vm.DomainRouterVO;
|
||||
import com.cloud.vm.Nic;
|
||||
import com.cloud.vm.NicProfile;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
|
||||
@ -112,4 +113,4 @@ public interface VirtualNetworkApplianceManager extends Manager, VirtualNetworkA
|
||||
|
||||
boolean removeDhcpSupportForSubnet(Network network, List<DomainRouterVO> routers) throws ResourceUnavailableException;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,6 +34,7 @@ import com.cloud.agent.api.GetDomRVersionCmd;
|
||||
import com.cloud.agent.api.ModifySshKeysCommand;
|
||||
import com.cloud.agent.api.NetworkUsageAnswer;
|
||||
import com.cloud.agent.api.NetworkUsageCommand;
|
||||
import com.cloud.agent.api.PvlanSetupCommand;
|
||||
import com.cloud.agent.api.StartupCommand;
|
||||
import com.cloud.agent.api.StopAnswer;
|
||||
import com.cloud.agent.api.check.CheckSshAnswer;
|
||||
@ -2222,6 +2223,28 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V
|
||||
return dhcpRange;
|
||||
}
|
||||
|
||||
private boolean setupDhcpForPvlan(boolean add, DomainRouterVO router, Nic nic) {
|
||||
if (!nic.getBroadcastUri().getScheme().equals("pvlan")) {
|
||||
return false;
|
||||
}
|
||||
String op = "add";
|
||||
if (!add) {
|
||||
op = "delete";
|
||||
}
|
||||
Network network = _networkDao.findById(nic.getNetworkId());
|
||||
String networkTag = _networkModel.getNetworkTag(router.getHypervisorType(), network);
|
||||
PvlanSetupCommand cmd = PvlanSetupCommand.createDhcpSetup(op, nic.getBroadcastUri(), networkTag, router.getInstanceName(), nic.getMacAddress(), nic.getIp4Address());
|
||||
Commands cmds = new Commands(cmd);
|
||||
// In fact we send command to the host of router, we're not programming router but the host
|
||||
try {
|
||||
sendCommandsToRouter(router, cmds);
|
||||
} catch (AgentUnavailableException e) {
|
||||
s_logger.warn("Agent Unavailable ", e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean finalizeDeployment(Commands cmds, VirtualMachineProfile<DomainRouterVO> profile,
|
||||
DeployDestination dest, ReservationContext context) throws ResourceUnavailableException {
|
||||
@ -2535,13 +2558,20 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V
|
||||
List<Network> guestNetworks = new ArrayList<Network>();
|
||||
|
||||
List<? extends Nic> routerNics = _nicDao.listByVmId(profile.getId());
|
||||
for (Nic routerNic : routerNics) {
|
||||
Network network = _networkModel.getNetwork(routerNic.getNetworkId());
|
||||
for (Nic nic : routerNics) {
|
||||
Network network = _networkModel.getNetwork(nic.getNetworkId());
|
||||
if (network.getTrafficType() == TrafficType.Guest) {
|
||||
guestNetworks.add(network);
|
||||
if (nic.getBroadcastUri().getScheme().equals("pvlan")) {
|
||||
result = setupDhcpForPvlan(true, router, nic);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
answer = cmds.getAnswer("getDomRVersion");
|
||||
if (answer != null && answer instanceof GetDomRVersionAnswer) {
|
||||
GetDomRVersionAnswer versionAnswer = (GetDomRVersionAnswer)answer;
|
||||
@ -2567,6 +2597,14 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V
|
||||
VMInstanceVO vm = profile.getVirtualMachine();
|
||||
DomainRouterVO domR = _routerDao.findById(vm.getId());
|
||||
processStopOrRebootAnswer(domR, answer);
|
||||
List<? extends Nic> routerNics = _nicDao.listByVmId(profile.getId());
|
||||
for (Nic nic : routerNics) {
|
||||
Network network = _networkModel.getNetwork(nic.getNetworkId());
|
||||
if (network.getTrafficType() == TrafficType.Guest && nic.getBroadcastUri().getScheme().equals("pvlan")) {
|
||||
setupDhcpForPvlan(false, domR, nic);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -2025,8 +2025,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
|
||||
|
||||
//2) Create network
|
||||
Network guestNetwork = _ntwkMgr.createGuestNetwork(ntwkOffId, name, displayText, gateway, cidr, vlanId,
|
||||
networkDomain, owner, domainId, pNtwk, zoneId, aclType, subdomainAccess, vpcId, null, null, isDisplayNetworkEnabled);
|
||||
|
||||
networkDomain, owner, domainId, pNtwk, zoneId, aclType, subdomainAccess, vpcId, null, null, isDisplayNetworkEnabled, null);
|
||||
|
||||
if(guestNetwork != null){
|
||||
guestNetwork.setNetworkACLId(aclId);
|
||||
|
||||
@ -69,6 +69,7 @@ import com.cloud.agent.api.GetVmStatsAnswer;
|
||||
import com.cloud.agent.api.GetVmStatsCommand;
|
||||
import com.cloud.agent.api.PlugNicAnswer;
|
||||
import com.cloud.agent.api.PlugNicCommand;
|
||||
import com.cloud.agent.api.PvlanSetupCommand;
|
||||
import com.cloud.agent.api.StartAnswer;
|
||||
import com.cloud.agent.api.StopAnswer;
|
||||
import com.cloud.agent.api.UnPlugNicAnswer;
|
||||
@ -2191,7 +2192,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
||||
s_logger.debug("Creating network for account " + owner + " from the network offering id=" +requiredOfferings.get(0).getId() + " as a part of deployVM process");
|
||||
Network newNetwork = _networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(),
|
||||
owner.getAccountName() + "-network", owner.getAccountName() + "-network", null, null,
|
||||
null, null, owner, null, physicalNetwork, zone.getId(), ACLType.Account, null, null, null, null, true);
|
||||
null, null, owner, null, physicalNetwork, zone.getId(), ACLType.Account, null, null, null, null, true, null);
|
||||
defaultNetwork = _networkDao.findById(newNetwork.getId());
|
||||
} else if (virtualNetworks.size() > 1) {
|
||||
throw new InvalidParameterValueException(
|
||||
@ -2788,6 +2789,37 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean setupVmForPvlan(boolean add, Long hostId, NicVO nic) {
|
||||
if (!nic.getBroadcastUri().getScheme().equals("pvlan")) {
|
||||
return false;
|
||||
}
|
||||
String op = "add";
|
||||
if (!add) {
|
||||
// "delete" would remove all the rules(if using ovs) related to this vm
|
||||
op = "delete";
|
||||
}
|
||||
Network network = _networkDao.findById(nic.getNetworkId());
|
||||
Host host = _hostDao.findById(hostId);
|
||||
String networkTag = _networkModel.getNetworkTag(host.getHypervisorType(), network);
|
||||
PvlanSetupCommand cmd = PvlanSetupCommand.createVmSetup(op, nic.getBroadcastUri(), networkTag, nic.getMacAddress());
|
||||
Answer answer = null;
|
||||
try {
|
||||
answer = _agentMgr.send(hostId, cmd);
|
||||
} catch (OperationTimedoutException e) {
|
||||
s_logger.warn("Timed Out", e);
|
||||
return false;
|
||||
} catch (AgentUnavailableException e) {
|
||||
s_logger.warn("Agent Unavailable ", e);
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean result = true;
|
||||
if (answer == null || !answer.getResult()) {
|
||||
result = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean finalizeDeployment(Commands cmds,
|
||||
VirtualMachineProfile<UserVmVO> profile, DeployDestination dest,
|
||||
@ -2849,6 +2881,11 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
||||
originalIp = nic.getIp4Address();
|
||||
guestNic = nic;
|
||||
guestNetwork = network;
|
||||
if (nic.getBroadcastUri().getScheme().equals("pvlan")) {
|
||||
if (!setupVmForPvlan(true, hostId, nic)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
boolean ipChanged = false;
|
||||
@ -2979,6 +3016,17 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
||||
+ " stop due to exception ", ex);
|
||||
}
|
||||
}
|
||||
|
||||
VMInstanceVO vm = profile.getVirtualMachine();
|
||||
List<NicVO> nics = _nicDao.listByVmId(vm.getId());
|
||||
for (NicVO nic : nics) {
|
||||
NetworkVO network = _networkDao.findById(nic.getNetworkId());
|
||||
if (network.getTrafficType() == TrafficType.Guest) {
|
||||
if (nic.getBroadcastUri().getScheme().equals("pvlan")) {
|
||||
setupVmForPvlan(false, vm.getHostId(), nic);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String generateRandomPassword() {
|
||||
@ -4038,7 +4086,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
||||
requiredOfferings.get(0).getId() + " as a part of deployVM process");
|
||||
Network newNetwork = _networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(),
|
||||
newAccount.getAccountName() + "-network", newAccount.getAccountName() + "-network", null, null,
|
||||
null, null, newAccount, null, physicalNetwork, zone.getId(), ACLType.Account, null, null, null, null, true);
|
||||
null, null, newAccount, null, physicalNetwork, zone.getId(), ACLType.Account, null, null, null, null, true, null);
|
||||
// if the network offering has persistent set to true, implement the network
|
||||
if (requiredOfferings.get(0).getIsPersistent()) {
|
||||
DeployDestination dest = new DeployDestination(zone, null, null, null);
|
||||
|
||||
@ -272,7 +272,7 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkManage
|
||||
|
||||
@Override
|
||||
public Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway, String cidr, String vlanId, String networkDomain, Account owner, Long domainId,
|
||||
PhysicalNetwork physicalNetwork, long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId, String gatewayv6, String cidrv6, Boolean displayNetworkEnabled) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException {
|
||||
PhysicalNetwork physicalNetwork, long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId, String gatewayv6, String cidrv6, Boolean displayNetworkEnabled, String isolatedPvlan) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -868,7 +868,8 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkManage
|
||||
@Override
|
||||
public Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway,
|
||||
String cidr, String vlanId, String networkDomain, Account owner, Long domainId,
|
||||
PhysicalNetwork physicalNetwork, long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId, String gatewayv6, String cidrv6, Boolean displayNetworkEnabled)
|
||||
PhysicalNetwork physicalNetwork, long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId, String gatewayv6, String cidrv6,
|
||||
Boolean displayNetworkEnabled, String isolatedPvlan)
|
||||
throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
|
||||
86
test/integration/smoke/test_pvlan.py
Normal file
86
test/integration/smoke/test_pvlan.py
Normal file
@ -0,0 +1,86 @@
|
||||
# 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.
|
||||
""" test for private vlan isolation
|
||||
"""
|
||||
#Import Local Modules
|
||||
import marvin
|
||||
from marvin.cloudstackTestCase import *
|
||||
from marvin.cloudstackAPI import *
|
||||
from marvin import remoteSSHClient
|
||||
from marvin.integration.lib.utils import *
|
||||
from marvin.integration.lib.base import *
|
||||
from marvin.integration.lib.common import *
|
||||
from nose.plugins.attrib import attr
|
||||
import telnetlib
|
||||
|
||||
#Import System modules
|
||||
import time
|
||||
_multiprocess_shared_ = True
|
||||
|
||||
class TestPVLAN(cloudstackTestCase):
|
||||
|
||||
zoneId = 1
|
||||
networkOfferingId = 7
|
||||
vlan = 1234
|
||||
isolatedpvlan = 567
|
||||
|
||||
def setUp(self):
|
||||
self.apiClient = self.testClient.getApiClient()
|
||||
|
||||
def test_create_pvlan_network(self):
|
||||
self.debug("Test create pvlan network")
|
||||
createNetworkCmd = createNetwork.createNetworkCmd()
|
||||
createNetworkCmd.name = "pvlan network"
|
||||
createNetworkCmd.displaytext = "pvlan network"
|
||||
createNetworkCmd.netmask = "255.255.255.0"
|
||||
createNetworkCmd.gateway = "10.10.10.1"
|
||||
createNetworkCmd.startip = "10.10.10.10"
|
||||
createNetworkCmd.gateway = "10.10.10.20"
|
||||
createNetworkCmd.vlan = "1234"
|
||||
createNetworkCmd.isolatedpvlan = "567"
|
||||
createNetworkCmd.zoneid = self.zoneId
|
||||
createNetworkCmd.networkofferingid = self.networkOfferingId
|
||||
createNetworkResponse = self.apiClient.createNetwork(createNetworkCmd)
|
||||
self.networkId = createNetworkResponse.id
|
||||
self.broadcasttype = createNetworkResponse.broadcastdomaintype
|
||||
self.broadcasturi = createNetworkResponse.broadcasturi
|
||||
|
||||
self.assertIsNotNone(createNetworkResponse.id, "Network failed to create")
|
||||
self.assertTrue(createNetworkResponse.broadcastdomaintype, "Pvlan")
|
||||
self.assertTrue(createNetworkResponse.broadcasturi, "pvlan://1234-i567")
|
||||
|
||||
self.debug("Clean up test pvlan network")
|
||||
deleteNetworkCmd = deleteNetwork.deleteNetworkCmd()
|
||||
deleteNetworkCmd.id = self.networkId;
|
||||
self.apiClient.deleteNetwork(deleteNetworkCmd)
|
||||
|
||||
#Test invalid parameter
|
||||
|
||||
# CLOUDSTACK-2392: Should not allow create pvlan with ipv6
|
||||
createNetworkCmd.ip6gateway="fc00:1234::1"
|
||||
createNetworkCmd.ip6cidr="fc00:1234::/64"
|
||||
createNetworkCmd.startipv6="fc00:1234::10"
|
||||
createNetworkCmd.endipv6="fc00:1234::20"
|
||||
err = 0;
|
||||
try:
|
||||
createNetworkResponse = self.apiClient.createNetwork(createNetworkCmd)
|
||||
except Exception as e:
|
||||
err = 1;
|
||||
self.debug("Try alloc with ipv6, got:%s" % e)
|
||||
self.assertEqual(err, 1, "Shouldn't allow create PVLAN network with IPv6");
|
||||
|
||||
|
||||
@ -1300,6 +1300,7 @@
|
||||
name: { label: 'label.name' },
|
||||
type: { label: 'label.type' },
|
||||
vlan: { label: 'label.vlan.id' },
|
||||
broadcasturi: { label: 'broadcast URI' },
|
||||
cidr: { label: 'IPv4 CIDR' },
|
||||
ip6cidr: { label: 'IPv6 CIDR'}
|
||||
//scope: { label: 'label.scope' }
|
||||
@ -1335,7 +1336,10 @@
|
||||
label: 'label.vlan.id',
|
||||
docID: 'helpGuestNetworkZoneVLANID'
|
||||
},
|
||||
|
||||
isolatedpvlanId: {
|
||||
label: 'Private VLAN ID'
|
||||
},
|
||||
|
||||
scope: {
|
||||
label: 'label.scope',
|
||||
docID: 'helpGuestNetworkZoneScope',
|
||||
@ -1549,11 +1553,15 @@
|
||||
if(this.id == selectedNetworkOfferingId) {
|
||||
if(this.specifyvlan == false) {
|
||||
$form.find('.form-item[rel=vlanId]').hide();
|
||||
cloudStack.dialog.createFormField.validation.required.remove($form.find('.form-item[rel=vlanId]')); //make vlanId optional
|
||||
cloudStack.dialog.createFormField.validation.required.remove($form.find('.form-item[rel=vlanId]')); //make vlanId optional
|
||||
|
||||
$form.find('.form-item[rel=isolatedpvlanId]').hide();
|
||||
}
|
||||
else {
|
||||
$form.find('.form-item[rel=vlanId]').css('display', 'inline-block');
|
||||
cloudStack.dialog.createFormField.validation.required.add($form.find('.form-item[rel=vlanId]')); //make vlanId required
|
||||
cloudStack.dialog.createFormField.validation.required.add($form.find('.form-item[rel=vlanId]')); //make vlanId required
|
||||
|
||||
$form.find('.form-item[rel=isolatedpvlanId]').css('display', 'inline-block');
|
||||
}
|
||||
return false; //break each loop
|
||||
}
|
||||
@ -1639,7 +1647,10 @@
|
||||
|
||||
if(($form.find('.form-item[rel=vlanId]').css("display") != "none") && (args.data.vlanId != null && args.data.vlanId.length > 0))
|
||||
array1.push("&vlan=" + todb(args.data.vlanId));
|
||||
|
||||
|
||||
if(($form.find('.form-item[rel=isolatedpvlanId]').css("display") != "none") && (args.data.isolatedpvlanId != null && args.data.isolatedpvlanId.length > 0))
|
||||
array1.push("&isolatedpvlan=" + todb(args.data.isolatedpvlanId));
|
||||
|
||||
if($form.find('.form-item[rel=domainId]').css("display") != "none") {
|
||||
array1.push("&domainId=" + args.data.domainId);
|
||||
|
||||
@ -2007,6 +2018,7 @@
|
||||
}
|
||||
},
|
||||
vlan: { label: 'label.vlan.id' },
|
||||
broadcasturi: { label: 'broadcast URI' },
|
||||
scope: { label: 'label.scope' },
|
||||
networkofferingdisplaytext: { label: 'label.network.offering' },
|
||||
networkofferingid: {
|
||||
|
||||
@ -24,6 +24,7 @@ import java.net.InetAddress;
|
||||
import java.net.InterfaceAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.SocketException;
|
||||
import java.net.URI;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Formatter;
|
||||
@ -1294,4 +1295,29 @@ public class NetUtils {
|
||||
}
|
||||
return resultIp;
|
||||
}
|
||||
|
||||
public static URI generateUriForPvlan(String primaryVlan, String isolatedPvlan) {
|
||||
return URI.create("pvlan://" + primaryVlan + "-i" + isolatedPvlan);
|
||||
}
|
||||
|
||||
public static String getPrimaryPvlanFromUri(URI uri) {
|
||||
String[] vlans = uri.getHost().split("-");
|
||||
if (vlans.length < 1) {
|
||||
return null;
|
||||
}
|
||||
return vlans[0];
|
||||
}
|
||||
|
||||
public static String getIsolatedPvlanFromUri(URI uri) {
|
||||
String[] vlans = uri.getHost().split("-");
|
||||
if (vlans.length < 2) {
|
||||
return null;
|
||||
}
|
||||
for (String vlan : vlans) {
|
||||
if (vlan.startsWith("i")) {
|
||||
return vlan.replace("i", " ").trim();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
package com.cloud.utils.net;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.net.URI;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
@ -128,4 +129,11 @@ public class NetUtilsTest extends TestCase {
|
||||
assertFalse(NetUtils.isIp6InRange("1234:5678:abcd::1", null));
|
||||
assertTrue(NetUtils.isIp6InRange("1234:5678:abcd::1", "1234:5678::1-1234:5679::1"));
|
||||
}
|
||||
|
||||
public void testPvlan() {
|
||||
URI uri = NetUtils.generateUriForPvlan("123", "456");
|
||||
assertTrue(uri.toString().equals("pvlan://123-i456"));
|
||||
assertTrue(NetUtils.getPrimaryPvlanFromUri(uri).equals("123"));
|
||||
assertTrue(NetUtils.getIsolatedPvlanFromUri(uri).equals("456"));
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user