You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by mu...@apache.org on 2014/05/02 15:24:35 UTC

git commit: updated refs/heads/master to 9e98cbf

Repository: cloudstack
Updated Branches:
  refs/heads/master 5bc72ea25 -> 9e98cbf1c


CLOUDSTACK-6564: OVS distributed routing: use file based OF rule updates

use ovs-ofctl replace flows by file name option to update the OF rules
instead of sequenetially configuring the rules.


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/9e98cbf1
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/9e98cbf1
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/9e98cbf1

Branch: refs/heads/master
Commit: 9e98cbf1c1c5371e02f0325dba841532ddad116d
Parents: 5bc72ea
Author: Murali Reddy <mu...@gmail.com>
Authored: Fri May 2 18:51:28 2014 +0530
Committer: Murali Reddy <mu...@gmail.com>
Committed: Fri May 2 18:54:30 2014 +0530

----------------------------------------------------------------------
 .../xenserver/cloudstack_pluginlib.py           | 339 +++++++++++--------
 scripts/vm/hypervisor/xenserver/ovstunnel       |  32 +-
 2 files changed, 218 insertions(+), 153 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/9e98cbf1/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py b/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py
index bcb9540..bccb7ae 100644
--- a/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py
+++ b/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py
@@ -39,6 +39,23 @@ VSCTL_PATH = "/usr/bin/ovs-vsctl"
 OFCTL_PATH = "/usr/bin/ovs-ofctl"
 XE_PATH = "/opt/xensource/bin/xe"
 
+# OpenFlow tables set in a pipeline processing fashion for the bridge created for a VPC's that are enabled for
+# distributed routing.
+# L2 path (intra-tier traffic)  CLASSIFIER-> L2 lookup -> L2 flooding tables
+# L3 path (inter-tier traffic)  CLASSIFIER-> EGRESS ACL -> L3 lookup -> INGRESS ACL-> L2 lookup -> L2 flooding tables
+
+# Classifier table has the rules to separate broadcast/multi-cast traffic, inter-tier traffic, intra-tier traffic
+CLASSIFIER_TABLE=0
+# Lookup table to determine the output port (vif/tunnel port) based on the MAC address
+L2_LOOKUP_TABLE=1
+# flooding table has the rules to flood on ports (both VIF, tunnel ports) except on the port on which packet arrived
+L2_FLOOD_TABLE=2
+# table has flow rules derived from egress ACL's
+EGRESS_ACL_TABLE=3
+# Lookup table to determine the output port (vif/tunnel port) based on the IP address
+L3_LOOKUP_TABLE=4
+# table has flow rules derived from egress ACL's
+INGRESS_ACL_TABLE=5
 
 class PluginError(Exception):
     """Base Exception class for all plugin errors."""
@@ -179,9 +196,10 @@ def _build_flow_expr(**kwargs):
     nw_src = 'nw_src' in kwargs and ",nw_src=%s" % kwargs['nw_src'] or ''
     nw_dst = 'nw_dst' in kwargs and ",nw_dst=%s" % kwargs['nw_dst'] or ''
     table = 'table' in kwargs and ",table=%s" % kwargs['table'] or ''
+    cookie = 'cookie' in kwargs and ",cookie=%s" % kwargs['cookie'] or ''
     proto = 'proto' in kwargs and ",%s" % kwargs['proto'] or ''
     ip = ('nw_src' in kwargs or 'nw_dst' in kwargs) and ',ip' or ''
