Updated Branches: refs/heads/master be5a7b45f -> 4a9f05bda
CLOUDSTACK-4967 1) vxlan will use bridge scheme 'brvx-<vni>'. Multiple physical networks can host guest traffic type with vxlan isolation, so long as they don't use the same VNI range. 2) Guest traffic labels can be physical interface if bridge by given name is not found. Normally we take traffic label name, find the matching bridge, then resolve that to a physical interface. Then we create guest bridges on that interface. Now we can just specify the interface. Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/4a9f05bd Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/4a9f05bd Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/4a9f05bd Branch: refs/heads/master Commit: 4a9f05bda075d03c4a5a015e081c70b3d8b72267 Parents: be5a7b4 Author: Marcus Sorensen <mar...@betterservers.com> Authored: Tue Oct 29 15:32:45 2013 -0600 Committer: Marcus Sorensen <mar...@betterservers.com> Committed: Tue Oct 29 15:34:39 2013 -0600 ---------------------------------------------------------------------- .../kvm/resource/BridgeVifDriver.java | 29 ++++++++++++++++---- .../kvm/resource/LibvirtComputingResource.java | 27 ++++++++++++++---- scripts/vm/network/vnet/modifyvxlan.sh | 28 +++++++++++-------- .../com/cloud/network/NetworkServiceImpl.java | 14 ++++++++++ 4 files changed, 76 insertions(+), 22 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4a9f05bd/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java ---------------------------------------------------------------------- diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java index f945b74..84743ec 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java @@ -110,10 +110,10 @@ public class BridgeVifDriver extends VifDriverBase { || nic.getBroadcastType() == Networks.BroadcastDomainType.Vxlan) { if(trafficLabel != null && !trafficLabel.isEmpty()) { s_logger.debug("creating a vNet dev and bridge for guest traffic per traffic label " + trafficLabel); - String brName = createVnetBr(vNetId, _pifs.get(trafficLabel), protocol); + String brName = createVnetBr(vNetId, trafficLabel, protocol); intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType), networkRateKBps); } else { - String brName = createVnetBr(vNetId, _pifs.get("private"), protocol); + String brName = createVnetBr(vNetId, "private", protocol); intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType), networkRateKBps); } } else { @@ -129,10 +129,10 @@ public class BridgeVifDriver extends VifDriverBase { && !vNetId.equalsIgnoreCase("untagged")) { if(trafficLabel != null && !trafficLabel.isEmpty()){ s_logger.debug("creating a vNet dev and bridge for public traffic per traffic label " + trafficLabel); - String brName = createVnetBr(vNetId, _pifs.get(trafficLabel), protocol); + String brName = createVnetBr(vNetId, trafficLabel, protocol); intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType), networkRateKBps); } else { - String brName = createVnetBr(vNetId, _pifs.get("public"), protocol); + String brName = createVnetBr(vNetId, "public", protocol); intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType), networkRateKBps); } } else { @@ -157,9 +157,26 @@ public class BridgeVifDriver extends VifDriverBase { return "br" + pifName + "-"+ vnetId; } - private String createVnetBr(String vNetId, String nic, String protocol) + private String setVxnetBrName(String pifName, String vnetId) { + return "brvx-" + vnetId; + } + + private String createVnetBr(String vNetId, String pifKey, String protocol) throws InternalErrorException { - String brName = setVnetBrName(nic, vNetId); + String nic = _pifs.get(pifKey); + if (nic == null) { + // if not found in bridge map, maybe traffic label refers to pif already? + File pif = new File("/sys/class/net/" + pifKey); + if (pif.isDirectory()){ + nic = pifKey; + } + } + String brName = ""; + if (protocol.equals(Networks.BroadcastDomainType.Vxlan.scheme())) { + brName = setVxnetBrName(nic, vNetId); + } else { + brName = setVnetBrName(nic, vNetId); + } createVnet(vNetId, nic, brName, protocol); return brName; } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4a9f05bd/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java ---------------------------------------------------------------------- diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java index 286d0f7..8d3a0e9 100755 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java @@ -986,6 +986,18 @@ ServerResource { } _pifs.put(bridge, pif); } + + // guest(private) creates bridges on a pif, if private bridge not found try pif direct + // This addresses the unnecessary requirement of someone to create an unused bridge just for traffic label + if (_pifs.get("private") == null) { + s_logger.debug("guest(private) traffic label '" + _guestBridgeName+ "' not found as bridge, looking for physical interface"); + File dev = new File("/sys/class/net/" + _guestBridgeName); + if (dev.exists()) { + s_logger.debug("guest(private) traffic label '" + _guestBridgeName + "' found as a physical device"); + _pifs.put("private", _guestBridgeName); + } + } + s_logger.debug("done looking for pifs, no more bridges"); } @@ -1023,16 +1035,21 @@ ServerResource { } private String matchPifFileInDirectory(String bridgeName){ - File f = new File("/sys/devices/virtual/net/" + bridgeName + "/brif"); + File brif = new File("/sys/devices/virtual/net/" + bridgeName + "/brif"); - if (! f.isDirectory()){ + if (! brif.isDirectory()){ + File pif = new File("/sys/class/net/" + bridgeName); + if (pif.isDirectory()) { + // if bridgeName already refers to a pif, return it as-is + return bridgeName; + } s_logger.debug("failing to get physical interface from bridge " - + bridgeName + ", does " + f.getAbsolutePath() + + bridgeName + ", does " + brif.getAbsolutePath() + "exist?"); return ""; } - File[] interfaces = f.listFiles(); + File[] interfaces = brif.listFiles(); for (int i = 0; i < interfaces.length; i++) { String fname = interfaces[i].getName(); @@ -1046,7 +1063,7 @@ ServerResource { s_logger.debug("failing to get physical interface from bridge " + bridgeName + ", did not find an eth*, bond*, vlan*, em*, or p*p* in " - + f.getAbsolutePath()); + + brif.getAbsolutePath()); return ""; } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4a9f05bd/scripts/vm/network/vnet/modifyvxlan.sh ---------------------------------------------------------------------- diff --git a/scripts/vm/network/vnet/modifyvxlan.sh b/scripts/vm/network/vnet/modifyvxlan.sh index a3ec71f..f7d08f1 100755 --- a/scripts/vm/network/vnet/modifyvxlan.sh +++ b/scripts/vm/network/vnet/modifyvxlan.sh @@ -39,18 +39,24 @@ addVxlan() { 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 + if [ -d "/sys/class/net/${pif}" ] + then + # if bridge is not found, but matches a pif, use it + brif=$pif + else + printf "Failed to lookup bridge interface which includes pif: $pif." + return 1 + fi + else + # 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 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" http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4a9f05bd/server/src/com/cloud/network/NetworkServiceImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java b/server/src/com/cloud/network/NetworkServiceImpl.java index cf419f3..70f0d5a 100755 --- a/server/src/com/cloud/network/NetworkServiceImpl.java +++ b/server/src/com/cloud/network/NetworkServiceImpl.java @@ -2694,6 +2694,20 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { } else if (network.getIsolationMethods().contains("VXLAN")) { minVnet = MIN_VXLAN_VNI; maxVnet = MAX_VXLAN_VNI; + // fail if zone already contains VNI, need to be unique per zone. + // since adding a range adds each VNI to the database, need only check min/max + for(String vnet : VnetRange) { + s_logger.debug("Looking to see if VNI " + vnet + " already exists on another network in zone " + network.getDataCenterId()); + List<DataCenterVnetVO> vnis = _datacneter_vnet.findVnet(network.getDataCenterId(), vnet); + if (vnis != null && ! vnis.isEmpty()) { + for (DataCenterVnetVO vni : vnis) { + if (vni.getPhysicalNetworkId() != network.getId()) { + s_logger.debug("VNI " + vnet + " already exists on another network in zone, please specify a unique range"); + throw new InvalidParameterValueException("VNI " + vnet + " already exists on another network in zone, please specify a unique range"); + } + } + } + } } String rangeMessage = " between " + minVnet + " and " + maxVnet; if (VnetRange.length == 1 && VnetRange[0].equals("")) {