From 2d87e643710d63c2a6dad90bf4f596e86b4eaf56 Mon Sep 17 00:00:00 2001 From: Anthony Xu Date: Tue, 30 Jul 2013 17:04:21 -0700 Subject: [PATCH] CLOUDSTACK-3963: in security group, CS put a rule in ebtables filter table FORWARD chain to prevent user from changing VM mac address util.pread2(['ebtables', '-A', vm_chain, '-i', vif, '-s', '!', vm_mac, '-j', 'DROP']) if user changes the VM mac address, all egress packet from the VM will be dropped, but the egress packet still contaminate the bridge cache with fake MAC, This patch moves the rule to ebtables nat table PREROUTING chain, then the egress packet with modified MAC will not contaminate the bridge cache. --- .../vm/hypervisor/xenserver/ovs-vif-flows.py | 25 +++++++++++++++---- scripts/vm/hypervisor/xenserver/vmops | 11 +++++++- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/scripts/vm/hypervisor/xenserver/ovs-vif-flows.py b/scripts/vm/hypervisor/xenserver/ovs-vif-flows.py index 46aedc831ee..8452daef147 100644 --- a/scripts/vm/hypervisor/xenserver/ovs-vif-flows.py +++ b/scripts/vm/hypervisor/xenserver/ovs-vif-flows.py @@ -52,19 +52,34 @@ def apply_flows(bridge, this_vif_ofport, vif_ofports): pluginlib.add_flow(bridge, priority=1100, nw_dst='224.0.0.0/24', actions=action) +def clear_rules(vif): + try: + delcmd = "/sbin/ebtables -t nat -L PREROUTING | grep " + vif + delcmds = pluginlib.do_cmd(['/bin/bash', '-c', delcmd]).split('\n') + for cmd in delcmds: + try: + cmd = '/sbin/ebtables -t nat -D PREROUTING ' + cmd + pluginlib.do_cmd(['/bin/bash', '-c', cmd]) + except: + pass + except: + pass + def main(command, vif_raw): if command not in ('online', 'offline'): return - # Make sure the networking stack is not linux bridge! - net_stack = pluginlib.do_cmd(['cat', '/etc/xensource/network.conf']) - if net_stack.lower() == "bridge": - # Nothing to do here! - return vif_name, dom_id, vif_index = vif_raw.split('-') # validate vif and dom-id this_vif = "%s%s.%s" % (vif_name, dom_id, vif_index) + # Make sure the networking stack is not linux bridge! + net_stack = pluginlib.do_cmd(['cat', '/etc/xensource/network.conf']) + if net_stack.lower() == "bridge": + if command == 'offline': + clear_rules(this_vif) + # Nothing to do here! + return bridge = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'iface-to-br', this_vif]) diff --git a/scripts/vm/hypervisor/xenserver/vmops b/scripts/vm/hypervisor/xenserver/vmops index 3b6ff3c97d0..ff33c2d2aa2 100755 --- a/scripts/vm/hypervisor/xenserver/vmops +++ b/scripts/vm/hypervisor/xenserver/vmops @@ -486,6 +486,11 @@ def can_bridge_firewall(session, args): try: util.pread2(['ebtables', '-V']) util.pread2(['ipset', '-V']) + cmd = ['cat', '/etc/xensource/network.conf'] + result = util.pread2(cmd) + if result.lower().strip() != "bridge": + return 'false' + except: return 'false' @@ -749,7 +754,11 @@ def default_ebtables_antispoof_rules(vm_chain, vifs, vm_ip, vm_mac): try: for vif in vifs: # only allow source mac that belongs to the vm - util.pread2(['ebtables', '-A', vm_chain, '-i', vif, '-s', '!', vm_mac, '-j', 'DROP']) + try: + util.pread2(['ebtables', '-t', 'nat', '-I', 'PREROUTING', '-i', vif, '-s', '!' , vm_mac, '-j', 'DROP']) + except: + util.pread2(['ebtables', '-A', vm_chain, '-i', vif, '-s', '!', vm_mac, '-j', 'DROP']) + # do not allow fake dhcp responses util.pread2(['ebtables', '-A', vm_chain, '-i', vif, '-p', 'IPv4', '--ip-proto', 'udp', '--ip-dport', '68', '-j', 'DROP']) # do not allow snooping of dhcp requests