-    flow = (flow + in_port + dl_type + dl_src + dl_dst +
+    flow = (flow + cookie+ in_port + dl_type + dl_src + dl_dst +
             (ip or proto) + nw_src + nw_dst + table)
     return flow
 
@@ -236,11 +254,14 @@ def get_network_id_for_tunnel_port(tunnelif_name):
     return vnet
 
 def clear_flooding_rules_for_port(bridge, ofport):
-        del_flows(bridge, in_port=ofport, table=2)
+        del_flows(bridge, in_port=ofport, table=L2_FLOOD_TABLE)
+
+def clear_flooding_rules_for_all_ports(bridge):
+        del_flows(bridge, cookie=111, table=L2_FLOOD_TABLE)
 
 def add_flooding_rules_for_port(bridge, in_ofport, out_ofports):
         action = "".join("output:%s," %ofport for ofport in out_ofports)[:-1]
-        add_flow(bridge, priority=1100, in_port=in_ofport, table=2, actions=action)
+        add_flow(bridge, cookie=111, priority=1100, in_port=in_ofport, table=L2_FLOOD_TABLE, actions=action)
 
 def get_ofport_for_vif(vif_name):
     return do_cmd([VSCTL_PATH, "get", "interface", vif_name, "ofport"])
@@ -261,18 +282,18 @@ def get_vif_name_from_macaddress(macaddress):
 
 def add_mac_lookup_table_entry(bridge, mac_address, out_of_port):
     action = "output=%s" %out_of_port
-    add_flow(bridge, priority=1100, dl_dst=mac_address, table=1, actions=action)
+    add_flow(bridge, priority=1100, dl_dst=mac_address, table=L2_LOOKUP_TABLE, actions=action)
 
 def delete_mac_lookup_table_entry(bridge, mac_address):
-    del_flows(bridge, dl_dst=mac_address, table=1)
+    del_flows(bridge, dl_dst=mac_address, table=L2_LOOKUP_TABLE)
 
 def add_ip_lookup_table_entry(bridge, ip, dst_tier_gateway_mac, dst_vm_mac):
-    action_str = "mod_dl_src:%s" % dst_tier_gateway_mac + ",mod_dl_dst:%s" % dst_vm_mac + ",resubmit(,5)"
-    action_str = "table=4, ip, nw_dst=%s" % ip + ",  actions=%s" %action_str
+    action_str = "mod_dl_src:%s" % dst_tier_gateway_mac + ",mod_dl_dst:%s" % dst_vm_mac + ",resubmit(,%s)"%INGRESS_ACL_TABLE
+    action_str = "table=%s"%L3_LOOKUP_TABLE + ", ip, nw_dst=%s" % ip + ",  actions=%s" %action_str
     addflow = [OFCTL_PATH, "add-flow", bridge, action_str]
     do_cmd(addflow)
 
-def get_vms_on_host(vpc, host_id):
+def get_vpc_vms_on_host(vpc, host_id):
     all_vms = vpc.vms
     vms_on_host = []
     for vm in all_vms:
@@ -314,43 +335,64 @@ class jsonLoader(object):
   def __str__(self):
         return '{%s}' % str(', '.join('%s : %s' % (k, repr(v)) for (k, v)
                                       in self.__dict__.iteritems()))
+def get_acl(vpcconfig, required_acl_id):
+    acls = vpcconfig.acls
+    for acl in acls:
+        if acl.id == required_acl_id:
+            return acl
+    return None
 
+# Configures the bridge created for a VPC enabled for distributed routing. Management server sends VPC physical topology
+# details. Based on the VPC physical topology L2 lookup table and L3 lookup tables are updated by this function.
 def configure_bridge_for_network_topology(bridge, this_host_id, json_config, sequence_no):
-    vpconfig = jsonLoader(json.loads(json_config)).vpc
 
+    vpconfig = jsonLoader(json.loads(json_config)).vpc
     if vpconfig is None:
-        logging.debug("WARNING:Can't find VPC info in json config file")
+        logging.debug("WARNING:Can't find VPC topology information in the json configuration file")
         return "FAILURE:IMPROPER_JSON_CONFG_FILE"
 
     try:
-        # get the list of Vm's in the VPC from the JSON config
-        this_host_vms = get_vms_on_host(vpconfig, this_host_id)
+        if not os.path.exists('/var/run/cloud'):
+            os.makedirs('/var/run/cloud')
+
+        # create a temporary file to store OpenFlow rules corresponding to L2 and L3 lookup table updates
+        ofspec_filename = "/var/run/cloud/" + bridge + sequence_no + ".ofspec"
+        ofspec = open(ofspec_filename, 'w')
+
+        # get the list of VM's in all the tiers of VPC running in this host from the JSON config
+        this_host_vms = get_vpc_vms_on_host(vpconfig, this_host_id)
 
         for vm in this_host_vms:
             for nic in vm.nics:
                 mac_addr = nic.macaddress
                 ip = nic.ipaddress
                 vif_name = get_vif_name_from_macaddress(mac_addr)
-                of_port = get_ofport_for_vif(vif_name)
-                network = get_network_details(vpconfig, nic.networkuuid)
-
-                # Add flow rule in L2 look up table, if the destination mac = MAC of the nic send packet on the found OFPORT
-                add_mac_lookup_table_entry(bridge, mac_addr, of_port)
-
-                # Add flow rule in L3 look up table: if the destination IP = VM's IP then modify the packet
-                # to set DST MAC = VM's MAC, SRC MAC=tier gateway MAC and send to egress table
-                add_ip_lookup_table_entry(bridge, ip, network.gatewaymac, mac_addr)
-
-                # Add flow entry to send with intra tier traffic from the NIC to L2 lookup path)
-                action_str = "table=0, in_port=%s," %of_port + " ip, nw_dst=%s," %network.cidr + " actions=resubmit(,1)"
-                addflow = [OFCTL_PATH, "add-flow", bridge, action_str]
-                do_cmd(addflow)
-
-                #add flow entry to send inter-tier traffic from the NIC to egress ACL table(to L3 lookup path)
-                action_str = "table=0, in_port=%s," % of_port + " ip, dl_dst=%s," %network.gatewaymac +\
-                             "nw_dst=%s," %vpconfig.cidr + "actions=resubmit(,3)"
-                addflow = [OFCTL_PATH, "add-flow", bridge, action_str]
-                do_cmd(addflow)
+                of_port  = get_ofport_for_vif(vif_name)
+                network  = get_network_details(vpconfig, nic.networkuuid)
+
+                # Add OF rule in L2 look up table, if packet's destination mac matches MAC of the VM's nic
+                # then send packet on the found OFPORT
+                ofspec.write(" table=%s" %L2_LOOKUP_TABLE + " priority=1100 dl_dst=%s " %mac_addr +
+                             " actions=output:%s" %of_port + "\n")
+
+                # Add OF rule in L3 look up table: if packet's destination IP matches VM's IP then modify the packet
+                # to set DST MAC = VM's MAC, SRC MAC= destination tier gateway MAC and send to egress table. This step
+                # emulates steps VPC virtual router would have done on the current host itself.
+                action_str = " mod_dl_src:%s"%network.gatewaymac + ",mod_dl_dst:%s" % mac_addr \
+                             + ",resubmit(,%s)"%INGRESS_ACL_TABLE
+                action_str = " table=%s"%L3_LOOKUP_TABLE + " ip nw_dst=%s"%ip + " actions=%s" %action_str
+                ofspec.write(action_str + "\n")
+
+                # Add OF rule to send intra-tier traffic from this nic of the VM to L2 lookup path (L2 switching)
+                action_str = " table=%s" %CLASSIFIER_TABLE + " priority=1200 in_port=%s " %of_port + \
+                             " ip nw_dst=%s " %network.cidr + " actions=resubmit(,%s)" %L2_LOOKUP_TABLE
+                ofspec.write(action_str + "\n")
+
+                # Add OF rule to send inter-tier traffic from this nic of the VM to egress ACL table(L3 lookup path)
+                action_str = " table=%s "%CLASSIFIER_TABLE + " priority=1100 in_port=%s " %of_port +\
+                             " ip dl_dst=%s " %network.gatewaymac + " nw_dst=%s " %vpconfig.cidr + \
+                             " actions=resubmit(,%s)" %EGRESS_ACL_TABLE
+                ofspec.write(action_str + "\n")
 
         # get the list of hosts on which VPC spans from the JSON config
         vpc_spanning_hosts = vpconfig.hosts
@@ -358,7 +400,9 @@ def configure_bridge_for_network_topology(bridge, this_host_id, json_config, seq
         for host in vpc_spanning_hosts:
             if str(this_host_id) == str(host.hostid):
                 continue
-            other_host_vms = get_vms_on_host(vpconfig, str(host.hostid))
+
+            other_host_vms = get_vpc_vms_on_host(vpconfig, str(host.hostid))
+
             for vm in other_host_vms:
                 for nic in vm.nics:
                     mac_addr = nic.macaddress
@@ -366,40 +410,65 @@ def configure_bridge_for_network_topology(bridge, this_host_id, json_config, seq
                     network = get_network_details(vpconfig, nic.networkuuid)
                     gre_key = network.grekey
 
-                    # generate tunnel name from tunnel naming convention
+                    # generate tunnel name as per the tunnel naming convention and get the OF port
                     tunnel_name = "t%s-%s-%s" % (gre_key, this_host_id, host.hostid)
                     of_port = get_ofport_for_vif(tunnel_name)
 
-                    # Add flow rule in L2 look up table, if the destination mac = MAC of the nic send packet tunnel port
-                    add_mac_lookup_table_entry(bridge, mac_addr, of_port)
+                    # Add flow rule in L2 look up table, if packet's destination mac matches MAC of the VM's nic
+                    # on the remote host then send packet on the found OFPORT corresponding to the tunnel
+                    ofspec.write("table=%s" %L2_LOOKUP_TABLE + " priority=1100 dl_dst=%s " %mac_addr +
+                                 " actions=output:%s" %of_port + "\n")
+
+                    # Add flow rule in L3 look up table. if packet's destination IP matches VM's IP then modify the
+                    # packet to set DST MAC = VM's MAC, SRC MAC=tier gateway MAC and send to ingress table. This step
+                    # emulates steps VPC virtual router would have done on the current host itself.
+                    action_str = "mod_dl_src:%s"%network.gatewaymac + ",mod_dl_dst:%s" % mac_addr + \
+                                 ",resubmit(,%s)"%INGRESS_ACL_TABLE
+                    action_str = "table=%s"%L3_LOOKUP_TABLE + " ip nw_dst=%s"%ip + " actions=%s" %action_str
+                    ofspec.write(action_str + "\n")
+
+        action_str = "table=%s "%L2_LOOKUP_TABLE + " priority=0 " + " actions=resubmit(,%s)"%L2_FLOOD_TABLE
+        ofspec.write(action_str + "\n")
+        action_str = "table=%s "%L3_LOOKUP_TABLE + " priority=0 " + " actions=resubmit(,%s)"%L2_LOOKUP_TABLE
+        ofspec.write(action_str + "\n")
+
+        del_flows(bridge, table=L2_LOOKUP_TABLE)
+        del_flows(bridge, table=L3_LOOKUP_TABLE)
 
-                    # Add flow tule in L3 look up table: if the destination IP = VM's IP then modify the packet
-                    # set DST MAC = VM's MAC, SRC MAC=tier gateway MAC and send to egress table
-                    add_ip_lookup_table_entry(bridge, ip, network.gatewaymac, mac_addr)
+        # update bridge with the flow-rules added in the file in one attempt
+        do_cmd([OFCTL_PATH, 'add-flows', bridge, ofspec_filename])
+
+        ofspec.close()
+        return "SUCCESS: successfully configured bridge as per the VPC topology update with sequence no: %s"%sequence_no
 
-        return "SUCCESS: successfully configured bridge as per the VPC topology"
     except:
-        logging.debug("An unexpected error occurred while configuring bridge as per VPC topology.")
+        logging.debug("An unexpected error occurred while configuring bridge as per VPC topology "
+                      "update with sequence no: %s"%sequence_no)
+        # now that we updated the bridge with flow rules delete the file.
+        os.remove(ofspec_filename)
         raise
 
-def get_acl(vpcconfig, required_acl_id):
-    acls = vpcconfig.acls
-    for acl in acls:
-        if acl.id == required_acl_id:
-            return acl
-    return None
+    else:
+        # now that we updated the bridge with flow rules delete the file.
+        os.remove(ofspec_filename)
 
+# Configures the bridge created for a VPC enabled for distributed firewall. Management server sends VPC routing policies
+# details. Based on the VPC routing policies ingress ACL table and egress ACL tables are updated by this function.
 def configure_ovs_bridge_for_routing_policies(bridge, json_config, sequence_no):
-    vpconfig = jsonLoader(json.loads(json_config)).vpc
 
+    vpconfig = jsonLoader(json.loads(json_config)).vpc
     if vpconfig is None:
-        logging.debug("WARNING:Can't find VPC info in json config file")
+        logging.debug("WARNING: Can't find VPC routing policies info in json config file")
         return "FAILURE:IMPROPER_JSON_CONFG_FILE"
 
     try:
-        # First flush current ingress and egress ACL's before re-applying the ACL's
-        del_flows(bridge, table=3)
-        del_flows(bridge, table=5)
+
+        if not os.path.exists('/var/run/cloud'):
+            os.makedirs('/var/run/cloud')
+
+        # create a temporary file to store OpenFlow rules corresponding to ingress and egress ACL table updates
+        ofspec_filename = "/var/run/cloud/" + bridge + sequence_no + ".ofspec"
+        ofspec = open(ofspec_filename, 'w')
 
         egress_rules_added = False
         ingress_rules_added = False
@@ -419,99 +488,92 @@ def configure_ovs_bridge_for_routing_policies(bridge, json_config, sequence_no):
                 protocol = acl_item.protocol
                 source_cidrs = acl_item.sourcecidrs
                 acl_priority = 1000 + number
+                if direction == "ingress":
+                    matching_table = INGRESS_ACL_TABLE
+                    resubmit_table = L2_LOOKUP_TABLE
+                elif direction == "egress":
+                    matching_table = EGRESS_ACL_TABLE
+                    resubmit_table = L3_LOOKUP_TABLE
+
                 for source_cidr in source_cidrs:
-                    if direction == "ingress":
-                        ingress_rules_added = True
-                        if source_port_start is None and source_port_end is None:
-                            if source_cidr.startswith('0.0.0.0'):
-                                if action == "deny":
-                                    add_flow(bridge, priority= acl_priority, table=5, nw_dst=tier_cidr,
-                                         nw_proto=protocol, actions='drop')
-                                if action == "allow":
-                                    add_flow(bridge, priority= acl_priority,table=5, nw_dst=tier_cidr,
-                                         nw_proto=protocol, actions='resubmit(,1)')
-                            else:
-                                if action == "deny":
-                                    add_flow(bridge, priority= acl_priority, table=5, nw_src=source_cidr, nw_dst=tier_cidr,
-                                         nw_proto=protocol, actions='drop')
-                                if action == "allow":
-                                    add_flow(bridge, priority= acl_priority,table=5, nw_src=source_cidr, nw_dst=tier_cidr,
-                                         nw_proto=protocol, actions='resubmit(,1)')
-                            continue
-
-                        # add flow rule to do action (allow/deny) for flows where source IP of the packet is in
-                        # source_cidr and destination ip is in tier_cidr
-                        port = source_port_start
-                        while (port < source_port_end):
-                            if source_cidr.startswith('0.0.0.0'):
-                                if action == "deny":
-                                    add_flow(bridge, priority= acl_priority, table=5, nw_dst=tier_cidr, tp_dst=port,
-                                         nw_proto=protocol, actions='drop')
-                                if action == "allow":
-                                    add_flow(bridge, priority= acl_priority,table=5, nw_dst=tier_cidr, tp_dst=port,
-                                         nw_proto=protocol, actions='resubmit(,1)')
-                            else:
-                                if action == "deny":
-                                    add_flow(bridge, priority= acl_priority, table=5, nw_src=source_cidr, nw_dst=tier_cidr, tp_dst=port,
-                                         nw_proto=protocol, actions='drop')
-                                if action == "allow":
-                                    add_flow(bridge, priority= acl_priority,table=5, nw_src=source_cidr, nw_dst=tier_cidr, tp_dst=port,
-                                         nw_proto=protocol, actions='resubmit(,1)')
-                            port = port + 1
-
-                    elif direction == "egress":
-                        egress_rules_added = True
-                        if source_port_start is None and source_port_end is None:
-                            if source_cidr.startswith('0.0.0.0'):
-                                if action == "deny":
-                                    add_flow(bridge, priority= acl_priority, table=3, nw_dst=tier_cidr,
-                                         nw_proto=protocol, actions='drop')
-                                if action == "allow":
-                                    add_flow(bridge, priority= acl_priority,table=3, nw_dst=tier_cidr,
-                                         nw_proto=protocol, actions='resubmit(,4)')
-                            else:
-                                if action == "deny":
-                                    add_flow(bridge, priority= acl_priority, table=3, nw_src=source_cidr, nw_dst=tier_cidr,
-                                         nw_proto=protocol, actions='drop')
-                                if action == "allow":
-                                    add_flow(bridge, priority= acl_priority,table=3, nw_src=source_cidr, nw_dst=tier_cidr,
-                                         nw_proto=protocol, actions='resubmit(,4)')
-                            continue
-
-                        # add flow rule to do action (allow/deny) for flows where destination IP of the packet is in
-                        # source_cidr and source ip is in tier_cidr
-                        port = source_port_start
-                        while (port < source_port_end):
-                            if source_cidr.startswith('0.0.0.0'):
-                                if action == "deny":
-                                    add_flow(bridge, priority= acl_priority, table=3, nw_dst=source_cidr, tp_dst=port,
-                                             nw_proto=protocol, actions='drop')
-                                if action == "allow":
-                                    add_flow(bridge, priority= acl_priority, table=3, nw_dst=source_cidr, tp_dst=port,
-                                             nw_proto=protocol, actions='resubmit(,4)')
-                            else:
-                                if action == "deny":
-                                    add_flow(bridge, priority= acl_priority, table=3, nw_src=tier_cidr, nw_dst=source_cidr, tp_dst=port,
-                                             nw_proto=protocol, actions='drop')
-                                if action == "allow":
-                                    add_flow(bridge, priority= acl_priority, table=3, nw_src=tier_cidr, nw_dst=source_cidr, tp_dst=port,
-                                             nw_proto=protocol, actions='resubmit(,4)')
-                            port = port + 1
-
-        if egress_rules_added is False:
-            # add a default rule in egress table to forward packet to L3 lookup table
-            add_flow(bridge, priority=0, table=3, actions='resubmit(,4)')
-
-        if ingress_rules_added is False:
-            # add a default rule in ingress table drop packets
-            add_flow(bridge, priority=0, table=5, actions='drop')
+                    ingress_rules_added = True
+                    if source_port_start is None and source_port_end is None:
+                        if source_cidr.startswith('0.0.0.0'):
+                            if action == "deny":
+                                ofspec.write(" table=%s "%matching_table + " priority=%s " %acl_priority +
+                                             " nw_dst=%s " %tier_cidr + " nw_proto=%s " %protocol +
+                                             " actions='drop'" + "\n")
+                            if action == "allow":
+                                ofspec.write(" table=%s "%matching_table + " priority=%s " %acl_priority +
+                                             " nw_dst=%s " %tier_cidr + " nw_proto=%s " %protocol +
+                                             " actions='resubmit(,%s)'"%resubmit_table + "\n")
+
+                        else:
+                            if action == "deny":
+                                ofspec.write(" table=%s "%matching_table + " priority=%s " %acl_priority +
+                                             " nw_src=%s " %source_cidr + " nw_dst=%s " %tier_cidr +
+                                             " nw_proto=%s " %protocol + " actions='drop'" + "\n")
+                            if action == "allow":
+                                ofspec.write(" table=%s "%matching_table + " priority=%s " %acl_priority +
+                                             " nw_src=%s "%source_cidr + " nw_dst=%s " %tier_cidr +
+                                             " nw_proto=%s " %protocol +
+                                             " actions='resubmit(,%s)'"%resubmit_table  + "\n")
+                        continue
+
+                    # add flow rule to do action (allow/deny) for flows where source IP of the packet is in
+                    # source_cidr and destination ip is in tier_cidr
+                    port = source_port_start
+                    while (port < source_port_end):
+                        if source_cidr.startswith('0.0.0.0'):
+                            if action == "deny":
+                                ofspec.write(" table=%s " %matching_table + " priority=%s " %acl_priority +
+                                             " tp_dst=%s " %port + " nw_dst=%s " %tier_cidr +
+                                             " nw_proto=%s " %protocol + " actions='drop'"  + "\n")
+                            if action == "allow":
+                                ofspec.write(" table=%s "%matching_table + " priority=%s " %acl_priority +
+                                             " tp_dst=%s " %port + " nw_dst=%s " %tier_cidr +
+                                             " nw_proto=%s " %protocol +
+                                             " actions='resubmit(,%s)'"%resubmit_table  + "\n")
+                        else:
+                            if action == "deny":
+                                ofspec.write(" table=%s " %matching_table + " priority=%s " %acl_priority +
+                                             " tp_dst=%s " %port + " nw_src=%s "%source_cidr + " nw_dst=%s "%tier_cidr +
+                                             " nw_proto=%s " %protocol + " actions='drop'"  + "\n")
+                            if action == "allow":
+                                ofspec.write(" table=%s "%matching_table + " priority=%s " %acl_priority +
+                                             " tp_dst=%s " %port + " nw_src=%s "%source_cidr + " nw_dst=%s "%tier_cidr +
+                                             " nw_proto=%s " %protocol +
+                                             " actions='resubmit(,%s)'"%resubmit_table + "\n")
+                        port = port + 1
+
+        # add a default rule in egress table to allow packets (so forward packet to L3 lookup table)
+        ofspec.write(" table=%s " %EGRESS_ACL_TABLE + " priority=0 actions='resubmit(,%s)')"%L3_LOOKUP_TABLE + "\n")
+
+        # add a default rule in ingress table drop packets
+        ofspec.write(" table=%s " %INGRESS_ACL_TABLE + " priority=0 actions='drop'" + "\n")
+
+        # First flush current ingress and egress ACL's before re-applying the ACL's
+        del_flows(bridge, table=EGRESS_ACL_TABLE)
+        del_flows(bridge, table=INGRESS_ACL_TABLE)
+
+        # update bridge with the flow-rules for ingress and egress ACL's added in the file in one attempt
+        do_cmd([OFCTL_PATH, 'add-flows', bridge, ofspec_filename])
 
+        ofspec.close()
         return "SUCCESS: successfully configured bridge as per the latest routing policies of the VPC"
 
     except:
         logging.debug("An unexpected error occurred while configuring bridge as per VPC's routing policies.")
+        # now that we updated the bridge with flow rules delete the file.
+        ofspec.close()
+        os.remove(ofspec_filename)
         raise
 
+    else:
+        # now that we updated the bridge with flow rules delete the file.
+        ofspec.close()
+        os.remove(ofspec_filename)
+
 def update_flooding_rules_on_port_plug_unplug(bridge, interface, command, if_network_id):
 
     vnet_vif_ofports = []
@@ -540,7 +602,6 @@ def update_flooding_rules_on_port_plug_unplug(bridge, interface, command, if_net
                 vnet_all_ofports.append(if_ofport)
 
         if command == 'online':
-
             if len(vnet_all_ofports) == 1 :
                 return
 
@@ -582,7 +643,7 @@ def update_flooding_rules_on_port_plug_unplug(bridge, interface, command, if_net
                 vnet_all_ofports_copy.remove(port)
                 add_flooding_rules_for_port(bridge, port, vnet_all_ofports_copy)
 
-            #un-learn that MAC is reachable through the VIF port
+            # un-learn that MAC is reachable through the VIF port
             if interface.startswith('vif'):
                 mac = get_macaddress_of_vif(interface)
                 delete_mac_lookup_table_entry(bridge, mac)

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/9e98cbf1/scripts/vm/hypervisor/xenserver/ovstunnel
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/xenserver/ovstunnel b/scripts/vm/hypervisor/xenserver/ovstunnel
index db3216b..2d6105e 100755
--- a/scripts/vm/hypervisor/xenserver/ovstunnel
+++ b/scripts/vm/hypervisor/xenserver/ovstunnel
@@ -37,7 +37,6 @@ from time import localtime as _localtime, asctime as _asctime
 xePath = "/opt/xensource/bin/xe"
 lib.setup_logging("/var/log/cloud/ovstunnel.log")
 
-
 def block_ipv6_v5(bridge):
     lib.add_flow(bridge, priority=65000, dl_type='0x86dd', actions='drop')
 
@@ -124,6 +123,7 @@ def setup_ovs_bridge(session, args):
     logging.debug("Setup_ovs_bridge completed with result:%s" % result)
     return result
 
+
 @echo
 def setup_ovs_bridge_for_distributed_routing(session, args):
     bridge = args.pop("bridge")
@@ -165,30 +165,32 @@ def setup_ovs_bridge_for_distributed_routing(session, args):
         lib.do_cmd([lib.XE_PATH, "network-param-set", "uuid=%s" % xs_nw_uuid,
                    "other-config:ovs-host-setup=%s" % conf_hosts])
 
-        # first clear the default rule (i.e rule for NORMAL processing)
+        # first clear the default rule (rule for 'NORMAL' processing which makes a bridge simple L2 learn & flood switch)
         lib.del_flows(bridge, table=0)
 
         # add a default flow rule to send broadcast and multi-cast packets to L2 flooding table
-        lib.add_flow(bridge, priority=1200, dl_dst='ff:ff:ff:ff:ff:ff', table=0, actions='resubmit(,2)')
-        lib.add_flow(bridge, priority=1200, nw_dst='224.0.0.0/24', table=0, actions='resubmit(,2)')
+        lib.add_flow(bridge, priority=1200, dl_dst='ff:ff:ff:ff:ff:ff', table=lib.CLASSIFIER_TABLE,
+                     actions='resubmit(,%s)'%lib.L2_FLOOD_TABLE)
+        lib.add_flow(bridge, priority=1200, nw_dst='224.0.0.0/24', table=lib.CLASSIFIER_TABLE,
+                     actions='resubmit(,%s)'%lib.L2_FLOOD_TABLE)
 
         # add a default flow rule to send uni-cast traffic to L2 lookup table
-        lib.add_flow(bridge, priority=0, table=0, actions='resubmit(,1)')
+        lib.add_flow(bridge, priority=0, table=lib.CLASSIFIER_TABLE, actions='resubmit(,%s)'%lib.L2_LOOKUP_TABLE)
 
         # add a default rule to send unknown mac address to L2 flooding table
-        lib.add_flow(bridge, priority=0, table=1, actions='resubmit(,2)')
+        lib.add_flow(bridge, priority=0, table=lib.L2_LOOKUP_TABLE, actions='resubmit(,%s)'%lib.L2_FLOOD_TABLE)
 
         # add a default rule in L2 flood table to drop packet
-        lib.add_flow(bridge, priority=0, table=2, actions='drop')
+        lib.add_flow(bridge, priority=0, table=lib.L2_FLOOD_TABLE, actions='drop')
 
         # add a default rule in egress ACL table to forward packet to L3 lookup table
-        lib.add_flow(bridge, priority=0, table=3, actions='resubmit(,4)')
+        lib.add_flow(bridge, priority=0, table=lib.EGRESS_ACL_TABLE, actions='resubmit(,%s)'%lib.L3_LOOKUP_TABLE)
 
         # add a default rule in L3 lookup table to forward packet to L2 lookup table
-        lib.add_flow(bridge, priority=0, table=4, actions='resubmit(,1)')
+        lib.add_flow(bridge, priority=0, table=lib.L3_LOOKUP_TABLE, actions='resubmit(,%s)'%lib.L2_LOOKUP_TABLE)
 
         # add a default rule in ingress table to drop in bound packets
-        lib.add_flow(bridge, priority=0, table=5, actions='drop')
+        lib.add_flow(bridge, priority=0, table=lib.INGRESS_ACL_TABLE, actions='drop')
 
         # initialize the sequence number for the bridge
         lib.do_cmd([lib.VSCTL_PATH, "set", "bridge", bridge, "other-config:sequence-number=0"])
@@ -414,11 +416,12 @@ def configure_ovs_bridge_for_network_topology(session, args):
     # get the last update sequence number
     last_seq_no = lib.do_cmd([lib.VSCTL_PATH, "get", "bridge", bridge, "other-config:sequence-number"])
     last_seq_no = last_seq_no[1:-1]
-    if sequence_no > last_seq_no:
+    if long(sequence_no) > long(last_seq_no):
         lib.do_cmd([lib.VSCTL_PATH, "set", "bridge", bridge, "other-config:sequence-number=%s"%sequence_no])
         return lib.configure_bridge_for_network_topology(bridge, this_host_id, json_config, sequence_no)
     else:
-        return "SUCCESS: Ignoring the update as there is already recent update received and applied"
+        return "SUCCESS: Ignoring the update with the sequence number %s" %sequence_no + " as there is already recent" \
+                " update received and applied with sequence number %s" %last_seq_no
 
 
 @echo
@@ -429,11 +432,12 @@ def configure_ovs_bridge_for_routing_policies(session, args):
     # get the last update sequence number
     last_seq_no = lib.do_cmd([lib.VSCTL_PATH, "get", "bridge", bridge, "other-config:sequence-number"])
     last_seq_no = last_seq_no[1:-1]
-    if sequence_no > last_seq_no:
+    if long(sequence_no) > long(last_seq_no):
         lib.do_cmd([lib.VSCTL_PATH, "set", "bridge", bridge, "other-config:sequence-number=%s"%sequence_no])
         return lib.configure_ovs_bridge_for_routing_policies(bridge, json_config, sequence_no)
     else:
-        return "SUCCESS: Ignoring the update as there is already recent update received and applied"
+        return "SUCCESS: Ignoring the update with the sequence number %s" %sequence_no + " as there is already recent" \
+                " update received and applied with sequence number %s" %last_seq_no
 
 if __name__ == "__main__":
     XenAPIPlugin.dispatch({"create_tunnel": create_tunnel,