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 f945b74f709..84743ec124e 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; } 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 286d0f7c20b..8d3a0e9cdf1 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 ""; } diff --git a/scripts/vm/network/vnet/modifyvxlan.sh b/scripts/vm/network/vnet/modifyvxlan.sh index a3ec71fa91f..f7d08f1d8c4 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 + 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 - - # 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" diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java b/server/src/com/cloud/network/NetworkServiceImpl.java index cf419f37ad1..70f0d5a1182 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 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("")) {