CLOUDSTACK-4405: additional patch for bridge name and firewall rules issues after KVM upgrade to 4.2
There still exist two issues after Edison's commits. (1) Migration from new hosts to old hosts failed. The bridge name on old host is set to cloudVirBr* if network.bridge.name.schema is set to 3.0 in /etc/cloudstack/agent/agent.properties, but the actual bridge name is breth*-* after running cloudstack-agent-upgrade. (2) all ports of vms (Basic zone, or Advanced zone with security groups) on old hosts are open, because the iptables rules are binding to device (bridge) name which is changed by cloudstack-agent-upgrade. After this, the KVM upgrade steps : a. Install 4.2 cloudstack agent on each kvm host b. Run "cloudstack-agent-upgrade". This script will upgrade all the existing bridge name to new bridge name, and update related firewall rules. c. install a libvirt hook: c1. mkdir /etc/libvirt/hooks c2. cp /usr/share/cloudstack-agent/lib/libvirtqemuhook /etc/libvirt/hooks/qemu c3. chmod +x /etc/libvirt/hooks/qemu c4. service libvirtd restart c5. service cloudstack-agent restart Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/175549f3 Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/175549f3 Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/175549f3 Branch: refs/heads/4.2 Commit: 175549f3ab952bbd39318c16c269c16526255475 Parents: 4280f6e Author: Wei Zhou <w.z...@leaseweb.com> Authored: Tue Sep 24 08:51:58 2013 +0200 Committer: Wei Zhou <w.z...@leaseweb.com> Committed: Tue Sep 24 08:51:58 2013 +0200 ---------------------------------------------------------------------- agent/bindir/cloudstack-agent-upgrade.in | 13 +++++++++++++ .../hypervisor/kvm/resource/BridgeVifDriver.java | 16 +--------------- scripts/vm/network/security_group.py | 19 +++++++++++++------ 3 files changed, 27 insertions(+), 21 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/175549f3/agent/bindir/cloudstack-agent-upgrade.in ---------------------------------------------------------------------- diff --git a/agent/bindir/cloudstack-agent-upgrade.in b/agent/bindir/cloudstack-agent-upgrade.in index 4972d39..72b0fae 100644 --- a/agent/bindir/cloudstack-agent-upgrade.in +++ b/agent/bindir/cloudstack-agent-upgrade.in @@ -17,6 +17,8 @@ # under the License. from cloudutils.networkConfig import networkConfig from cloudutils.utilities import bash +import logging +import re def isOldStyleBridge(brName): if brName.find("cloudVirBr") == 0: return True @@ -33,6 +35,17 @@ def upgradeBridgeName(brName, enslavedDev): bash("ip link set %s down"%brName) bash("ip link set %s name %s"%(brName, newBrName)) bash("ip link set %s up" %newBrName) + cmd = "iptables-save | grep FORWARD | grep -w " + brName + rules = bash(cmd).stdout.split('\n') + rules.pop() + for rule in rules: + try: + delrule = re.sub("-A", "-D", rule) + newrule = re.sub(" " + brName + " ", " " + newBrName + " ", rule) + bash("iptables " + delrule) + bash("iptables " + newrule) + except: + logging.exception("Ignoring failure to update rules for rule " + rule + " on bridge " + brName) if __name__ == '__main__': netlib = networkConfig() bridges = netlib.listNetworks() http://git-wip-us.apache.org/repos/asf/cloudstack/blob/175549f3/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 e3779a7..42b2df2 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 @@ -45,7 +45,6 @@ public class BridgeVifDriver extends VifDriverBase { private static final Object _vnetBridgeMonitor = new Object(); private String _modifyVlanPath; - private String bridgeNameSchema; @Override public void configure(Map<String, Object> params) throws ConfigurationException { @@ -61,8 +60,6 @@ public class BridgeVifDriver extends VifDriverBase { networkScriptsDir = "scripts/vm/network/vnet"; } - bridgeNameSchema = (String) params.get("network.bridge.name.schema"); - String value = (String) params.get("scripts.timeout"); _timeout = NumbersUtil.parseInt(value, 30 * 60) * 1000; @@ -147,18 +144,7 @@ public class BridgeVifDriver extends VifDriverBase { } private String setVnetBrName(String pifName, String vnetId) { - String brName = null; - if (bridgeNameSchema != null) { - if (bridgeNameSchema.equalsIgnoreCase("3.0")) { - brName = "cloudVirBr" + vnetId; - } else if (bridgeNameSchema.equalsIgnoreCase("4.0")) { - brName = "br" + pifName + "-"+ vnetId; - } - } else { - brName = "br" + pifName + "-"+ vnetId; - } - - return brName; + return "br" + pifName + "-"+ vnetId; } private String createVlanBr(String vlanId, String nic) http://git-wip-us.apache.org/repos/asf/cloudstack/blob/175549f3/scripts/vm/network/security_group.py ---------------------------------------------------------------------- diff --git a/scripts/vm/network/security_group.py b/scripts/vm/network/security_group.py index 0ac8b74..674cceb 100755 --- a/scripts/vm/network/security_group.py +++ b/scripts/vm/network/security_group.py @@ -250,7 +250,7 @@ def default_network_rules_systemvm(vm_name, localbrname): if bridge != localbrname: if not addFWFramework(bridge): return False - brfw = "BF-" + bridge + brfw = getBrfw(bridge) vifs = getVifsForBridge(vm_name, bridge) for vif in vifs: try: @@ -356,7 +356,7 @@ def default_network_rules(vm_name, vm_id, vm_ip, vm_mac, vif, brname, sec_ips): return False vmName = vm_name - brfw = "BF-" + brname + brfw = getBrfw(brname) domID = getvmId(vm_name) delete_rules_for_vm_in_bridge_firewall_chain(vmName) vmchain = vm_name @@ -549,7 +549,7 @@ def network_rules_for_rebooted_vm(vmName): if brName is None or brName is "": brName = "cloudbr0" else: - brName = re.sub("^BF-", "", brName) + brName = execute("iptables-save |grep physdev-is-bridged |grep FORWARD |grep BF |grep '\-o' |awk '{print $4}' | head -1").strip() if 1 in [ vm_name.startswith(c) for c in ['r-', 's-', 'v-'] ]: @@ -562,8 +562,8 @@ def network_rules_for_rebooted_vm(vmName): vifs = getVifs(vmName) logging.debug(vifs, brName) for v in vifs: - execute("iptables -A " + "BF-" + brName + "-IN " + " -m physdev --physdev-is-bridged --physdev-in " + v + " -j "+ vmchain_default) - execute("iptables -A " + "BF-" + brName + "-OUT " + " -m physdev --physdev-is-bridged --physdev-out " + v + " -j "+ vmchain_default) + execute("iptables -A " + getBrfw(brName) + "-IN " + " -m physdev --physdev-is-bridged --physdev-in " + v + " -j "+ vmchain_default) + execute("iptables -A " + getBrfw(brName) + "-OUT " + " -m physdev --physdev-is-bridged --physdev-out " + v + " -j "+ vmchain_default) #change antispoof rule in vmchain try: @@ -871,6 +871,13 @@ def getBridges(vmName): def getvmId(vmName): cmd = "virsh list |grep " + vmName + " | awk '{print $1}'" return bash("-c", cmd).stdout.strip() + +def getBrfw(brname): + cmd = "iptables-save |grep physdev-is-bridged |grep FORWARD |grep BF |grep '\-o' | grep -w " + brname + "|awk '{print $9}' | head -1" + brfwname = bash("-c", cmd).stdout.strip() + if brfwname == "": + brfwname = "BF-" + brname + return brfwname def addFWFramework(brname): try: @@ -885,7 +892,7 @@ def addFWFramework(brname): logging.debug("failed to turn on bridge netfilter") return False - brfw = "BF-" + brname + brfw = getBrfw(brname) try: execute("iptables -L " + brfw) except: