--- /opt/xensource/libexec/setup-vif-rules.orig	2013-01-22 14:31:37.000000000 -0500
+++ /opt/xensource/libexec/setup-vif-rules	2013-02-06 18:45:25.000000000 -0500
@@ -68,11 +68,13 @@
 
 def get_locking_config(domid, devid):
     mac = xenstore_read("/local/domain/0/backend/vif/%s/%s/mac" % (domid, devid))
-    private_path = "/xapi/%s/private/vif/%s" % (domid, devid)
+    private_path = "/local/domain/%s/vm-data/networking/%s" % (domid, mac.replace(':', ''))
     locking_mode = xenstore_read("/".join([private_path, "locking-mode"]))
     ipv4_allowed = xenstore_read("/".join([private_path, "ipv4-allowed"]))
     ipv6_allowed = xenstore_read("/".join([private_path, "ipv6-allowed"]))
-    send_to_syslog("Got locking config: MAC=%s; locking_mode=%s; ipv4_allowed=%s; ipv6_allowed=%s"
+    if not locking_mode:
+      locking_mode = 'unlocked'
+    send_to_syslog("Got locking config: MAC=%s; locking_mode=%s; ipv4_allowed=%s; ipv6_allowed=%s;"
                     % (mac, locking_mode, ipv4_allowed, ipv6_allowed))
     return {
         "mac": mac,
@@ -171,10 +173,12 @@
 ###############################################################################
 
 def get_vswitch_port(vif_name):
+    send_to_syslog("Getting vswitch port for VIF [%s]" % (vif_name))
     (rc, stdout, stderr) = doexec([vsctl, "get", "interface", vif_name, "ofport"])
     return stdout.readline().strip()
 
 def clear_vswitch_rules(bridge_name, port):
+    send_to_syslog("Clearing rules on bridge %s port %s" % (bridge_name, port))
     doexec([ofctl, "del-flows", bridge_name, "in_port=%s" % port])
 
 def add_flow(bridge_name, args):
@@ -182,6 +186,7 @@
 
 def create_vswitch_rules(bridge_name, port, config):
     mac = config["mac"]
+    locking_mode = config["locking_mode"]
     ipv4_allowed = config["ipv4_allowed"]
     ipv6_allowed = config["ipv6_allowed"]
     # Allow DHCP traffic (outgoing UDP on port 67).
@@ -194,9 +199,15 @@
         # Filter ARP responses.
         add_flow(bridge_name, "in_port=%s,priority=7000,dl_type=0x0806,dl_src=%s,arp_sha=%s,"
                               "nw_src=%s,idle_timeout=0,action=normal" % (port, mac, mac, ipv4))
-        # Allow traffic from specified ipv4 addresses.
-        add_flow(bridge_name, "in_port=%s,priority=6000,dl_type=0x0800,nw_src=%s,"
-                              "dl_src=%s,idle_timeout=0,action=normal" % (port, ipv4, mac))
+        
+        if locking_mode == "isolated":
+        	# Allow traffic ONLY to specified ipv4 addresses.
+        	add_flow(bridge_name, "in_port=%s,priority=6000,dl_type=0x0800,nw_dst=%s,"
+                              	"dl_src=%s,idle_timeout=0,action=normal" % (port, ipv4, mac))
+        else:
+        	# Allow ALL traffic from specified ipv4 addresses.
+        	add_flow(bridge_name, "in_port=%s,priority=6000,dl_type=0x0800,nw_src=%s,"
+                              	"dl_src=%s,idle_timeout=0,action=normal" % (port, ipv4, mac))
     for ipv6 in ipv6_allowed:
         # Neighbour solicitation.
         add_flow(bridge_name, "in_port=%s,priority=8000,dl_src=%s,icmp6,ipv6_src=%s,"
@@ -205,9 +216,16 @@
         add_flow(bridge_name, "in_port=%s,priority=8000,dl_src=%s,icmp6,ipv6_src=%s,"
                               "icmp_type=136,nd_target=%s,idle_timeout=0,action=normal" % (port, mac, ipv6, ipv6))
         # Allow traffic from specified ipv6 addresses.
-        add_flow(bridge_name, "in_port=%s,priority=5000,dl_src=%s,ipv6_src=%s,icmp6,action=normal" % (port, mac, ipv6))
-        add_flow(bridge_name, "in_port=%s,priority=5000,dl_src=%s,ipv6_src=%s,tcp6,action=normal" % (port, mac, ipv6))
-        add_flow(bridge_name, "in_port=%s,priority=5000,dl_src=%s,ipv6_src=%s,udp6,action=normal" % (port, mac, ipv6))
+        if locking_mode == "isolated":
+        	# Allow traffic ONLY to specified ipv6 addresses.
+        	add_flow(bridge_name, "in_port=%s,priority=5000,dl_dst=%s,ipv6_src=%s,icmp6,action=normal" % (port, mac, ipv6))
+        	add_flow(bridge_name, "in_port=%s,priority=5000,dl_dst=%s,ipv6_src=%s,tcp6,action=normal" % (port, mac, ipv6))
+        	add_flow(bridge_name, "in_port=%s,priority=5000,dl_dst=%s,ipv6_src=%s,udp6,action=normal" % (port, mac, ipv6))
+        else:
+        	# Allow ALL traffic from specified ipv4 addresses.
+        	add_flow(bridge_name, "in_port=%s,priority=5000,dl_src=%s,ipv6_src=%s,icmp6,action=normal" % (port, mac, ipv6))
+        	add_flow(bridge_name, "in_port=%s,priority=5000,dl_src=%s,ipv6_src=%s,tcp6,action=normal" % (port, mac, ipv6))
+        	add_flow(bridge_name, "in_port=%s,priority=5000,dl_src=%s,ipv6_src=%s,udp6,action=normal" % (port, mac, ipv6))
     # Drop all other neighbour discovery.
     add_flow(bridge_name, "in_port=%s,priority=7000,icmp6,icmp_type=135,action=drop" % port)
     add_flow(bridge_name, "in_port=%s,priority=7000,icmp6,icmp_type=136,action=drop" % port)
@@ -229,19 +247,29 @@
     # Drop everything else.
     add_flow(bridge_name, "in_port=%s,priority=4000,idle_timeout=0,action=drop" % port)
 
+def get_bridge_name_vswitch(vif_name):
+    '''return bridge vif belong to'''
+    (rc, stdout, stderr) = doexec([vsctl, "iface-to-br",  vif_name ])
+    fake_bridge = stdout.readline().strip()
+    (rc, stdout, stderr) = doexec([vsctl, "br-to-parent",  fake_bridge ])
+    real_bridge = stdout.readline().strip()
+    send_to_syslog("Get bridge name vswitch reports: fake bridge = %s / real bridge = %s" % (fake_bridge, real_bridge))
+    return real_bridge
+
+
 def handle_vswitch(vif_type, domid, devid, action):
-    if (action == "clear") or (action == "filter"):
-        bridge_name = "xenbr%s" % devid
+    if action in ["clear", "filter"]:
         vif_name = "%s%s.%s" % (vif_type, domid, devid)
-        ip_link_set(vif_name, "down")
+        bridge_name = get_bridge_name_vswitch(vif_name)
         port = get_vswitch_port(vif_name)
+        ip_link_set(vif_name, "down")
         clear_vswitch_rules(bridge_name, port)
         if action == "filter":
             config = get_locking_config(domid, devid)
             locking_mode = config["locking_mode"]
-            if locking_mode == "locked":
+            if locking_mode in ["locked", "isolated"]:
                 create_vswitch_rules(bridge_name, port, config)
-            if locking_mode in ["locked", "unlocked"]:
+            if locking_mode in ["locked", "unlocked","isolated"]:
                 ip_link_set(vif_name, "up")
         if action == "clear":
             ip_link_set(vif_name, "up")
