Updated Branches: refs/heads/master de13b097a -> 915babd97
fix kvm traffic labels (guest traffic types on multiple networks don't work) Cloudstack seems to let you create guest traffic types on multiple physical networks. However, when I try this with KVM I end up always bridging to whatever device is used for guest.network.device. This pulls the traffic label (NicTO.getName()) and uses that bridge to ensure that we get on the correct physical network, rather than just always using the guest.network.device. This also changes the bridge naming scheme from cloudVirBr + vlanid to br + physicalinterface + "-" + vlanid. This is because we should be able to support the same vlan numbers per physical network, and the previous bridge name would not support this and collide. Signed-off-by: Edison Su <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/commit/915babd9 Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/915babd9 Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/915babd9 Branch: refs/heads/master Commit: 915babd970a9b4f209deceb3c4973b7d1c9c0c12 Parents: de13b09 Author: Marcus Sorensen <[email protected]> Authored: Wed Sep 26 17:14:57 2012 -0700 Committer: Edison Su <[email protected]> Committed: Wed Sep 26 17:14:57 2012 -0700 ---------------------------------------------------------------------- .../hypervisor/kvm/resource/BridgeVifDriver.java | 41 ++++++++-- .../kvm/resource/LibvirtComputingResource.java | 61 +++++++++------ scripts/vm/network/vnet/modifyvlan.sh | 31 +++----- 3 files changed, 79 insertions(+), 54 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/915babd9/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 cf4de09..116c09d 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 @@ -85,11 +85,18 @@ public class BridgeVifDriver extends VifDriverBase { URI broadcastUri = nic.getBroadcastUri(); vlanId = broadcastUri.getHost(); } + String trafficLabel = nic.getName(); if (nic.getType() == Networks.TrafficType.Guest) { if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan && !vlanId.equalsIgnoreCase("untagged")) { - String brName = createVlanBr(vlanId, _pifs.get("private")); - intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType)); + 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)); + intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType)); + } else { + String brName = createVlanBr(vlanId, _pifs.get("private")); + intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType)); + } } else { intf.defBridgeNet(_bridges.get("guest"), null, nic.getMac(), getGuestNicModel(guestOsType)); } @@ -100,8 +107,14 @@ public class BridgeVifDriver extends VifDriverBase { } else if (nic.getType() == Networks.TrafficType.Public) { if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan && !vlanId.equalsIgnoreCase("untagged")) { - String brName = createVlanBr(vlanId, _pifs.get("public")); - intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType)); + 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)); + intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType)); + } else { + String brName = createVlanBr(vlanId, _pifs.get("public")); + intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType)); + } } else { intf.defBridgeNet(_bridges.get("public"), null, nic.getMac(), getGuestNicModel(guestOsType)); } @@ -120,22 +133,32 @@ public class BridgeVifDriver extends VifDriverBase { // Nothing needed as libvirt cleans up tap interface from bridge. } - private String setVnetBrName(String vnetId) { - return "cloudVirBr" + vnetId; + private String setVnetBrName(String pifName, String vnetId) { + String brName = "br" + pifName + "-"+ vnetId; + String oldStyleBrName = "cloudVirBr" + vnetId; + + 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"); + brName = oldStyleBrName; + } + + return brName; } private String createVlanBr(String vlanId, String nic) throws InternalErrorException { - String brName = setVnetBrName(vlanId); - createVnet(vlanId, nic); + String brName = setVnetBrName(nic, vlanId); + createVnet(vlanId, nic, brName); return brName; } - private void createVnet(String vnetId, String pif) + private void createVnet(String vnetId, String pif, String brName) throws InternalErrorException { final Script command = new Script(_modifyVlanPath, _timeout, s_logger); command.add("-v", vnetId); command.add("-p", pif); + command.add("-b", brName); command.add("-o", "add"); final String result = command.execute(); http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/915babd9/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 22b149f..f6a6494 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 @@ -44,6 +44,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; +import java.util.regex.Pattern; +import java.util.regex.Matcher; import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; @@ -777,32 +779,32 @@ public class LibvirtComputingResource extends ServerResourceBase implements } private void getPifs() { - /* get pifs from bridge */ - String pubPif = null; - String privPif = null; - String vlan = null; - if (_publicBridgeName != null) { - pubPif = Script.runSimpleBashScript("brctl show | grep " - + _publicBridgeName + " | awk '{print $4}'"); - vlan = Script.runSimpleBashScript("ls /proc/net/vlan/" + pubPif); - if (vlan != null && !vlan.isEmpty()) { - pubPif = Script - .runSimpleBashScript("grep ^Device\\: /proc/net/vlan/" - + pubPif + " | awk {'print $2'}"); + /* gather all available bridges and find their pifs, so that we can match them against traffic labels later */ + String cmdout = Script.runSimpleBashScript("brctl show | tail -n +2 | grep -v \"^\\s\"|awk '{print $1}'|sed '{:q;N;s/\\n/%/g;t q}'"); + s_logger.debug("cmdout was " + cmdout); + List<String> bridges = Arrays.asList(cmdout.split("%")); + for (String bridge : bridges) { + s_logger.debug("looking for pif for bridge " + bridge); + String pif = getPif(bridge); + if(_publicBridgeName != null && bridge.equals(_publicBridgeName)){ + _pifs.put("public", pif); + } else if (_guestBridgeName != null) { + _pifs.put("private", pif); } + _pifs.put(bridge, pif); } - if (_guestBridgeName != null) { - privPif = Script.runSimpleBashScript("brctl show | grep " - + _guestBridgeName + " | awk '{print $4}'"); - vlan = Script.runSimpleBashScript("ls /proc/net/vlan/" + privPif); - if (vlan != null && !vlan.isEmpty()) { - privPif = Script - .runSimpleBashScript("grep ^Device\\: /proc/net/vlan/" - + privPif + " | awk {'print $2'}"); - } + s_logger.debug("done looking for pifs, no more bridges"); + } + + private String getPif(String bridge) { + String pif = Script.runSimpleBashScript("brctl show | grep " + bridge + " | awk '{print $4}'"); + String vlan = Script.runSimpleBashScript("ls /proc/net/vlan/" + pif); + + if (vlan != null && !vlan.isEmpty()) { + pif = Script.runSimpleBashScript("grep ^Device\\: /proc/net/vlan/" + pif + " | awk {'print $2'}"); } - _pifs.put("private", privPif); - _pifs.put("public", pubPif); + + return pif; } private boolean checkNetwork(String networkName) { @@ -3914,7 +3916,18 @@ public class LibvirtComputingResource extends ServerResourceBase implements } private String getVnetIdFromBrName(String vnetBrName) { - return vnetBrName.replaceAll("cloudVirBr", ""); + if (vnetBrName.contains("cloudVirBr")) { + return vnetBrName.replaceAll("cloudVirBr", ""); + } else { + Pattern r = Pattern.compile("-(\\d+)$"); + Matcher m = r.matcher(vnetBrName); + if(m.group(1) != null || !m.group(1).isEmpty()) { + return m.group(1); + } else { + s_logger.debug("unable to get a vlan ID from name " + vnetBrName); + return ""; + } + } } private void cleanupVMNetworks(Connect conn, List<InterfaceDef> nics) { http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/915babd9/scripts/vm/network/vnet/modifyvlan.sh ---------------------------------------------------------------------- diff --git a/scripts/vm/network/vnet/modifyvlan.sh b/scripts/vm/network/vnet/modifyvlan.sh index 33d697a..5577825 100755 --- a/scripts/vm/network/vnet/modifyvlan.sh +++ b/scripts/vm/network/vnet/modifyvlan.sh @@ -22,15 +22,14 @@ # set -x usage() { - printf "Usage: %s: -o <op>(add | delete) -v <vlan id> -p <pif> \n" + printf "Usage: %s: -o <op>(add | delete) -v <vlan id> -p <pif> -b <bridge name>\n" } -VIRBR=cloudVirBr addVlan() { local vlanId=$1 local pif=$2 local vlanDev=$pif.$vlanId - local vlanBr=$VIRBR$vlanId + local vlanBr=$3 vconfig set_name_type DEV_PLUS_VID_NO_PAD @@ -99,7 +98,7 @@ deleteVlan() { local vlanId=$1 local pif=$2 local vlanDev=$pif.$vlanId - local vlanBr=$VIRBR$vlanId + local vlanBr=$3 vconfig rem $vlanDev > /dev/null @@ -132,7 +131,7 @@ op= vlanId= option=$@ -while getopts 'o:v:p:' OPTION +while getopts 'o:v:p:b:' OPTION do case $OPTION in o) oflag=1 @@ -144,6 +143,9 @@ do p) pflag=1 pif="$OPTARG" ;; + b) bflag=1 + brName="$OPTARG" + ;; ?) usage exit 2 ;; @@ -151,7 +153,7 @@ do done # Check that all arguments were passed in -if [ "$oflag$vflag$pflag" != "111" ] +if [ "$oflag$vflag$pflag$bflag" != "1111" ] then usage exit 2 @@ -167,7 +169,7 @@ fi if [ "$op" == "add" ] then # Add the vlan - addVlan $vlanId $pif + addVlan $vlanId $pif $brName # If the add fails then return failure if [ $? -gt 0 ] @@ -178,22 +180,9 @@ else if [ "$op" == "delete" ] then # Delete the vlan - deleteVlan $vlanId $pif + deleteVlan $vlanId $pif $brName # Always exit with success exit 0 fi fi - - - - - - - - - - - - -
